diff options
author | Eugene Burmako <xeno.by@gmail.com> | 2013-01-31 20:40:16 +0100 |
---|---|---|
committer | Eugene Burmako <xeno.by@gmail.com> | 2013-02-01 16:55:40 +0100 |
commit | f1701f704a2485fcc2eb6d5d8b5d0228beddd9b3 (patch) | |
tree | 1ed30237e997bfcd76f7f595adaab4e21dcfaecb /src/reflect | |
parent | 309ff57ba62b6a6ec1a9c1b28b8bbabfd1b47b72 (diff) | |
download | scala-f1701f704a2485fcc2eb6d5d8b5d0228beddd9b3.tar.gz scala-f1701f704a2485fcc2eb6d5d8b5d0228beddd9b3.tar.bz2 scala-f1701f704a2485fcc2eb6d5d8b5d0228beddd9b3.zip |
SI-7008 @throws annotations are now populated in reflect
Runtime reflection in JavaMirrors previously forgot to fill in
@throws when importing Java reflection artifacts. Now this is fixed.
Note that generic exception types used in `throws` specifications will
be garbled (i.e. erased), because we don't use `getGenericExceptionTypes`
in favor of just `getExceptionTypes` to stay compatible with the behavior
of ClassfileParser. That's a bug, but a separate one and should be fixed
separately.
Also note that this commit updated javac-artifacts.jar, because we need
to test how reflection works with javac-produced classfiles. The sources
that were used to produce those classfiles can be found in the jar next
to the classfiles.
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/internal/AnnotationInfos.scala | 17 | ||||
-rw-r--r-- | src/reflect/scala/reflect/runtime/JavaMirrors.scala | 8 |
2 files changed, 22 insertions, 3 deletions
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala index 6a5a742cc7..29879f9806 100644 --- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala +++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala @@ -33,6 +33,17 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => case ThrownException(exc) => exc } + def addThrowsAnnotation(excSym: Symbol): Self = { + val excTpe = if (excSym.isMonomorphicType) excSym.tpe else { + debuglog(s"Encountered polymorphic exception `${excSym.fullName}` while parsing class file.") + // in case we encounter polymorphic exception the best we can do is to convert that type to + // monomorphic one by introducing existentials, see SI-7009 for details + existentialAbstraction(excSym.typeParams, excSym.tpe) + } + val throwsAnn = AnnotationInfo(appliedType(definitions.ThrowsClass, excTpe), List(Literal(Constant(excTpe))), Nil) + withAnnotations(List(throwsAnn)) + } + /** Tests for, get, or remove an annotation */ def hasAnnotation(cls: Symbol): Boolean = //OPT inlined from exists to save on #closures; was: annotations exists (_ matches cls) @@ -330,14 +341,14 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => implicit val AnnotationTag = ClassTag[AnnotationInfo](classOf[AnnotationInfo]) object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil) - + /** Extracts symbol of thrown exception from AnnotationInfo. - * + * * Supports both “old-style” `@throws(classOf[Exception])` * as well as “new-stye” `@throws[Exception]("cause")` annotations. */ object ThrownException { - def unapply(ann: AnnotationInfo): Option[Symbol] = + def unapply(ann: AnnotationInfo): Option[Symbol] = ann match { case AnnotationInfo(tpe, _, _) if tpe.typeSymbol != ThrowsClass => None diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 01e0634902..698b60b929 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -610,11 +610,19 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni /** * Copy all annotations of Java annotated element `jann` over to Scala symbol `sym`. + * Also creates `@throws` annotations if necessary. * Pre: `sym` is already initialized with a concrete type. * Note: If `sym` is a method or constructor, its parameter annotations are copied as well. */ private def copyAnnotations(sym: Symbol, jann: AnnotatedElement) { sym setAnnotations (jann.getAnnotations map JavaAnnotationProxy).toList + // FIXME: we're not using getGenericExceptionTypes here to be consistent with ClassfileParser + val jexTpes = jann match { + case jm: jMethod => jm.getExceptionTypes.toList + case jconstr: jConstructor[_] => jconstr.getExceptionTypes.toList + case _ => Nil + } + jexTpes foreach (jexTpe => sym.addThrowsAnnotation(classSymbol(jexTpe))) } /** |