Skip to content

Commit afef5fe

Browse files
committed
Merge pull request scala#1324 from scalamacros/ticket/6374
Scala reflection now supports Java CRTP
2 parents c9b2ef6 + 22270c6 commit afef5fe

7 files changed

+25
-50
lines changed

src/reflect/scala/reflect/runtime/JavaMirrors.scala

+8-8
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,10 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { thisUnive
148148
object AnnotationClass { def unapply(x: jClass[_]) = x.isAnnotation }
149149

150150
object ConstantArg {
151-
def enumToSymbol(enum: Enum[_]): Symbol =
152-
classToScala(enum.getClass).typeSignature.declaration(enum.name: TermName)
151+
def enumToSymbol(enum: Enum[_]): Symbol = {
152+
val staticPartOfEnum = classToScala(enum.getClass).companionSymbol
153+
staticPartOfEnum.typeSignature.declaration(enum.name: TermName)
154+
}
153155

154156
def unapply(schemaAndValue: (jClass[_], Any)): Option[Any] = schemaAndValue match {
155157
case (StringClass | PrimitiveClass(), value) => Some(value)
@@ -659,7 +661,6 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { thisUnive
659661
}
660662

661663
override def complete(sym: Symbol): Unit = {
662-
if (jclazz.isEnum) throw new ScalaReflectionException("implementation restriction: Java enums are not supported")
663664
load(sym)
664665
completeRest()
665666
}
@@ -1024,13 +1025,12 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { thisUnive
10241025
rawToExistential(typeRef(clazz.owner.thisType, clazz, List()))
10251026
}
10261027
case japplied: ParameterizedType =>
1027-
val (pre, sym) = typeToScala(japplied.getRawType) match {
1028-
case ExistentialType(tparams, TypeRef(pre, sym, _)) => (pre, sym)
1029-
case TypeRef(pre, sym, _) => (pre, sym)
1030-
}
1028+
// http://stackoverflow.com/questions/5767122/parameterizedtype-getrawtype-returns-j-l-r-type-not-class
1029+
val sym = classToScala(japplied.getRawType.asInstanceOf[jClass[_]])
1030+
val pre = sym.owner.thisType
10311031
val args0 = japplied.getActualTypeArguments
10321032
val (args, bounds) = targsToScala(pre.typeSymbol, args0.toList)
1033-
ExistentialType(bounds, typeRef(pre, sym, args))
1033+
newExistentialType(bounds, typeRef(pre, sym, args))
10341034
case jarr: GenericArrayType =>
10351035
arrayType(typeToScala(jarr.getGenericComponentType))
10361036
case jtvar: jTypeVariable[_] =>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c5788c5e518eb267445c5a995fd98b2210f90a58 ?javac-artifacts.jar
Original file line numberDiff line numberDiff line change
@@ -1,22 +1 @@
1-
Type in expressions to have them evaluated.
2-
Type :help for more information.
3-
4-
scala>
5-
6-
scala> import scala.reflect.runtime.universe._
7-
import scala.reflect.runtime.universe._
8-
9-
scala> val sym = typeOf[Foo].typeSymbol
10-
sym: reflect.runtime.universe.Symbol = class Foo
11-
12-
scala> sym.typeSignature
13-
res0: reflect.runtime.universe.Type = java.lang.Object{def <init>(): Foo}
14-
15-
scala> sym.getAnnotations foreach (_.javaArgs)
16-
17-
scala> println(sym.getAnnotations)
18-
List(ComplexAnnotation(v1 = 1, v10 = "hello", v101 = [101, 101], v102 = [102, 102], v103 = ['g', 'g'], v104 = [104, 104], v105 = [105L, 105L], v106 = [106.0, 106.0], v107 = [107.0, 107.0], v108 = [false, true], v11 = classOf[Foo], v110 = ["hello", "world"], v111 = [classOf[SimpleAnnotation], classOf[ComplexAnnotation]], v113 = [SimpleAnnotation(v1 = 21, v10 = "world2", v11 = classOf[ComplexAnnotation], v2 = 22, v3 = '\027', v4 = 24, v5 = 25L, v6 = 26.0, v7 = 27.0, v8 = false)], v13 = SimpleAnnotation(v1 = 11, v10 = "world1", v11 = classOf[SimpleAnnotation], v2 = 12, v3 = '\r', v4 = 14, v5 = 15L, v6 = 16.0, v7 = 17.0, v8 = false), v2 = 2, v3 = '\03', v4 = 4, v5 = 5L, v6 = 6.0, v7 = 7.0, v8 = false))
19-
20-
scala>
21-
22-
scala>
1+
List(JavaComplexAnnotation(v1 = 1, v10 = "hello", v101 = [101, 101], v102 = [102, 102], v103 = ['g', 'g'], v104 = [104, 104], v105 = [105L, 105L], v106 = [106.0, 106.0], v107 = [107.0, 107.0], v108 = [false, true], v11 = classOf[JavaAnnottee], v110 = ["hello", "world"], v111 = [classOf[JavaSimpleAnnotation], classOf[JavaComplexAnnotation]], v112 = [FOO, BAR], v113 = [JavaSimpleAnnotation(v1 = 21, v10 = "world2", v11 = classOf[JavaComplexAnnotation], v12 = BAR, v2 = 22, v3 = '\027', v4 = 24, v5 = 25L, v6 = 26.0, v7 = 27.0, v8 = false)], v12 = FOO, v13 = JavaSimpleAnnotation(v1 = 11, v10 = "world1", v11 = classOf[JavaSimpleAnnotation], v12 = FOO, v2 = 12, v3 = '\r', v4 = 14, v5 = 15L, v6 = 16.0, v7 = 17.0, v8 = false), v2 = 2, v3 = '\03', v4 = 4, v5 = 5L, v6 = 6.0, v7 = 7.0, v8 = false))

test/files/run/reflection-java-annotations.jar.desired.sha1

-1
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,7 @@
1-
import scala.tools.partest._
2-
import scala.tools.nsc.Settings
3-
4-
object Test extends ReplTest {
5-
def code = """
6-
import scala.reflect.runtime.universe._
7-
val sym = typeOf[Foo].typeSymbol
8-
sym.typeSignature
9-
sym.getAnnotations foreach (_.javaArgs)
10-
println(sym.getAnnotations)
11-
"""
12-
13-
override def transformSettings(settings: Settings): Settings = {
14-
val thisFile = testPath.jfile.getAbsolutePath
15-
val javaCompiledAnnotationsJar = (thisFile stripSuffix "scala") + "jar"
16-
val classpath = List(sys.props("partest.lib"), sys.props("partest.reflect"), sys.props("partest.comp"), javaCompiledAnnotationsJar) mkString sys.props("path.separator")
17-
settings.processArguments(List("-cp", classpath), true)
18-
settings
19-
}
1+
object Test extends App {
2+
import scala.reflect.runtime.universe._
3+
val sym = typeOf[JavaAnnottee].typeSymbol
4+
sym.typeSignature
5+
sym.getAnnotations foreach (_.javaArgs)
6+
println(sym.getAnnotations)
207
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(type E,type E,true)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
object Test extends App {
2+
import scala.reflect.runtime.universe._
3+
val enum = typeOf[JavaSimpleEnumeration].baseClasses(1).asClass
4+
// make sure that the E's in Enum<E extends Enum<E>> are represented by the same symbol
5+
val e1 = enum.typeParams(0).asType
6+
val TypeBounds(_, TypeRef(_, _, List(TypeRef(_, e2: TypeSymbol, _)))) = e1.typeSignature
7+
println(e1, e2, e1 eq e2)
8+
}

0 commit comments

Comments
 (0)