diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2016-03-08 14:12:48 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2016-03-08 14:12:48 +0100 |
commit | ead309423796f1a6ef59330112044b69ce719a58 (patch) | |
tree | 9f647b9dd725ab8c453a16649e447f78fe3636ca /src/dotty/tools/dotc/transform/CheckStatic.scala | |
parent | 51dfcb81cf9f1c6eb9fa6fbb7f77c81086af230f (diff) | |
download | dotty-ead309423796f1a6ef59330112044b69ce719a58.tar.gz dotty-ead309423796f1a6ef59330112044b69ce719a58.tar.bz2 dotty-ead309423796f1a6ef59330112044b69ce719a58.zip |
CheckStatic: do not eliminate non-pure expressions.
Implemented by checking that tree is allowed to access the static member
and all the members on the path to it. Needed as typer has a tendency
to desugar calls into series of selections&calls to This.
Diffstat (limited to 'src/dotty/tools/dotc/transform/CheckStatic.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/CheckStatic.scala | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/transform/CheckStatic.scala b/src/dotty/tools/dotc/transform/CheckStatic.scala index 264c20eb2..445e9f839 100644 --- a/src/dotty/tools/dotc/transform/CheckStatic.scala +++ b/src/dotty/tools/dotc/transform/CheckStatic.scala @@ -36,7 +36,7 @@ import TypeUtils._ class CheckStatic extends MiniPhaseTransform { thisTransformer => import ast.tpd._ - override def phaseName = "elimRepeated" + override def phaseName = "checkStatic" def check(tree: tpd.DefTree)(implicit ctx: Context) = { @@ -76,8 +76,19 @@ class CheckStatic extends MiniPhaseTransform { thisTransformer => } override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = { - if (tree.symbol.hasAnnotation(defn.ScalaStaticAnnot)) - ref(tree.symbol) - else tree + if (tree.symbol.hasAnnotation(defn.ScalaStaticAnnot)) { + val symbolWhitelist = tree.symbol.ownersIterator.flatMap(x => if (x.is(Flags.Module)) List(x, x.companionModule) else List(x)).toSet + def isSafeQual(t: Tree): Boolean = { // follow the desugared paths created by typer + t match { + case t: This => true + case t: Select => isSafeQual(t.qualifier) && symbolWhitelist.contains(t.symbol) + case t: Ident => symbolWhitelist.contains(t.symbol) + case t: Block => t.stats.forall(tpd.isPureExpr) && isSafeQual(t.expr) + } + } + if (isSafeQual(tree.qualifier)) + ref(tree.symbol) + else tree + } else tree } } |