From 594e8dd17b1b3c7f26a7ee979ecdf43d77a51cb1 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 9 Aug 2016 13:31:33 +0200 Subject: 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. --- src/dotty/tools/dotc/Compiler.scala | 1 + src/dotty/tools/dotc/transform/SelectStatic.scala | 37 +++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/dotty/tools/dotc/transform/SelectStatic.scala (limited to 'src') 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 + } +} -- cgit v1.2.3 From 2ada4ccf81a4c81e350287a40ac1ac35ab63b2a1 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 9 Aug 2016 13:56:53 +0200 Subject: Fix NoDenotation.owner in SelectStatic. --- src/dotty/tools/dotc/transform/SelectStatic.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/transform/SelectStatic.scala b/src/dotty/tools/dotc/transform/SelectStatic.scala index fc79b7cbe..a53184e57 100644 --- a/src/dotty/tools/dotc/transform/SelectStatic.scala +++ b/src/dotty/tools/dotc/transform/SelectStatic.scala @@ -23,11 +23,11 @@ class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { th 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) && + if (!sym.is(isPackage) && !sym.maybeOwner.is(isPackage) && ( - ((sym is Flags.Module) && sym.owner.isStaticOwner) || + ((sym is Flags.Module) && sym.maybeOwner.isStaticOwner) || (sym is Flags.JavaStatic) || - (sym.owner is Flags.ImplClass) || + (sym.maybeOwner is Flags.ImplClass) || sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot) ) ) -- cgit v1.2.3 From a1a35c92207c78bfefb95bb1265b3a2968d52d90 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 9 Aug 2016 15:04:33 +0200 Subject: Fix SelectStatic: do not lift java statics to free idents. --- src/dotty/tools/dotc/transform/SelectStatic.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/transform/SelectStatic.scala b/src/dotty/tools/dotc/transform/SelectStatic.scala index a53184e57..5810d18ca 100644 --- a/src/dotty/tools/dotc/transform/SelectStatic.scala +++ b/src/dotty/tools/dotc/transform/SelectStatic.scala @@ -31,7 +31,9 @@ class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { th sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot) ) ) - Block(List(tree.qualifier), ref(sym)) + if (!tree.qualifier.symbol.is(JavaModule)) + Block(List(tree.qualifier), ref(sym)) + else tree else tree } } -- cgit v1.2.3 From debc5fd624526747712114293a1e7b7b6bc3730a Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 9 Aug 2016 16:50:15 +0200 Subject: SelectStatic: do not create blocks that are qualifier of select\apply Blocks are not denoting trees(why aren't they?) For now, I'm fixing this using a quick fix. For future, it may make sense to discuss this on dotty meeting and make blocks be a Denoting tree and return denotation of expo. Another option is to move regularisation logic into tree transformers. --- src/dotty/tools/dotc/transform/SelectStatic.scala | 38 ++++++++++++++++------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/transform/SelectStatic.scala b/src/dotty/tools/dotc/transform/SelectStatic.scala index 5810d18ca..c6d47df16 100644 --- a/src/dotty/tools/dotc/transform/SelectStatic.scala +++ b/src/dotty/tools/dotc/transform/SelectStatic.scala @@ -1,6 +1,7 @@ package dotty.tools.dotc package transform +import dotty.tools.dotc.ast.Trees._ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.DenotTransformers.IdentityDenotTransformer @@ -23,17 +24,32 @@ class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { th override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = { val sym = tree.symbol - if (!sym.is(isPackage) && !sym.maybeOwner.is(isPackage) && - ( - ((sym is Flags.Module) && sym.maybeOwner.isStaticOwner) || - (sym is Flags.JavaStatic) || - (sym.maybeOwner is Flags.ImplClass) || - sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot) - ) - ) - if (!tree.qualifier.symbol.is(JavaModule)) - Block(List(tree.qualifier), ref(sym)) + val r1 = + if (!sym.is(isPackage) && !sym.maybeOwner.is(isPackage) && + ( + ((sym is Flags.Module) && sym.maybeOwner.isStaticOwner) || + (sym is Flags.JavaStatic) || + (sym.maybeOwner is Flags.ImplClass) || + sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot) + ) + ) + if (!tree.qualifier.symbol.is(JavaModule)) + Block(List(tree.qualifier), ref(sym)) + else tree else tree - else tree + + normalize(r1) + } + + private def normalize(t: Tree)(implicit ctx: Context) = t match { + case Select(Block(stats, qual), nm) => + Block(stats, Select(qual, nm)) + case Apply(Block(stats, qual), nm) => + Block(stats, Apply(qual, nm)) + case _ => t + } + + override def transformApply(tree: tpd.Apply)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = { + normalize(tree) } } -- cgit v1.2.3 From 67bb2f74a596120fd3408769c4fdd52063f964b3 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 9 Aug 2016 17:42:42 +0200 Subject: SelectStatic: also normalise TypeApply nodes. --- src/dotty/tools/dotc/transform/SelectStatic.scala | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/dotty/tools/dotc/transform/SelectStatic.scala b/src/dotty/tools/dotc/transform/SelectStatic.scala index c6d47df16..a517b1856 100644 --- a/src/dotty/tools/dotc/transform/SelectStatic.scala +++ b/src/dotty/tools/dotc/transform/SelectStatic.scala @@ -46,10 +46,16 @@ class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { th Block(stats, Select(qual, nm)) case Apply(Block(stats, qual), nm) => Block(stats, Apply(qual, nm)) + case TypeApply(Block(stats, qual), nm) => + Block(stats, TypeApply(qual, nm)) case _ => t } override def transformApply(tree: tpd.Apply)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = { normalize(tree) } + + override def transformTypeApply(tree: tpd.TypeApply)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = { + normalize(tree) + } } -- cgit v1.2.3 From 92e13fe00f2bef5dc8ef5c46583aa745b04a6bc1 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 9 Aug 2016 18:28:20 +0200 Subject: SelectStatic: retain symbols on overloaded selects --- src/dotty/tools/dotc/transform/SelectStatic.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/transform/SelectStatic.scala b/src/dotty/tools/dotc/transform/SelectStatic.scala index a517b1856..0cb054b1c 100644 --- a/src/dotty/tools/dotc/transform/SelectStatic.scala +++ b/src/dotty/tools/dotc/transform/SelectStatic.scala @@ -13,7 +13,6 @@ 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 => @@ -43,7 +42,7 @@ class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { th private def normalize(t: Tree)(implicit ctx: Context) = t match { case Select(Block(stats, qual), nm) => - Block(stats, Select(qual, nm)) + Block(stats, cpy.Select(t)(qual, nm)) case Apply(Block(stats, qual), nm) => Block(stats, Apply(qual, nm)) case TypeApply(Block(stats, qual), nm) => -- cgit v1.2.3 From 8fcbd0adb69550b9cb2fb7e573b572f490175863 Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Tue, 9 Aug 2016 19:13:50 +0200 Subject: SelectStatic: do not promote types-qualifiers. --- src/dotty/tools/dotc/transform/SelectStatic.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/transform/SelectStatic.scala b/src/dotty/tools/dotc/transform/SelectStatic.scala index 0cb054b1c..504a66c2f 100644 --- a/src/dotty/tools/dotc/transform/SelectStatic.scala +++ b/src/dotty/tools/dotc/transform/SelectStatic.scala @@ -32,7 +32,7 @@ class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { th sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot) ) ) - if (!tree.qualifier.symbol.is(JavaModule)) + if (!tree.qualifier.symbol.is(JavaModule) && !tree.qualifier.isType) Block(List(tree.qualifier), ref(sym)) else tree else tree -- cgit v1.2.3