-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3409 from xeno-by/ticket/6411
SI-6411 SI-7328 value class fixes for runtime reflection
- Loading branch information
Showing
17 changed files
with
407 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/reflect/scala/reflect/internal/transform/PostErasure.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package scala.reflect | ||
package internal | ||
package transform | ||
|
||
trait PostErasure { | ||
val global: SymbolTable | ||
import global._ | ||
import definitions._ | ||
|
||
object elimErasedValueType extends TypeMap { | ||
def apply(tp: Type) = tp match { | ||
case ConstantType(Constant(tp: Type)) => ConstantType(Constant(apply(tp))) | ||
case ErasedValueType(_, underlying) => underlying | ||
case _ => mapOver(tp) | ||
} | ||
} | ||
|
||
def transformInfo(sym: Symbol, tp: Type) = elimErasedValueType(tp) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
meth = method yg_1 | ||
as seen by Scala reflection: def yg_1[T](y: Y[T]): T | ||
as seen by Java reflection: public java.lang.Object a$.yg_1(java.lang.Object) | ||
result = 1 | ||
meth = method yg_1 | ||
as seen by Scala reflection: def yg_1[T](y: Y[T]): T | ||
as seen by Java reflection: public java.lang.Object a$.yg_1(java.lang.Object) | ||
result = 1 | ||
meth = method yi_2 | ||
as seen by Scala reflection: def yi_2(y: Y[Int]): Int | ||
as seen by Java reflection: public int a$.yi_2(java.lang.Integer) | ||
result = 2 | ||
meth = method yi_2 | ||
as seen by Scala reflection: def yi_2(y: Y[Int]): Int | ||
as seen by Java reflection: public int a$.yi_2(java.lang.Integer) | ||
result = class java.lang.IllegalArgumentException: argument type mismatch | ||
meth = method ys_3 | ||
as seen by Scala reflection: def ys_3(y: Y[String]): String | ||
as seen by Java reflection: public java.lang.String a$.ys_3(java.lang.String) | ||
result = class java.lang.IllegalArgumentException: argument type mismatch | ||
meth = method ys_3 | ||
as seen by Scala reflection: def ys_3(y: Y[String]): String | ||
as seen by Java reflection: public java.lang.String a$.ys_3(java.lang.String) | ||
result = 3 | ||
meth = method ya_4 | ||
as seen by Scala reflection: def ya_4(ys: Array[Y[String]]): List[String] | ||
as seen by Java reflection: public scala.collection.immutable.List a$.ya_4(Y[]) | ||
result = class java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String | ||
meth = method ya_4 | ||
as seen by Scala reflection: def ya_4(ys: Array[Y[String]]): List[String] | ||
as seen by Java reflection: public scala.collection.immutable.List a$.ya_4(Y[]) | ||
result = List(4) | ||
meth = method yl_5 | ||
as seen by Scala reflection: def yl_5(ys: List[Y[String]]): List[String] | ||
as seen by Java reflection: public scala.collection.immutable.List a$.yl_5(scala.collection.immutable.List) | ||
result = class java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String | ||
meth = method yl_5 | ||
as seen by Scala reflection: def yl_5(ys: List[Y[String]]): List[String] | ||
as seen by Java reflection: public scala.collection.immutable.List a$.yl_5(scala.collection.immutable.List) | ||
result = List(5) | ||
meth = method yni_7 | ||
as seen by Scala reflection: def yni_7(y: => Y[Int]): Int | ||
as seen by Java reflection: public int a$.yni_7(scala.Function0) | ||
result = 7 | ||
meth = method yns_8 | ||
as seen by Scala reflection: def yns_8(y: => Y[String]): String | ||
as seen by Java reflection: public java.lang.String a$.yns_8(scala.Function0) | ||
result = 8 | ||
meth = method zg_1 | ||
as seen by Scala reflection: def zg_1[T](z: Z[T]): T | ||
as seen by Java reflection: public java.lang.Object a$.zg_1(Z) | ||
result = 1 | ||
meth = method zg_1 | ||
as seen by Scala reflection: def zg_1[T](z: Z[T]): T | ||
as seen by Java reflection: public java.lang.Object a$.zg_1(Z) | ||
result = 1 | ||
meth = method zi_2 | ||
as seen by Scala reflection: def zi_2(z: Z[Int]): Int | ||
as seen by Java reflection: public int a$.zi_2(Z) | ||
result = 2 | ||
meth = method zi_2 | ||
as seen by Scala reflection: def zi_2(z: Z[Int]): Int | ||
as seen by Java reflection: public int a$.zi_2(Z) | ||
result = class java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer | ||
meth = method zs_3 | ||
as seen by Scala reflection: def zs_3(z: Z[String]): String | ||
as seen by Java reflection: public java.lang.String a$.zs_3(Z) | ||
result = class java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String | ||
meth = method zs_3 | ||
as seen by Scala reflection: def zs_3(z: Z[String]): String | ||
as seen by Java reflection: public java.lang.String a$.zs_3(Z) | ||
result = 3 | ||
meth = method za_4 | ||
as seen by Scala reflection: def za_4(zs: Array[Z[String]]): List[String] | ||
as seen by Java reflection: public scala.collection.immutable.List a$.za_4(Z[]) | ||
result = class java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String | ||
meth = method za_4 | ||
as seen by Scala reflection: def za_4(zs: Array[Z[String]]): List[String] | ||
as seen by Java reflection: public scala.collection.immutable.List a$.za_4(Z[]) | ||
result = List(4) | ||
meth = method zl_5 | ||
as seen by Scala reflection: def zl_5(zs: List[Z[String]]): List[String] | ||
as seen by Java reflection: public scala.collection.immutable.List a$.zl_5(scala.collection.immutable.List) | ||
result = class java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String | ||
meth = method zl_5 | ||
as seen by Scala reflection: def zl_5(zs: List[Z[String]]): List[String] | ||
as seen by Java reflection: public scala.collection.immutable.List a$.zl_5(scala.collection.immutable.List) | ||
result = List(5) | ||
meth = method zni_7 | ||
as seen by Scala reflection: def zni_7(z: => Z[Int]): Int | ||
as seen by Java reflection: public int a$.zni_7(scala.Function0) | ||
result = 7 | ||
meth = method zns_8 | ||
as seen by Scala reflection: def zns_8(z: => Z[String]): String | ||
as seen by Java reflection: public java.lang.String a$.zns_8(scala.Function0) | ||
result = 8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import scala.reflect.runtime.universe._ | ||
import scala.reflect.runtime.{currentMirror => cm} | ||
import scala.language.reflectiveCalls | ||
|
||
class Y[T](val i: T) extends AnyVal { | ||
override def toString = s"Y($i)" | ||
} | ||
class Z[T](val i: T) extends AnyRef { | ||
override def toString = s"Z($i)" | ||
} | ||
|
||
object a { | ||
def yg_1[T](y: Y[T]) = y.i | ||
def yi_2(y: Y[Int]) = y.i | ||
def ys_3(y: Y[String]) = y.i | ||
def ya_4(ys: Array[Y[String]]) = ys.toList.map(_.i) | ||
def yl_5(ys: List[Y[String]]) = ys.map(_.i) | ||
def yv_6(ys: Y[String]*) = ys.toList.map(_.i) | ||
def yni_7(y: => Y[Int]) = y.i | ||
def yns_8(y: => Y[String]) = y.i | ||
|
||
def zg_1[T](z: Z[T]) = z.i | ||
def zi_2(z: Z[Int]) = z.i | ||
def zs_3(z: Z[String]) = z.i | ||
def za_4(zs: Array[Z[String]]) = zs.toList.map(_.i) | ||
def zl_5(zs: List[Z[String]]) = zs.map(_.i) | ||
def zv_6(zs: Z[String]*) = zs.toList.map(_.i) | ||
def zni_7(z: => Z[Int]) = z.i | ||
def zns_8(z: => Z[String]) = z.i | ||
} | ||
|
||
object Test extends App { | ||
def test(methName: String, arg: Any) = { | ||
val moduleA = cm.reflect(a) | ||
val msym = moduleA.symbol.typeSignature.declaration(TermName(methName)).asMethod | ||
println(s"meth = $msym") | ||
val mmirror = moduleA.reflectMethod(msym) | ||
val mresult = | ||
try { mmirror(arg) } | ||
catch { | ||
case ex: Exception => | ||
val ex1 = scala.reflect.runtime.ReflectionUtils.unwrapThrowable(ex) | ||
s"${ex1.getClass}: ${ex1.getMessage}" | ||
} | ||
println(s"as seen by Scala reflection: ${msym.asInstanceOf[scala.reflect.internal.Symbols#Symbol].defString}") | ||
println(s"as seen by Java reflection: ${mmirror.asInstanceOf[{val jmeth: java.lang.reflect.Method}].jmeth}") | ||
println(s"result = $mresult") | ||
} | ||
|
||
test("yg_1", new Y(1)) | ||
test("yg_1", new Y("1")) | ||
test("yi_2", new Y(2)) | ||
test("yi_2", new Y("2")) | ||
test("ys_3", new Y(3)) | ||
test("ys_3", new Y("3")) | ||
test("ya_4", Array(new Y(4))) | ||
test("ya_4", Array(new Y("4"))) | ||
test("yl_5", List(new Y(5))) | ||
test("yl_5", List(new Y("5"))) | ||
// FIXME: disabled because of SI-7056 | ||
// test("yv_6", new Y(6)) | ||
// test("yv_6", new Y("6")) | ||
test("yni_7", new Y(7)) | ||
test("yns_8", new Y("8")) | ||
|
||
test("zg_1", new Z(1)) | ||
test("zg_1", new Z("1")) | ||
test("zi_2", new Z(2)) | ||
test("zi_2", new Z("2")) | ||
test("zs_3", new Z(3)) | ||
test("zs_3", new Z("3")) | ||
test("za_4", Array(new Z(4))) | ||
test("za_4", Array(new Z("4"))) | ||
test("zl_5", List(new Z(5))) | ||
test("zl_5", List(new Z("5"))) | ||
// FIXME: disabled because of SI-7056 | ||
// test("zv_6", new Z(6)) | ||
// test("zv_6", new Z("6")) | ||
test("zni_7", new Z(7)) | ||
test("zns_8", new Z("8")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Bar(Foo(3)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import scala.reflect.runtime.universe._ | ||
|
||
case class Foo(n: Int) extends AnyVal | ||
case class Bar(foo: Foo) | ||
|
||
object Test extends App { | ||
val mirror = runtimeMirror(getClass.getClassLoader) | ||
val cm = mirror.reflectClass(typeOf[Bar].typeSymbol.asClass) | ||
val ctor = typeOf[Bar].declaration(nme.CONSTRUCTOR).asMethod | ||
val ctorm = cm.reflectConstructor(ctor) | ||
println(ctorm(Foo(3))) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Foo | ||
Foo(3) | ||
Foo(3) | ||
Foo(5) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import scala.reflect.runtime.universe._ | ||
import scala.reflect.runtime.{currentMirror => cm} | ||
|
||
case class Foo(x: Int) extends AnyVal | ||
case class Bar(foo: Foo) | ||
|
||
object Test extends App { | ||
val foo = typeOf[Bar].declaration(TermName("foo")).asMethod | ||
println(foo.returnType) // Foo | ||
|
||
val bar = Bar(Foo(3)) | ||
println(bar.foo) // Foo(3) | ||
|
||
val im = cm.reflect(bar) | ||
println(im.reflectField(foo).get) // incorrectly gives java.lang.Integer(3) not Foo(3) | ||
im.reflectField(foo).set(Foo(5)) // java.lang.IllegalArgumentException: Can not set int field Bar.foo to Foo | ||
println(im.reflectMethod(foo)()) // incorrectly gives java.lang.Integer(3) not Foo(3) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters