@@ -28,42 +28,32 @@ import dotty.tools.dotc.core.Denotations.SingleDenotation
2828import dotty .tools .dotc .core .SymDenotations .SymDenotation
2929import StdNames ._
3030
31- // @DarkDimius The getClass scheme changed. We no longer can have
32- // two different methods in Any and Object. The tests pass but I
33- // am not sure Intercepted methods treats getClass right now.
34- // Please check and delete comment when done.
3531/** Replace member references as follows:
3632 *
37- * - `x == y` for == in class Any becomes `x equals y ` with equals in class Object .
38- * - `x != y ` for != in class Any becomes `!(x equals y)` with equals in class Object.
39- * - `x.##` for ## in other classes becomes calls to ScalaRunTime.hash,
33+ * - `x != y` for != in class Any becomes `!(x != y) ` with != in class Any .
34+ * - `x.## ` for ## in NullClass becomes `0`
35+ * - `x.##` for ## in Any becomes calls to ScalaRunTime.hash,
4036 * using the most precise overload available
4137 * - `x.getClass` for getClass in primitives becomes `x.getClass` with getClass in class Object.
4238 */
43- class InterceptedMethods extends MiniPhaseTransform { thisTransform =>
39+ class InterceptedMethods extends MiniPhaseTransform {
40+ thisTransform =>
4441
4542 import tpd ._
4643
4744 override def phaseName : String = " intercepted"
4845
49- private var getClassMethods : Set [Symbol ] = _
50- private var poundPoundMethods : Set [Symbol ] = _
51- private var Any_comparisons : Set [Symbol ] = _
52- private var interceptedMethods : Set [Symbol ] = _
5346 private var primitiveGetClassMethods : Set [Symbol ] = _
5447
5548 /** perform context-dependant initialization */
5649 override def prepareForUnit (tree : Tree )(implicit ctx : Context ) = {
57- poundPoundMethods = Set (defn.Any_## )
58- Any_comparisons = Set (defn.Any_== , defn.Any_!= )
59- interceptedMethods = poundPoundMethods ++ Any_comparisons
6050 primitiveGetClassMethods = Set [Symbol ]() ++ defn.ScalaValueClasses .map(x => x.requiredMethod(nme.getClass_))
6151 this
6252 }
6353
6454 // this should be removed if we have guarantee that ## will get Apply node
6555 override def transformSelect (tree : tpd.Select )(implicit ctx : Context , info : TransformerInfo ): Tree = {
66- if (tree.symbol.isTerm && poundPoundMethods.contains( tree.symbol.asTerm)) {
56+ if (tree.symbol.isTerm && ( Any_## eq tree.symbol.asTerm)) {
6757 val rewrite = poundPoundValue(tree.qualifier)
6858 ctx.log(s " $phaseName rewrote $tree to $rewrite" )
6959 rewrite
@@ -103,43 +93,36 @@ class InterceptedMethods extends MiniPhaseTransform { thisTransform =>
10393 s " that means the intercepted methods set doesn't match the code " )
10494 tree
10595 }
106- if (tree.fun.symbol.isTerm &&
107- (interceptedMethods contains tree.fun.symbol.asTerm)) {
108- val rewrite : Tree = tree.fun match {
109- case Select (qual, name) =>
110- if (poundPoundMethods contains tree.fun.symbol.asTerm) {
111- poundPoundValue(qual)
112- } else if (Any_comparisons contains tree.fun.symbol.asTerm) {
113- if (tree.fun.symbol eq defn.Any_== ) {
114- qual.selectWithSig(defn.Any_equals ).appliedToArgs(tree.args)
115- } else if (tree.fun.symbol eq defn.Any_!= ) {
116- qual.selectWithSig(defn.Any_equals ).appliedToArgs(tree.args).select(defn.Boolean_! )
117- } else unknown
118- } /* else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) {
96+ lazy val Select (qual, _) = tree.fun
97+ val Any_## = defn.Any_##
98+ val Any_!= = defn.Any_!=
99+ val rewrite : Tree = tree.fun.symbol match {
100+ case Any_## =>
101+ poundPoundValue(qual)
102+ case Any_!= =>
103+ qual.select(defn.Any_== ).appliedToArgs(tree.args).select(defn.Boolean_! )
104+ /*
105+ /* else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) {
119106 // todo: this is needed to support value classes
120107 // Rewrite 5.getClass to ScalaRunTime.anyValClass(5)
121108 global.typer.typed(gen.mkRuntimeCall(nme.anyValClass,
122109 List(qual, typer.resolveClassTag(tree.pos, qual.tpe.widen))))
123110 }*/
124- else if (primitiveGetClassMethods.contains(tree.fun.symbol)) {
125- // if we got here then we're trying to send a primitive getClass method to either
126- // a) an Any, in which cage Object_getClass works because Any erases to object. Or
127- //
128- // b) a non-primitive, e.g. because the qualifier's type is a refinement type where one parent
129- // of the refinement is a primitive and another is AnyRef. In that case
130- // we get a primitive form of _getClass trying to target a boxed value
131- // so we need replace that method name with Object_getClass to get correct behavior.
132- // See SI-5568.
133- qual.selectWithSig(defn.Any_getClass ).appliedToNone
134- } else {
135- unknown
136- }
137- case _ =>
138- unknown
139- }
140- ctx.log(s " $phaseName rewrote $tree to $rewrite" )
141- rewrite
111+ */
112+ case t if primitiveGetClassMethods.contains(t) =>
113+ // if we got here then we're trying to send a primitive getClass method to either
114+ // a) an Any, in which cage Object_getClass works because Any erases to object. Or
115+ //
116+ // b) a non-primitive, e.g. because the qualifier's type is a refinement type where one parent
117+ // of the refinement is a primitive and another is AnyRef. In that case
118+ // we get a primitive form of _getClass trying to target a boxed value
119+ // so we need replace that method name with Object_getClass to get correct behavior.
120+ // See SI-5568.
121+ qual.selectWithSig(defn.Any_getClass ).appliedToNone
122+ case _ =>
123+ tree
142124 }
143- else tree
125+ ctx.log(s " $phaseName rewrote $tree to $rewrite" )
126+ rewrite
144127 }
145128}
0 commit comments