diff options
author | Martin Odersky <odersky@gmail.com> | 2011-09-23 16:21:16 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2011-09-23 16:21:16 +0000 |
commit | 2b699c3fdb8586051fa20cc1e37d4d40a7418605 (patch) | |
tree | 31b1605a95eb096586256089b7bdd1cfcf5b55c3 /src | |
parent | 7bfdac0b73c28109b5d3130783feaca4a7c06100 (diff) | |
download | scala-2b699c3fdb8586051fa20cc1e37d4d40a7418605.tar.gz scala-2b699c3fdb8586051fa20cc1e37d4d40a7418605.tar.bz2 scala-2b699c3fdb8586051fa20cc1e37d4d40a7418605.zip |
Handling Freevars in Importers and discovering ...
Handling Freevars in Importers and discovering whole new classes of
errors in Liftcode.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/reflect/internal/Importers.scala | 117 | ||||
-rw-r--r-- | src/compiler/scala/reflect/internal/Symbols.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/reflect/runtime/RuntimeTypes.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/LiftCode.scala | 14 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 13 |
5 files changed, 90 insertions, 76 deletions
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index 440b5aa509..66cb990f06 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -38,6 +38,8 @@ trait Importers { self: SymbolTable => mysym case x: from.ModuleSymbol => new ModuleSymbol(myowner, mypos, myname) + case x: from.FreeVar => + new FreeVar(importName(x.name), importType(x.tpe), x.value) case x: from.TermSymbol => new TermSymbol(myowner, mypos, myname) case x: from.TypeSkolem => @@ -122,55 +124,57 @@ trait Importers { self: SymbolTable => } def importType(tpe: from.Type): Type = tpe match { - case x: from.TypeRef => - TypeRef(importType(x.pre), importSymbol(x.sym), x.args map importType) - case x: from.ThisType => - ThisType(importSymbol(x.typeSymbol)) - case x: from.SingleType => - SingleType(importType(x.pre), importSymbol(x.sym)) - case x: from.MethodType => - MethodType(x.params map importSymbol, importType(x.resultType)) - case x: from.PolyType => - PolyType(x.typeParams map importSymbol, importType(x.resultType)) - case x: from.NullaryMethodType => - NullaryMethodType(importType(x.resultType)) - case x: from.ConstantType => - ConstantType(Constant(x.value.value)) - case x: from.SuperType => - SuperType(importType(x.thistpe), importType(x.supertpe)) - case x: from.TypeBounds => - TypeBounds(importType(x.lo), importType(x.hi)) - case x: from.BoundedWildcardType => - BoundedWildcardType(importTypeBounds(x.bounds)) - case x: from.ClassInfoType => - val myclazz = importSymbol(x.typeSymbol) + case from.TypeRef(pre, sym, args) => + TypeRef(importType(pre), importSymbol(sym), args map importType) + case from.ThisType(clazz) => + ThisType(importSymbol(clazz)) + case from.SingleType(pre, sym) => + SingleType(importType(pre), importSymbol(sym)) + case from.MethodType(params, restpe) => + MethodType(params map importSymbol, importType(restpe)) + case from.PolyType(tparams, restpe) => + PolyType(tparams map importSymbol, importType(restpe)) + case from.NullaryMethodType(restpe) => + NullaryMethodType(importType(restpe)) + case from.ConstantType(from.Constant(value)) => + ConstantType(Constant(value)) + case from.SuperType(thistpe, supertpe) => + SuperType(importType(thistpe), importType(supertpe)) + case from.TypeBounds(lo, hi) => + TypeBounds(importType(lo), importType(hi)) + case from.BoundedWildcardType(bounds) => + BoundedWildcardType(importTypeBounds(bounds)) + case from.ClassInfoType(parents, decls, clazz) => + val myclazz = importSymbol(clazz) val myscope = if (myclazz.isPackageClass) newPackageScope(myclazz) else newScope - val myclazzTpe = ClassInfoType(x.parents map importType, myscope, myclazz) + val myclazzTpe = ClassInfoType(parents map importType, myscope, myclazz) myclazz setInfo polyType(myclazz.typeParams, myclazzTpe) // needed so that newly created symbols find their scope - for (sym <- x.decls) importSymbol(sym) // will enter itself into myclazz + decls foreach importSymbol // will enter itself into myclazz myclazzTpe - case x: from.RefinedType => - RefinedType(x.parents map importType, importScope(x.decls), importSymbol(x.typeSymbol)) - case x: from.ExistentialType => - ExistentialType(x.typeParams map importSymbol, importType(x.resultType)) - case x: from.OverloadedType => - OverloadedType(importType(x.pre), x.alternatives map importSymbol) - case x: from.AntiPolyType => - AntiPolyType(importType(x.pre), x.targs map importType) + case from.RefinedType(parents, decls) => + RefinedType(parents map importType, importScope(decls), importSymbol(tpe.typeSymbol)) + case from.ExistentialType(tparams, restpe) => + ExistentialType(tparams map importSymbol, importType(restpe)) + case from.OverloadedType(pre, alts) => + OverloadedType(importType(pre), alts map importSymbol) + case from.AntiPolyType(pre, targs) => + AntiPolyType(importType(pre), targs map importType) case x: from.TypeVar => new TypeVar(importType(x.origin), importTypeConstraint(x.constr0), x.typeArgs map importType, x.params map importSymbol) - case x: from.NotNullType => - NotNullType(importType(x.underlying)) - case x: from.AnnotatedType => - AnnotatedType(x.annotations map importAnnotationInfo, importType(x.underlying), importSymbol(x.selfsym)) - case x => - val xclazz = x.getClass - if (xclazz == ErrorType.getClass) ErrorType - else if (xclazz == WildcardType.getClass) WildcardType - else if (xclazz == NoType.getClass) NoType - else if (xclazz == NoPrefix.getClass) NoPrefix - else if (x == null) null - else throw new MatchError(x) + case from.NotNullType(tpe) => + NotNullType(importType(tpe)) + case from.AnnotatedType(annots, tpe, selfsym) => + AnnotatedType(annots map importAnnotationInfo, importType(tpe), importSymbol(selfsym)) + case from.ErrorType => + ErrorType + case from.WildcardType => + WildcardType + case from.NoType => + NoType + case from.NoPrefix => + NoPrefix + case null => + null } def importTypeBounds(bounds: from.TypeBounds) = importType(bounds).asInstanceOf[TypeBounds] @@ -181,14 +185,14 @@ trait Importers { self: SymbolTable => }) def importAnnotArg(arg: from.ClassfileAnnotArg): ClassfileAnnotArg = arg match { - case x: from.LiteralAnnotArg => - LiteralAnnotArg(Constant(x.const.value)) - case x: from.ArrayAnnotArg => - ArrayAnnotArg(x.args map importAnnotArg) - case x: from.ScalaSigBytes => - ScalaSigBytes(x.bytes) - case x: from.NestedAnnotArg => - NestedAnnotArg(importAnnotationInfo(x.annInfo)) + case from.LiteralAnnotArg(from.Constant(value)) => + LiteralAnnotArg(Constant(value)) + case from.ArrayAnnotArg(args) => + ArrayAnnotArg(args map importAnnotArg) + case from.ScalaSigBytes(bytes) => + ScalaSigBytes(bytes) + case from.NestedAnnotArg(annInfo) => + NestedAnnotArg(importAnnotationInfo(annInfo)) } def importTypeConstraint(constr: from.TypeConstraint): TypeConstraint = { @@ -213,7 +217,7 @@ trait Importers { self: SymbolTable => new ImportSelector(importName(sel.name), sel.namePos, importName(sel.rename), sel.renamePos) def importTree(tree: from.Tree): Tree = { - tree match { + val mytree = tree match { case from.ClassDef(mods, name, tparams, impl) => new ClassDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTemplate(impl)) case from.PackageDef(pid, stats) => @@ -311,7 +315,12 @@ trait Importers { self: SymbolTable => case null => null } - } // copyAttrs tree + if (mytree != null) { + if (mytree hasSymbol) mytree.symbol = importSymbol(tree.symbol) + mytree.tpe = importType(tree.tpe) + } + mytree + } def importValDef(tree: from.ValDef): ValDef = importTree(tree).asInstanceOf[ValDef] def importTypeDef(tree: from.TypeDef): TypeDef = importTree(tree).asInstanceOf[TypeDef] diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index b459c64978..fcf70e5825 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -2348,6 +2348,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def sourceModule_=(module: Symbol) { this.module = module } } + class FreeVar(name: TermName, tpe: Type, val value: Any) extends TermSymbol(definitions.RootClass, NoPosition, name) { + setInfo(tpe) + + override def hashCode = value.hashCode + + override def equals(other: Any): Boolean = other match { + case that: FreeVar => this.value.asInstanceOf[AnyRef] eq that.value.asInstanceOf[AnyRef] + case _ => false + } + } + /** An object representing a missing symbol */ object NoSymbol extends Symbol(null, NoPosition, nme.NO_NAME) { setInfo(NoType) diff --git a/src/compiler/scala/reflect/runtime/RuntimeTypes.scala b/src/compiler/scala/reflect/runtime/RuntimeTypes.scala index 26681dff4d..a1a555c22e 100644 --- a/src/compiler/scala/reflect/runtime/RuntimeTypes.scala +++ b/src/compiler/scala/reflect/runtime/RuntimeTypes.scala @@ -5,17 +5,6 @@ import collection.mutable.ListBuffer trait RuntimeTypes extends Universe with api.RuntimeTypes { - case class FreeVar(_name: TermName, _tpe: Type, value: Any) extends TermSymbol(definitions.RootClass, NoPosition, _name) { - setInfo(_tpe) - - override def hashCode = value.hashCode - - override def equals(other: Any): Boolean = other match { - case FreeVar(_, _, value1) => value.asInstanceOf[AnyRef] eq value1.asInstanceOf[AnyRef] - case _ => false - } - } - case class InstanceRefSymbol(value: AnyRef) extends TermSymbol(NoSymbol, NoPosition, nme.EMPTY) object InstanceRefSymbol extends InstanceRefSymbolExtractor diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index ce7938a60e..f17bdf3416 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -97,7 +97,7 @@ abstract class LiftCode extends Transform with TypingTransformers { private val localSyms = mutable.ArrayBuffer[Symbol]() private val symIndex = mutable.HashMap[Symbol, Int]() - private var localClasses = Set[Symbol]() + private var boundSyms = Set[Symbol]() private val typeTree = mutable.HashMap[Type, Tree]() private val typeTreeCount = mutable.HashMap[Tree, Int]() @@ -182,6 +182,9 @@ abstract class LiftCode extends Transform with TypingTransformers { private def isLocatable(sym: Symbol) = sym.isPackageClass || sym.owner.isClass || sym.isParameter && sym.paramPos >= 0 + private def isFree(sym: Symbol) = + !(symIndex contains sym) + /** Reify a reference to a symbol */ private def reifySymRef(sym: Symbol): Tree = { @@ -284,13 +287,12 @@ abstract class LiftCode extends Transform with TypingTransformers { private def reifyTree(tree: Tree): Tree = tree match { case EmptyTree => reifyCaseObject(tree) - case ClassDef(_, _, _, _) => - localClasses += tree.symbol - reifyCaseClassInstance(tree) - case tree @ This(_) if !(localClasses contains tree.symbol) => + case tree @ This(_) if !(boundSyms contains tree.symbol) => + reifyFree(tree) + case tree @ Ident(_) if !(boundSyms contains tree.symbol) => reifyFree(tree) case _ => -// var rtree = + if (tree.isDef) boundSyms += tree.symbol reifyCaseClassInstance(tree.asInstanceOf[Product]) /* if (tree.isDef || tree.isInstanceOf[Function]) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index a1343fb7d7..0f6f3c93e1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3683,8 +3683,10 @@ trait Typers extends Modes with Adaptations { return makeErrorTree if (!qual.tpe.widen.isErroneous) { - val lastTry = missingHook(qual.tpe.typeSymbol, name) - if (lastTry != NoSymbol) return typed1(tree setSymbol lastTry, mode, pt) + if ((mode & QUALmode) != 0) { + val lastTry = missingHook(qual.tpe.typeSymbol, name) + if (lastTry != NoSymbol) return typed1(tree setSymbol lastTry, mode, pt) + } notAMemberError(tree.pos, qual, name) } @@ -3880,9 +3882,10 @@ trait Typers extends Modes with Adaptations { else if (settings.exposeEmptyPackage.value && checkEmptyPackage()) log("Allowing empty package member " + name + " due to settings.") else { - val lastTry = missingHook(RootClass, name) - if (lastTry != NoSymbol) return typed1(tree setSymbol lastTry, mode, pt) - + if ((mode & QUALmode) != 0) { + val lastTry = missingHook(RootClass, name) + if (lastTry != NoSymbol) return typed1(tree setSymbol lastTry, mode, pt) + } if (settings.debug.value) { log(context.imports)//debug } |