diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 5 | ||||
-rw-r--r-- | src/library/scala/throws.scala | 6 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/AnnotationInfos.scala | 21 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Definitions.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 2 |
6 files changed, 31 insertions, 16 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala index 4738ad8a38..f9eeb41e6d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala @@ -832,15 +832,10 @@ abstract class GenASM extends SubComponent with BytecodeWriters { * * The contents of that attribute are determined by the `String[] exceptions` argument to ASM's ClassVisitor.visitMethod() * This method returns such list of internal names. - * */ - def getExceptions(excs: List[AnnotationInfo]): List[String] = { - for (AnnotationInfo(tp, List(exc), _) <- excs.distinct if tp.typeSymbol == ThrowsClass) - yield { - val Literal(const) = exc - javaName(const.typeValue.typeSymbol) - } - } + def getExceptions(excs: List[AnnotationInfo]): List[String] = + for (ThrownException(exc) <- excs.distinct) + yield javaName(exc) /** Whether an annotation should be emitted as a Java annotation * .initialize: if 'annot' is read from pickle, atp might be un-initialized diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 62c281b82f..cb6156c59c 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -606,11 +606,10 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with // put some random value; the actual number is determined at the end buf putShort 0xbaba.toShort - for (AnnotationInfo(tp, List(exc), _) <- excs.distinct if tp.typeSymbol == ThrowsClass) { - val Literal(const) = exc + for (ThrownException(exc) <- excs.distinct) { buf.putShort( cpool.addClass( - javaName(const.typeValue.typeSymbol)).shortValue) + javaName(exc)).shortValue) nattr += 1 } diff --git a/src/library/scala/throws.scala b/src/library/scala/throws.scala index 0aa0d31c9f..02dffb00b0 100644 --- a/src/library/scala/throws.scala +++ b/src/library/scala/throws.scala @@ -14,7 +14,7 @@ package scala * {{{ * class Reader(fname: String) { * private val in = new BufferedReader(new FileReader(fname)) - * @throws(classOf[IOException]) + * @throws[IOException]("if the file doesn't exist") * def read() = in.read() * } * }}} @@ -23,4 +23,6 @@ package scala * @version 1.0, 19/05/2006 * @since 2.1 */ -class throws(clazz: Class[_]) extends scala.annotation.StaticAnnotation +class throws[T <: Throwable](cause: String = "") extends scala.annotation.StaticAnnotation { + def this(clazz: Class[T]) = this() +} diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala index 3bd7f4f4fa..46e4329b2e 100644 --- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala +++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala @@ -30,7 +30,7 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable => /** Symbols of any @throws annotations on this symbol. */ def throwsAnnotations(): List[Symbol] = annotations collect { - case AnnotationInfo(tp, Literal(Constant(tpe: Type)) :: Nil, _) if tp.typeSymbol == ThrowsClass => tpe.typeSymbol + case ThrownException(exc) => exc } /** Tests for, get, or remove an annotation */ @@ -325,4 +325,23 @@ 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] = + ann match { + case AnnotationInfo(tpe, _, _) if tpe.typeSymbol != ThrowsClass => + None + // old-style: @throws(classOf[Exception]) (which is throws[T](classOf[Exception])) + case AnnotationInfo(_, List(Literal(Constant(tpe: Type))), _) => + Some(tpe.typeSymbol) + // new-style: @throws[Exception], @throws[Exception]("cause") + case AnnotationInfo(TypeRef(_, _, args), _, _) => + Some(args.head.typeSymbol) + } + } } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 6cdca3d7f8..2bc9f02758 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -954,7 +954,7 @@ trait Definitions extends api.StandardDefinitions { lazy val ScalaNoInlineClass = requiredClass[scala.noinline] lazy val SerialVersionUIDAttr = requiredClass[scala.SerialVersionUID] lazy val SpecializedClass = requiredClass[scala.specialized] - lazy val ThrowsClass = requiredClass[scala.throws] + lazy val ThrowsClass = requiredClass[scala.throws[_]] lazy val TransientAttr = requiredClass[scala.transient] lazy val UncheckedClass = requiredClass[scala.unchecked] lazy val UnspecializedClass = requiredClass[scala.annotation.unspecialized] diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index d387ad764d..b132b91946 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -2999,7 +2999,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => } override def derivedValueClassUnbox = - (info.decl(nme.unbox)) orElse + // (info.decl(nme.unbox)) orElse uncomment once we accept unbox methods (info.decls.find(_ hasAllFlags PARAMACCESSOR | METHOD) getOrElse NoSymbol) |