scala.tools.nsc.transform.PostErasure.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-compiler Show documentation
Show all versions of scala-compiler Show documentation
Compiler for the Scala Programming Language
/* NSC -- new Scala compiler
* Copyright 2005-2013 LAMP/EPFL
* @author Martin odersky
*/
package scala.tools.nsc
package transform
/** This phase maps ErasedValueTypes to the underlying unboxed representation and
* performs peephole optimizations.
*/
trait PostErasure extends InfoTransform with TypingTransformers {
val global: Global
import global._
import definitions._
val phaseName: String = "posterasure"
def newTransformer(unit: CompilationUnit): Transformer = new PostErasureTransformer(unit)
override def changesBaseClasses = false
object elimErasedValueType extends TypeMap {
def apply(tp: Type) = tp match {
case ConstantType(Constant(tp: Type)) =>
ConstantType(Constant(apply(tp)))
case ErasedValueType(tref) =>
atPhase(currentRun.erasurePhase)(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) =
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 atPhase(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 atPhase(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
}
}
}