aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/ElimErasedValueType.scala
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2015-03-18 23:56:27 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-05-01 13:27:41 +0200
commit9c94605d5464936cc156680c5db5344d5ff092ef (patch)
treea885076d8f53397998d7c4cf67617e34bc1d30c2 /src/dotty/tools/dotc/transform/ElimErasedValueType.scala
parent5dec4ce8a64d44ee602c09d468414b13eecba389 (diff)
downloaddotty-9c94605d5464936cc156680c5db5344d5ff092ef.tar.gz
dotty-9c94605d5464936cc156680c5db5344d5ff092ef.tar.bz2
dotty-9c94605d5464936cc156680c5db5344d5ff092ef.zip
New phase: ElimErasedValueType
This phase erases ErasedValueType to their underlying type, in scalac this was done in PostErasure.
Diffstat (limited to 'src/dotty/tools/dotc/transform/ElimErasedValueType.scala')
-rw-r--r--src/dotty/tools/dotc/transform/ElimErasedValueType.scala82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/transform/ElimErasedValueType.scala b/src/dotty/tools/dotc/transform/ElimErasedValueType.scala
new file mode 100644
index 000000000..8a18c9c17
--- /dev/null
+++ b/src/dotty/tools/dotc/transform/ElimErasedValueType.scala
@@ -0,0 +1,82 @@
+package dotty.tools.dotc
+package transform
+
+import ast.{Trees, tpd}
+import core._, core.Decorators._
+import TreeTransforms._, Phases.Phase
+import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTransformers._
+import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
+import TypeErasure.ErasedValueType, ValueClasses._
+
+/** This phase erases ErasedValueType to their underlying type.
+ * It also removes the synthetic cast methods u2evt$ and evt2u$ which are
+ * no longer needed afterwards.
+ */
+class ElimErasedValueType extends MiniPhaseTransform with InfoTransformer {
+
+ import tpd._
+
+ override def phaseName: String = "elimErasedValueType"
+
+ override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Erasure])
+
+ def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = sym match {
+ case sym: ClassSymbol if sym is ModuleClass =>
+ sym.companionClass match {
+ case origClass: ClassSymbol if isDerivedValueClass(origClass) =>
+ val cinfo = tp.asInstanceOf[ClassInfo]
+ val decls1 = cinfo.decls.cloneScope
+ ctx.atPhase(this.next) { implicit ctx =>
+ // Remove synthetic cast methods introduced by ExtensionMethods,
+ // they are no longer needed after this phase.
+ decls1.unlink(cinfo.decl(nme.U2EVT).symbol)
+ decls1.unlink(cinfo.decl(nme.EVT2U).symbol)
+ }
+ cinfo.derivedClassInfo(decls = decls1)
+ case _ =>
+ tp
+ }
+ case _ =>
+ elimEVT(tp)
+ }
+
+ def elimEVT(tp: Type)(implicit ctx: Context): Type = tp match {
+ case ErasedValueType(_, underlying) =>
+ elimEVT(underlying)
+ case tp: MethodType =>
+ val paramTypes = tp.paramTypes.mapConserve(elimEVT)
+ val retType = elimEVT(tp.resultType)
+ tp.derivedMethodType(tp.paramNames, paramTypes, retType)
+ case _ =>
+ tp
+ }
+
+ def transformTypeOfTree(tree: Tree)(implicit ctx: Context): Tree =
+ tree.withType(elimEVT(tree.tpe))
+
+ override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ val Apply(fun, args) = tree
+ val name = fun.symbol.name
+
+ // The casts to and from ErasedValueType are no longer needed once ErasedValueType
+ // has been eliminated.
+ val t =
+ if ((name eq nme.U2EVT) || (name eq nme.EVT2U))
+ args.head
+ else
+ tree
+ transformTypeOfTree(t)
+ }
+
+ // FIXME: transformIf and transformBlock won't be required anymore once #444 is fixed.
+ override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree =
+ transformTypeOfTree(tree)
+ override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree =
+ transformTypeOfTree(tree)
+ override def transformBlock(tree: Block)(implicit ctx: Context, info: TransformerInfo): Tree =
+ transformTypeOfTree(tree)
+ override def transformIf(tree: If)(implicit ctx: Context, info: TransformerInfo): Tree =
+ transformTypeOfTree(tree)
+ override def transformTypeTree(tree: TypeTree)(implicit ctx: Context, info: TransformerInfo): Tree =
+ transformTypeOfTree(tree)
+}