aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexander Myltsev <alexander.myltsev@phystech.edu>2015-06-21 12:54:44 +0300
committerAlexander Myltsev <alexander.myltsev@phystech.edu>2015-06-22 14:51:21 +0300
commit12caa2fd4c6774604704d09d0ba7932f9aca674e (patch)
tree3cb079261f02e714077abb3b4e218155784ff32c /src
parentbb75d4039ee127dfee2630609924f7f3c9132ff6 (diff)
downloaddotty-12caa2fd4c6774604704d09d0ba7932f9aca674e.tar.gz
dotty-12caa2fd4c6774604704d09d0ba7932f9aca674e.tar.bz2
dotty-12caa2fd4c6774604704d09d0ba7932f9aca674e.zip
Closes #579 Implement mini-phase for classOf[T]
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/Compiler.scala3
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala10
-rw-r--r--src/dotty/tools/dotc/transform/ClassOf.scala54
3 files changed, 66 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index 386f976cf..a10201bd0 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -46,7 +46,8 @@ class Compiler {
new NormalizeFlags,
new ExtensionMethods,
new ExpandSAMs,
- new TailRec),
+ new TailRec,
+ new ClassOf),
List(new PatternMatcher,
new ExplicitOuter,
new Splitter),
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index fdeee82de..e3348d4f3 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -271,6 +271,16 @@ class Definitions {
lazy val BoxedFloatClass = ctx.requiredClass("java.lang.Float")
lazy val BoxedDoubleClass = ctx.requiredClass("java.lang.Double")
+ lazy val BoxedBooleanModule = ctx.requiredModule("java.lang.Boolean")
+ lazy val BoxedByteModule = ctx.requiredModule("java.lang.Byte")
+ lazy val BoxedShortModule = ctx.requiredModule("java.lang.Short")
+ lazy val BoxedCharModule = ctx.requiredModule("java.lang.Character")
+ lazy val BoxedIntModule = ctx.requiredModule("java.lang.Integer")
+ lazy val BoxedLongModule = ctx.requiredModule("java.lang.Long")
+ lazy val BoxedFloatModule = ctx.requiredModule("java.lang.Float")
+ lazy val BoxedDoubleModule = ctx.requiredModule("java.lang.Double")
+ lazy val BoxedVoidModule = ctx.requiredModule("java.lang.Void")
+
lazy val ByNameParamClass2x = specialPolyClass(tpnme.BYNAME_PARAM_CLASS, Covariant, AnyType)
lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN, EmptyFlags, AnyType)
diff --git a/src/dotty/tools/dotc/transform/ClassOf.scala b/src/dotty/tools/dotc/transform/ClassOf.scala
new file mode 100644
index 000000000..948e0117b
--- /dev/null
+++ b/src/dotty/tools/dotc/transform/ClassOf.scala
@@ -0,0 +1,54 @@
+package dotty.tools.dotc
+package transform
+
+import ast.tpd
+import core.Constants.Constant
+import core.Contexts.Context
+import core.StdNames.nme
+import core.Symbols.TermSymbol
+import core.TypeErasure
+import TreeTransforms.{MiniPhaseTransform, TransformerInfo, TreeTransform}
+
+/** Performs rewritings as follows for `classOf` calls:
+ * classOf[CustomValueClass] ~> CustomValueClass class
+ * classOf[ValueClass] ~> ValueClass class, where ValueClass is Boolean, Byte, Short, etc.
+ * classOf[AnyOtherClass] ~> erasure(AnyOtherClass)
+ */
+class ClassOf extends MiniPhaseTransform {
+ import tpd._
+
+ override def phaseName: String = "classOf"
+
+ private var classOfMethod: TermSymbol = _
+
+ override def prepareForUnit(tree: tpd.Tree)(implicit ctx: Context): TreeTransform = {
+ val predefModule = ctx.definitions.ScalaPredefModule
+ classOfMethod = ctx.requiredMethod(predefModule.moduleClass.asClass, nme.classOf)
+ this
+ }
+
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ if (tree.symbol eq classOfMethod) {
+ val tp = tree.args.head.tpe
+ val defn = ctx.definitions
+ val claz = tp.classSymbol
+ if (ValueClasses.isDerivedValueClass(claz)) {
+ Literal(Constant(ref(claz).tpe))
+ } else {
+ def TYPE(module: TermSymbol) = ref(module).select(nme.TYPE_).ensureConforms(tree.tpe)
+ claz match {
+ case defn.BooleanClass => TYPE(defn.BoxedBooleanModule)
+ case defn.ByteClass => TYPE(defn.BoxedByteModule)
+ case defn.ShortClass => TYPE(defn.BoxedShortModule)
+ case defn.CharClass => TYPE(defn.BoxedCharModule)
+ case defn.IntClass => TYPE(defn.BoxedIntModule)
+ case defn.LongClass => TYPE(defn.BoxedLongModule)
+ case defn.FloatClass => TYPE(defn.BoxedFloatModule)
+ case defn.DoubleClass => TYPE(defn.BoxedDoubleModule)
+ case defn.UnitClass => TYPE(defn.BoxedVoidModule)
+ case _ => Literal(Constant(TypeErasure.erasure(tp)))
+ }
+ }
+ } else tree
+ }
+}