diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/reflect/internal/Importers.scala | 108 | ||||
-rw-r--r-- | src/compiler/scala/reflect/runtime/ToolBoxes.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/reflect/runtime/TreeBuildUtil.scala | 20 | ||||
-rw-r--r-- | src/compiler/scala/reflect/runtime/Universe.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Reifiers.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Trees.scala | 30 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Macros.scala | 8 |
7 files changed, 121 insertions, 68 deletions
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala index 63efaede07..c232e3b7c1 100644 --- a/src/compiler/scala/reflect/internal/Importers.scala +++ b/src/compiler/scala/reflect/internal/Importers.scala @@ -32,8 +32,11 @@ trait Importers { self: SymbolTable => def importPosition(pos: from.Position): Position = NoPosition - def importSymbol(sym: from.Symbol): Symbol = { + def importSymbol(sym0: from.Symbol): Symbol = { def doImport(sym: from.Symbol): Symbol = { + if (symMap.contains(sym)) + return symMap(sym) + val myowner = importSymbol(sym.owner) val mypos = importPosition(sym.pos) val myname = importName(sym.name).toTermName @@ -47,7 +50,7 @@ trait Importers { self: SymbolTable => case x: from.MethodSymbol => linkReferenced(myowner.newMethod(myname, mypos, myflags), x, importSymbol) case x: from.ModuleSymbol => - linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, doImport) + linkReferenced(myowner.newModuleSymbol(myname, mypos, myflags), x, importSymbol) case x: from.FreeVar => newFreeVar(importName(x.name).toTermName, importType(x.tpe), x.value, myflags) case x: from.TermSymbol => @@ -59,14 +62,14 @@ trait Importers { self: SymbolTable => case y: from.Symbol => importSymbol(y) } myowner.newTypeSkolemSymbol(myname.toTypeName, origin, mypos, myflags) - /* - case x: from.ModuleClassSymbol => - val mysym = new ModuleClassSymbol(myowner, mypos, myname.toTypeName) - mysym.sourceModule = importSymbol(x.sourceModule) - mysym -*/ + case x: from.ModuleClassSymbol => + val mysym = myowner.newModuleClassSymbol(myname.toTypeName, mypos, myflags) + symMap(x) = mysym + mysym.sourceModule = importSymbol(x.sourceModule) + mysym case x: from.ClassSymbol => val mysym = myowner.newClassSymbol(myname.toTypeName, mypos, myflags) + symMap(x) = mysym if (sym.thisSym != sym) { mysym.typeOfThis = importType(sym.typeOfThis) mysym.thisSym.name = importName(sym.thisSym.name) @@ -78,7 +81,7 @@ trait Importers { self: SymbolTable => symMap(sym) = mysym mysym setFlag Flags.LOCKED mysym setInfo { - val mytypeParams = sym.typeParams map doImport + val mytypeParams = sym.typeParams map importSymbol new LazyPolyType(mytypeParams) { override def complete(s: Symbol) { val result = sym.info match { @@ -94,6 +97,7 @@ trait Importers { self: SymbolTable => } // end doImport def importOrRelink: Symbol = { + val sym = sym0 // makes sym visible in the debugger if (sym == null) null else if (sym == from.NoSymbol) @@ -101,51 +105,61 @@ trait Importers { self: SymbolTable => else if (sym.isRoot) definitions.RootClass else { - val myowner = importSymbol(sym.owner) - val myname = importName(sym.name) - if (sym.isModuleClass) { - assert(sym.sourceModule != NoSymbol, sym) - val mymodule = importSymbol(sym.sourceModule) - assert(mymodule != NoSymbol, sym) - assert(mymodule.moduleClass != NoSymbol, mymodule) - mymodule.moduleClass - } else if (myowner.isClass && !myowner.isRefinementClass && !(myowner hasFlag Flags.LOCKED) && sym.owner.info.decl(sym.name).exists) { - // symbol is in class scope, try to find equivalent one in local scope - if (sym.isOverloaded) - myowner.newOverloaded(myowner.thisType, sym.alternatives map importSymbol) - else { - var existing: Symbol = myowner.info.decl(myname) - if (existing.isOverloaded) { - existing = - if (sym.isMethod) { - val localCopy = doImport(sym) - existing filter (_.tpe matches localCopy.tpe) - } else { - existing filter (!_.isMethod) - } - assert(!existing.isOverloaded, - "import failure: cannot determine unique overloaded method alternative from\n "+ - (existing.alternatives map (_.defString) mkString "\n")+"\n that matches "+sym+":"+sym.tpe) + val name = sym.name + val owner = sym.owner + var scope = if (owner.isClass && !owner.isRefinementClass) owner.info else from.NoType + var existing = scope.decl(name) + if (sym.isPackageClass || sym.isModuleClass) existing = existing.moduleClass + if (!existing.exists) scope = from.NoType + + val myname = importName(name) + val myowner = importSymbol(owner) + val myscope = if (scope != from.NoType && !(myowner hasFlag Flags.LOCKED)) myowner.info else NoType + var myexisting = if (myscope != NoType) myowner.info.decl(myname) else NoSymbol // cannot load myexisting in general case, because it creates cycles for methods + if (sym.isPackageClass || sym.isModuleClass) myexisting = importSymbol(sym.sourceModule).moduleClass + if (!sym.isOverloaded && myexisting.isOverloaded) { + myexisting = + if (sym.isMethod) { + val localCopy = doImport(sym) + myexisting filter (_.tpe matches localCopy.tpe) + } else { + myexisting filter (!_.isMethod) } - if (existing != NoSymbol) existing - else { + assert(!myexisting.isOverloaded, + "import failure: cannot determine unique overloaded method alternative from\n "+ + (myexisting.alternatives map (_.defString) mkString "\n")+"\n that matches "+sym+":"+sym.tpe) + } + + val mysym = { + if (sym.isOverloaded) { + myowner.newOverloaded(myowner.thisType, sym.alternatives map importSymbol) + } else if (sym.isTypeParameter && sym.paramPos >= 0 && !(myowner hasFlag Flags.LOCKED)) { + assert(myowner.typeParams.length > sym.paramPos, + "import failure: cannot determine parameter "+sym+" (#"+sym.paramPos+") in "+ + myowner+typeParamsString(myowner.rawInfo)+"\n original symbol was: "+ + sym.owner+from.typeParamsString(sym.owner.info)) + myowner.typeParams(sym.paramPos) + } else { + if (myexisting != NoSymbol) { + myexisting + } else { val mysym = doImport(sym) - assert(myowner.info.decls.lookup(myname) == NoSymbol, myname+" "+myowner.info.decl(myname)+" "+existing) - myowner.info.decls enter mysym + + if (myscope != NoType) { + assert(myowner.info.decls.lookup(myname) == NoSymbol, myname+" "+myowner.info.decl(myname)+" "+myexisting) + myowner.info.decls enter mysym + } + mysym } } - } else if (sym.isTypeParameter && sym.paramPos >= 0 && !(myowner hasFlag Flags.LOCKED)) { - assert(myowner.typeParams.length > sym.paramPos, - "import failure: cannot determine parameter "+sym+" (#"+sym.paramPos+") in "+ - myowner+typeParamsString(myowner.rawInfo)+"\n original symbol was: "+ - sym.owner+from.typeParamsString(sym.owner.info)) - myowner.typeParams(sym.paramPos) - } else - doImport(sym) + } + + mysym } } // end importOrRelink + val sym = sym0 if (symMap contains sym) { symMap(sym) } else { @@ -410,4 +424,4 @@ trait Importers { self: SymbolTable => case _ => constant.value }) } -} +}
\ No newline at end of file diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala index c09022e535..880c68eaa0 100644 --- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala +++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala @@ -44,11 +44,11 @@ trait ToolBoxes extends { self: Universe => // !!! Why is this is in the empty package? If it's only to make // it inaccessible then please put it somewhere designed for that // rather than polluting the empty package with synthetics. - trace("typing: ")(showAttributed(tree)) + trace("typing: ")(showAttributed(tree, true, true, settings.Yshowsymkinds.value)) val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName("<expression-owner>"), List(ObjectClass.tpe), newScope) val owner = ownerClass.newLocalDummy(tree.pos) val ttree = typer.atOwner(tree, owner).typed(tree, analyzer.EXPRmode, pt) - trace("typed: ")(showAttributed(ttree)) + trace("typed: ")(showAttributed(ttree, true, true, settings.Yshowsymkinds.value)) ttree } @@ -78,9 +78,9 @@ trait ToolBoxes extends { self: Universe => List(List()), List(methdef), NoPosition)) - trace("wrapped: ")(showAttributed(moduledef)) + trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value)) val cleanedUp = resetLocalAttrs(moduledef) - trace("cleaned up: ")(showAttributed(cleanedUp)) + trace("cleaned up: ")(showAttributed(cleanedUp, true, true, settings.Yshowsymkinds.value)) cleanedUp } @@ -192,7 +192,8 @@ trait ToolBoxes extends { self: Universe => def typeCheck(tree: rm.Tree, expectedType: rm.Type): rm.Tree = { if (compiler.settings.verbose.value) println("typing "+tree+", pt = "+expectedType) val ttree = importAndTypeCheck(tree, expectedType) - exporter.importTree(ttree).asInstanceOf[rm.Tree] + val ettree = exporter.importTree(ttree).asInstanceOf[rm.Tree] + ettree } def typeCheck(tree: rm.Tree): rm.Tree = diff --git a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala index 275c85f332..0b54843344 100644 --- a/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala +++ b/src/compiler/scala/reflect/runtime/TreeBuildUtil.scala @@ -2,9 +2,23 @@ package scala.reflect package runtime trait TreeBuildUtil extends Universe with api.TreeBuildUtil { - def staticClass(fullname: String): Symbol = definitions.getRequiredClass(fullname) - def staticModule(fullname: String): Symbol = definitions.getRequiredModule(fullname) - def thisModuleType(fullname: String) = staticModule(fullname).moduleClass.thisType + def staticClass(fullname: String): Symbol = { + val sym = definitions.getRequiredClass(fullname) + sym.initialize + sym + } + + def staticModule(fullname: String): Symbol = { + val sym = definitions.getRequiredModule(fullname) + sym.initialize + sym + } + + def thisModuleType(fullname: String) = { + val sym = staticModule(fullname).moduleClass + sym.initialize + sym.thisType + } /** Selects type symbol with given name from the defined members of prefix type */ diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala index c786bb86c5..700f819226 100644 --- a/src/compiler/scala/reflect/runtime/Universe.scala +++ b/src/compiler/scala/reflect/runtime/Universe.scala @@ -16,7 +16,7 @@ class Universe extends SymbolTable { val gen = new TreeGen { val global: Universe.this.type = Universe.this } - def settings = new Settings + lazy val settings = new Settings def forInteractive = false def forScaladoc = false diff --git a/src/compiler/scala/tools/nsc/ast/Reifiers.scala b/src/compiler/scala/tools/nsc/ast/Reifiers.scala index b82d78b786..91d5d2bf4a 100644 --- a/src/compiler/scala/tools/nsc/ast/Reifiers.scala +++ b/src/compiler/scala/tools/nsc/ast/Reifiers.scala @@ -325,6 +325,16 @@ trait Reifiers { self: Global => // registerReifiableSymbol(tree.symbol) boundSyms += tree.symbol + if (tree.symbol.sourceModule != NoSymbol) { + if (reifyDebug) println("boundSym (sourceModule): " + tree.symbol.sourceModule) + boundSyms += tree.symbol.sourceModule + } + + if (tree.symbol.moduleClass != NoSymbol) { + if (reifyDebug) println("boundSym (moduleClass): " + tree.symbol.moduleClass) + boundSyms += tree.symbol.moduleClass + } + val prefix = tree.productPrefix val elements = (tree.productIterator map { // annotations exist in two flavors: diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 9e304a0eb5..855b55bb5e 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -251,12 +251,27 @@ trait Trees extends reflect.internal.Trees { self: Global => * (bq:) This transformer has mutable state and should be discarded after use */ private class ResetAttrs(localOnly: Boolean) { + val debug = settings.debug.value + val trace = scala.tools.nsc.util.trace when debug + val locals = util.HashSet[Symbol](8) + val orderedLocals = collection.mutable.ListBuffer[Symbol]() + def registerLocal(sym: Symbol) { + if (sym != null && sym != NoSymbol) { + if (debug && !(locals contains sym)) orderedLocals append sym + locals addEntry sym + } + } class MarkLocals extends self.Traverser { - def markLocal(tree: Tree) = - if (tree.symbol != null && tree.symbol != NoSymbol) - locals addEntry tree.symbol + def markLocal(tree: Tree) { + if (tree.symbol != null && tree.symbol != NoSymbol) { + val sym = tree.symbol + registerLocal(sym) + registerLocal(sym.sourceModule) + registerLocal(sym.moduleClass) + } + } override def traverse(tree: Tree) = { tree match { @@ -301,9 +316,12 @@ trait Trees extends reflect.internal.Trees { self: Global => def transform[T <: Tree](x: T): T = { new MarkLocals().traverse(x) - val trace = scala.tools.nsc.util.trace when settings.debug.value - val eoln = System.getProperty("line.separator") - trace("locals (%d total): %n".format(locals.size))(locals.toList map {" " + _} mkString eoln) + if (debug) { + assert(locals.size == orderedLocals.size) + val eoln = System.getProperty("line.separator") + val msg = orderedLocals.toList filter {_ != NoSymbol} map {" " + _} mkString eoln + trace("locals (%d total): %n".format(orderedLocals.size))(msg) + } val x1 = new Transformer().transform(x) assert(x.getClass isInstance x1) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index ed249796a8..470f3e7117 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -20,15 +20,12 @@ trait Macros { self: Analyzer => macroArgs(fn) :+ args case TypeApply(fn, args) => macroArgs(fn) :+ args - case Select(qual, name) if !isStaticMacro(tree.symbol) => + case Select(qual, name) => List(List(qual)) case _ => List(List()) } - private def isStaticMacro(mac: Symbol): Boolean = - mac.owner.isModuleClass - /** * The definition of the method implementing a macro. Example: * Say we have in a class C @@ -46,7 +43,6 @@ trait Macros { self: Analyzer => * expr * } * - * If `foo` is declared in an object, the second parameter list is () instead of (_this: _context.Tree). * If macro has no type arguments, the third parameter list is omitted (it's not empty, but omitted altogether). * * To find out the desugared representation of your particular macro, compile it with -Ymacro-debug. @@ -58,7 +54,7 @@ trait Macros { self: Analyzer => def globSelect(name: Name) = Select(Ident(nme.macroContext), name) def globTree = globSelect(tpnme.Tree) def globTypeTree = globSelect(tpnme.TypeTree) - val thisParamSec = if (isStaticMacro(mdef.symbol)) List() else List(paramDef(nme.macroThis, globTree)) + val thisParamSec = List(paramDef(newTermName(nme.macroThis), globTree)) def tparamInMacro(tdef: TypeDef) = paramDef(tdef.name.toTermName, globTypeTree) def vparamInMacro(vdef: ValDef): ValDef = paramDef(vdef.name, vdef.tpt match { case tpt @ AppliedTypeTree(hk, _) if treeInfo.isRepeatedParamType(tpt) => AppliedTypeTree(hk, List(globTree)) |