summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-02-23 21:56:27 +0000
committerMartin Odersky <odersky@gmail.com>2008-02-23 21:56:27 +0000
commit12a0200eae15615cf81caa3be8febda00c968919 (patch)
tree71a56d496898f16bc0a01c757f58faa801a1c644 /src/compiler
parentdbf12a761a461e95282e37cf8ff548e431c601cb (diff)
downloadscala-12a0200eae15615cf81caa3be8febda00c968919.tar.gz
scala-12a0200eae15615cf81caa3be8febda00c968919.tar.bz2
scala-12a0200eae15615cf81caa3be8febda00c968919.zip
fixed tests
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala109
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala10
3 files changed, 73 insertions, 49 deletions
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 {