summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/reflect/package.scala3
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala45
2 files changed, 31 insertions, 17 deletions
diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala
index 9f9d4089c4..d97f2ec633 100644
--- a/src/library/scala/reflect/package.scala
+++ b/src/library/scala/reflect/package.scala
@@ -65,3 +65,6 @@ package object reflect {
@deprecated("Use `@scala.beans.ScalaBeanInfo` instead", "2.10.0")
type ScalaBeanInfo = scala.beans.ScalaBeanInfo
}
+
+/** An exception that indicates an error during Scala reflection */
+case class ScalaReflectionException(msg: String) extends Exception(msg)
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]]: _*)