@@ -40,30 +40,29 @@ import StdNames._
4040 * using the most precise overload available
4141 * - `x.getClass` for getClass in primitives becomes `x.getClass` with getClass in class Object.
4242 */
43- class InterceptedMethods extends MiniPhaseTransform { thisTransform =>
43+ class InterceptedMethods extends MiniPhaseTransform {
44+ thisTransform =>
4445
4546 import tpd ._
4647
4748 override def phaseName : String = " intercepted"
4849
4950 private var getClassMethods : Set [Symbol ] = _
50- private var poundPoundMethods : Set [Symbol ] = _
51- private var Any_comparisons : Set [Symbol ] = _
52- private var interceptedMethods : Set [Symbol ] = _
51+ private var Any_## : Symbol = _
52+ private var Any_!= : Symbol = _
5353 private var primitiveGetClassMethods : Set [Symbol ] = _
5454
5555 /** perform context-dependant initialization */
5656 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
57+ Any_## = defn.Any_##
58+ Any_!= = defn.Any_!=
6059 primitiveGetClassMethods = Set [Symbol ]() ++ defn.ScalaValueClasses .map(x => x.requiredMethod(nme.getClass_))
6160 this
6261 }
6362
6463 // this should be removed if we have guarantee that ## will get Apply node
6564 override def transformSelect (tree : tpd.Select )(implicit ctx : Context , info : TransformerInfo ): Tree = {
66- if (tree.symbol.isTerm && poundPoundMethods.contains( tree.symbol.asTerm)) {
65+ if (tree.symbol.isTerm && ( Any_## eq tree.symbol.asTerm)) {
6766 val rewrite = poundPoundValue(tree.qualifier)
6867 ctx.log(s " $phaseName rewrote $tree to $rewrite" )
6968 rewrite
@@ -99,47 +98,42 @@ class InterceptedMethods extends MiniPhaseTransform { thisTransform =>
9998
10099 override def transformApply (tree : Apply )(implicit ctx : Context , info : TransformerInfo ): Tree = {
101100 def unknown = {
102- assert(false , s " The symbol ' ${tree.fun.symbol.showLocated}' was intercepted but didn't match any cases, " +
101+ assert(false , s " The symbol ' ${ tree.fun.symbol.showLocated }' was intercepted but didn't match any cases, " +
103102 s " that means the intercepted methods set doesn't match the code " )
104103 tree
105104 }
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)) {
105+ lazy val Select (qual, _) = tree.fun
106+ val Any_## = this .Any_##
107+ val Any_!= = this .Any_!=
108+
109+ val rewrite : Tree = tree.fun.symbol match {
110+ case Any_## =>
111+ poundPoundValue(qual)
112+ case Any_!= =>
113+ qual.select(defn.Any_== ).appliedToArgs(tree.args).select(defn.Boolean_! )
114+
115+ /*
116+ /* else if (isPrimitiveValueClass(qual.tpe.typeSymbol)) {
119117 // todo: this is needed to support value classes
120118 // Rewrite 5.getClass to ScalaRunTime.anyValClass(5)
121119 global.typer.typed(gen.mkRuntimeCall(nme.anyValClass,
122120 List(qual, typer.resolveClassTag(tree.pos, qual.tpe.widen))))
123121 }*/
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
122+ */
123+ case t if primitiveGetClassMethods.contains(t) =>
124+ // if we got here then we're trying to send a primitive getClass method to either
125+ // a) an Any, in which cage Object_getClass works because Any erases to object. Or
126+ //
127+ // b) a non-primitive, e.g. because the qualifier's type is a refinement type where one parent
128+ // of the refinement is a primitive and another is AnyRef. In that case
129+ // we get a primitive form of _getClass trying to target a boxed value
130+ // so we need replace that method name with Object_getClass to get correct behavior.
131+ // See SI-5568.
132+ qual.selectWithSig(defn.Any_getClass ).appliedToNone
133+ case _ =>
134+ tree
142135 }
143- else tree
136+ ctx.log(s " $phaseName rewrote $tree to $rewrite" )
137+ rewrite
144138 }
145139}
0 commit comments