diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2016-08-09 13:31:33 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2016-08-09 13:31:33 +0200 |
commit | 594e8dd17b1b3c7f26a7ee979ecdf43d77a51cb1 (patch) | |
tree | 8f34a5f1e9f0ce761af86821d9a6433a932d4fe5 | |
parent | 62348dea92476f1bbb9d7f163f168be9c7e189b5 (diff) | |
download | dotty-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.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/SelectStatic.scala | 37 |
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 + } +} |