aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/Compiler.scala7
-rw-r--r--src/dotty/tools/dotc/transform/ExpandPrivate.scala49
-rw-r--r--src/dotty/tools/dotc/typer/RefChecks.scala30
-rw-r--r--tests/pos/privates.scala4
4 files changed, 60 insertions, 30 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index 102d99347..046e3861d 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -65,7 +65,12 @@ class Compiler {
List(new LambdaLift, // in this mini-phase block scopes are incorrect. No phases that rely on scopes should be here
new Flatten,
new RestoreScopes),
- List(/*new PrivateToStatic,*/ new CollectEntryPoints, new LabelDefs, new ElimWildcardIdents, new TraitConstructors),
+ List(/*new PrivateToStatic,*/
+ new ExpandPrivate,
+ new CollectEntryPoints,
+ new LabelDefs,
+ new ElimWildcardIdents,
+ new TraitConstructors),
List(new GenBCode)
)
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
+ }
+}
diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala
index e7ada1254..532668a67 100644
--- a/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -726,7 +726,7 @@ import RefChecks._
* todo: But RefChecks is not done yet. It's still a somewhat dirty port from the Scala 2 version.
* todo: move untrivial logic to their own mini-phases
*/
-class RefChecks extends MiniPhase with SymTransformer { thisTransformer =>
+class RefChecks extends MiniPhase { thisTransformer =>
import tpd._
@@ -734,32 +734,6 @@ class RefChecks extends MiniPhase with SymTransformer { thisTransformer =>
val treeTransform = new Transform(NoLevelInfo)
- /** Ensure the following members are not private:
- * - term members of traits
- * - the primary constructor of a value class
- * - the parameter accessor of a value class
- */
- override def transformSym(d: SymDenotation)(implicit ctx: Context) = {
- def mustBePublicInValueClass = d.isPrimaryConstructor || d.is(ParamAccessor)
- def mustBePublic = {
- val cls = d.owner
- (isDerivedValueClass(cls) && mustBePublicInValueClass
- }
- if ((d is PrivateTerm) && mustBePublic) notPrivate(d) else d
- }
-
- /** 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)
- notPrivate(d).installAfter(thisTransformer)
-
- private def notPrivate(d: SymDenotation)(implicit ctx: Context) =
- d.copySymDenotation(initFlags = d.flags | NotJavaPrivate)
-
class Transform(currentLevel: RefChecks.OptLevelInfo = RefChecks.NoLevelInfo) extends TreeTransform {
def phase = thisTransformer
@@ -810,14 +784,12 @@ class RefChecks extends MiniPhase with SymTransformer { thisTransformer =>
override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = {
checkUndesiredProperties(tree.symbol, tree.pos)
- ensurePrivateAccessible(tree.symbol)
currentLevel.enterReference(tree.symbol, tree.pos)
tree
}
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) = {
checkUndesiredProperties(tree.symbol, tree.pos)
- ensurePrivateAccessible(tree.symbol)
tree
}
diff --git a/tests/pos/privates.scala b/tests/pos/privates.scala
index edaa10cb6..a0099e03e 100644
--- a/tests/pos/privates.scala
+++ b/tests/pos/privates.scala
@@ -6,4 +6,8 @@ trait Test {
private def bar() = foo()
+ class Inner {
+ foo()
+ }
+
}