Skip to content

Commit f36e452

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

File tree

1 file changed

+31
-48
lines changed

1 file changed

+31
-48
lines changed

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

Lines changed: 31 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -28,42 +28,32 @@ import dotty.tools.dotc.core.Denotations.SingleDenotation
2828
import dotty.tools.dotc.core.SymDenotations.SymDenotation
2929
import 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

Comments
 (0)