@@ -2,6 +2,7 @@ package dotty.tools.dotc
2
2
package transform
3
3
4
4
import core ._
5
+ import dotty .tools .dotc .ast .tpd
5
6
import dotty .tools .dotc .core .DenotTransformers .{SymTransformer , IdentityDenotTransformer }
6
7
import Contexts .Context
7
8
import Symbols ._
@@ -18,12 +19,38 @@ import TreeTransforms._
18
19
19
20
/** Make private term members that are accessed from another class
20
21
* non-private by resetting the Private flag and expanding their name.
22
+ *
23
+ * Also, make non-private any private parameter forwarders that forward to an inherited
24
+ * public or protected parameter accessor with the same name as the forwarder.
25
+ * This is necessary since private methods are not allowed to have the same name
26
+ * as inherited public ones.
27
+ *
28
+ * See discussion in https://github.com/lampepfl/dotty/pull/784
29
+ * and https://github.com/lampepfl/dotty/issues/783
21
30
*/
22
31
class ExpandPrivate extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
23
32
import ast .tpd ._
24
33
25
34
override def phaseName : String = " expandPrivate"
26
35
36
+ override def checkPostCondition (tree : Tree )(implicit ctx : Context ): Unit = {
37
+ tree match {
38
+ case t : DefDef =>
39
+ val sym = t.symbol
40
+ def hasWeakerAccess (other : Symbol ) = {
41
+ // public > protected > /* default */ > private
42
+ if (sym.is(Private )) other.is(Private )
43
+ else if (sym.is(Protected )) other.is(Protected | Private )
44
+ else true // sym is public
45
+ }
46
+ val fail = sym.allOverriddenSymbols.findSymbol(x => ! hasWeakerAccess(x))
47
+ if (fail.exists) {
48
+ assert(false , i " ${sym.showFullName} has weaker access that superclass method ${fail.showFullName}" )
49
+ }
50
+ case _ =>
51
+ }
52
+ }
53
+
27
54
/** Make private terms accessed from different classes non-private.
28
55
* Note: this happens also for accesses between class and linked module class.
29
56
* If we change the scheme at one point to make static module class computations
@@ -42,4 +69,15 @@ class ExpandPrivate extends MiniPhaseTransform with IdentityDenotTransformer { t
42
69
ensurePrivateAccessible(tree.symbol)
43
70
tree
44
71
}
72
+
73
+ override def transformDefDef (tree : DefDef )(implicit ctx : Context , info : TransformerInfo ) = {
74
+ val sym = tree.symbol
75
+ tree.rhs match {
76
+ case Apply (sel @ Select (_ : Super , _), _)
77
+ if sym.is(PrivateParamAccessor ) && sel.symbol.is(ParamAccessor ) && sym.name == sel.symbol.name =>
78
+ sym.ensureNotPrivate.installAfter(thisTransform)
79
+ case _ =>
80
+ }
81
+ tree
82
+ }
45
83
}
0 commit comments