From 12a0200eae15615cf81caa3be8febda00c968919 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 23 Feb 2008 21:56:27 +0000 Subject: fixed tests --- .../nsc/symtab/classfile/ClassfileParser.scala | 109 ++++++++++++--------- .../scala/tools/nsc/typechecker/RefChecks.scala | 3 +- .../scala/tools/nsc/typechecker/Typers.scala | 10 +- 3 files changed, 73 insertions(+), 49 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 5bff9d070f..991808bad0 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -472,51 +472,62 @@ abstract class ClassfileParser { case SHORT_TAG => definitions.ShortClass.tpe case VOID_TAG => definitions.UnitClass.tpe case BOOL_TAG => definitions.BooleanClass.tpe - case 'L' => { - val classSym = classNameToSymbol(subName(c => c == ';' || c == '<')) - assert(!classSym.hasFlag(OVERLOADED), classSym.alternatives) - val existentials = new ListBuffer[Symbol]() - val tpe: Type = if (sig(index) == '<') { - accept('<') - val xs = new ListBuffer[Type]() - var i = 0 - while (sig(index) != '>') { - sig(index) match { - case variance @ ('+' | '-' | '*') => - index += 1 - val bounds = variance match { - case '+' => mkTypeBounds(definitions.AllClass.tpe, - sig2type(tparams)) - case '-' => mkTypeBounds(sig2type(tparams), - definitions.AnyClass.tpe) - case '*' => mkTypeBounds(definitions.AllClass.tpe, - definitions.AnyClass.tpe) - } - val newtparam = makeExistential("?"+i, sym, bounds) - existentials += newtparam - xs += newtparam.tpe - i += 1 - case _ => - xs += sig2type(tparams) + case 'L' => + def processClassType(tp: Type): Type = { + val classSym = tp.typeSymbol + val existentials = new ListBuffer[Symbol]() + if (sig(index) == '<') { + accept('<') + val xs = new ListBuffer[Type]() + var i = 0 + while (sig(index) != '>') { + sig(index) match { + case variance @ ('+' | '-' | '*') => + index += 1 + val bounds = variance match { + case '+' => mkTypeBounds(definitions.AllClass.tpe, + sig2type(tparams)) + case '-' => mkTypeBounds(sig2type(tparams), + definitions.AnyClass.tpe) + case '*' => mkTypeBounds(definitions.AllClass.tpe, + definitions.AnyClass.tpe) + } + val newtparam = makeExistential("?"+i, sym, bounds) + existentials += newtparam + xs += newtparam.tpe + i += 1 + case _ => + xs += sig2type(tparams) + } } + accept('>') + assert(xs.length > 0) + existentialAbstraction(existentials.toList, + appliedType(tp, xs.toList)) + } else if (classSym.isMonomorphicType) { + tp + } else { + // raw type - existentially quantify all type parameters + val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams) + val t = appliedType(classSym.typeConstructor, eparams.map(_.tpe)) + val res = existentialAbstraction(eparams, t) + if (settings.debug.value && settings.verbose.value) println("raw type " + classSym + " -> " + res) + res } - accept('>') - assert(xs.length > 0) - existentialAbstraction(existentials.toList, - appliedType(classSym.tpe, xs.toList)) } - else if (classSym.isMonomorphicType) classSym.tpe - else { - // raw type - existentially quantify all type parameters - val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams) - val t = appliedType(classSym.typeConstructor, eparams.map(_.tpe)) - val res = existentialAbstraction(eparams, t) - if (settings.debug.value && settings.verbose.value) println("raw type " + classSym + " -> " + res) - res + val classSym = classNameToSymbol(subName(c => c == ';' || c == '<')) + assert(!classSym.hasFlag(OVERLOADED), classSym.alternatives) + var tpe = processClassType(classSym.tpe) + while (sig(index) == '.') { + accept('.') + val name = subName(c => c == ';' || c == '.').toTypeName + val clazz = tpe.typeSymbol.info.member(name) + assert(clazz.isClass, + tpe.typeSymbol.linkedModuleOfClass.moduleClass.info+" "+tpe+" . "+name+"/"+tpe.typeSymbol.info.decls) + tpe = processClassType(clazz.tpe) } accept(';') tpe - } case ARRAY_TAG => while ('0' <= sig(index) && sig(index) <= '9') index += 1 appliedType(definitions.ArrayClass.tpe, List(sig2type(tparams))) @@ -719,6 +730,16 @@ abstract class ClassfileParser { } } + def makeInnerAlias(outer: Symbol, name: Name, iclazz: Symbol, scope: Scope): Symbol = { + var innerAlias = scope.lookup(name) + if (!innerAlias.isAliasType) { + innerAlias = outer.newAliasType(NoPosition, name).setFlag(JAVA) + .setInfo(new LazyAliasType(iclazz)) + scope.enter(innerAlias) + } + innerAlias + } + def parseInnerClasses() { for (i <- 0 until in.nextChar) { val innerIndex = in.nextChar @@ -728,11 +749,11 @@ abstract class ClassfileParser { if (innerIndex != 0 && outerIndex != 0 && nameIndex != 0 && (jflags & (JAVA_ACC_PUBLIC | JAVA_ACC_PROTECTED)) != 0 && pool.getClassSymbol(outerIndex) == sym) { - val innerAlias = getOwner(jflags) - .newAliasType(NoPosition, pool.getName(nameIndex).toTypeName) - .setFlag(JAVA) - .setInfo(new LazyAliasType(pool.getClassSymbol(innerIndex))) - getScope(jflags).enter(innerAlias) + makeInnerAlias( + getOwner(jflags), + pool.getName(nameIndex).toTypeName, + pool.getClassSymbol(innerIndex), + getScope(jflags)) if ((jflags & JAVA_ACC_STATIC) != 0) { val innerVal = staticModule.newValue(NoPosition, pool.getName(nameIndex).toTermName) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index a689aa6fd5..de1f3f3119 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -538,7 +538,8 @@ abstract class RefChecks extends InfoTransform { !(receiver isSubClass actual)) nonSensible("", false) else if ((receiver hasFlag FINAL) && hasObjectEquals && !isValueClass(receiver) && - !(receiver isSubClass actual) && receiver != AllRefClass && actual != AllRefClass) + !(receiver isSubClass actual) && receiver != AllRefClass && actual != AllRefClass && + (name == nme.EQ || name == nme.LE)) nonSensible("non-null ", false) else if ((isNew(qual) || isNew(args.head)) && hasObjectEquals) nonSensibleWarning("a fresh object", false) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 41a96d3e5c..290d603282 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -237,10 +237,12 @@ trait Typers { self: Analyzer => else errorTree(tree, "stable identifier required, but " + tree + " found.") /** Check that `tpt' refers to a non-refinement class type */ - def checkClassType(tpt: Tree) { + def checkClassType(tpt: Tree, existentialOK: Boolean) { def check(tpe: Type): Unit = tpe.normalize match { case TypeRef(_, sym, _) if sym.isClass && !sym.isRefinementClass => ; + case ErrorType => ; case PolyType(_, restpe) => check(restpe) + case ExistentialType(_, restpe) if existentialOK => check(restpe) case t => error(tpt.pos, "class type required but "+t+" found") } check(tpt.tpe) @@ -956,7 +958,7 @@ trait Typers { self: Analyzer => def validateParentClass(parent: Tree, superclazz: Symbol) { if (!parent.tpe.isError) { val psym = parent.tpe.typeSymbol.initialize - checkClassType(parent) + checkClassType(parent, false) if (psym != superclazz) { if (psym.isTrait) { val ps = psym.info.parents @@ -2301,7 +2303,7 @@ trait Typers { self: Analyzer => def typedNew(tpt: Tree) = { var tpt1 = typedTypeConstructor(tpt) - checkClassType(tpt1) + checkClassType(tpt1, false) if (tpt1.hasSymbol && !tpt1.symbol.typeParams.isEmpty) { context.undetparams = cloneSymbols(tpt1.symbol.typeParams) tpt1 = TypeTree() @@ -2381,7 +2383,7 @@ trait Typers { self: Analyzer => val targs = args map (_.tpe) checkBounds(tree.pos, NoPrefix, NoSymbol, tparams, targs, "") if (fun.symbol == Predef_classOf) { - checkClassType(args.head) + checkClassType(args.head, true) Literal(Constant(targs.head)) setPos tree.pos setType Predef_classOfType(targs.head) // @M: targs.head.normalize is not necessary --> toTypeKind eventually normalizes the type } else { -- cgit v1.2.3