aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/ExpandPrivate.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-05-01 18:38:31 +0200
committerMartin Odersky <odersky@gmail.com>2015-05-01 18:38:56 +0200
commitd9c215757f49d7984889e8e695828f71f685f163 (patch)
tree19ccea9593192bcc56ffd61e7d16350e41469f87 /src/dotty/tools/dotc/transform/ExpandPrivate.scala
parenta263b5f3aaabe96e7ad238cb18e8f9b98d287ffc (diff)
downloaddotty-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.scala49
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
+ }
+}