diff options
-rw-r--r-- | src/dotty/tools/dotc/Compiler.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ExpandPrivate.scala | 49 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/RefChecks.scala | 30 | ||||
-rw-r--r-- | tests/pos/privates.scala | 4 |
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() + } + } |