summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-02-13 22:04:54 +0100
committerEugene Burmako <xeno.by@gmail.com>2012-02-14 00:40:51 +0100
commitadb218d8d230b4713942f5b220d8cd0602995aae (patch)
treeed6db1c13ca3a36098ca54f9a5c46e2e82f0e59f
parent6548dcf12d83e327df2f90048140fb95346b7e95 (diff)
downloadscala-adb218d8d230b4713942f5b220d8cd0602995aae.tar.gz
scala-adb218d8d230b4713942f5b220d8cd0602995aae.tar.bz2
scala-adb218d8d230b4713942f5b220d8cd0602995aae.zip
Fixes https://issues.scala-lang.org/browse/SI-5229
-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
-rw-r--r--test/files/run/reify_inner1.check1
-rw-r--r--test/files/run/reify_inner1.scala22
-rw-r--r--test/files/run/reify_inner2.check1
-rw-r--r--test/files/run/reify_inner2.scala22
-rw-r--r--test/files/run/reify_inner3.check1
-rw-r--r--test/files/run/reify_inner3.scala22
-rw-r--r--test/files/run/reify_inner4.check1
-rw-r--r--test/files/run/reify_inner4.scala22
-rw-r--r--test/files/run/t5229_1.check (renamed from test/pending/run/t5229_1.check)0
-rw-r--r--test/files/run/t5229_1.scala (renamed from test/pending/run/t5229_1.scala)0
-rw-r--r--test/files/run/t5229_2.check (renamed from test/pending/run/t5229_2.check)0
-rw-r--r--test/files/run/t5229_2.scala (renamed from test/pending/run/t5229_2.scala)0
-rw-r--r--test/files/run/t5270.check (renamed from test/pending/run/t5270.check)0
-rw-r--r--test/files/run/t5270.scala (renamed from test/pending/run/t5270.scala)0
-rw-r--r--test/pending/run/t5229_1_nolift.scala1
21 files changed, 211 insertions, 63 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/test/files/run/reify_inner1.check b/test/files/run/reify_inner1.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_inner1.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_inner1.scala b/test/files/run/reify_inner1.scala
new file mode 100644
index 0000000000..69931198e0
--- /dev/null
+++ b/test/files/run/reify_inner1.scala
@@ -0,0 +1,22 @@
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ val code = scala.reflect.Code.lift{
+ class C {
+ class D {
+ val x = 2
+ }
+ }
+
+ val outer = new C()
+ val inner = new outer.D()
+ println(inner.x)
+ };
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(code.tree)
+ toolbox.runExpr(ttree)
+}
diff --git a/test/files/run/reify_inner2.check b/test/files/run/reify_inner2.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_inner2.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_inner2.scala b/test/files/run/reify_inner2.scala
new file mode 100644
index 0000000000..0f12fd472a
--- /dev/null
+++ b/test/files/run/reify_inner2.scala
@@ -0,0 +1,22 @@
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ val code = scala.reflect.Code.lift{
+ class C {
+ object D {
+ val x = 2
+ }
+ }
+
+ val outer = new C()
+ val inner = outer.D
+ println(inner.x)
+ };
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(code.tree)
+ toolbox.runExpr(ttree)
+}
diff --git a/test/files/run/reify_inner3.check b/test/files/run/reify_inner3.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_inner3.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_inner3.scala b/test/files/run/reify_inner3.scala
new file mode 100644
index 0000000000..6b97b42b34
--- /dev/null
+++ b/test/files/run/reify_inner3.scala
@@ -0,0 +1,22 @@
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ val code = scala.reflect.Code.lift{
+ object C {
+ class D {
+ val x = 2
+ }
+ }
+
+ val outer = C
+ val inner = new outer.D
+ println(inner.x)
+ };
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(code.tree)
+ toolbox.runExpr(ttree)
+}
diff --git a/test/files/run/reify_inner4.check b/test/files/run/reify_inner4.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/files/run/reify_inner4.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/files/run/reify_inner4.scala b/test/files/run/reify_inner4.scala
new file mode 100644
index 0000000000..de8c973b09
--- /dev/null
+++ b/test/files/run/reify_inner4.scala
@@ -0,0 +1,22 @@
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ val code = scala.reflect.Code.lift{
+ object C {
+ object D {
+ val x = 2
+ }
+ }
+
+ val outer = C
+ val inner = outer.D
+ println(inner.x)
+ };
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(code.tree)
+ toolbox.runExpr(ttree)
+}
diff --git a/test/pending/run/t5229_1.check b/test/files/run/t5229_1.check
index e69de29bb2..e69de29bb2 100644
--- a/test/pending/run/t5229_1.check
+++ b/test/files/run/t5229_1.check
diff --git a/test/pending/run/t5229_1.scala b/test/files/run/t5229_1.scala
index 1d7bf0590b..1d7bf0590b 100644
--- a/test/pending/run/t5229_1.scala
+++ b/test/files/run/t5229_1.scala
diff --git a/test/pending/run/t5229_2.check b/test/files/run/t5229_2.check
index 5db6ec9b38..5db6ec9b38 100644
--- a/test/pending/run/t5229_2.check
+++ b/test/files/run/t5229_2.check
diff --git a/test/pending/run/t5229_2.scala b/test/files/run/t5229_2.scala
index 67be7328a6..67be7328a6 100644
--- a/test/pending/run/t5229_2.scala
+++ b/test/files/run/t5229_2.scala
diff --git a/test/pending/run/t5270.check b/test/files/run/t5270.check
index 08839f6bb2..08839f6bb2 100644
--- a/test/pending/run/t5270.check
+++ b/test/files/run/t5270.check
diff --git a/test/pending/run/t5270.scala b/test/files/run/t5270.scala
index 10f79790b0..10f79790b0 100644
--- a/test/pending/run/t5270.scala
+++ b/test/files/run/t5270.scala
diff --git a/test/pending/run/t5229_1_nolift.scala b/test/pending/run/t5229_1_nolift.scala
deleted file mode 100644
index 33855d2e4f..0000000000
--- a/test/pending/run/t5229_1_nolift.scala
+++ /dev/null
@@ -1 +0,0 @@
-object C