Skip to content

Commit 0897d90

Browse files
committed
Simplify InterceptedMethods. Fix #439
1 parent 52d6ac3 commit 0897d90

File tree

1 file changed

+35
-41
lines changed

1 file changed

+35
-41
lines changed

src/dotty/tools/dotc/transform/InterceptedMethods.scala

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)