summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-02-02 14:39:44 +0100
committerEugene Burmako <xeno.by@gmail.com>2012-02-02 14:39:44 +0100
commitd940371bd50098c4146e52941880ccdbcb4ea47a (patch)
tree2d4f7093fad48fcaf44ac491bf3a13e3cc2bcbe0 /src
parent3aebe255b87f534239f0c46a2a6e0d696c8a31d4 (diff)
downloadscala-d940371bd50098c4146e52941880ccdbcb4ea47a.tar.gz
scala-d940371bd50098c4146e52941880ccdbcb4ea47a.tar.bz2
scala-d940371bd50098c4146e52941880ccdbcb4ea47a.zip
Miscellaneous fixes to reification
More specifically: * Importers now preserve wasEmpty and original * ToolBoxes no longer auto-evaluate nullary functions returned by runExpr * All local symbols from previous typechecks are now correctly erased by ResetAttrs * Originals are now reified
Diffstat (limited to 'src')
-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
8 files changed, 170 insertions, 86 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
}