summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-02-13 16:01:45 -0800
committerPaul Phillips <paulp@improving.org>2012-02-13 16:01:45 -0800
commitadbe9ee345c620c59d34806032c9a00c8d04a634 (patch)
tree0db1cf47fd86a196d9d4c9777fd1ed85efd4d4d8 /src
parent2fc92eb4f0ab8f12b4ed6c2439ef9a53484b3e45 (diff)
parentadb218d8d230b4713942f5b220d8cd0602995aae (diff)
downloadscala-adbe9ee345c620c59d34806032c9a00c8d04a634.tar.gz
scala-adbe9ee345c620c59d34806032c9a00c8d04a634.tar.bz2
scala-adbe9ee345c620c59d34806032c9a00c8d04a634.zip
Merge remote-tracking branches 'scalamacros/pullrequest/5453' and 'scalamacros/pullrequest/5229' into develop
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala108
-rw-r--r--src/compiler/scala/reflect/runtime/ToolBoxes.scala11
-rw-r--r--src/compiler/scala/reflect/runtime/TreeBuildUtil.scala20
-rw-r--r--src/compiler/scala/reflect/runtime/Universe.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/Reifiers.scala10
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala30
6 files changed, 119 insertions, 62 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)