summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect/runtime/JavaMirrors.scala
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-07-17 17:54:41 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-07-19 21:58:57 +0200
commit911bbc4fdd889ea8a880b4ae47a490f64c54a2a9 (patch)
treef0b937a8f0eb5ee6da027ba100e4ec207a85009a /src/reflect/scala/reflect/runtime/JavaMirrors.scala
parentbab827a5426aeb654006573712eb7aabc047db36 (diff)
downloadscala-911bbc4fdd889ea8a880b4ae47a490f64c54a2a9.tar.gz
scala-911bbc4fdd889ea8a880b4ae47a490f64c54a2a9.tar.bz2
scala-911bbc4fdd889ea8a880b4ae47a490f64c54a2a9.zip
SI-5984 improves error reporting in JavaMirrors
Factors out error raising code and introduces a special exception class for Scala reflection errors. Also adds membership sanity checks to reflectXXX. Previously reflectField, reflectMethod, reflectClass and reflectModule in InstanceMirror didn't check that the symbols being passed to them actually correspond to some member of the related class.
Diffstat (limited to 'src/reflect/scala/reflect/runtime/JavaMirrors.scala')
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala45
1 files changed, 28 insertions, 17 deletions
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 1c5ea9caba..e7bebd624c 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -107,15 +107,28 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
// ----------- Implementations of mirror operations and classes -------------------
+ private def ErrorInnerClass(wannabe: Symbol) = throw new ScalaReflectionException(s"$wannabe is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror")
+ private def ErrorInnerModule(wannabe: Symbol) = throw new ScalaReflectionException(s"$wannabe is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror")
+ private def ErrorStaticClass(wannabe: Symbol) = throw new ScalaReflectionException(s"$wannabe is a static class, use reflectClass on a RuntimeMirror to obtain its ClassMirror")
+ private def ErrorStaticModule(wannabe: Symbol) = throw new ScalaReflectionException(s"$wannabe is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror")
+ private def ErrorNotMember(wannabe: Symbol, owner: Symbol) = throw new ScalaReflectionException(s"expected a member of $owner, you provided ${wannabe.kind} ${wannabe.fullName}")
+ private def ErrorNotField(wannabe: Symbol) = throw new ScalaReflectionException(s"expected a field or an accessor method symbol, you provided $wannabe}")
+ private def ErrorNonExistentField(wannabe: Symbol) = throw new ScalaReflectionException(s"""
+ |Scala field ${wannabe.name} isn't represented as a Java field, neither it has a Java accessor method
+ |note that private parameters of class constructors don't get mapped onto fields and/or accessors,
+ |unless they are used outside of their declaring constructors.
+ """.trim.stripMargin)
+ private def ErrorSetImmutableField(wannabe: Symbol) = throw new ScalaReflectionException(s"cannot set an immutable field ${wannabe.name}")
+
def reflect(obj: Any): InstanceMirror = new JavaInstanceMirror(obj.asInstanceOf[AnyRef])
def reflectClass(cls: ClassSymbol): ClassMirror = {
- if (!cls.isStatic) throw new Error("this is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror")
+ if (!cls.isStatic) ErrorInnerClass(cls)
new JavaClassMirror(null, cls)
}
def reflectModule(mod: ModuleSymbol): ModuleMirror = {
- if (!mod.isStatic) throw new Error("this is an inner module, use reflectModule on an InstanceMirror to obtain its ModuleMirror")
+ if (!mod.isStatic) ErrorInnerModule(mod)
new JavaModuleMirror(null, mod)
}
@@ -127,13 +140,16 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
def moduleSymbol(rtcls: RuntimeClass): ModuleSymbol = classToScala(rtcls).companionModule.asModuleSymbol
+ private def checkMemberOf(wannabe: Symbol, owner: Symbol) =
+ if (!owner.info.member(wannabe.name).alternatives.contains(wannabe)) ErrorNotMember(wannabe, owner)
+
private class JavaInstanceMirror(obj: AnyRef)
extends InstanceMirror {
def instance = obj
def symbol = wholemirror.classSymbol(obj.getClass)
def reflectField(field: TermSymbol): FieldMirror = {
- // [Eugene+++] check whether `field` represents a member of a `symbol`
- if ((field.isMethod && !field.isAccessor) || field.isModule) throw new Error(s"expected a field or accessor method symbol, you provided a ${field.kind} symbol")
+ checkMemberOf(field, symbol)
+ if ((field.isMethod && !field.isAccessor) || field.isModule) ErrorNotField(field)
val name =
if (field.isGetter) nme.getterToLocal(field.name)
else if (field.isSetter) nme.getterToLocal(nme.setterToGetter(field.name))
@@ -141,27 +157,22 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
val field1 = (field.owner.info decl name).asTermSymbol
try fieldToJava(field1)
catch {
- case _: NoSuchFieldException =>
- throw new Error(s"""
- |this Scala field isn't represented as a Java field, neither it has a Java accessor method
- |note that private parameters of class constructors don't get mapped onto fields and/or accessors,
- |unless they are used outside of their declaring constructors.
- """.trim.stripMargin)
+ case _: NoSuchFieldException => ErrorNonExistentField(field1)
}
new JavaFieldMirror(obj, field1)
}
def reflectMethod(method: MethodSymbol): MethodMirror = {
- // [Eugene+++] check whether `method` represents a member of a `symbol`
+ checkMemberOf(method, symbol)
new JavaMethodMirror(obj, method)
}
def reflectClass(cls: ClassSymbol): ClassMirror = {
- // [Eugene+++] check whether `cls` represents a member of a `symbol`
- if (cls.isStatic) throw new Error("this is a static class, use reflectClass on a RuntimeMirror to obtain its ClassMirror")
+ if (cls.isStatic) ErrorStaticClass(cls)
+ checkMemberOf(cls, symbol)
new JavaClassMirror(instance, cls)
}
def reflectModule(mod: ModuleSymbol): ModuleMirror = {
- // [Eugene+++] check whether `mod` represents a member of a `symbol`
- if (mod.isStatic) throw new Error("this is a static module, use reflectModule on a RuntimeMirror to obtain its ModuleMirror")
+ if (mod.isStatic) ErrorStaticModule(mod)
+ checkMemberOf(mod, symbol)
new JavaModuleMirror(instance, mod)
}
}
@@ -175,7 +186,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
}
def get = jfield.get(receiver)
def set(value: Any) = {
- if (!symbol.isMutable) throw new Error("cannot set an immutable field")
+ if (!symbol.isMutable) ErrorSetImmutableField(symbol)
jfield.set(receiver, value)
}
}
@@ -193,7 +204,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
case nme.length => jArray.getLength(receiver)
case nme.apply => jArray.get(receiver, args(0).asInstanceOf[Int])
case nme.update => jArray.set(receiver, args(0).asInstanceOf[Int], args(1))
- case _ => throw new Error(s"unexpected array method $symbol")
+ case _ => assert(false, s"unexpected array method: $symbol")
}
else
jmeth.invoke(receiver, args.asInstanceOf[Seq[AnyRef]]: _*)