@@ -40,30 +40,29 @@ import StdNames._
40
40
* using the most precise overload available
41
41
* - `x.getClass` for getClass in primitives becomes `x.getClass` with getClass in class Object.
42
42
*/
43
- class InterceptedMethods extends MiniPhaseTransform { thisTransform =>
43
+ class InterceptedMethods extends MiniPhaseTransform {
44
+ thisTransform =>
44
45
45
46
import tpd ._
46
47
47
48
override def phaseName : String = " intercepted"
48
49
49
50
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 = _
53
53
private var primitiveGetClassMethods : Set [Symbol ] = _
54
54
55
55
/** perform context-dependant initialization */
56
56
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_!=
60
59
primitiveGetClassMethods = Set [Symbol ]() ++ defn.ScalaValueClasses .map(x => x.requiredMethod(nme.getClass_))
61
60
this
62
61
}
63
62
64
63
// this should be removed if we have guarantee that ## will get Apply node
65
64
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)) {
67
66
val rewrite = poundPoundValue(tree.qualifier)
68
67
ctx.log(s " $phaseName rewrote $tree to $rewrite" )
69
68
rewrite
@@ -99,47 +98,42 @@ class InterceptedMethods extends MiniPhaseTransform { thisTransform =>
99
98
100
99
override def transformApply (tree : Apply )(implicit ctx : Context , info : TransformerInfo ): Tree = {
101
100
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, " +
103
102
s " that means the intercepted methods set doesn't match the code " )
104
103
tree
105
104
}
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)) {
119
117
// todo: this is needed to support value classes
120
118
// Rewrite 5.getClass to ScalaRunTime.anyValClass(5)
121
119
global.typer.typed(gen.mkRuntimeCall(nme.anyValClass,
122
120
List(qual, typer.resolveClassTag(tree.pos, qual.tpe.widen))))
123
121
}*/
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
142
135
}
143
- else tree
136
+ ctx.log(s " $phaseName rewrote $tree to $rewrite" )
137
+ rewrite
144
138
}
145
139
}
0 commit comments