diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/PostErasure.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/PostErasure.scala | 60 |
1 files changed, 21 insertions, 39 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/PostErasure.scala b/src/compiler/scala/tools/nsc/transform/PostErasure.scala index a8dc47046b..2a86d711f1 100644 --- a/src/compiler/scala/tools/nsc/transform/PostErasure.scala +++ b/src/compiler/scala/tools/nsc/transform/PostErasure.scala @@ -9,10 +9,10 @@ package transform * performs peephole optimizations. */ trait PostErasure extends InfoTransform with TypingTransformers { - val global: Global + import global._ - import definitions._ + import treeInfo._ val phaseName: String = "posterasure" @@ -21,51 +21,33 @@ trait PostErasure extends InfoTransform with TypingTransformers { object elimErasedValueType extends TypeMap { def apply(tp: Type) = tp match { - case ConstantType(Constant(tp: Type)) => - ConstantType(Constant(apply(tp))) - case ErasedValueType(tref) => - enteringPhase(currentRun.erasurePhase)(erasure.erasedValueClassArg(tref)) - case _ => mapOver(tp) + case ConstantType(Constant(tp: Type)) => ConstantType(Constant(apply(tp))) + case ErasedValueType(tref) => enteringErasure(erasure.erasedValueClassArg(tref)) + case _ => mapOver(tp) } } def transformInfo(sym: Symbol, tp: Type) = elimErasedValueType(tp) class PostErasureTransformer(unit: CompilationUnit) extends TypingTransformer(unit) { + override def transform(tree: Tree) = { + def finish(res: Tree) = logResult(s"Posterasure reduction\n Old: $tree\n New")(res) + + /** We use the name of the operation being performed and not the symbol + * itself because the symbol hails from the boxed class, and this transformation + * exists to operate directly on the values. So we are for instance looking + * up == on an lhs of type Int, whereas the symbol which has been passed in + * is from java.lang.Integer. + */ + def binop(lhs: Tree, op: Symbol, rhs: Tree) = + finish(localTyper typed (Apply(Select(lhs, op.name) setPos tree.pos, rhs :: Nil) setPos tree.pos)) - override def transform(tree: Tree) = super.transform(tree) setType elimErasedValueType(tree.tpe) match { - case // new C(arg).underlying ==> arg - Apply(sel @ Select( - Apply(Select(New(tpt), nme.CONSTRUCTOR), List(arg)), - acc), List()) - if enteringPhase(currentRun.erasurePhase) { - tpt.tpe.typeSymbol.isDerivedValueClass && - sel.symbol == tpt.tpe.typeSymbol.derivedValueClassUnbox - } => - if (settings.debug.value) log("Removing "+tree+" -> "+arg) - arg - case // new C(arg1) == new C(arg2) ==> arg1 == arg2 - Apply(sel @ Select( - Apply(Select(New(tpt1), nme.CONSTRUCTOR), List(arg1)), - cmp), - List(Apply(Select(New(tpt2), nme.CONSTRUCTOR), List(arg2)))) - if enteringPhase(currentRun.erasurePhase) { - tpt1.tpe.typeSymbol.isDerivedValueClass && - (sel.symbol == Object_== || sel.symbol == Object_!=) && - tpt2.tpe.typeSymbol == tpt1.tpe.typeSymbol - } => - val result = Apply(Select(arg1, cmp) setPos sel.pos, List(arg2)) setPos tree.pos - log("shortcircuiting equality "+tree+" -> "+result) - localTyper.typed(result) - - case // arg.asInstanceOf[T] ==> arg if arg.tpe == T - Apply(TypeApply(cast @ Select(arg, asinstanceof), List(tpt)), List()) - if cast.symbol == Object_asInstanceOf && arg.tpe =:= tpt.tpe => // !!! <:< ? - if (settings.debug.value) log("Shortening "+tree+" -> "+arg) - arg - case tree1 => - tree1 + case AsInstanceOf(v, tpe) if v.tpe <:< tpe => finish(v) // x.asInstanceOf[X] ==> x + case ValueClass.BoxAndUnbox(v) => finish(v) // (new B(v)).unbox ==> v + case ValueClass.BoxAndCompare(v1, op, v2) => binop(v1, op, v2) // new B(v1) == new B(v2) ==> v1 == v2 + case tree => tree } + } } } |