1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
class Parent[@specialized(Int) T]
object Test extends App {
/**
* This method will check if specialization is correctly rewiring parents
* for classes defined inside methods. The pattern is important since this
* is how closures are currently represented: as locally-defined anonymous
* classes, which usually end up inside methods. For these closures we do
* want their parents rewired correctly:
*
* ```
* def checkSuperClass$mIc$sp[T](t: T, ...) = {
* class X extends Parent$mcI$sp // instead of just Parent
* ...
* }
*/
def checkSuperClass[@specialized(Int) T](t: T, expectedXSuper: String) = {
// test target:
// - in checkSuperClass, X should extend Parent
// - in checkSuperClass$mIc$sp, X should extend Parent$mcI$sp
class X extends Parent[T]()
// get the superclass for X and make sure it's correct
val actualXSuper = (new X).getClass().getSuperclass().getSimpleName()
assert(actualXSuper == expectedXSuper, actualXSuper + " != " + expectedXSuper)
}
checkSuperClass("x", "Parent")
checkSuperClass(101, "Parent$mcI$sp")
/**
* This is the same check, but in value. It should work exactly the same
* as its method counterpart.
*/
class Val[@specialized(Int) T](t: T, expectedXSuper: String) {
val check: T = {
class X extends Parent[T]()
// get the superclass for X and make sure it's correct
val actualXSuper = (new X).getClass().getSuperclass().getSimpleName()
assert(actualXSuper == expectedXSuper, actualXSuper + " != " + expectedXSuper)
t
}
}
new Val("x", "Parent")
new Val(101, "Parent$mcI$sp")
/**
* NOTE: The the same check, only modified to affect constructors, won't
* work since the class X definition will always be lifted to become a
* member of the class, making it impossible to force its duplication.
*/
}
|