summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala15
-rw-r--r--src/compiler/scala/reflect/runtime/ToolBoxes.scala49
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala107
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/LiftCode.scala62
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rwxr-xr-xsrc/library/scala/reflect/api/StandardDefinitions.scala7
-rw-r--r--src/partest/scala/tools/partest/utils/CodeTest.scala10
-rw-r--r--test/files/run/code.check7
-rw-r--r--test/files/run/reify_complex.check (renamed from test/pending/run/reify_complex.check)0
-rw-r--r--test/files/run/reify_complex.scala (renamed from test/pending/run/reify_complex.scala)0
-rw-r--r--test/files/run/reify_extendbuiltins.check (renamed from test/pending/run/reify_extendbuiltins.check)0
-rw-r--r--test/files/run/reify_extendbuiltins.scala (renamed from test/pending/run/reify_extendbuiltins.scala)0
-rw-r--r--test/files/run/reify_generic2.check1
-rw-r--r--test/files/run/reify_generic2.scala16
-rw-r--r--test/files/run/reify_getter.check1
-rw-r--r--test/files/run/reify_getter.scala19
-rw-r--r--test/files/run/reify_sort1.check (renamed from test/pending/run/reify_sort1.check)0
-rw-r--r--test/files/run/reify_sort1.scala (renamed from test/pending/run/reify_sort1.scala)0
-rw-r--r--test/files/run/t5269.check (renamed from test/pending/run/t5269.check)0
-rw-r--r--test/files/run/t5269.scala (renamed from test/pending/run/t5269.scala)0
-rw-r--r--test/files/run/t5274_1.check (renamed from test/pending/run/t5274_1.check)0
-rw-r--r--test/files/run/t5274_1.scala (renamed from test/pending/run/t5274_1.scala)0
-rw-r--r--test/files/run/t5275.check (renamed from test/pending/run/t5275.check)0
-rw-r--r--test/files/run/t5275.scala (renamed from test/pending/run/t5275.scala)0
-rw-r--r--test/files/run/t5277_1.check (renamed from test/pending/run/t5277_1.check)0
-rw-r--r--test/files/run/t5277_1.scala (renamed from test/pending/run/t5277_1.scala)0
-rw-r--r--test/files/run/t5277_2.check2
-rw-r--r--test/files/run/t5277_2.scala (renamed from test/pending/run/t5277_2.scala)0
-rw-r--r--test/files/run/t5335.check (renamed from test/pending/run/t5277_2.check)1
-rw-r--r--test/files/run/t5335.scala14
-rw-r--r--test/pending/run/reify_closure6.check6
-rw-r--r--test/pending/run/reify_closure6.scala2
-rw-r--r--test/pending/run/reify_closure7.check6
-rw-r--r--test/pending/run/reify_closure7.scala32
-rw-r--r--test/pending/run/reify_closure8a.check1
-rw-r--r--test/pending/run/reify_closure8a.scala17
-rw-r--r--test/pending/run/reify_closure8b.check1
-rw-r--r--test/pending/run/reify_closure8b.scala17
-rw-r--r--test/pending/run/reify_closure9a.check1
-rw-r--r--test/pending/run/reify_closure9a.scala20
-rw-r--r--test/pending/run/reify_closure9b.check1
-rw-r--r--test/pending/run/reify_closure9b.scala20
-rw-r--r--test/pending/run/reify_closures10.check2
-rw-r--r--test/pending/run/reify_closures10.scala15
-rw-r--r--test/pending/run/reify_closures11.check1
-rw-r--r--test/pending/run/reify_closures11.scala18
-rw-r--r--test/pending/run/reify_this.check5
-rw-r--r--test/pending/run/reify_this.scala31
-rw-r--r--test/pending/run/t5415.check0
-rw-r--r--test/pending/run/t5415.scala14
51 files changed, 439 insertions, 88 deletions
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index 4f5b28d370..6c843e6f15 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -327,8 +327,19 @@ trait Importers { self: SymbolTable =>
null
}
if (mytree != null) {
- if (mytree hasSymbol) mytree.symbol = importSymbol(tree.symbol)
- mytree.tpe = importType(tree.tpe)
+ val mysym = if (tree hasSymbol) importSymbol(tree.symbol) else NoSymbol
+ val mytpe = importType(tree.tpe)
+
+ mytree match {
+ case mytt: TypeTree =>
+ val tt = tree.asInstanceOf[from.TypeTree]
+ if (mytree hasSymbol) mytt.symbol = mysym
+ if (tt.wasEmpty) mytt.defineType(mytpe) else mytt.setType(mytpe)
+ if (tt.original != null) mytt.setOriginal(importTree(tt.original))
+ case _ =>
+ if (mytree hasSymbol) mytree.symbol = importSymbol(tree.symbol)
+ mytree.tpe = importType(tree.tpe)
+ }
}
mytree
}
diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
index 46d890c5d1..6e671ae06e 100644
--- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala
+++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala
@@ -44,17 +44,19 @@ 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))
val ownerClass = EmptyPackageClass.newClassWithInfo(newTypeName("<expression-owner>"), List(ObjectClass.tpe), newScope)
val owner = ownerClass.newLocalDummy(tree.pos)
-
- typer.atOwner(tree, owner).typed(tree, analyzer.EXPRmode, pt)
+ val ttree = typer.atOwner(tree, owner).typed(tree, analyzer.EXPRmode, pt)
+ trace("typed: ")(showAttributed(ttree))
+ ttree
}
-
+
def defOwner(tree: Tree): Symbol = tree find (_.isDef) map (_.symbol) match {
case Some(sym) if sym != null && sym != NoSymbol => sym.owner
case _ => NoSymbol
}
-
+
def wrapInObject(expr: Tree, fvs: List[Symbol]): ModuleDef = {
val obj = EmptyPackageClass.newModule(nextWrapperModuleName())
val minfo = ClassInfoType(List(ObjectClass.tpe, ScalaObjectClass.tpe), newScope, obj.moduleClass)
@@ -66,9 +68,7 @@ trait ToolBoxes extends { self: Universe =>
minfo.decls enter meth
trace("wrapping ")(defOwner(expr) -> meth)
val methdef = DefDef(meth, expr changeOwner (defOwner(expr) -> meth))
- trace("wrapped: ")(showAttributed(methdef))
- resetAllAttrs(
- ModuleDef(
+ val moduledef = ModuleDef(
obj,
Template(
List(TypeTree(ObjectClass.tpe)),
@@ -77,7 +77,11 @@ trait ToolBoxes extends { self: Universe =>
List(),
List(List()),
List(methdef),
- NoPosition)))
+ NoPosition))
+ trace("wrapped: ")(showAttributed(moduledef))
+ val cleanedUp = resetLocalAttrs(moduledef)
+ trace("cleaned up: ")(showAttributed(cleanedUp))
+ cleanedUp
}
def wrapInPackage(clazz: Tree): PackageDef =
@@ -91,7 +95,7 @@ trait ToolBoxes extends { self: Universe =>
def compileExpr(expr: Tree, fvs: List[Symbol]): String = {
val mdef = wrapInObject(expr, fvs)
- val pdef = trace("wrapped: ")(wrapInPackage(mdef))
+ val pdef = wrapInPackage(mdef)
val unit = wrapInCompilationUnit(pdef)
val run = new Run
run.compileUnits(List(unit), run.namerPhase)
@@ -104,24 +108,27 @@ trait ToolBoxes extends { self: Universe =>
def runExpr(expr: Tree): Any = {
val etpe = expr.tpe
val fvs = (expr filter isFree map (_.symbol)).distinct
-
+
reporter.reset()
val className = compileExpr(expr, fvs)
if (reporter.hasErrors) {
throw new Error("reflective compilation has failed")
}
-
+
if (settings.debug.value) println("generated: "+className)
val jclazz = jClass.forName(moduleFileName(className), true, classLoader)
val jmeth = jclazz.getDeclaredMethods.find(_.getName == wrapperMethodName).get
val jfield = jclazz.getDeclaredFields.find(_.getName == NameTransformer.MODULE_INSTANCE_NAME).get
val singleton = jfield.get(null)
- val result = jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*)
- if (etpe.typeSymbol != FunctionClass(0)) result
- else {
- val applyMeth = result.getClass.getMethod("apply")
- applyMeth.invoke(result)
- }
+ // @odersky writes: Not sure we will be able to drop this. I forgot the reason why we dereference () functions,
+ // but there must have been one. So I propose to leave old version in comments to be resurrected if the problem resurfaces.
+// val result = jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*)
+// if (etpe.typeSymbol != FunctionClass(0)) result
+// else {
+// val applyMeth = result.getClass.getMethod("apply")
+// applyMeth.invoke(result)
+// }
+ jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*)
}
def showAttributed(tree: Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String = {
@@ -131,7 +138,7 @@ trait ToolBoxes extends { self: Universe =>
try {
settings.printtypes.value = printTypes
settings.uniqid.value = printIds
- settings.uniqid.value = printKinds
+ settings.Yshowsymkinds.value = printKinds
tree.toString
} finally {
settings.printtypes.value = saved1
@@ -167,7 +174,7 @@ trait ToolBoxes extends { self: Universe =>
lazy val exporter = importer.reverse
lazy val classLoader = new AbstractFileClassLoader(virtualDirectory, defaultReflectiveClassLoader)
-
+
private def importAndTypeCheck(tree: rm.Tree, expectedType: rm.Type): compiler.Tree = {
// need to establish a run an phase because otherwise we run into an assertion in TypeHistory
// that states that the period must be different from NoPeriod
@@ -189,8 +196,8 @@ trait ToolBoxes extends { self: Universe =>
def typeCheck(tree: rm.Tree): rm.Tree =
typeCheck(tree, WildcardType.asInstanceOf[rm.Type])
- def showAttributed(tree: rm.Tree): String =
- compiler.showAttributed(importer.importTree(tree.asInstanceOf[Tree]))
+ def showAttributed(tree: rm.Tree, printTypes: Boolean = true, printIds: Boolean = true, printKinds: Boolean = false): String =
+ compiler.showAttributed(importer.importTree(tree.asInstanceOf[Tree]), printTypes, printIds, printKinds)
def runExpr(tree: rm.Tree, expectedType: rm.Type): Any = {
val ttree = importAndTypeCheck(tree, expectedType)
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index c80b07c44d..83b6252b26 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -42,8 +42,8 @@ trait Trees extends reflect.internal.Trees { self: Global =>
/** emitted by typer, eliminated by refchecks */
case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends TypTree
-
- /** Marks underlying reference to id as boxed.
+
+ /** Marks underlying reference to id as boxed.
* @pre: id must refer to a captured variable
* A reference such marked will refer to the boxed entity, no dereferencing
* with `.elem` is done on it.
@@ -208,7 +208,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
case _ => this.treeCopy.SelectFromArray(tree, qualifier, selector, erasure)
}
def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match {
- case t @ ReferenceToBoxed(idt0)
+ case t @ ReferenceToBoxed(idt0)
if (idt0 == idt) => t
case _ => this.treeCopy.ReferenceToBoxed(tree, idt)
}
@@ -251,62 +251,79 @@ trait Trees extends reflect.internal.Trees { self: Global =>
}
}
- /** resets symbol and tpe fields in a tree, @see ResetAttrsTraverse
+ /** resets symbol and tpe fields in a tree, @see ResetAttrs
*/
// def resetAllAttrs[A<:Tree](x:A): A = { new ResetAttrsTraverser().traverse(x); x }
// def resetLocalAttrs[A<:Tree](x:A): A = { new ResetLocalAttrsTraverser().traverse(x); x }
-
- def resetAllAttrs[A<:Tree](x:A): A = new ResetAttrsTransformer(false).transformPoly(x)
- def resetLocalAttrs[A<:Tree](x:A): A = new ResetAttrsTransformer(true).transformPoly(x)
+
+ def resetAllAttrs[A<:Tree](x:A): A = new ResetAttrs(false).transform(x)
+ def resetLocalAttrs[A<:Tree](x:A): A = new ResetAttrs(true).transform(x)
/** A transformer which resets symbol and tpe fields of all nodes in a given tree,
* with special treatment of:
* TypeTree nodes: are replaced by their original if it exists, otherwise tpe field is reset
* to empty if it started out empty or refers to local symbols (which are erased).
* TypeApply nodes: are deleted if type arguments end up reverted to empty
- * This(pkg) notes where pkg is a pckage: these are kept.
+ * This(pkg) nodes where pkg is a package: these are kept.
*
- * (bq:) This traverser has mutable state and should be discarded after use
+ * (bq:) This transformer has mutable state and should be discarded after use
*/
- private class ResetAttrsTransformer(localOnly: Boolean) extends Transformer {
- private val erasedSyms = util.HashSet[Symbol](8)
- private def resetDef(tree: Tree) {
- if (tree.symbol != null && tree.symbol != NoSymbol)
- erasedSyms addEntry tree.symbol
- tree.symbol = NoSymbol
+ private class ResetAttrs(localOnly: Boolean) {
+ val locals = util.HashSet[Symbol](8)
+
+ class MarkLocals extends self.Traverser {
+ def markLocal(tree: Tree) =
+ if (tree.symbol != null && tree.symbol != NoSymbol)
+ locals addEntry tree.symbol
+
+ override def traverse(tree: Tree) = {
+ tree match {
+ case _: DefTree | Function(_, _) | Template(_, _, _) =>
+ markLocal(tree)
+ case _ if tree.symbol.isInstanceOf[FreeVar] =>
+ markLocal(tree)
+ case _ =>
+ ;
+ }
+
+ super.traverse(tree)
+ }
}
- override def transform(tree: Tree): Tree = super.transform {
- tree match {
- case Template(_, _, body) =>
- body foreach resetDef
- resetDef(tree)
- tree.tpe = null
- tree
- case _: DefTree | Function(_, _) | Template(_, _, _) =>
- resetDef(tree)
- tree.tpe = null
- tree
- case tpt: TypeTree =>
- if (tpt.original != null)
- tpt.original
- else if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => erasedSyms contains tp.typeSymbol))))
- tpt.tpe = null
- tree
- case TypeApply(fn, args) if args map transform exists (_.isEmpty) =>
- fn
- case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
- tree
- case EmptyTree =>
- tree
- case _ =>
- if (tree.hasSymbol && (!localOnly || (erasedSyms contains tree.symbol)))
- tree.symbol = NoSymbol
- tree.tpe = null
- tree
+
+ class Transformer extends self.Transformer {
+ override def transform(tree: Tree): Tree = super.transform {
+ tree match {
+ case tpt: TypeTree =>
+ if (tpt.original != null) {
+ transform(tpt.original)
+ } else {
+ if (tpt.tpe != null && (tpt.wasEmpty || (tpt.tpe exists (tp => locals contains tp.typeSymbol))))
+ tpt.tpe = null
+ tree
+ }
+ case TypeApply(fn, args) if args map transform exists (_.isEmpty) =>
+ transform(fn)
+ case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
+ tree
+ case EmptyTree =>
+ tree
+ case _ =>
+ if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol)))
+ tree.symbol = NoSymbol
+ tree.tpe = null
+ tree
+ }
}
}
- def transformPoly[T <: Tree](x: T): T = {
- val x1 = transform(x)
+
+ 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)
+
+ val x1 = new Transformer().transform(x)
assert(x.getClass isInstance x1)
x1.asInstanceOf[T]
}
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 107ffc35c6..d1ce460eb9 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -166,7 +166,9 @@ trait ScalaSettings extends AbsScalaSettings
val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.")
val Yreifycopypaste =
BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.")
- val Yreifydebug = BooleanSetting ("-Yreify-debug", "Trace reification actions.")
+ val Yreifydebug = BooleanSetting ("-Yreify-debug", "Trace reification.")
+ val Yreifytyperdebug
+ = BooleanSetting ("-Yreifytyper-debug", "Trace typings of reified trees.")
val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup")
val Yrepldebug = BooleanSetting ("-Yrepl-debug", "Trace all repl activity.") .
withPostSetHook(_ => interpreter.replProps.debug setValue true)
diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
index f1182fc2a9..197a52f011 100644
--- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala
+++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
@@ -55,10 +55,16 @@ abstract class LiftCode extends Transform with TypingTransformers {
class Codifier(unit: CompilationUnit) extends TypingTransformer(unit) {
val reifyDebug = settings.Yreifydebug.value
+ val reifyTyperDebug = settings.Yreifytyperdebug.value
val debugTrace = util.trace when reifyDebug
val reifyCopypaste = settings.Yreifycopypaste.value
def printCopypaste(tree: Tree) {
+ if (reifyDebug) println("=======================")
+ printCopypaste1(tree)
+ if (reifyDebug) println("=======================")
+ }
+ def printCopypaste1(tree: Tree) {
import scala.reflect.api.Modifier
import scala.reflect.api.Modifier._
@@ -123,11 +129,14 @@ abstract class LiftCode extends Transform with TypingTransformers {
case Apply(_, List(tree)) if sym == Code_lift => // reify Code.lift[T](expr) instances
val saved = printTypings
try {
- printTypings = reifyDebug
+ debugTrace("transforming = ")(if (settings.Xshowtrees.value) "\n" + nodePrinters.nodeToString(tree).trim else tree.toString)
debugTrace("transformed = ") {
- val result = localTyper.typedPos(tree.pos)(codify(super.transform(tree)))
- if (reifyCopypaste) printCopypaste(result)
- result
+ val untyped = codify(super.transform(tree))
+ if (reifyCopypaste) printCopypaste(untyped)
+
+ printTypings = reifyTyperDebug
+ val typed = localTyper.typedPos(tree.pos)(untyped)
+ typed
}
} catch {
case ex: ReifierError =>
@@ -145,7 +154,8 @@ abstract class LiftCode extends Transform with TypingTransformers {
val targetType = definitions.CodeClass.primaryConstructor.info.paramTypes.head
val reifier = new Reifier()
val arg = gen.mkAsInstanceOf(reifier.reifyTopLevel(tree), targetType, wrapInApply = false)
- val treetpe =
+ val treetpe = // this really should use packedType(tree.tpe, context.owner)
+ // where packedType is defined in Typers. But we can do that only if liftCode is moved to Typers.
if (tree.tpe.typeSymbol.isAnonymousClass) tree.tpe.typeSymbol.classBound
else tree.tpe
New(TypeTree(appliedType(definitions.CodeClass.typeConstructor, List(treetpe.widen))),
@@ -274,6 +284,14 @@ abstract class LiftCode extends Transform with TypingTransformers {
case None =>
if (sym == NoSymbol)
mirrorSelect("NoSymbol")
+ else if (sym == RootPackage)
+ mirrorSelect("definitions.RootPackage")
+ else if (sym == RootClass)
+ mirrorSelect("definitions.RootClass")
+ else if (sym == EmptyPackage)
+ mirrorSelect("definitions.EmptyPackage")
+ else if (sym == EmptyPackageClass)
+ mirrorSelect("definitions.EmptyPackageClass")
else if (sym.isModuleClass)
Select(reifySymRef(sym.sourceModule), "moduleClass")
else if (sym.isStatic && sym.isClass)
@@ -300,7 +318,7 @@ abstract class LiftCode extends Transform with TypingTransformers {
if (sym.isTerm) {
if (reifyDebug) println("Free: " + sym)
val symtpe = lambdaLift.boxIfCaptured(sym, sym.tpe, erasedTypes = false)
- def markIfCaptured(arg: Ident): Tree =
+ def markIfCaptured(arg: Ident): Tree =
if (sym.isCapturedVariable) referenceCapturedVariable(arg) else arg
mirrorCall("freeVar", reify(sym.name.toString), reify(symtpe), markIfCaptured(Ident(sym)))
} else {
@@ -381,6 +399,14 @@ abstract class LiftCode extends Transform with TypingTransformers {
}
}
+ private def definedInLiftedCode(tpe: Type) =
+ tpe exists (tp => boundSyms contains tp.typeSymbol)
+
+ private def isErased(tree: Tree) = tree match {
+ case tt: TypeTree => definedInLiftedCode(tt.tpe) && tt.original == null
+ case _ => false
+ }
+
/** Reify a tree */
private def reifyTree(tree: Tree): Tree = tree match {
case EmptyTree =>
@@ -393,13 +419,21 @@ abstract class LiftCode extends Transform with TypingTransformers {
mirrorCall("Select", reifyFree(tree), reifyName(nme.elem))
} else reifyFree(tree)
case tt: TypeTree if (tt.tpe != null) =>
- if (!(boundSyms exists (tt.tpe contains _))) mirrorCall("TypeTree", reifyType(tt.tpe))
- else if (tt.original != null) reify(tt.original)
- else mirrorCall(nme.TypeTree)
+ if (definedInLiftedCode(tt.tpe)) {
+ // erase non-essential (i.e. inferred) types
+ // reify symless counterparts of essential types
+ if (tt.original != null) reify(tt.original) else mirrorCall("TypeTree")
+ } else {
+ var rtt = mirrorCall(nme.TypeTree, reifyType(tt.tpe))
+ if (tt.original != null) {
+ val setOriginal = Select(rtt, newTermName("setOriginal"))
+ val reifiedOriginal = reify(tt.original)
+ rtt = Apply(setOriginal, List(reifiedOriginal))
+ }
+ rtt
+ }
case ta @ TypeApply(hk, ts) =>
- val thereAreOnlyTTs = ts collect { case t if !t.isInstanceOf[TypeTree] => t } isEmpty;
- val ttsAreNotEssential = ts collect { case tt: TypeTree => tt } find { tt => tt.original != null } isEmpty;
- if (thereAreOnlyTTs && ttsAreNotEssential) reifyTree(hk) else reifyProduct(ta)
+ if (ts exists isErased) reifyTree(hk) else reifyProduct(ta)
case global.emptyValDef =>
mirrorSelect(nme.emptyValDef)
case Literal(constant @ Constant(tpe: Type)) if boundSyms exists (tpe contains _) =>
@@ -407,8 +441,10 @@ abstract class LiftCode extends Transform with TypingTransformers {
case Literal(constant @ Constant(sym: Symbol)) if boundSyms contains sym =>
CannotReifyClassOfBoundEnum(tree, constant.tpe)
case _ =>
- if (tree.isDef)
+ if (tree.isDef) {
+ if (reifyDebug) println("boundSym: " + tree.symbol)
boundSyms += tree.symbol
+ }
reifyProduct(tree)
/*
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index d3ff331f98..4cf134d58b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2915,7 +2915,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
existentialAbstraction(captured.toList, tpe)
}
- /** convert skolems to existentials */
+ /** convert local symbols and skolems to existentials */
def packedType(tree: Tree, owner: Symbol): Type = {
def defines(tree: Tree, sym: Symbol) =
sym.isExistentialSkolem && sym.unpackLocation == tree ||
diff --git a/src/library/scala/reflect/api/StandardDefinitions.scala b/src/library/scala/reflect/api/StandardDefinitions.scala
index 08071660a2..3526cf259d 100755
--- a/src/library/scala/reflect/api/StandardDefinitions.scala
+++ b/src/library/scala/reflect/api/StandardDefinitions.scala
@@ -12,7 +12,7 @@ trait StandardDefinitions { self: Universe =>
abstract class AbsDefinitions {
// outer packages and their classes
- def RootPackage: Symbol
+ def RootPackage: Symbol // under consideration
def RootClass: Symbol
def EmptyPackage: Symbol
def EmptyPackageClass: Symbol
@@ -46,6 +46,11 @@ trait StandardDefinitions { self: Universe =>
def StringClass : Symbol
def ClassClass : Symbol
+ // product, tuple, function
+ def TupleClass : Array[Symbol]
+ def ProductClass : Array[Symbol]
+ def FunctionClass : Array[Symbol]
+
// fundamental modules
def PredefModule: Symbol
diff --git a/src/partest/scala/tools/partest/utils/CodeTest.scala b/src/partest/scala/tools/partest/utils/CodeTest.scala
index c90168a313..c236d89bbd 100644
--- a/src/partest/scala/tools/partest/utils/CodeTest.scala
+++ b/src/partest/scala/tools/partest/utils/CodeTest.scala
@@ -24,11 +24,17 @@ object CodeTest {
def apply[T](code: Code[T], args: Array[String] = Array()) = {
println("testing: "+code.tree)
+ println("type is: "+code.manifest.tpe)
+ val isNullary = code.manifest.tpe.typeSymbol == scala.reflect.mirror.definitions.FunctionClass(0)
val reporter = new ConsoleReporter(new Settings)
val toolbox = new ToolBox(reporter, args mkString " ")
val ttree = toolbox.typeCheck(code.tree, code.manifest.tpe)
- println("result = " + toolbox.showAttributed(ttree))
- val evaluated = toolbox.runExpr(ttree)
+ println("result = " + toolbox.showAttributed(ttree, printTypes = true, printIds = false))
+ var evaluated = toolbox.runExpr(ttree)
+ if (evaluated != null && isNullary) {
+ val applyMeth = evaluated.getClass.getMethod("apply")
+ evaluated = applyMeth.invoke(evaluated)
+ }
println("evaluated = "+evaluated)
evaluated
}
diff --git a/test/files/run/code.check b/test/files/run/code.check
index b946554fda..9b0351bbf9 100644
--- a/test/files/run/code.check
+++ b/test/files/run/code.check
@@ -1,29 +1,36 @@
testing: ((x: Int) => x.$plus(ys.length))
+type is: Int => Int
result = ((x: Int) => x.+{(x: <?>)Int}(ys.length{Int}){Int}){Int => Int}
evaluated = <function1>
testing: (() => {
val e: Element = new Element("someName");
e
})
+type is: () => Element
result = (() => {
val e: Element = new Element{Element}{(name: <?>)Element}("someName"{String("someName")}){Element};
e{Element}
}{Element}){() => Element}
evaluated = Element(someName)
testing: (() => truc.elem = 6)
+type is: () => Unit
result = (() => truc.elem{Int} = 6{Int(6)}{Unit}){() => Unit}
evaluated = null
testing: (() => truc.elem = truc.elem.$plus(6))
+type is: () => Unit
result = (() => truc.elem{Int} = truc.elem.+{(x: <?>)Int}(6{Int(6)}){Int}{Unit}){() => Unit}
evaluated = null
testing: (() => new baz.BazElement("someName"))
+type is: () => baz.BazElement
result = (() => new baz.BazElement{baz.BazElement}{(name: <?>)baz.BazElement}("someName"{String("someName")}){baz.BazElement}){() => baz.BazElement}
evaluated = BazElement(someName)
testing: ((x: Int) => x.$plus(ys.length))
+type is: Int => Int
result = ((x: Int) => x.+{(x: <?>)Int}(ys.length{Int}){Int}){Int => Int}
evaluated = <function1>
static: 2
testing: (() => x.$plus(1))
+type is: () => Int
result = (() => x.+{(x: <?>)Int}(1{Int(1)}){Int}){() => Int}
evaluated = 2
1+1 = 2
diff --git a/test/pending/run/reify_complex.check b/test/files/run/reify_complex.check
index 7df35e33a0..7df35e33a0 100644
--- a/test/pending/run/reify_complex.check
+++ b/test/files/run/reify_complex.check
diff --git a/test/pending/run/reify_complex.scala b/test/files/run/reify_complex.scala
index aae4d558cf..aae4d558cf 100644
--- a/test/pending/run/reify_complex.scala
+++ b/test/files/run/reify_complex.scala
diff --git a/test/pending/run/reify_extendbuiltins.check b/test/files/run/reify_extendbuiltins.check
index a48033a30d..a48033a30d 100644
--- a/test/pending/run/reify_extendbuiltins.check
+++ b/test/files/run/reify_extendbuiltins.check
diff --git a/test/pending/run/reify_extendbuiltins.scala b/test/files/run/reify_extendbuiltins.scala
index 57acd699ff..57acd699ff 100644
--- a/test/pending/run/reify_extendbuiltins.scala
+++ b/test/files/run/reify_extendbuiltins.scala
diff --git a/test/files/run/reify_generic2.check b/test/files/run/reify_generic2.check
new file mode 100644
index 0000000000..b8626c4cff
--- /dev/null
+++ b/test/files/run/reify_generic2.check
@@ -0,0 +1 @@
+4
diff --git a/test/files/run/reify_generic2.scala b/test/files/run/reify_generic2.scala
new file mode 100644
index 0000000000..d03fe7602b
--- /dev/null
+++ b/test/files/run/reify_generic2.scala
@@ -0,0 +1,16 @@
+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
+ val product = List(new C, new C).length * List[C](new C, new C).length
+ println(product)
+ };
+
+ 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_getter.check b/test/files/run/reify_getter.check
new file mode 100644
index 0000000000..5ef4ff4d04
--- /dev/null
+++ b/test/files/run/reify_getter.check
@@ -0,0 +1 @@
+evaluated = 2
diff --git a/test/files/run/reify_getter.scala b/test/files/run/reify_getter.scala
new file mode 100644
index 0000000000..83eaded506
--- /dev/null
+++ b/test/files/run/reify_getter.scala
@@ -0,0 +1,19 @@
+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 {
+ val x = 2
+ }
+
+ new C().x
+ };
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(code.tree)
+ val evaluated = toolbox.runExpr(ttree)
+ println("evaluated = " + evaluated)
+}
diff --git a/test/pending/run/reify_sort1.check b/test/files/run/reify_sort1.check
index 0d30805141..0d30805141 100644
--- a/test/pending/run/reify_sort1.check
+++ b/test/files/run/reify_sort1.check
diff --git a/test/pending/run/reify_sort1.scala b/test/files/run/reify_sort1.scala
index 42f4c824a5..42f4c824a5 100644
--- a/test/pending/run/reify_sort1.scala
+++ b/test/files/run/reify_sort1.scala
diff --git a/test/pending/run/t5269.check b/test/files/run/t5269.check
index 0cfbf08886..0cfbf08886 100644
--- a/test/pending/run/t5269.check
+++ b/test/files/run/t5269.check
diff --git a/test/pending/run/t5269.scala b/test/files/run/t5269.scala
index a30509f3fe..a30509f3fe 100644
--- a/test/pending/run/t5269.scala
+++ b/test/files/run/t5269.scala
diff --git a/test/pending/run/t5274_1.check b/test/files/run/t5274_1.check
index fca8bc3d3e..fca8bc3d3e 100644
--- a/test/pending/run/t5274_1.check
+++ b/test/files/run/t5274_1.check
diff --git a/test/pending/run/t5274_1.scala b/test/files/run/t5274_1.scala
index c501172518..c501172518 100644
--- a/test/pending/run/t5274_1.scala
+++ b/test/files/run/t5274_1.scala
diff --git a/test/pending/run/t5275.check b/test/files/run/t5275.check
index 0cfbf08886..0cfbf08886 100644
--- a/test/pending/run/t5275.check
+++ b/test/files/run/t5275.check
diff --git a/test/pending/run/t5275.scala b/test/files/run/t5275.scala
index d419834ded..d419834ded 100644
--- a/test/pending/run/t5275.scala
+++ b/test/files/run/t5275.scala
diff --git a/test/pending/run/t5277_1.check b/test/files/run/t5277_1.check
index a48033a30d..a48033a30d 100644
--- a/test/pending/run/t5277_1.check
+++ b/test/files/run/t5277_1.check
diff --git a/test/pending/run/t5277_1.scala b/test/files/run/t5277_1.scala
index 57acd699ff..57acd699ff 100644
--- a/test/pending/run/t5277_1.scala
+++ b/test/files/run/t5277_1.scala
diff --git a/test/files/run/t5277_2.check b/test/files/run/t5277_2.check
new file mode 100644
index 0000000000..ca017e2a40
--- /dev/null
+++ b/test/files/run/t5277_2.check
@@ -0,0 +1,2 @@
+2()
+1()
diff --git a/test/pending/run/t5277_2.scala b/test/files/run/t5277_2.scala
index 67b6b000bc..67b6b000bc 100644
--- a/test/pending/run/t5277_2.scala
+++ b/test/files/run/t5277_2.scala
diff --git a/test/pending/run/t5277_2.check b/test/files/run/t5335.check
index 5f1d0ecea5..0cfbf08886 100644
--- a/test/pending/run/t5277_2.check
+++ b/test/files/run/t5335.check
@@ -1,2 +1 @@
2
-1
diff --git a/test/files/run/t5335.scala b/test/files/run/t5335.scala
new file mode 100644
index 0000000000..9a8b91f04d
--- /dev/null
+++ b/test/files/run/t5335.scala
@@ -0,0 +1,14 @@
+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{
+ println(new {def x = 2}.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/reify_closure6.check b/test/pending/run/reify_closure6.check
index 3526d04b0e..e521ea874d 100644
--- a/test/pending/run/reify_closure6.check
+++ b/test/pending/run/reify_closure6.check
@@ -1,3 +1,7 @@
+q = 1
+y = 1
first invocation = 15
-second invocation = 18
+q = 2
+y = 1
+second invocation = 17
q after second invocation = 2
diff --git a/test/pending/run/reify_closure6.scala b/test/pending/run/reify_closure6.scala
index 909071aa44..43ddfde28d 100644
--- a/test/pending/run/reify_closure6.scala
+++ b/test/pending/run/reify_closure6.scala
@@ -10,6 +10,8 @@ object Test extends App {
val fun: reflect.Code[Int => Int] = x => {
y += 1
q += 1
+ println("q = " + q)
+ println("y = " + y)
x + ys.length * z + q + y
}
diff --git a/test/pending/run/reify_closure7.check b/test/pending/run/reify_closure7.check
new file mode 100644
index 0000000000..bf58b52bce
--- /dev/null
+++ b/test/pending/run/reify_closure7.check
@@ -0,0 +1,6 @@
+q = 1
+y = 1
+first invocation = 15
+q = 2
+y = 2
+second invocation = 17
diff --git a/test/pending/run/reify_closure7.scala b/test/pending/run/reify_closure7.scala
new file mode 100644
index 0000000000..8933df23fa
--- /dev/null
+++ b/test/pending/run/reify_closure7.scala
@@ -0,0 +1,32 @@
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ var q = 0
+ var clo: Int => Int = null
+ def foo[T](ys: List[T]): Int => Int = {
+ val z = 1
+ var y = 0
+ val fun: reflect.Code[Int => Int] = x => {
+ y += 1
+ q += 1
+ println("q = " + q)
+ println("y = " + y)
+ x + ys.length * z + q + y
+ }
+
+ if (clo == null) {
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(fun.tree)
+ val dyn = toolbox.runExpr(ttree)
+ clo = dyn.asInstanceOf[Int => Int]
+ }
+
+ clo
+ }
+
+ println("first invocation = " + foo(List(1, 2, 3))(10))
+ println("second invocation = " + foo(List(1, 2, 3, 4))(10))
+}
diff --git a/test/pending/run/reify_closure8a.check b/test/pending/run/reify_closure8a.check
new file mode 100644
index 0000000000..9a037142aa
--- /dev/null
+++ b/test/pending/run/reify_closure8a.check
@@ -0,0 +1 @@
+10 \ No newline at end of file
diff --git a/test/pending/run/reify_closure8a.scala b/test/pending/run/reify_closure8a.scala
new file mode 100644
index 0000000000..5e54bfc8c7
--- /dev/null
+++ b/test/pending/run/reify_closure8a.scala
@@ -0,0 +1,17 @@
+import scala.reflect.Code._
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ class Foo(val y: Int) {
+ def fun = lift{y}
+ }
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(new Foo(10).fun.tree)
+ val dyn = toolbox.runExpr(ttree)
+ val foo = dyn.asInstanceOf[Int]
+ println(foo)
+}
diff --git a/test/pending/run/reify_closure8b.check b/test/pending/run/reify_closure8b.check
new file mode 100644
index 0000000000..9a037142aa
--- /dev/null
+++ b/test/pending/run/reify_closure8b.check
@@ -0,0 +1 @@
+10 \ No newline at end of file
diff --git a/test/pending/run/reify_closure8b.scala b/test/pending/run/reify_closure8b.scala
new file mode 100644
index 0000000000..9e37e4e09a
--- /dev/null
+++ b/test/pending/run/reify_closure8b.scala
@@ -0,0 +1,17 @@
+import scala.reflect.Code._
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ class Foo(y: Int) {
+ def fun = lift{y}
+ }
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(new Foo(10).fun.tree)
+ val dyn = toolbox.runExpr(ttree)
+ val foo = dyn.asInstanceOf[Int]
+ println(foo)
+}
diff --git a/test/pending/run/reify_closure9a.check b/test/pending/run/reify_closure9a.check
new file mode 100644
index 0000000000..9a037142aa
--- /dev/null
+++ b/test/pending/run/reify_closure9a.check
@@ -0,0 +1 @@
+10 \ No newline at end of file
diff --git a/test/pending/run/reify_closure9a.scala b/test/pending/run/reify_closure9a.scala
new file mode 100644
index 0000000000..f3ee153d3c
--- /dev/null
+++ b/test/pending/run/reify_closure9a.scala
@@ -0,0 +1,20 @@
+import scala.reflect.Code._
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ def foo(y: Int) = {
+ class Foo(val y: Int) {
+ def fun = lift{y}
+ }
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(new Foo(y).fun.tree)
+ val dyn = toolbox.runExpr(ttree)
+ dyn.asInstanceOf[Int]
+ }
+
+ println(foo(10))
+}
diff --git a/test/pending/run/reify_closure9b.check b/test/pending/run/reify_closure9b.check
new file mode 100644
index 0000000000..9a037142aa
--- /dev/null
+++ b/test/pending/run/reify_closure9b.check
@@ -0,0 +1 @@
+10 \ No newline at end of file
diff --git a/test/pending/run/reify_closure9b.scala b/test/pending/run/reify_closure9b.scala
new file mode 100644
index 0000000000..8d349e8701
--- /dev/null
+++ b/test/pending/run/reify_closure9b.scala
@@ -0,0 +1,20 @@
+import scala.reflect.Code._
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ def foo(y: Int) = {
+ class Foo(y: Int) {
+ def fun = lift{y}
+ }
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(new Foo(y).fun.tree)
+ val dyn = toolbox.runExpr(ttree)
+ dyn.asInstanceOf[Int]
+ }
+
+ println(foo(10))
+}
diff --git a/test/pending/run/reify_closures10.check b/test/pending/run/reify_closures10.check
new file mode 100644
index 0000000000..fd3c81a4d7
--- /dev/null
+++ b/test/pending/run/reify_closures10.check
@@ -0,0 +1,2 @@
+5
+5
diff --git a/test/pending/run/reify_closures10.scala b/test/pending/run/reify_closures10.scala
new file mode 100644
index 0000000000..d0f895ae4d
--- /dev/null
+++ b/test/pending/run/reify_closures10.scala
@@ -0,0 +1,15 @@
+import scala.reflect.Code._
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ val x = 2
+ val y = 3
+ val code = lift{println(x + y); x + y}
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(code.tree)
+ println(toolbox.runExpr(ttree))
+}
diff --git a/test/pending/run/reify_closures11.check b/test/pending/run/reify_closures11.check
new file mode 100644
index 0000000000..d8263ee986
--- /dev/null
+++ b/test/pending/run/reify_closures11.check
@@ -0,0 +1 @@
+2 \ No newline at end of file
diff --git a/test/pending/run/reify_closures11.scala b/test/pending/run/reify_closures11.scala
new file mode 100644
index 0000000000..42053bd029
--- /dev/null
+++ b/test/pending/run/reify_closures11.scala
@@ -0,0 +1,18 @@
+import scala.reflect.Code._
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+object Test extends App {
+ def fun() = {
+ def z() = 2
+ lift{z}
+ }
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(fun().tree)
+ val dyn = toolbox.runExpr(ttree)
+ val foo = dyn.asInstanceOf[Int]
+ println(foo)
+}
diff --git a/test/pending/run/reify_this.check b/test/pending/run/reify_this.check
new file mode 100644
index 0000000000..af3d0652a9
--- /dev/null
+++ b/test/pending/run/reify_this.check
@@ -0,0 +1,5 @@
+foo
+false
+2
+bar
+2 \ No newline at end of file
diff --git a/test/pending/run/reify_this.scala b/test/pending/run/reify_this.scala
new file mode 100644
index 0000000000..38ef72b6eb
--- /dev/null
+++ b/test/pending/run/reify_this.scala
@@ -0,0 +1,31 @@
+import scala.reflect._
+import scala.reflect.Code._
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import reflect.runtime.Mirror.ToolBox
+
+trait Eval {
+ def eval(code: Code[_]): Any = eval(code.tree)
+
+ def eval(tree: Tree): Any = {
+ val settings = new Settings
+ val reporter = new ConsoleReporter(settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(tree)
+ toolbox.runExpr(ttree)
+ }
+}
+
+object Test extends App with Eval {
+ // select a value from package
+ eval(lift{println("foo")})
+ eval(lift{println((new Object).toString == (new Object).toString)})
+
+ // select a type from package
+ eval(lift{val x: Any = 2; println(x)})
+ eval(lift{val x: Object = "bar"; println(x)})
+
+ // select a value from module
+ val x = 2
+ eval(lift{println(x)})
+}
diff --git a/test/pending/run/t5415.check b/test/pending/run/t5415.check
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/pending/run/t5415.check
diff --git a/test/pending/run/t5415.scala b/test/pending/run/t5415.scala
new file mode 100644
index 0000000000..3db356da86
--- /dev/null
+++ b/test/pending/run/t5415.scala
@@ -0,0 +1,14 @@
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
+import scala.reflect.runtime.Mirror.ToolBox
+
+object Test extends App{
+ case class Queryable2[T]() { def filter(predicate: T => Boolean) = ??? }
+ trait CoffeesTable{ def sales : Int }
+ val q = Queryable2[CoffeesTable]()
+ val code = scala.reflect.Code.lift{q.filter(_.sales > 5)}
+
+ val reporter = new ConsoleReporter(new Settings)
+ val toolbox = new ToolBox(reporter)
+ val ttree = toolbox.typeCheck(code.tree)
+}