@@ -20,7 +20,7 @@ import internal.Flags._
2020// import scala.tools.nsc.util.ScalaClassLoader._
2121import ReflectionUtils .{singletonInstance }
2222import language .existentials
23- import scala .runtime .ScalaRunTime
23+ import scala .runtime .{ ScalaRunTime , BoxesRunTime }
2424
2525trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self : SymbolTable =>
2626
@@ -133,7 +133,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
133133 """ .trim.stripMargin)
134134 private def ErrorSetImmutableField (wannabe : Symbol ) = throw new ScalaReflectionException (s " cannot set an immutable field ${wannabe.name}" )
135135
136- def reflect (obj : Any ): InstanceMirror = new JavaInstanceMirror (obj. asInstanceOf [ AnyRef ] )
136+ def reflect [ T : ClassTag ] (obj : T ): InstanceMirror = new JavaInstanceMirror (obj)
137137
138138 def reflectClass (cls : ClassSymbol ): ClassMirror = {
139139 if (! cls.isStatic) ErrorInnerClass (cls)
@@ -155,18 +155,23 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
155155
156156 private def checkMemberOf (wannabe : Symbol , owner : ClassSymbol ) {
157157 if (wannabe.owner == AnyClass || wannabe.owner == AnyRefClass || wannabe.owner == ObjectClass ) {
158- // do nothing
158+ // do nothing
159159 } else if (wannabe.owner == AnyValClass ) {
160160 if (! owner.isPrimitiveValueClass && ! owner.isDerivedValueClass) ErrorNotMember (wannabe, owner)
161161 } else {
162162 if (! owner.info.member(wannabe.name).alternatives.contains(wannabe)) ErrorNotMember (wannabe, owner)
163163 }
164164 }
165165
166- private class JavaInstanceMirror (obj : AnyRef )
166+ private def preciseClass [T : ClassTag ](instance : T ) = {
167+ val staticClazz = classTag[T ].runtimeClass
168+ val dynamicClazz = instance.getClass
169+ if (staticClazz.isPrimitive) staticClazz else dynamicClazz
170+ }
171+
172+ private class JavaInstanceMirror [T : ClassTag ](val instance : T )
167173 extends InstanceMirror {
168- def instance = obj
169- def symbol = wholemirror.classSymbol(obj.getClass)
174+ def symbol = wholemirror.classSymbol(preciseClass(instance))
170175 def reflectField (field : TermSymbol ): FieldMirror = {
171176 checkMemberOf(field, symbol)
172177 if ((field.isMethod && ! field.isAccessor) || field.isModule) ErrorNotField (field)
@@ -179,26 +184,26 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
179184 catch {
180185 case _ : NoSuchFieldException => ErrorNonExistentField (field1)
181186 }
182- new JavaFieldMirror (obj , field1)
187+ new JavaFieldMirror (instance , field1)
183188 }
184189 def reflectMethod (method : MethodSymbol ): MethodMirror = {
185190 checkMemberOf(method, symbol)
186- mkJavaMethodMirror(obj , method)
191+ mkJavaMethodMirror(instance , method)
187192 }
188193 def reflectClass (cls : ClassSymbol ): ClassMirror = {
189194 if (cls.isStatic) ErrorStaticClass (cls)
190195 checkMemberOf(cls, symbol)
191- new JavaClassMirror (instance, cls)
196+ new JavaClassMirror (instance. asInstanceOf [ AnyRef ] , cls)
192197 }
193198 def reflectModule (mod : ModuleSymbol ): ModuleMirror = {
194199 if (mod.isStatic) ErrorStaticModule (mod)
195200 checkMemberOf(mod, symbol)
196- new JavaModuleMirror (instance, mod)
201+ new JavaModuleMirror (instance. asInstanceOf [ AnyRef ] , mod)
197202 }
198- override def toString = s " instance mirror for $obj "
203+ override def toString = s " instance mirror for $instance "
199204 }
200205
201- private class JavaFieldMirror (val receiver : AnyRef , val symbol : TermSymbol )
206+ private class JavaFieldMirror (val receiver : Any , val symbol : TermSymbol )
202207 extends FieldMirror {
203208 lazy val jfield = {
204209 val jfield = fieldToJava(symbol)
@@ -255,12 +260,12 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
255260 // that's because we want to have decent performance
256261 // therefore we move special cases into separate subclasses
257262 // rather than have them on a hot path them in a unified implementation of the `apply` method
258- private def mkJavaMethodMirror (receiver : AnyRef , symbol : MethodSymbol ): JavaMethodMirror = {
263+ private def mkJavaMethodMirror [ T : ClassTag ] (receiver : T , symbol : MethodSymbol ): JavaMethodMirror = {
259264 if (isMagicMethod(symbol)) new JavaMagicMethodMirror (receiver, symbol)
260265 else new JavaVanillaMethodMirror (receiver, symbol)
261266 }
262267
263- private abstract class JavaMethodMirror (val receiver : AnyRef , val symbol : MethodSymbol )
268+ private abstract class JavaMethodMirror (val symbol : MethodSymbol )
264269 extends MethodMirror {
265270 lazy val jmeth = {
266271 val jmeth = methodToJava(symbol)
@@ -271,13 +276,13 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
271276 override def toString = s " method mirror for ${showMethodSig(symbol)} (bound to $receiver) "
272277 }
273278
274- private class JavaVanillaMethodMirror (receiver : AnyRef , symbol : MethodSymbol )
275- extends JavaMethodMirror (receiver, symbol) {
279+ private class JavaVanillaMethodMirror (val receiver : Any , symbol : MethodSymbol )
280+ extends JavaMethodMirror (symbol) {
276281 def apply (args : Any * ): Any = jmeth.invoke(receiver, args.asInstanceOf [Seq [AnyRef ]]: _* )
277282 }
278283
279- private class JavaMagicMethodMirror ( receiver : AnyRef , symbol : MethodSymbol )
280- extends JavaMethodMirror (receiver, symbol) {
284+ private class JavaMagicMethodMirror [ T : ClassTag ]( val receiver : T , symbol : MethodSymbol )
285+ extends JavaMethodMirror (symbol) {
281286 def apply (args : Any * ): Any = {
282287 // checking type conformance is too much of a hassle, so we don't do it here
283288 // actually it's not even necessary, because we manually dispatch arguments to magic methods below
@@ -293,37 +298,44 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
293298 throw new ScalaReflectionException (s " ${showMethodSig(symbol)} takes $n_arguments $s_arguments" )
294299 }
295300
301+ def objReceiver = receiver.asInstanceOf [AnyRef ]
296302 def objArg0 = args(0 ).asInstanceOf [AnyRef ]
297303 def objArgs = args.asInstanceOf [Seq [AnyRef ]]
298304 def fail (msg : String ) = throw new ScalaReflectionException (msg + " , it cannot be invoked with mirrors" )
299305
306+ def invokeMagicPrimitiveMethod = {
307+ val jmeths = classOf [BoxesRunTime ].getDeclaredMethods.filter(_.getName == nme.primitiveMethodName(symbol.name).toString)
308+ assert(jmeths.length == 1 , jmeths.toList)
309+ jmeths.head.invoke(null , (objReceiver +: objArgs): _* )
310+ }
311+
300312 symbol match {
301- case Any_== | Object_== => ScalaRunTime .inlinedEquals(receiver , objArg0)
302- case Any_!= | Object_!= => ! ScalaRunTime .inlinedEquals(receiver , objArg0)
303- case Any_## | Object_## => ScalaRunTime .hash(receiver )
313+ case Any_== | Object_== => ScalaRunTime .inlinedEquals(objReceiver , objArg0)
314+ case Any_!= | Object_!= => ! ScalaRunTime .inlinedEquals(objReceiver , objArg0)
315+ case Any_## | Object_## => ScalaRunTime .hash(objReceiver )
304316 case Any_equals => receiver.equals(objArg0)
305317 case Any_hashCode => receiver.hashCode
306318 case Any_toString => receiver.toString
307- case Object_eq => receiver eq objArg0
308- case Object_ne => receiver ne objArg0
309- case Object_synchronized => receiver .synchronized (objArg0)
310- case sym if isGetClass(sym) => receiver.getClass
319+ case Object_eq => objReceiver eq objArg0
320+ case Object_ne => objReceiver ne objArg0
321+ case Object_synchronized => objReceiver .synchronized (objArg0)
322+ case sym if isGetClass(sym) => preciseClass( receiver)
311323 case Any_asInstanceOf => fail(" Any.asInstanceOf requires a type argument" )
312324 case Any_isInstanceOf => fail(" Any.isInstanceOf requires a type argument" )
313325 case Object_asInstanceOf => fail(" AnyRef.$asInstanceOf is an internal method" )
314326 case Object_isInstanceOf => fail(" AnyRef.$isInstanceOf is an internal method" )
315- case Array_length => ScalaRunTime .array_length(receiver )
316- case Array_apply => ScalaRunTime .array_apply(receiver , args(0 ).asInstanceOf [Int ])
317- case Array_update => ScalaRunTime .array_update(receiver , args(0 ).asInstanceOf [Int ], args(1 ))
318- case Array_clone => ScalaRunTime .array_clone(receiver )
327+ case Array_length => ScalaRunTime .array_length(objReceiver )
328+ case Array_apply => ScalaRunTime .array_apply(objReceiver , args(0 ).asInstanceOf [Int ])
329+ case Array_update => ScalaRunTime .array_update(objReceiver , args(0 ).asInstanceOf [Int ], args(1 ))
330+ case Array_clone => ScalaRunTime .array_clone(objReceiver )
319331 case sym if isStringConcat(sym) => receiver.toString + objArg0
320- case sym if isMagicPrimitiveMethod(sym) => fail( " implementation restriction: ${symbol.fullName} is a magic primitive method " )
332+ case sym if isMagicPrimitiveMethod(sym) => invokeMagicPrimitiveMethod
321333 case sym if sym == Predef_classOf => fail(" Predef.classOf is a compile-time function" )
322334 case sym if sym.isTermMacro => fail(s " ${symbol.fullName} is a macro, i.e. a compile-time function " )
323335 case _ => assert(false , this )
324336 }
325337 }
326- }
338+ }
327339
328340 private class JavaConstructorMirror (val outer : AnyRef , val symbol : MethodSymbol )
329341 extends MethodMirror {
0 commit comments