diff options
author | Martin Odersky <odersky@gmail.com> | 2011-07-30 21:04:43 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2011-07-30 21:04:43 +0000 |
commit | c0db3f2d065e22796a2c917c6c3b0f14f3982cf0 (patch) | |
tree | a21a5982ec9d0a6311843b2e1397192a3a64aecd | |
parent | d0c5e4be5554f4862da0690ac0315a4433fcb5d5 (diff) | |
download | scala-c0db3f2d065e22796a2c917c6c3b0f14f3982cf0.tar.gz scala-c0db3f2d065e22796a2c917c6c3b0f14f3982cf0.tar.bz2 scala-c0db3f2d065e22796a2c917c6c3b0f14f3982cf0.zip |
LiftCode works again, now integrated with new r...
LiftCode works again, now integrated with new reflection library.
Other changes: def Literal(x: Any) has been deprecated, and all its uses removed.
Modifiers has lost positions as fourth case class argument; is now a field, mirroring Tree.pos (this removes junk in patterns and makes reification simpler). Review by extempore.
29 files changed, 208 insertions, 489 deletions
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF index ce1471b2de..67019ed9a1 100644 --- a/META-INF/MANIFEST.MF +++ b/META-INF/MANIFEST.MF @@ -41,7 +41,6 @@ Export-Package: scala.tools.util, scala.reflect.internal, scala.reflect.internal.settings, - scala.reflect.api, scala.reflect.runtime, scala.reflect.std, scala.reflect.internal.transform, diff --git a/src/compiler/scala/reflect/internal/TreeGen.scala b/src/compiler/scala/reflect/internal/TreeGen.scala index 15c339aefd..61c4edf75e 100644 --- a/src/compiler/scala/reflect/internal/TreeGen.scala +++ b/src/compiler/scala/reflect/internal/TreeGen.scala @@ -243,15 +243,15 @@ abstract class TreeGen { */ def mkZero(tp: Type): Tree = { val tree = tp.typeSymbol match { - case UnitClass => Literal(()) - case BooleanClass => Literal(false) - case FloatClass => Literal(0.0f) - case DoubleClass => Literal(0.0d) - case ByteClass => Literal(0.toByte) - case ShortClass => Literal(0.toShort) - case IntClass => Literal(0) - case LongClass => Literal(0L) - case CharClass => Literal(0.toChar) + case UnitClass => Literal(Constant()) + case BooleanClass => Literal(Constant(false)) + case FloatClass => Literal(Constant(0.0f)) + case DoubleClass => Literal(Constant(0.0d)) + case ByteClass => Literal(Constant(0.toByte)) + case ShortClass => Literal(Constant(0.toShort)) + case IntClass => Literal(Constant(0)) + case LongClass => Literal(Constant(0L)) + case CharClass => Literal(Constant(0.toChar)) case _ => Literal(Constant(null)) } tree setType tp @@ -259,7 +259,7 @@ abstract class TreeGen { /** Builds a tuple */ def mkTuple(elems: List[Tree]): Tree = - if (elems.isEmpty) Literal(()) + if (elems.isEmpty) Literal(Constant()) else Apply( Select(mkAttributedRef(TupleClass(elems.length).caseModule), nme.apply), elems) diff --git a/src/compiler/scala/reflect/internal/TreePrinters.scala b/src/compiler/scala/reflect/internal/TreePrinters.scala index aef9219ed4..e5b9fafa00 100644 --- a/src/compiler/scala/reflect/internal/TreePrinters.scala +++ b/src/compiler/scala/reflect/internal/TreePrinters.scala @@ -435,7 +435,8 @@ trait TreePrinters { self: SymbolTable => } } - def xprintRaw(treePrinter: TreePrinter, tree: Tree) = print("<unknown tree of class "+tree.getClass+">") + def xprintRaw(treePrinter: TreePrinter, tree: Tree) = + treePrinter.print(tree.productPrefix+tree.productIterator.mkString("(", ", ", ")")) def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer) def newTreePrinter(stream: OutputStream): TreePrinter = newTreePrinter(new PrintWriter(stream)) diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala index ef80b5d479..5ba1a1221e 100644 --- a/src/compiler/scala/reflect/internal/Trees.scala +++ b/src/compiler/scala/reflect/internal/Trees.scala @@ -22,8 +22,13 @@ trait Trees extends api.Trees { self: SymbolTable => */ case class Modifiers(flags: Long, privateWithin: Name, - annotations: List[Tree], - positions: Map[Long, Position]) extends AbsModifiers with HasFlags { + annotations: List[Tree]) extends AbsModifiers with HasFlags { + + var positions: Map[Long, Position] = Map() + + def setPositions(poss: Map[Long, Position]): this.type = { + positions = poss; this + } /* Abstract types from HasFlags. */ type FlagsType = Long @@ -40,42 +45,43 @@ trait Trees extends api.Trees { self: SymbolTable => def & (flag: Long): Modifiers = { val flags1 = flags & flag if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations, positions) + else Modifiers(flags1, privateWithin, annotations) setPositions positions } def &~ (flag: Long): Modifiers = { val flags1 = flags & (~flag) if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations, positions) + else Modifiers(flags1, privateWithin, annotations) setPositions positions } def | (flag: Long): Modifiers = { val flags1 = flags | flag if (flags1 == flags) this - else Modifiers(flags1, privateWithin, annotations, positions) + else Modifiers(flags1, privateWithin, annotations) setPositions positions } def withAnnotations(annots: List[Tree]) = if (annots.isEmpty) this - else copy(annotations = annotations ::: annots) + else copy(annotations = annotations ::: annots) setPositions positions + def withPosition(flag: Long, position: Position) = - copy(positions = positions + (flag -> position)) + copy() setPositions positions + (flag -> position) override def hasModifier(mod: Modifier.Value) = hasFlag(flagOfModifier(mod)) override def allModifiers: Set[Modifier.Value] = Modifier.values filter hasModifier override def mapAnnotations(f: List[Tree] => List[Tree]): Modifiers = - Modifiers(flags, privateWithin, f(annotations), positions) + Modifiers(flags, privateWithin, f(annotations)) setPositions positions override def toString = "Modifiers(%s, %s, %s)".format(hasFlagsToString(-1L), annotations mkString ", ", positions) } - def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List(), Map.empty) + def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List()) def Modifiers(flags: Long): Modifiers = Modifiers(flags, tpnme.EMPTY) def Modifiers(mods: Set[Modifier.Value], privateWithin: Name, annotations: List[Tree]): Modifiers = { val flagSet = mods map flagOfModifier - Modifiers((0L /: flagSet)(_ | _), privateWithin, annotations, Map.empty) + Modifiers((0L /: flagSet)(_ | _), privateWithin, annotations) } lazy val NoMods = Modifiers(0) diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 545b86f6ab..81962f89d8 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -826,7 +826,8 @@ trait Types extends api.Types { self: SymbolTable => /** The string representation of this type, with singletypes explained. */ def toLongString = { val str = toString - if (str endsWith ".type") str + " (with underlying type " + widen + ")" + if (str == "type") widen.toString + else if (str endsWith ".type") str + " (with underlying type " + widen + ")" else str } diff --git a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala index 6d0b22ac05..dfae6c50be 100644 --- a/src/compiler/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/compiler/scala/reflect/internal/pickling/UnPickler.scala @@ -766,7 +766,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ { val pflags = (pflagsHi.toLong << 32) + pflagsLo val flags = pickledToRawFlags(pflags) val privateWithin = readNameRef() - Modifiers(flags, privateWithin, Nil, Map.empty) + Modifiers(flags, privateWithin, Nil) } /* Read a reference to a pickled item */ diff --git a/src/compiler/scala/reflect/runtime/Mirror.scala b/src/compiler/scala/reflect/runtime/Mirror.scala index 561d0c9abf..b1724d6450 100644 --- a/src/compiler/scala/reflect/runtime/Mirror.scala +++ b/src/compiler/scala/reflect/runtime/Mirror.scala @@ -35,6 +35,9 @@ class Mirror extends Universe with api.Mirror { def freeValue(x: Any): Tree = FreeValue(x) + // 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 } diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index d33ca3a6bc..10762bfa98 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -90,7 +90,7 @@ abstract class TreeGen extends reflect.internal.TreeGen { mkMethodCall(ScalaRunTimeModule, meth, targs, args) def mkSysErrorCall(message: String): Tree = - mkMethodCall(Sys_error, List(Literal(message))) + mkMethodCall(Sys_error, List(Literal(Constant(message)))) /** A creator for a call to a scala.reflect.Manifest or ClassManifest factory method. * diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala index 346cc10393..86aca26ba6 100644 --- a/src/compiler/scala/tools/nsc/ast/Trees.scala +++ b/src/compiler/scala/tools/nsc/ast/Trees.scala @@ -92,7 +92,7 @@ trait Trees extends reflect.internal.Trees { self: Global => if (body forall treeInfo.isInterfaceMember) List() else List( atPos(wrappingPos(superPos, lvdefs)) ( - DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), List(List()), TypeTree(), Block(lvdefs, Literal(()))))) + DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), List(List()), TypeTree(), Block(lvdefs, Literal(Constant()))))) } else { // convert (implicit ... ) to ()(implicit ... ) if its the only parameter section if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit) @@ -103,7 +103,7 @@ trait Trees extends reflect.internal.Trees { self: Global => val superCall = (superRef /: argss) (Apply) List( atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) ( - DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(()))))) + DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant()))))) } } // println("typed template, gvdefs = "+gvdefs+", parents = "+parents+", constrs = "+constrs) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index ac9f853477..6b9f7bf79e 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -51,7 +51,7 @@ trait ParsersCommon extends ScannersCommon { def inParensOrError[T](body: => T, alt: T): T = if (in.token == LPAREN) inParens(body) else { accept(LPAREN) ; alt } - def inParensOrUnit[T](body: => Tree): Tree = inParensOrError(body, Literal(())) + def inParensOrUnit[T](body: => Tree): Tree = inParensOrError(body, Literal(Constant())) def inParensOrNil[T](body: => List[T]): List[T] = inParensOrError(body, Nil) def inBraces[T](body: => T): T = { @@ -64,7 +64,7 @@ trait ParsersCommon extends ScannersCommon { if (in.token == LBRACE) inBraces(body) else { accept(LBRACE) ; alt } def inBracesOrNil[T](body: => List[T]): List[T] = inBracesOrError(body, Nil) - def inBracesOrUnit[T](body: => Tree): Tree = inBracesOrError(body, Literal(())) + def inBracesOrUnit[T](body: => Tree): Tree = inBracesOrError(body, Literal(Constant())) def inBrackets[T](body: => T): T = { accept(LBRACKET) @@ -1197,7 +1197,7 @@ self => r } else { accept(LPAREN) - Literal(true) + Literal(Constant(true)) } } @@ -1250,7 +1250,7 @@ self => newLinesOpt() val thenp = expr() val elsep = if (in.token == ELSE) { in.nextToken(); expr() } - else Literal(()) + else Literal(Constant()) If(cond, thenp, elsep) } case TRY => @@ -1311,7 +1311,7 @@ self => } case RETURN => atPos(in.skipToken()) { - Return(if (isExprIntro) expr() else Literal(())) + Return(if (isExprIntro) expr() else Literal(Constant())) } case THROW => atPos(in.skipToken()) { @@ -2431,7 +2431,7 @@ self => */ def constrExpr(vparamss: List[List[ValDef]]): Tree = if (in.token == LBRACE) constrBlock(vparamss) - else Block(List(selfInvocation(vparamss)), Literal(())) + else Block(List(selfInvocation(vparamss)), Literal(Constant())) /** {{{ * SelfInvocation ::= this ArgumentExprs {ArgumentExprs} @@ -2461,7 +2461,7 @@ self => else Nil } accept(RBRACE) - Block(stats, Literal(())) + Block(stats, Literal(Constant())) } /** {{{ @@ -2902,7 +2902,7 @@ self => else List(tmplDef(pos, mods)) in.token match { - case RBRACE | CASE => defs :+ (Literal(()) setPos o2p(in.offset)) + case RBRACE | CASE => defs :+ (Literal(Constant()) setPos o2p(in.offset)) case _ => defs } } diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index a154009ce0..e3af9f52ae 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -134,7 +134,7 @@ abstract class TreeBuilder { ImportSelector(name, nameOffset, name, nameOffset) def makeTupleTerm(trees: List[Tree], flattenUnary: Boolean): Tree = trees match { - case Nil => Literal(()) + case Nil => Literal(Constant()) case List(tree) if flattenUnary => tree case _ => makeTuple(trees, false) } @@ -243,21 +243,21 @@ abstract class TreeBuilder { /** Create tree representing a while loop */ def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = { val continu = atPos(o2p(body.pos.endOrPoint)) { Apply(Ident(lname), Nil) } - val rhs = If(cond, Block(List(body), continu), Literal(())) + val rhs = If(cond, Block(List(body), continu), Literal(Constant())) LabelDef(lname, Nil, rhs) } /** Create tree representing a do-while loop */ def makeDoWhile(lname: TermName, body: Tree, cond: Tree): Tree = { val continu = Apply(Ident(lname), Nil) - val rhs = Block(List(body), If(cond, continu, Literal(()))) + val rhs = Block(List(body), If(cond, continu, Literal(Constant()))) LabelDef(lname, Nil, rhs) } /** Create block of statements `stats` */ def makeBlock(stats: List[Tree]): Tree = - if (stats.isEmpty) Literal(()) - else if (!stats.last.isTerm) Block(stats, Literal(())) + if (stats.isEmpty) Literal(Constant()) + else if (!stats.last.isTerm) Block(stats, Literal(Constant())) else if (stats.length == 1) stats.head else Block(stats.init, stats.last) @@ -276,8 +276,8 @@ abstract class TreeBuilder { List( makeVisitor( List( - CaseDef(pat1.duplicate, EmptyTree, Literal(true)), - CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false))), + CaseDef(pat1.duplicate, EmptyTree, Literal(Constant(true))), + CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false)))), false, nme.CHECK_IF_REFUTABLE_STRING ))) diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 1ea0255515..742e9e03ca 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -549,7 +549,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { atPos(pos) { New(Select(scalaDot(newTermName("runtime")), tpnme.AnnotationDefaultATTR), List(List())) } - mods1 = Modifiers(mods1.flags, mods1.privateWithin, annot :: mods1.annotations, mods1.positions) + mods1 = mods1 withAnnotations List(annot) skipTo(SEMI) accept(SEMI) blankExpr diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index 91626313ee..dc3328de70 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -311,7 +311,7 @@ trait ParallelMatching extends ast.TreeDSL val r = remake(newRows ++ defaultRows, includeScrut = false) val r2 = make(r.tvars, r.rows map (x => x rebind bindVars(tag, x.subst))) - CASE(Literal(tag)) ==> r2.toTree + CASE(Literal(Constant(tag))) ==> r2.toTree } lazy val defaultTree = remake(defaultRows, includeScrut = false).toTree @@ -834,7 +834,7 @@ trait ParallelMatching extends ast.TreeDSL typer typed { tpe match { case ConstantType(Constant(null)) if isRef => scrutTree OBJ_EQ NULL - case ConstantType(Constant(value)) => scrutTree MEMBER_== Literal(value) + case ConstantType(const) => scrutTree MEMBER_== Literal(const) case SingleType(NoPrefix, sym) => genEquals(sym) case SingleType(pre, sym) if sym.isStable => genEquals(sym) case ThisType(sym) if sym.isModule => genEquals(sym) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 475804c2a6..12a17abe91 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -422,7 +422,7 @@ abstract class Pickler extends SubComponent { * argument of some Annotation */ private def putMods(mods: Modifiers) = if (putEntry(mods)) { // annotations in Modifiers are removed by the typechecker - val Modifiers(flags, privateWithin, Nil, _) = mods + val Modifiers(flags, privateWithin, Nil) = mods putEntry(privateWithin) } @@ -966,7 +966,7 @@ abstract class Pickler extends SubComponent { writeRefs(whereClauses) TREE - case Modifiers(flags, privateWithin, _, _) => + case Modifiers(flags, privateWithin, _) => val pflags = rawFlagsToPickled(flags) writeNat((pflags >> 32).toInt) writeNat((pflags & 0xFFFFFFFF).toInt) diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index b01b1541b6..c467ed9445 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -253,7 +253,7 @@ abstract class AddInterfaces extends InfoTransform { */ private def addMixinConstructorDef(clazz: Symbol, stats: List[Tree]): List[Tree] = if (treeInfo.firstConstructor(stats) != EmptyTree) stats - else DefDef(clazz.primaryConstructor, Block(List(), Literal(()))) :: stats + else DefDef(clazz.primaryConstructor, Block(List(), Literal(Constant()))) :: stats private def implTemplate(clazz: Symbol, templ: Template): Template = atPos(templ.pos) { val templ1 = atPos(templ.pos) { diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 86afd8f078..f31d853967 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -696,7 +696,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { val staticCtorSym = currentClass.newConstructor(template.pos) .setFlag(STATIC) .setInfo(UnitClass.tpe) - val rhs = Block(newStaticInits.toList, Literal(())) + val rhs = Block(newStaticInits.toList, Literal(Constant())) val staticCtorTree = DefDef(staticCtorSym, rhs) localTyper.typed { atPos(template.pos)(staticCtorTree) } } diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index b5b770b003..98d6286d02 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -374,7 +374,7 @@ abstract class Constructors extends Transform with ast.TreeDSL { Apply(gen.mkAttributedRef(specializedFlag), List()), definitions.getMember(definitions.BooleanClass, nme.UNARY_!)), List()), - Block(stats, Literal(())), + Block(stats, Literal(Constant())), EmptyTree) List(localTyper.typed(tree)) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 99df069e3b..b53baf45eb 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -361,10 +361,10 @@ abstract class Erasure extends AddInterfaces case LabelDef(name, params, Boxed(rhs)) => Some(treeCopy.LabelDef(tree, name, params, rhs) setType rhs.tpe) case Select(_, _) if tree.symbol == BoxedUnit_UNIT => - Some(Literal(()) setPos tree.pos setType UnitClass.tpe) + Some(Literal(Constant()) setPos tree.pos setType UnitClass.tpe) case Block(List(unboxed), ret @ Select(_, _)) if ret.symbol == BoxedUnit_UNIT => Some(if (unboxed.tpe.typeSymbol == UnitClass) tree - else Block(List(unboxed), Literal(()) setPos tree.pos setType UnitClass.tpe)) + else Block(List(unboxed), Literal(Constant()) setPos tree.pos setType UnitClass.tpe)) case Apply(fn, List(unboxed)) if isBox(fn.symbol) => Some(unboxed) case _ => diff --git a/src/compiler/scala/tools/nsc/transform/LiftCode.scala b/src/compiler/scala/tools/nsc/transform/LiftCode.scala index 9c4ed0d25d..bd0e8c1e08 100644 --- a/src/compiler/scala/tools/nsc/transform/LiftCode.scala +++ b/src/compiler/scala/tools/nsc/transform/LiftCode.scala @@ -49,6 +49,7 @@ abstract class LiftCode extends Transform with TypingTransformers { case Apply(lift, List(tree)) if sym == Code_lift => //printTypings = true //debug val result = transform(localTyper.typedPos(tree.pos)(codify(tree))) + //println("transformed = "+result) //debug //printTypings = false //debug result case ValDef(mods, name, tpt, rhs) if (freeMutableVars(sym)) => @@ -73,117 +74,151 @@ abstract class LiftCode extends Transform with TypingTransformers { super.transform(tree) } } - } - case class FreeValue(tree: Tree) extends Tree + /** todo: Treat embedded Code blocks by merging them into containing block + * + */ + class Reifier() { - class Reifier() { - import reflect.runtime.{Mirror => rm} + private val boundVars: mutable.Set[Symbol] = mutable.Set() - private val boundVars: mutable.Set[Symbol] = mutable.Set() + // todo: review & rework + // 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 MethodType(_, _) => "scala.reflect.runtime.Mirror.MethodType" + case x: Product => "scala.reflect.runtime.Mirror." + x.productPrefix + case _ => "" + } - // 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 MethodType(_, _) => "scala.reflect.runtime.Mirror.MethodType" - case x: Product => "scala.reflect.runtime.Mirror."+x.productPrefix - case _ => "" - } + // todo: review & rework + def objectName(value: Any): String = value match { + 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 objectName(value: Any): String = value match { - 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 _ => "" - } + /** Reify a free reference. The result will be either a mirror reference + * to a global value, or else a mirror Literal. + */ + def reifyFree(tree: Tree): Tree = + if (tree.symbol.hasFlag(MODULE) && tree.symbol.isStatic) + reifiedPath(tree.symbol.fullName) + else + Apply(termPath("scala.reflect.runtime.Mirror.freeValue"), 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: DefTree => - boundVars += tree.symbol - reify1(tree) - case tree @ This(_) if !(boundVars contains tree.symbol) => - makeFree(tree) - case tree @ Ident(_) if !(boundVars contains tree.symbol) => - makeFree(tree) - case _ => - reify1(value) - }} - } + /** Reify an arbitary value */ + def reify(value: Any): Tree = { + //println("reifing "+value) //debug + /*util.trace("reified "+value+" --> ")*/ { + value match { + case tree: DefTree => + boundVars += tree.symbol + reify1(tree) + case tree @ This(_) if !(boundVars contains tree.symbol) => + reifyFree(tree) + case tree @ Ident(_) if !(boundVars contains tree.symbol) => + reifyFree(tree) + case tree @ TypeTree() if tree.original != null => + reify(tree.original) + // todo: should we also reify inferred types? + case _ => + reify1(value) + } + } + } + + /** Second part of reify */ + def reify1(value: Any): Tree = { + def treatProduct(c: Product): Tree = { + val fullname = objectName(c) + if (!fullname.isEmpty) + termPath(fullname) + else { + val fullname = className(c) + if (fullname.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(typePath(fullname), List(injectedArgs.toList)) + } + } - 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) + 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: Name => reifiedName(x) + case c: Product => treatProduct(c) + case _ => + abort("don't know how to inject " + value + " of class " + value.getClass) + } + } + + /** The reified version of given name */ + def reifiedName(name: Name) = { + val fn = "scala.reflect.runtime.Mirror.new"+(if (name.isTypeName) "TypeName" else "TermName") + Apply(termPath(fn), List(Literal(Constant(name.toString)))) } - } - def mkTerm(name: String) = mkMember(name, newTermName) - def mkType(name: String) = mkMember(name, newTypeName) + /** A reified identifier with given name */ + def reifiedIdent(name: Name) = + New(typePath("scala.reflect.runtime.Mirror.Ident"), List(List(reifiedName(name)))) - def reify1(value: Any): Tree = { - def treatProduct(c: Product): Tree = { - val name = objectName(c) - if (name != "") - mkTerm(name) + /** A reified selection over given qualifier and name */ + def reifiedSelect(qual: Tree, name: Name) = + New(typePath("scala.reflect.runtime.Mirror.Select"), List(List(qual, reifiedName(name)))) + + /** A reified path that selects definition with given fully qualified name */ + def reifiedPath(fullname: String): Tree = { + val parts = fullname split "\\." + val prefixParts = parts.init + val lastName = parts.last + if (prefixParts.isEmpty) reifiedIdent(lastName) else { - val name = className(c) - if (name == "") - 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)) - - // Note to self: do some profiling and find out how the speed - // of the above compares to: - // - // New(mkType(name), List(c.productIterator map reify toList)) + val prefixTree = ((reifiedIdent(prefixParts.head): Tree) /: prefixParts.tail)(reifiedSelect(_, _)) + reifiedSelect(prefixTree, lastName) } } - 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)) - //!!! Maps come from Modifiers, should not be part of case class - case x: Map[_,_] => Apply(mkTerm("scala.collection.immutable.Map.apply"), Nil) - 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 + " of class " + value.getClass) + /** An (unreified) path that refers to definition with given fully qualified name + * @param mkName Creator for last portion of name (either TermName or TypeName) + */ + private def path(fullname: String, mkName: String => Name): Tree = { + val parts = fullname 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 reify(tree: Tree): Tree = - new Reifier().reify(tree) + /** An (unreified) path that refers to term definition with given fully qualified name */ + def termPath(fullname: String) = path(fullname, newTermName) - 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))), + /** An (unreified) path that refers to type definition with given fully qualified name */ + def typePath(fullname: String) = path(fullname, newTypeName) + } + + def codify(tree: Tree): Tree = /*util.trace("codified " + tree + " -> ")*/ { + val targetType = definitions.CodeClass.primaryConstructor.info.paramTypes.head + val arg = gen.mkAsInstanceOf(new Reifier().reify(tree), targetType, wrapInApply = false) + New(TypeTree(appliedType(definitions.CodeClass.typeConstructor, List(tree.tpe))), List(List(arg))) + } } /** Set of mutable local variables that are free in some inner method. */ diff --git a/src/compiler/scala/tools/nsc/transform/Reifiers.scala b/src/compiler/scala/tools/nsc/transform/Reifiers.scala deleted file mode 100644 index b9e558add6..0000000000 --- a/src/compiler/scala/tools/nsc/transform/Reifiers.scala +++ /dev/null @@ -1,330 +0,0 @@ -package scala.tools.nsc -package transform - -import scala.tools.nsc.symtab.SymbolTable -import scala.reflect -import collection.mutable - -/** Functions to reify (and un-reify) symbols, types, and trees. - * These can be used with only a symbol table; they do not - * need a full compiler. - * - * @author Gilles Dubochet, Lex Spoon - */ -trait Reifiers { - val symbols: Global - import symbols._ - - private def mkGlobalSymbol(fullname: String, sym: Symbol): reflect.Symbol = - if (sym.isClass) reflect.Class(fullname) - else if (sym.isType) reflect.TypeField(fullname, reify(sym.info)) - else if (sym.isMethod) reflect.Method(fullname, reify(sym.info)) - else if (sym.isValueParameter) reflect.LocalValue(reflect.NoSymbol, fullname, reify(sym.info)) - else reflect.Field(fullname, reify(sym.info)); - - def reify(sym: Symbol): reflect.Symbol = { - if (sym.isRoot || sym.isRootPackage || sym.isEmptyPackageClass || sym.isEmptyPackage) - reflect.RootSymbol - else if (sym.isValueParameter) - mkGlobalSymbol(sym.name.toString, sym) - else if (sym.owner.isTerm) - reflect.NoSymbol - else reify(sym.owner) match { - case reflect.NoSymbol => - reflect.NoSymbol; - case reflect.RootSymbol => - mkGlobalSymbol(sym.name.toString(), sym) - case reflect.Class(ownername) => - mkGlobalSymbol(ownername + "." + sym.name, sym) - case _ => - reflect.NoSymbol - } - } - - var _log_reify_type_ = false - - def reify(tp: Type): reflect.Type = tp match { - case ErrorType => - reflect.NoType - case WildcardType => - if (_log_reify_type_) println("cannot handle WildcardType") - reflect.NoType - case NoType => - reflect.NoType - case NoPrefix => - reflect.NoType - case ThisType(sym) => - val rsym = reify(sym) - reflect.ThisType(rsym) - case SingleType(pre, sym) => - reflect.SingleType(reify(pre), reify(sym)) - case ConstantType(value) => - reify(value.tpe) - case TypeRef(pre, sym, args) => - val rpre = reify(pre) - val rsym = reify(sym) - val rargs = args map reify - val beforeArgs = reflect.PrefixedType(rpre, rsym) - if (rargs.isEmpty) - beforeArgs - else if (rpre == reflect.NoType || rsym == reflect.NoSymbol) - beforeArgs - else - reflect.AppliedType(beforeArgs, rargs) - case TypeBounds(lo, hi) => - reflect.TypeBounds(reify(lo), reify(hi)) - case RefinedType(parents, defs) => - if (_log_reify_type_) println("cannot handle RefinedType "+tp); reflect.NoType - case ClassInfoType(parents, defs, clazz) => - if (_log_reify_type_) println("cannot handle ClassInfoType "+tp); reflect.NoType - case MethodType(params, result) => - reflect.MethodType(params.map(reify), reify(result)) - case NullaryMethodType(result) => - reflect.NullaryMethodType(reify(result)) - case PolyType(tparams, result) => - val boundss = - for { - param <- tparams - TypeBounds(lo,hi) = param.info.bounds - } yield (reify(lo), reify(hi)) - - reflect.PolyType( - tparams.map(reify), - boundss, - reify(result)) - //todo: treat ExistentialType - case AnnotatedType(annots, tp, _) => - reify(tp) - case _ => - println("could not reify: " + tp) - reflect.NoType - } - - - /** This is woefully incomplete. It is barely enough - * to process the types of Constant's . - */ - def unreify(tpe: reflect.Type): Type = - tpe match { - case reflect.NoPrefix => NoPrefix - case reflect.NoType => NoType - case reflect.NamedType(fullname) => - //NamedType(fullname) - println("NamedType: " + fullname) - NoType - case reflect.PrefixedType(_, reflect.Class("scala.Array")) => - definitions.ArrayClass.tpe - case reflect.PrefixedType(_, reflect.Class("java.lang.String")) => - definitions.StringClass.tpe - case reflect.PrefixedType(_, reflect.Class("scala.Unit")) => - definitions.UnitClass.tpe - case reflect.PrefixedType(_, reflect.Class("scala.Boolean")) => - definitions.BooleanClass.tpe - case reflect.PrefixedType(_, reflect.Class("scala.Byte")) => - definitions.ByteClass.tpe - case reflect.PrefixedType(_, reflect.Class("scala.Short")) => - definitions.ShortClass.tpe - case reflect.PrefixedType(_, reflect.Class("scala.Int")) => - definitions.IntClass.tpe - case reflect.PrefixedType(_, reflect.Class("scala.Long")) => - definitions.LongClass.tpe - case reflect.PrefixedType(_, reflect.Class("scala.Float")) => - definitions.FloatClass.tpe - case reflect.PrefixedType(_, reflect.Class("scala.Double")) => - definitions.DoubleClass.tpe - case reflect.PrefixedType(pre, sym) => - NoType - case reflect.SingleType(pre, sym) => - SingleType(unreify(pre), unreify(sym)) - case reflect.ThisType(clazz) => - ThisType(unreify(clazz)) - case reflect.AppliedType(tpe, args) => - val untpe = unreify(tpe) - if (untpe == NoType) - NoType - else - appliedType(untpe, args.map(unreify)) - case reflect.TypeBounds(lo, hi) => - TypeBounds(unreify(lo), unreify(hi)) - case reflect.MethodType(params, restpe) => - MethodType(params.map(unreify), unreify(restpe)) - case reflect.NullaryMethodType(restpe) => - NullaryMethodType(unreify(restpe)) - case reflect.PolyType(typeParams, typeBounds, resultType) => - PolyType(typeParams.map(unreify), unreify(resultType)) - //todo: treat ExistentialType - case _ => NoType - } - - - /** This is woefully incomplete. It is barely enough - * to process the types of Constant's . - */ - def unreify(symbol: reflect.Symbol): Symbol = - symbol match { - case reflect.Class(fullname) => - fullname match { - case "scala.Unit" => definitions.UnitClass - case "scala.Boolean" => definitions.BooleanClass - case "scala.Byte" => definitions.ByteClass - case "scala.Short" => definitions.ShortClass - case "scala.Int" => definitions.IntClass - case "scala.Long" => definitions.LongClass - case "scala.Float" => definitions.FloatClass - case "scala.Double" => definitions.DoubleClass - - case "scala.Array" => definitions.ArrayClass - - case _ => NoSymbol - - } - - case _ => NoSymbol - } - - case class FreeValue(tree: Tree) extends reflect.Tree - - class ReifyEnvironment extends mutable.HashMap[Symbol, reflect.Symbol] { - var targets = new mutable.HashMap[String, Option[reflect.LabelSymbol]]() - def addTarget(name: String, target: reflect.LabelSymbol): Unit = - targets.update(name, Some(target)) - def getTarget(name: String): Option[reflect.LabelSymbol] = - targets.get(name) match { - case None => - targets.update(name, None) - None - //case Some(None) => None //bq:redundant - case Some(tgt) => tgt - } - def hasAllTargets: Boolean = - targets.iterator.map(_._2).forall { - case Some(_) => true - case None => false - } - override def update(sym: Symbol, rsym: reflect.Symbol) = - super.update(sym,rsym) - } - - - class Reifier(env: ReifyEnvironment, currentOwner: reflect.Symbol) - { - def reify(tree: Tree): reflect.Tree = tree match { - case Ident(_) => - val rsym = reify(tree.symbol); - //Console.println("LiftCode: seen ident") - if (rsym == reflect.NoSymbol) { - //Console.println(" free = "+tree) - FreeValue(tree) - } else { - //Console.println(" rsym = "+rsym) - reflect.Ident(rsym) - } - case Select(qual, _) => - val rsym = reify(tree.symbol); - if (rsym == reflect.NoSymbol) throw new TypeError("cannot reify symbol: " + tree.symbol) - else reflect.Select(reify(qual), reify(tree.symbol)) - - case Literal(constant) => - reflect.Literal(constant.value) - - case Apply(name, args) if name.toString().startsWith("label$") => - env.getTarget(name.toString()) match { - case None => throw new TypeError("cannot reify tree (no forward jumps allowed): " + tree) - case Some(label) => reflect.Goto(label) - } - - case Apply(fun, args) => - reflect.Apply(reify(fun), args map reify) - - case TypeApply(fun, args) => - reflect.TypeApply(reify(fun), args map (_.tpe) map reify) - - case Function(vparams, body) => - var env1 = env - for (vparam <- vparams) { - val local = reflect.LocalValue( - currentOwner, vparam.symbol.name.toString(), reify(vparam.symbol.tpe)); - env1.update(vparam.symbol, local); - } - reflect.Function(vparams map (_.symbol) map env1, - new Reifier(env1, currentOwner).reify(body)) - case tree@This(_) if tree.symbol.isModule => - // there is no reflect node for a module's this, so - // represent it as a selection of the module - reify( - Select(This(tree.symbol.owner), tree.symbol.name)) - case This(_) => - reflect.This(reify(tree.symbol)) - case Block(stats, expr) => - reflect.Block(stats.map(reify), reify(expr)) - case New(clazz) if (clazz.isType) => - val reifiedSymbol = reify(clazz.symbol) - reflect.New(reflect.Ident(reifiedSymbol)) - case New(clazz) => - val reifiedClass = reify(clazz) - reflect.New(reifiedClass) - case Typed(t, _) => - reify(t) - case If(cond, thenp, elsep) => - reflect.If(reify(cond), reify(thenp), reify(elsep)) - case Assign(lhs, rhs) => - reflect.Assign(reify(lhs), reify(rhs)) - - case LabelDef(name, Nil, body) => - val sym = new reflect.LabelSymbol(name.toString()) - env.addTarget(name.toString(), sym) - val res = reflect.Target(sym, reify(body)) - res - - case vd @ ValDef(mods, name, tpt, rhs) => - val rtpe = reify(vd.tpe) // will return null, currently?! - val sym = reflect.LocalValue(currentOwner, name.toString(), rtpe) - env(vd.symbol) = sym // bq: despite Scala's scoping rules, this should work because references to vd.symbol were type checked. - val rhs_ = reify(rhs) - reflect.ValDef(sym, rhs_) - - case cd @ ClassDef(mods, name, tparams, impl) => - if(!tparams.isEmpty) - throw new TypeError("cannot handle polymorphic ClassDef ("+name+"): " + tparams) - val rsym = reify(cd.symbol) - val rimp = reify(impl) - val rtpe = reify(impl.self.tpt.tpe) //todo: update - reflect.ClassDef(rsym, rtpe, rimp.asInstanceOf[reflect.Template]) - - case tmpl @ Template(parents, self, body) => - val rparents = for (p <- parents) yield { reify(p.tpe) } - //todo: add self to reified templates - reflect.Template(rparents, body.map(reify)) - - case dd @ DefDef(mods, name, tparams, vparamss, tpt, rhs) => - if(!tparams.isEmpty) - throw new TypeError("cannot handle polymorphic DefDef ("+name+"): " + tparams) - val rsym = reify(dd.symbol) - val rparss = vparamss map { x => x map (reify) } - val rret = reify(tpt.tpe) - val rrhs = reify(rhs) - reflect.DefDef(rsym, rparss, rret, rrhs) - - case sp @ Super(qual, mix) => - val rsym = reify(sp.symbol) - reflect.Super(rsym) - - case _ => - throw new TypeError("cannot reify tree ("+tree.getClass()+"): " + tree) - } - - def reify(sym: Symbol): reflect.Symbol = - env.get(sym) match { - case Some(rsym) => - rsym - case None => - Reifiers.this.reify(sym) - } - - def reify(tpe: Type): reflect.Type = - Reifiers.this.reify(tpe) - } - - def reify(tree: Tree): reflect.Tree = - new Reifier(new ReifyEnvironment(), reflect.NoSymbol).reify(tree) -} diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index ade15f2c81..35a736d34e 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1356,7 +1356,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { forwardCtorCall(tree.pos, superRef, vparamss, symbol.owner) } if (symbol.isPrimaryConstructor) localTyper typed { - atPos(symbol.pos)(treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, Block(List(t), Literal(())))) + atPos(symbol.pos)(treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, Block(List(t), Literal(Constant())))) } else { // duplicate the original constructor duplicateBody(ddef, info(symbol).target) @@ -1586,7 +1586,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { .setInfo(MethodType(Nil, BooleanClass.tpe)) cls.info.decls.enter(sym) mbrs += atPos(sym.pos) { - DefDef(sym, Literal(isSpecializedInstance).setType(BooleanClass.tpe)).setType(NoType) + DefDef(sym, Literal(Constant(isSpecializedInstance)).setType(BooleanClass.tpe)).setType(NoType) } } mbrs.toList diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index a636c75281..7a0cde8630 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -288,11 +288,11 @@ abstract class UnCurry extends InfoTransform def substTree[T <: Tree](t: T): T = substParam(resetLocalAttrs(t)) def transformCase(cdef: CaseDef): CaseDef = - substTree(CaseDef(cdef.pat.duplicate, cdef.guard.duplicate, Literal(true))) - def defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false)) + substTree(CaseDef(cdef.pat.duplicate, cdef.guard.duplicate, Literal(Constant(true)))) + def defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(Constant(false))) DefDef(m, mkUnchecked( - if (cases exists treeInfo.isDefaultCase) Literal(true) + if (cases exists treeInfo.isDefaultCase) Literal(Constant(true)) else Match(substTree(selector.duplicate), (cases map transformCase) :+ defaultCase) )) } @@ -401,7 +401,7 @@ abstract class UnCurry extends InfoTransform /** For removing calls to specially designated methods. */ - def elideIntoUnit(tree: Tree): Tree = Literal(()) setPos tree.pos setType UnitClass.tpe + def elideIntoUnit(tree: Tree): Tree = Literal(Constant()) setPos tree.pos setType UnitClass.tpe def isElidable(tree: Tree) = { val sym = treeInfo.methPart(tree).symbol // XXX settings.noassertions.value temporarily retained to avoid diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 9562862f0a..ab6d66e111 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -524,7 +524,7 @@ trait Namers { self: Analyzer => val getterName = if (hasBoolBP) "is" + beanName else "get" + beanName - val getterMods = Modifiers(flags, mods.privateWithin, Nil, mods.positions) + val getterMods = Modifiers(flags, mods.privateWithin, Nil) setPositions mods.positions val beanGetterDef = atPos(vd.pos.focus) { DefDef(getterMods, getterName, Nil, List(Nil), tpt.duplicate, if (mods.isDeferred) EmptyTree diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 37b5870ac5..9f957af136 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1397,7 +1397,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R private def transformIf(tree: If): Tree = { val If(cond, thenpart, elsepart) = tree def unitIfEmpty(t: Tree): Tree = - if (t == EmptyTree) Literal(()).setPos(tree.pos).setType(UnitClass.tpe) else t + if (t == EmptyTree) Literal(Constant()).setPos(tree.pos).setType(UnitClass.tpe) else t cond.tpe match { case ConstantType(value) => diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 23482eb609..0385cfee63 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -906,7 +906,7 @@ trait Typers extends Modes with Adaptations { if (sym == UnitClass && tree.tpe <:< AnyClass.tpe) { // (12) if (settings.warnValueDiscard.value) context.unit.warning(tree.pos, "discarded non-Unit value") - return typed(atPos(tree.pos)(Block(List(tree), Literal(()))), mode, pt) + return typed(atPos(tree.pos)(Block(List(tree), Literal(Constant()))), mode, pt) } else if (isNumericValueClass(sym) && isNumericSubType(tree.tpe, pt)) { if (settings.warnNumericWiden.value) @@ -986,7 +986,7 @@ trait Typers extends Modes with Adaptations { case t: Tree => t case _ => context.undetparams = savedUndetparams - val valueDiscard = atPos(tree.pos)(Block(List(instantiate(tree, mode, WildcardType)), Literal(()))) + val valueDiscard = atPos(tree.pos)(Block(List(instantiate(tree, mode, WildcardType)), Literal(Constant()))) typed(valueDiscard, mode, UnitClass.tpe) } } @@ -1534,7 +1534,7 @@ trait Typers extends Modes with Adaptations { * into the symbol's ``annotations'' in the type completer / namer) */ def removeAnnotations(mods: Modifiers): Modifiers = - mods.copy(annotations = Nil) + mods.copy(annotations = Nil) setPositions mods.positions /** * @param vdef ... diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 0dbc09c46e..16137379a8 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -540,8 +540,8 @@ trait Trees /*extends reflect.generic.Trees*/ { self: Universe => assert(value ne null) } - def Literal(value: Any): Literal = - Literal(Constant(value)) + @deprecated("will be removed and then be re-introduced with changed semantics, use Literal(Constant(x)) instead") + def Literal(x: Any) = new Literal(Constant(x)) /** A tree that has an annotation attached to it. Only used for annotated types and * annotation ascriptions, annotations on definitions are stored in the Modifiers. diff --git a/test/disabled/run/t2886.check b/test/disabled/run/t2886.check deleted file mode 100644 index 39ee46a3df..0000000000 --- a/test/disabled/run/t2886.check +++ /dev/null @@ -1 +0,0 @@ -Function(List(LocalValue(NoSymbol,x,PrefixedType(SingleType(ThisType(Class(scala)),Field(scala.Predef,PrefixedType(ThisType(Class(scala)),Class(scala.Predef)))),TypeField(scala.Predef.String,PrefixedType(ThisType(Class(java.lang)),Class(java.lang.String)))))),Block(List(ValDef(LocalValue(NoSymbol,x$1,NoType),Ident(LocalValue(NoSymbol,x,PrefixedType(SingleType(ThisType(Class(scala)),Field(scala.Predef,PrefixedType(ThisType(Class(scala)),Class(scala.Predef)))),TypeField(scala.Predef.String,PrefixedType(ThisType(Class(java.lang)),Class(java.lang.String))))))), ValDef(LocalValue(NoSymbol,x$2,NoType),Ident(LocalValue(NoSymbol,x,PrefixedType(SingleType(ThisType(Class(scala)),Field(scala.Predef,PrefixedType(ThisType(Class(scala)),Class(scala.Predef)))),TypeField(scala.Predef.String,PrefixedType(ThisType(Class(java.lang)),Class(java.lang.String)))))))),Apply(Select(This(Class(Test)),Method(Test.test,MethodType(List(LocalValue(NoSymbol,name,PrefixedType(SingleType(ThisType(Class(scala)),Field(scala.Predef,PrefixedType(ThisType(Class(scala)),Class(scala.Predef)))),TypeField(scala.Predef.String,PrefixedType(ThisType(Class(java.lang)),Class(java.lang.String))))), LocalValue(NoSymbol,address,PrefixedType(SingleType(ThisType(Class(scala)),Field(scala.Predef,PrefixedType(ThisType(Class(scala)),Class(scala.Predef)))),TypeField(scala.Predef.String,PrefixedType(ThisType(Class(java.lang)),Class(java.lang.String)))))),PrefixedType(ThisType(Class(scala)),Class(scala.Null))))),List(Ident(LocalValue(NoSymbol,x$2,NoType)), Ident(LocalValue(NoSymbol,x$1,NoType))))))
\ No newline at end of file diff --git a/test/files/run/t2886.check b/test/files/run/t2886.check new file mode 100644 index 0000000000..5fe1e73a45 --- /dev/null +++ b/test/files/run/t2886.check @@ -0,0 +1,5 @@ +((x: scala.Predef.String) => { + val x$1 = x; + val x$2 = x; + Test.test(x$2, x$1) +}) diff --git a/test/disabled/run/t2886.scala b/test/files/run/t2886.scala index eb392f0c58..eb392f0c58 100644 --- a/test/disabled/run/t2886.scala +++ b/test/files/run/t2886.scala |