diff options
author | Martin Odersky <odersky@gmail.com> | 2015-05-01 18:38:31 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-05-01 18:38:56 +0200 |
commit | d9c215757f49d7984889e8e695828f71f685f163 (patch) | |
tree | 19ccea9593192bcc56ffd61e7d16350e41469f87 /src/dotty/tools/dotc/transform/ExpandPrivate.scala | |
parent | a263b5f3aaabe96e7ad238cb18e8f9b98d287ffc (diff) | |
download | dotty-d9c215757f49d7984889e8e695828f71f685f163.tar.gz dotty-d9c215757f49d7984889e8e695828f71f685f163.tar.bz2 dotty-d9c215757f49d7984889e8e695828f71f685f163.zip |
New miniphase: ExpandPrivate
A late miniphase which resets private flag of all
members that are not accessed from within same class.
Replaces logic in RefChecks. Doing this late has two
advantages
- we can use name expansion, because references are
symbolic, so the names of symbols and references
to them do not need to correspond anymore.
- we can automatically correct for symbols moved in earlier
phases (e.g. lifted out by LambdaLift).
Diffstat (limited to 'src/dotty/tools/dotc/transform/ExpandPrivate.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/ExpandPrivate.scala | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/transform/ExpandPrivate.scala b/src/dotty/tools/dotc/transform/ExpandPrivate.scala new file mode 100644 index 000000000..ef36796cd --- /dev/null +++ b/src/dotty/tools/dotc/transform/ExpandPrivate.scala @@ -0,0 +1,49 @@ +package dotty.tools.dotc +package transform + +import core._ +import DenotTransformers.IdentityDenotTransformer +import Contexts.Context +import Symbols._ +import Scopes._ +import Flags._ +import StdNames._ +import SymDenotations._ +import Types._ +import collection.mutable +import TreeTransforms._ +import Decorators._ +import ast.Trees._ +import TreeTransforms._ + +/** Makes private methods static, provided they not deferred, accessors, or static, + * by rewriting a method `m` in class `C` as follows: + * + * private def m(ps) = e + * + * --> private static def($this: C, ps) = [this -> $this] e + */ +class ExpandPrivate extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform => + import ast.tpd._ + + override def phaseName: String = "expandPrivate" + + /** Make private terms accessed from different classes non-private. + * Note: this happens also for accesses between class and linked module class. + * If we change the scheme at one point to make static module class computations + * static members of the companion class, we should tighten the condition below. + */ + private def ensurePrivateAccessible(d: SymDenotation)(implicit ctx: Context) = + if (d.is(PrivateTerm) && d.owner != ctx.owner.enclosingClass) + d.ensureNotPrivate.installAfter(thisTransform) + + override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = { + ensurePrivateAccessible(tree.symbol) + tree + } + + override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) = { + ensurePrivateAccessible(tree.symbol) + tree + } +} |