aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2016-08-09 13:31:33 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2016-08-09 13:31:33 +0200
commit594e8dd17b1b3c7f26a7ee979ecdf43d77a51cb1 (patch)
tree8f34a5f1e9f0ce761af86821d9a6433a932d4fe5
parent62348dea92476f1bbb9d7f163f168be9c7e189b5 (diff)
downloaddotty-594e8dd17b1b3c7f26a7ee979ecdf43d77a51cb1.tar.gz
dotty-594e8dd17b1b3c7f26a7ee979ecdf43d77a51cb1.tar.bz2
dotty-594e8dd17b1b3c7f26a7ee979ecdf43d77a51cb1.zip
Fix #1442: add new phase, SelectStatic
GenBCode has an implicit assumption that I wasn't aware of: GetStatic should not be emitted against a valid selector. If it is, GenBCode messes up the stack by not pop-ing the selector. Surprisingly, this transformation is perfumed in nsc by flatten.
-rw-r--r--src/dotty/tools/dotc/Compiler.scala1
-rw-r--r--src/dotty/tools/dotc/transform/SelectStatic.scala37
2 files changed, 38 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index d447c3826..d1f126860 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -91,6 +91,7 @@ class Compiler {
new Flatten, // Lift all inner classes to package scope
new RestoreScopes), // Repair scopes rendered invalid by moving definitions in prior phases of the group
List(new ExpandPrivate, // Widen private definitions accessed from nested classes
+ new SelectStatic, // get rid of selects that would be compiled into GetStatic
new CollectEntryPoints, // Find classes with main methods
new CollectSuperCalls, // Find classes that are called with super
new MoveStatics, // Move static methods to companion classes
diff --git a/src/dotty/tools/dotc/transform/SelectStatic.scala b/src/dotty/tools/dotc/transform/SelectStatic.scala
new file mode 100644
index 000000000..fc79b7cbe
--- /dev/null
+++ b/src/dotty/tools/dotc/transform/SelectStatic.scala
@@ -0,0 +1,37 @@
+package dotty.tools.dotc
+package transform
+
+import dotty.tools.dotc.ast.tpd
+import dotty.tools.dotc.core.Contexts.Context
+import dotty.tools.dotc.core.DenotTransformers.IdentityDenotTransformer
+import dotty.tools.dotc.core.Flags._
+import dotty.tools.dotc.core.Symbols._
+import dotty.tools.dotc.core._
+import dotty.tools.dotc.transform.TreeTransforms._
+
+/** Removes selects that would be compiled into GetStatic
+ * otherwise backend needs to be aware that some qualifiers need to be dropped.
+ * Similar transformation seems to be performed by flatten in nsc
+ *
+ * @author Dmytro Petrashko
+ */
+class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+ import ast.tpd._
+
+ override def phaseName: String = "selectStatic"
+ private val isPackage = FlagConjunction(PackageCreationFlags.bits)
+
+ override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ val sym = tree.symbol
+ if (!sym.is(isPackage) && !sym.owner.is(isPackage) &&
+ (
+ ((sym is Flags.Module) && sym.owner.isStaticOwner) ||
+ (sym is Flags.JavaStatic) ||
+ (sym.owner is Flags.ImplClass) ||
+ sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot)
+ )
+ )
+ Block(List(tree.qualifier), ref(sym))
+ else tree
+ }
+}