Permalink
Browse files

Changes to Liftcode to use new reflection semantics, where a compiler…

… uses type checking.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@25697 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
  • Loading branch information...
1 parent e0cfcf3 commit ed89775a0551b4c4c29ac56490ce6f84e7954ea6 odersky committed Sep 20, 2011
@@ -39,6 +39,8 @@ class Mirror extends Universe with RuntimeTypes with api.Mirror {
def staticClass(name: String): Symbol = definitions.getClass(newTypeName(name))
def staticModule(name: String): Symbol = definitions.getModule(newTermName(name))
+ def freeVar(name: String, info: Type, value: Any) = new FreeVar(name, info, value)
+
/** Selects type symbol with given name from the defined members of prefix type
*/
def selectType(owner: Symbol, name: String): Symbol =
@@ -5,13 +5,15 @@ import collection.mutable.ListBuffer
trait RuntimeTypes extends Universe with api.RuntimeTypes {
- def freeValue(x: Any): Tree = FreeValue(x)
+ case class FreeVar(_name: TermName, _tpe: Type, value: Any) extends TermSymbol(definitions.RootClass, NoPosition, _name) {
+ setInfo(_tpe)
- // to do: replace with generalized
- // case class Literal(x: Any),
- // once calls to the deprecated factory Literal(x: Any) has been eliminated from all code.
- case class FreeValue(any: Any) extends Tree {
- protected def errorSubtrees = Nil
+ override def hashCode = value.hashCode
+
+ override def equals(other: Any): Boolean = other match {
+ case FreeVar(_, _, value1) => value.asInstanceOf[AnyRef] eq value1.asInstanceOf[AnyRef]
+ case _ => false
+ }
}
case class InstanceRefSymbol(value: AnyRef) extends TermSymbol(NoSymbol, NoPosition, nme.EMPTY)
@@ -97,21 +97,28 @@ abstract class LiftCode extends Transform with TypingTransformers {
private val localSyms = mutable.ArrayBuffer[Symbol]()
private val symIndex = mutable.HashMap[Symbol, Int]()
+ private var localClasses = Set[Symbol]()
private val typeTree = mutable.HashMap[Type, Tree]()
private val typeTreeCount = mutable.HashMap[Tree, Int]()
/** Generate tree of the form
*
- * { val $localSyms = Array(sym1, ..., symN)
- * localSyms(1).setInfo(tpe1)
+ * { val $mr = scala.reflect.runtime.Mirror
+ * val $memo = new scala.reflext.runtime.Memoizer
+ * $local1 = new TypeSymbol(owner1, NoPosition, name1)
* ...
- * localSyms(N).setInfo(tpeN)
+ * $localN = new TermSymbol(ownerN, NoPositiion, nameN)
+ * $local1.setInfo(tpe1)
+ * ...
+ * $localN.setInfo(tpeN)
+ * $localN.setAnnotations(annotsN)
* rtree
* }
*
* where
*
- * - `symI` are the symbols defined locally in `tree`
+ * - `$localI` are free type symbols in the environment, as well as local symbols
+ * of refinement types.
* - `tpeI` are the info's of `symI`
* - `rtree` is code that generates `tree` at runtime, maintaining all attributes.
*/
@@ -131,6 +138,8 @@ abstract class LiftCode extends Transform with TypingTransformers {
// helper methods
+ private def localName(sym: Symbol) = localPrefix + symIndex(sym)
+
private def call(fname: String, args: Tree*): Tree =
Apply(termPath(fname), args.toList)
@@ -178,7 +187,7 @@ abstract class LiftCode extends Transform with TypingTransformers {
private def reifySymRef(sym: Symbol): Tree = {
symIndex get sym match {
case Some(idx) =>
- Ident(localPrefix + symIndex(sym))
+ Ident(localName(sym))
case None =>
if (sym.isStatic)
mirrorCall(if (sym.isType) "staticClass" else "staticModule", reify(sym.fullName))
@@ -192,10 +201,15 @@ abstract class LiftCode extends Transform with TypingTransformers {
else mirrorCall("selectTerm", rowner, rname, reify(sym.tpe))
}
else {
- println("Late local: "+sym)
- assert(!sym.isParameter, sym+"/"+sym.owner+"/"+sym.owner.info+"/"+sym.paramPos)
- registerLocalSymbol(sym)
- reifySymRef(sym)
+ if (sym.isTerm) {
+ println("Free: "+sym)
+ mirrorCall("freeVar", reify(sym.name.toString), reify(sym.tpe), Ident(sym))
+ } else {
+ println("Late local: "+sym)
+ assert(!sym.isParameter, sym+"/"+sym.owner+"/"+sym.owner.info+"/"+sym.paramPos)
+ registerLocalSymbol(sym)
+ reifySymRef(sym)
+ }
}
}
}
@@ -209,7 +223,7 @@ abstract class LiftCode extends Transform with TypingTransformers {
List(List(reify(sym.owner), reify(sym.pos), reify(sym.name))))
if (sym.flags != 0L)
rsym = Apply(Select(rsym, "setFlag"), List(Literal(Constant(sym.flags))))
- ValDef(NoMods, localPrefix + symIndex(sym), TypeTree(), rsym)
+ ValDef(NoMods, localName(sym), TypeTree(), rsym)
}
/** Generate code to add type and annotation info to a reified symbol
@@ -255,7 +269,7 @@ abstract class LiftCode extends Transform with TypingTransformers {
case t @ ExistentialType(tparams, underlying) =>
reifyTypeBinder(t, tparams, underlying)
case t @ PolyType(tparams, underlying) =>
- reifyTypeBinder(t, tparams, underlying)
+ reifyTypeBinder(t, tparams, underlying)
case t @ MethodType(params, restpe) =>
reifyTypeBinder(t, params, restpe)
case _ =>
@@ -268,17 +282,23 @@ abstract class LiftCode extends Transform with TypingTransformers {
/** Reify a tree */
private def reifyTree(tree: Tree): Tree = tree match {
- case tree @ This(_) if !(symIndex isDefinedAt tree.symbol) =>
- reifyFree(tree)
- case tree @ Ident(_) if !(symIndex isDefinedAt tree.symbol) =>
+ case EmptyTree =>
+ reifyCaseObject(tree)
+ case ClassDef(_, _, _, _) =>
+ localClasses += tree.symbol
+ reifyCaseClassInstance(tree)
+ case tree @ This(_) if !(localClasses contains tree.symbol) =>
reifyFree(tree)
case _ =>
- var rtree = reifyCaseClassInstance(tree.asInstanceOf[Product])
+// var rtree =
+ reifyCaseClassInstance(tree.asInstanceOf[Product])
+/*
if (tree.isDef || tree.isInstanceOf[Function])
registerLocalSymbol(tree.symbol)
if (tree.hasSymbol)
rtree = Apply(Select(rtree, "setSymbol"), List(reifySymRef(tree.symbol)))
Apply(Select(rtree, "setType"), List(reifyType(tree.tpe)))
+*/
}
/** Reify a free reference. The result will be either a mirror reference
@@ -287,8 +307,8 @@ abstract class LiftCode extends Transform with TypingTransformers {
private def reifyFree(tree: Tree): Tree =
if (tree.symbol.hasFlag(MODULE) && tree.symbol.isStatic)
reify(termPath(tree.symbol.fullName))
- else
- mirrorCall("Literal", tree)
+ else // make an Ident to a freeVar
+ mirrorCall("Ident", reifySymRef(tree.symbol))
/** Reify an arbitary value */
private def reify(value: Any): Tree = {
@@ -11,7 +11,9 @@
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: scala.reflect.mirror.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 {
@@ -1,3 +1,7 @@
-class Test {
- val fun: reflect.Code[Int => Int] = x => x + 1;
+object Test extends App {
+ def foo[T](ys: List[T]) = {
+ val fun: reflect.Code[Int => Int] = x => x + ys.length
+ fun
+ }
+ println(foo(List(2)).tree)
}
@@ -1,10 +1,10 @@
-import scala.collection.generic._
+import scala.collection.generic.CanBuildFrom
import scala.collection._
object Test {
- def collect[A, Res](r: Traversable[A])(implicit bf: CanBuild[A, Res]) = {
- val b = bf()
- for (a <- r) b += a
+ def collect[A, Res](r: Traversable[A])(implicit bf: generic.CanBuild[A, Res]) = {
+ val b: collection.mutable.Builder[A, Res] = bf()
+ r foreach ((a: A) => b += a)
b.result
}
@@ -54,10 +54,10 @@ final class ClosureTest {
}
}
-object TestInt extends testing.Benchmark {
+object TestInt extends scala.testing.Benchmark {
def run() = (new IntTest).run()
}
-object TestClosure extends testing.Benchmark {
+object TestClosure extends scala.testing.Benchmark {
def run() = (new ClosureTest).run()
}

0 comments on commit ed89775

Please sign in to comment.