diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala index 2cb1069df8e..e9892621a3a 100644 --- a/src/compiler/scala/reflect/runtime/Mirror.scala +++ b/src/compiler/scala/reflect/runtime/Mirror.scala @@ -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 = diff --git a/src/compiler/scala/reflect/runtime/RuntimeTypes.scala b/src/compiler/scala/reflect/runtime/RuntimeTypes.scala index eff9fb05e4e..69306186d13 100644 --- a/src/compiler/scala/reflect/runtime/RuntimeTypes.scala +++ b/src/compiler/scala/reflect/runtime/RuntimeTypes.scala @@ -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) diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index 7ccad443e15..ba306b5ff5c 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -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 = { diff --git a/src/library/scala/reflect/Code.scala b/src/library/scala/reflect/Code.scala index 52a7f2119a6..d0a2d6ddba4 100644 --- a/src/library/scala/reflect/Code.scala +++ b/src/library/scala/reflect/Code.scala @@ -11,7 +11,9 @@ package scala.reflect /** This type is required by the compiler and should not be used in client code. */ -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 should not be used in client code. */ object Code { diff --git a/test/disabled/pos/code.scala b/test/disabled/pos/code.scala index 110e01c6196..707dda3e3b6 100644 --- a/test/disabled/pos/code.scala +++ b/test/disabled/pos/code.scala @@ -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) } diff --git a/test/files/pos/collectGenericCC.scala b/test/files/pos/collectGenericCC.scala index 750475207fb..8201c6a271f 100644 --- a/test/files/pos/collectGenericCC.scala +++ b/test/files/pos/collectGenericCC.scala @@ -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 } diff --git a/test/files/pos/spec-funs.scala b/test/files/pos/spec-funs.scala index 9acc5054c9b..611ec0ef62f 100644 --- a/test/files/pos/spec-funs.scala +++ b/test/files/pos/spec-funs.scala @@ -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() }