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.
*/
}
|