diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-02-04 19:40:12 -0800 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-02-04 19:40:12 -0800 |
commit | de2284b876da52114f567badbdcaa7ce06b98858 (patch) | |
tree | 4a4d1e3533bf6125d87c213812ff1cf686f89aef /src/reflect | |
parent | 59928c6b529b2221b96eaf3da90468676d507945 (diff) | |
parent | 02dd4c974f33d137ea353a72e27efb70928fb378 (diff) | |
download | scala-de2284b876da52114f567badbdcaa7ce06b98858.tar.gz scala-de2284b876da52114f567badbdcaa7ce06b98858.tar.bz2 scala-de2284b876da52114f567badbdcaa7ce06b98858.zip |
Merge pull request #2040 from scalamacros/ticket/7008
SI-7008 @throws annotations are now populated in reflect
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..032b45316e 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(throwableSym: Symbol): Self = { + val throwableTpe = if (throwableSym.isMonomorphicType) throwableSym.tpe else { + debuglog(s"Encountered polymorphic exception `${throwableSym.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(throwableSym.typeParams, throwableSym.tpe) + } + val throwsAnn = AnnotationInfo(appliedType(definitions.ThrowsClass, throwableTpe), List(Literal(Constant(throwableTpe))), 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..ea2fc4afe9 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 + // SI-7065: 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))) } /** |