summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-07-30 00:41:40 +0000
committerMartin Odersky <odersky@gmail.com>2011-07-30 00:41:40 +0000
commit613f30f1cd0170012fedf6608140a585f544db58 (patch)
tree0ea4099f0442040d07b4b1b02dcc5c94d86b1966
parent67a63278a6c4e9347792219086f11a87d177eee7 (diff)
downloadscala-613f30f1cd0170012fedf6608140a585f544db58.tar.gz
scala-613f30f1cd0170012fedf6608140a585f544db58.tar.bz2
scala-613f30f1cd0170012fedf6608140a585f544db58.zip
Getting LiftCode to work.
-rw-r--r--src/compiler/scala/reflect/internal/TreeGen.scala21
-rw-r--r--src/compiler/scala/reflect/runtime/JavaToScala.scala8
-rw-r--r--src/compiler/scala/reflect/runtime/Loaders.scala4
-rw-r--r--src/compiler/scala/reflect/runtime/Mirror.scala4
-rw-r--r--src/compiler/scala/reflect/runtime/ScalaToJava.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/LiftCode.scala138
-rw-r--r--src/library/scala/reflect/Code.scala2
-rw-r--r--test/files/pos/bug531.scala (renamed from test/disabled/pos/bug531.scala)0
-rw-r--r--test/files/pos/bug532.scala (renamed from test/disabled/pos/bug532.scala)0
-rw-r--r--test/files/pos/code.scala (renamed from test/disabled/pos/code.scala)0
-rw-r--r--test/files/pos/t0651.scala (renamed from test/disabled/pos/t0651.scala)0
11 files changed, 92 insertions, 87 deletions
diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala
index a5149898b2..15c339aefd 100644
--- a/src/compiler/scala/reflect/internal/TreeGen.scala
+++ b/src/compiler/scala/reflect/internal/TreeGen.scala
@@ -189,21 +189,18 @@ abstract class TreeGen {
}
}
- private def mkTypeApply(value: Tree, tpe: Type, what: Symbol) =
- Apply(
- TypeApply(
- mkAttributedSelect(value, what),
- List(TypeTree(tpe.normalize))
- ),
- Nil
- )
+ private def mkTypeApply(value: Tree, tpe: Type, what: Symbol, wrapInApply: Boolean) = {
+ val tapp = TypeApply(mkAttributedSelect(value, what), List(TypeTree(tpe.normalize)))
+ if (wrapInApply) Apply(tapp, List()) else tapp
+ }
+
/** Builds an instance test with given value and type. */
- def mkIsInstanceOf(value: Tree, tpe: Type, any: Boolean = true): Tree =
- mkTypeApply(value, tpe, (if (any) Any_isInstanceOf else Object_isInstanceOf))
+ def mkIsInstanceOf(value: Tree, tpe: Type, any: Boolean = true, wrapInApply: Boolean = true): Tree =
+ mkTypeApply(value, tpe, (if (any) Any_isInstanceOf else Object_isInstanceOf), wrapInApply)
/** Builds a cast with given value and type. */
- def mkAsInstanceOf(value: Tree, tpe: Type, any: Boolean = true): Tree =
- mkTypeApply(value, tpe, (if (any) Any_asInstanceOf else Object_asInstanceOf))
+ def mkAsInstanceOf(value: Tree, tpe: Type, any: Boolean = true, wrapInApply: Boolean = true): Tree =
+ mkTypeApply(value, tpe, (if (any) Any_asInstanceOf else Object_asInstanceOf), wrapInApply)
/** Cast `tree` to `pt`, unless tpe is a subtype of pt, or pt is Unit. */
def maybeMkAsInstanceOf(tree: Tree, pt: Type, tpe: Type, beforeRefChecks: Boolean = false): Tree =
diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala
index 60e14ecec7..4406ab74be 100644
--- a/src/compiler/scala/reflect/runtime/JavaToScala.scala
+++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala
@@ -38,7 +38,7 @@ trait JavaToScala extends ConversionUtil { self: Universe =>
* ScalaSignature or ScalaLongSignature annotation.
*/
def unpickleClass(clazz: Symbol, module: Symbol, jclazz: jClass[_]): Unit = {
- println("unpickling " + clazz + " " + module)
+ //println("unpickling " + clazz + " " + module)//debug
val ssig = jclazz.getAnnotation(classOf[scala.reflect.ScalaSignature])
if (ssig != null) {
val bytes = ssig.bytes.getBytes
@@ -55,10 +55,10 @@ trait JavaToScala extends ConversionUtil { self: Universe =>
bs.copyToArray(bytes, len, l)
len += l
}
- println("long sig")
+ //println("long sig")//debug
unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName)
} else { // class does not have a Scala signature; it's a Java class
- println("no sig found for " + jclazz)
+ //println("no sig found for " + jclazz)//debug
initClassModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz))
}
}
@@ -106,7 +106,7 @@ trait JavaToScala extends ConversionUtil { self: Universe =>
*/
private class FromJavaClassCompleter(clazz: Symbol, module: Symbol, jclazz: jClass[_]) extends LazyType {
override def complete(sym: Symbol) = {
- println("completing from Java " + sym + "/" + clazz.fullName)
+ //println("completing from Java " + sym + "/" + clazz.fullName)//debug
assert(sym == clazz || sym == module || sym == module.moduleClass, sym)
val flags = toScalaFlags(jclazz.getModifiers, isClass = true)
clazz setFlag (flags | JAVA)
diff --git a/src/compiler/scala/reflect/runtime/Loaders.scala b/src/compiler/scala/reflect/runtime/Loaders.scala
index 3cab02706a..b508c8e2fe 100644
--- a/src/compiler/scala/reflect/runtime/Loaders.scala
+++ b/src/compiler/scala/reflect/runtime/Loaders.scala
@@ -29,7 +29,7 @@ trait Loaders { self: Universe =>
}
}
override def complete(sym: Symbol) = {
- println("completing "+sym+"/"+clazz.fullName)
+ //println("completing "+sym+"/"+clazz.fullName) //debug
assert(sym == clazz || sym == module || sym == module.moduleClass)
try {
unpickleClass(clazz, module, jClass.forName(clazz.fullName))
@@ -84,7 +84,7 @@ trait Loaders { self: Universe =>
(decls lookup name) orElse {
assert(this eq pkg.info, this+" "+pkg.info)
assert(decls eq pkg.info.decls)
- println("creating "+name+" in "+pkg)
+ //println("creating "+name+" in "+pkg) //debug
val (clazz, module) = createClassModule(pkg, name.toTypeName, new TopClassCompleter(_, _))
if (name.isTypeName) clazz else module
}
diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala
index d5d3762fab..561d0c9abf 100644
--- a/src/compiler/scala/reflect/runtime/Mirror.scala
+++ b/src/compiler/scala/reflect/runtime/Mirror.scala
@@ -33,9 +33,9 @@ class Mirror extends Universe with api.Mirror {
methodToJava(meth).invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)
}
- def freeValue(x: Any) = FreeValue(x)
+ def freeValue(x: Any): Tree = FreeValue(x)
- case class FreeValue(any: Any)
+ case class FreeValue(any: Any) extends Tree
}
diff --git a/src/compiler/scala/reflect/runtime/ScalaToJava.scala b/src/compiler/scala/reflect/runtime/ScalaToJava.scala
index 4155d7ee06..06ce2cfca2 100644
--- a/src/compiler/scala/reflect/runtime/ScalaToJava.scala
+++ b/src/compiler/scala/reflect/runtime/ScalaToJava.scala
@@ -27,7 +27,7 @@ trait ScalaToJava extends ConversionUtil { self: Universe =>
@throws(classOf[ClassNotFoundException])
def classToJava(clazz: Symbol): jClass[_] = classCache.toJava(clazz) {
def noClass = throw new ClassNotFoundException("no Java class corresponding to "+clazz+" found")
- println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)
+ //println("classToJava "+clazz+" "+clazz.owner+" "+clazz.owner.isPackageClass)//debug
if (clazz.isValueClass)
clazz match {
case UnitClass => java.lang.Void.TYPE
diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
index 353fbf94ad..36ba0ee88d 100644
--- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala
+++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala
@@ -47,7 +47,10 @@ abstract class LiftCode extends Transform with TypingTransformers {
val sym = tree.symbol
tree match {
case Apply(lift, List(tree)) if sym == Code_lift =>
- transform(localTyper.typedPos(tree.pos)(codify(tree)))
+ //printTypings = true //debug
+ val result = transform(localTyper.typedPos(tree.pos)(codify(tree)))
+ //printTypings = false //debug
+ result
case ValDef(mods, name, tpt, rhs) if (freeMutableVars(sym)) =>
val tpt1 = TypeTree(sym.tpe) setPos tpt.pos
/* Creating a constructor argument if one isn't present. */
@@ -56,7 +59,7 @@ abstract class LiftCode extends Transform with TypingTransformers {
case _ => transform(rhs)
}
val rhs1 = typer.typedPos(rhs.pos) {
- /*util.errtrace("lifted rhs for "+tree+" in "+unit)*/(
+ /*util.errtrace("lifted rhs for "+tree+" in "+unit)*/ (
Apply(Select(New(TypeTree(sym.tpe)), nme.CONSTRUCTOR), List(constructorArg)))
}
sym resetFlag MUTABLE
@@ -74,58 +77,36 @@ abstract class LiftCode extends Transform with TypingTransformers {
case class FreeValue(tree: Tree) extends Tree
- // !!! was: class Reifier(owner: Symbol)
class Reifier() {
- import reflect.runtime.{ Mirror => rm }
+ import reflect.runtime.{Mirror => rm}
private val boundVars: mutable.Set[Symbol] = mutable.Set()
- private val freeTrees: mutable.Set[Tree] = mutable.Set()
- private val mirrorPrefix = gen.mkAttributedRef(ReflectRuntimeMirror)
// todo replace className by caseName in CaseClass once we have switched to nsc.
def className(value: AnyRef): String = value match {
case _ :: _ => "scala.$colon$colon"
- case reflect.MethodType(_, _) =>
- "scala.reflect.MethodType"
- case x:Product =>
- "scala.reflect."+x.productPrefix //caseName
- //case _ => // bq:unreachable code
- // ""
+ case MethodType(_, _) => "scala.reflect.runtime.Mirror.MethodType"
+ case x: Product => "scala.reflect.runtime.Mirror."+x.productPrefix
+ case _ => ""
}
def objectName(value: Any): String = value match {
- case Nil => "scala.collection.immutable.Nil"
- case reflect.NoSymbol => "scala.reflect.runtime.Mirror.NoSymbol"
- case reflect.RootSymbol => "scala.reflect.runtime.Mirror.definitions.RootSymbol"
- case reflect.NoPrefix => "scala.reflect.runtime.Mirror.NoPrefix"
- case reflect.NoType => "scala.reflect.runtime.Mirror.NoType"
+ case Nil => "scala.collection.immutable.Nil"
+ case EmptyTree => "scala.reflect.runtime.Mirror.EmptyTree"
+ case NoSymbol => "scala.reflect.runtime.Mirror.NoSymbol"
+ case definitions.RootClass => "scala.reflect.runtime.Mirror.definitions.RootClass"
+ case NoPrefix => "scala.reflect.runtime.Mirror.NoPrefix"
+ case NoType => "scala.reflect.runtime.Mirror.NoType"
case _ => ""
}
- def treatProduct(c: Product): rm.Tree = {
- val name = objectName(c)
- if (name.length != 0)
- rm.gen.mkAttributedRef(rm.definitions.getModule(name))
- else {
- val name = className(c)
- if (name.length == 0) abort("don't know how to inject " + c)
- val injectedArgs = new ListBuffer[rm.Tree]
- for (i <- 0 until c.productArity)
- injectedArgs += reify(c.productElement(i))
- rm.New(rm.gen.mkAttributedRef(rm.definitions.getClass(name)), List(injectedArgs.toList))
- }
- }
-
- def reify(value: Any): rm.Tree = {
- def makeFree(tree: Tree): rm.Tree = {
- freeTrees += tree
- reify(Apply(gen.mkAttributedRef(definitions.freeValueMethod), List(tree)))
- }
+ def makeFree(tree: Tree): Tree =
+ Apply(mkTerm("scala.reflect.runtime.Mirror.freeValue"), List(tree))
+ def reify(value: Any): Tree = {
+ //println("reifing "+value) //debug
+ /*util.trace("reified "+value+" --> ")*/ {
value match {
- case tree: Tree if freeTrees contains tree =>
- // !!! was: tree
- makeFree(tree)
case tree: DefTree =>
boundVars += tree.symbol
reify1(tree)
@@ -135,41 +116,68 @@ abstract class LiftCode extends Transform with TypingTransformers {
makeFree(tree)
case _ =>
reify1(value)
+ }}
+ }
+
+ def mkMember(name: String, mkName: String => Name): Tree = {
+ val parts = name split "\\."
+ val prefixParts = parts.init
+ val lastName = mkName(parts.last)
+ if (prefixParts.isEmpty) Ident(lastName)
+ else {
+ val prefixTree = ((Ident(prefixParts.head): Tree) /: prefixParts.tail) (Select(_, _))
+ Select(prefixTree, lastName)
}
}
- def reify1(value: Any): rm.Tree = value match {
- case () => rm.Literal(rm.Constant(()))
- case x: String => rm.Literal(rm.Constant(x))
- case x: Boolean => rm.Literal(rm.Constant(x))
- case x: Byte => rm.Literal(rm.Constant(x))
- case x: Short => rm.Literal(rm.Constant(x))
- case x: Char => rm.Literal(rm.Constant(x))
- case x: Int => rm.Literal(rm.Constant(x))
- case x: Long => rm.Literal(rm.Constant(x))
- case x: Float => rm.Literal(rm.Constant(x))
- case x: Double => rm.Literal(rm.Constant(x))
+ def mkTerm(name: String) = mkMember(name, newTermName)
+ def mkType(name: String) = mkMember(name, newTypeName)
+
+ def reify1(value: Any): Tree = {
+ def treatProduct(c: Product): Tree = {
+ val name = objectName(c)
+ if (!name.isEmpty)
+ mkTerm(name)
+ else {
+ val name = className(c)
+ if (name.isEmpty) abort("don't know how to inject " + value + " of class "+ value.getClass)
+ val injectedArgs = new ListBuffer[Tree]
+ for (i <- 0 until c.productArity)
+ injectedArgs += reify(c.productElement(i))
+ New(mkType(name), List(injectedArgs.toList))
+ }
+ }
+
+ value match {
+ case () => Literal(Constant(()))
+ case x: String => Literal(Constant(x))
+ case x: Boolean => Literal(Constant(x))
+ case x: Byte => Literal(Constant(x))
+ case x: Short => Literal(Constant(x))
+ case x: Char => Literal(Constant(x))
+ case x: Int => Literal(Constant(x))
+ case x: Long => Literal(Constant(x))
+ case x: Float => Literal(Constant(x))
+ case x: Double => Literal(Constant(x))
+ case x: Map[_,_] => Apply(mkTerm("scala.collection.immutable.Map.apply"), Nil)//!!! Maps come from Modifiers, should not be part of case class
+ case x: TermName => Apply(mkTerm("scala.reflect.runtime.Mirror.newTermName"), List(Literal(Constant(x.toString))))
+ case x: TypeName => Apply(mkTerm("scala.reflect.runtime.Mirror.newTypeName"), List(Literal(Constant(x.toString))))
case c: Product => treatProduct(c)
case _ =>
- abort("don't know how to inject " + value)
+ abort("don't know how to inject " + value+" of class "+ value.getClass)
+ }
}
- } // Injector
+ }
- def reify(tree: Tree) = new Reifier().reify(tree)
+ def reify(tree: Tree): Tree =
+ new Reifier().reify(tree)
- def codify(tree: Tree) = {
- val tp = appliedType(CodeClass.typeConstructor, List(tree.tpe))
- // !!!
- New(TypeTree(tp), List(List(tree)))
+ def codify (tree: Tree): Tree = {
+ val targetType = definitions.CodeClass.primaryConstructor.info.paramTypes.head
+ val arg = gen.mkAsInstanceOf(reify(tree), targetType, wrapInApply = false)
+ New(TypeTree(appliedType(definitions.CodeClass.typeConstructor, List(tree.tpe))),
+ List(List(arg)))
}
- // was:
- //
- // def codify(tree: Tree): Tree =
- // Block(
- // ValDef(
- // New(TypeTree(appliedType(definitions.CodeClass.typeConstructor,
- // List(tree.tpe))),
- // List(List(reify(tree))))
/** Set of mutable local variables that are free in some inner method. */
private val freeMutableVars: mutable.Set[Symbol] = new mutable.HashSet
diff --git a/src/library/scala/reflect/Code.scala b/src/library/scala/reflect/Code.scala
index 1a5154ced1..52a7f2119a 100644
--- a/src/library/scala/reflect/Code.scala
+++ b/src/library/scala/reflect/Code.scala
@@ -11,7 +11,7 @@
package scala.reflect
/** This type is required by the compiler and <b>should not be used in client code</b>. */
-class Code[T](val tree: Tree)
+class Code[T](val tree: scala.reflect.mirror.Tree)
/** This type is required by the compiler and <b>should not be used in client code</b>. */
object Code {
diff --git a/test/disabled/pos/bug531.scala b/test/files/pos/bug531.scala
index 02763e08f1..02763e08f1 100644
--- a/test/disabled/pos/bug531.scala
+++ b/test/files/pos/bug531.scala
diff --git a/test/disabled/pos/bug532.scala b/test/files/pos/bug532.scala
index 32649b1629..32649b1629 100644
--- a/test/disabled/pos/bug532.scala
+++ b/test/files/pos/bug532.scala
diff --git a/test/disabled/pos/code.scala b/test/files/pos/code.scala
index 110e01c619..110e01c619 100644
--- a/test/disabled/pos/code.scala
+++ b/test/files/pos/code.scala
diff --git a/test/disabled/pos/t0651.scala b/test/files/pos/t0651.scala
index 52bef7e02b..52bef7e02b 100644
--- a/test/disabled/pos/t0651.scala
+++ b/test/files/pos/t0651.scala