summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@typesafe.com>2015-10-27 09:03:15 +0100
committerLukas Rytz <lukas.rytz@typesafe.com>2015-10-27 09:03:15 +0100
commit4321ea458ad1258f273ee22a4c6a7606ab054501 (patch)
treefe68843b632bda3eed3066a83f66b5249dbb86dd /src
parentb194a4e7230334e441cd31b617fdce8e329dfa3a (diff)
parent4a5a800d4606d917289dc14c35f2035e83f58953 (diff)
downloadscala-4321ea458ad1258f273ee22a4c6a7606ab054501.tar.gz
scala-4321ea458ad1258f273ee22a4c6a7606ab054501.tar.bz2
scala-4321ea458ad1258f273ee22a4c6a7606ab054501.zip
Merge pull request #4820 from lrytz/t9535
SI-9535 correct bytecode and generic signatures for @throws[TypeParam]
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala21
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala13
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala11
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala16
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala2
6 files changed, 38 insertions, 27 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index a48a437ed7..d501d4239b 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -490,11 +490,15 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
* must-single-thread
*/
def addRemoteExceptionAnnot(isRemoteClass: Boolean, isJMethodPublic: Boolean, meth: Symbol) {
- val needsAnnotation = (
- ( isRemoteClass ||
- isRemote(meth) && isJMethodPublic
- ) && !(meth.throwsAnnotations contains definitions.RemoteExceptionClass)
- )
+ def hasThrowsRemoteException = meth.annotations.exists {
+ case ThrownException(exc) => exc.typeSymbol == definitions.RemoteExceptionClass
+ case _ => false
+ }
+ val needsAnnotation = {
+ (isRemoteClass ||
+ isRemote(meth) && isJMethodPublic
+ ) && !hasThrowsRemoteException
+ }
if (needsAnnotation) {
val c = Constant(definitions.RemoteExceptionClass.tpe)
val arg = Literal(c) setType c.tpe
@@ -603,8 +607,11 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
* must-single-thread
*/
def getExceptions(excs: List[AnnotationInfo]): List[String] = {
- for (ThrownException(exc) <- excs.distinct)
- yield internalName(exc)
+ for (ThrownException(tp) <- excs.distinct)
+ yield {
+ val erased = enteringErasure(erasure.erasure(tp.typeSymbol)(tp))
+ internalName(erased.typeSymbol)
+ }
}
} // end of trait BCForwardersGen
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 61abc55501..4424a3796b 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -891,8 +891,11 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
* This method returns such list of internal names.
*/
def getExceptions(excs: List[AnnotationInfo]): List[String] =
- for (ThrownException(exc) <- excs.distinct)
- yield javaName(exc)
+ for (ThrownException(tp) <- excs.distinct)
+ yield {
+ val erased = enteringErasure(erasure.erasure(tp.typeSymbol)(tp))
+ javaName(erased.typeSymbol)
+ }
def getCurrentCUnit(): CompilationUnit
@@ -995,10 +998,14 @@ abstract class GenASM extends SubComponent with BytecodeWriters { self =>
* Invoked from genMethod() and addForwarder().
*/
def addRemoteExceptionAnnot(isRemoteClass: Boolean, isJMethodPublic: Boolean, meth: Symbol) {
+ def hasThrowsRemoteException = meth.annotations.exists {
+ case ThrownException(exc) => exc.typeSymbol == definitions.RemoteExceptionClass
+ case _ => false
+ }
val needsAnnotation = (
( isRemoteClass ||
isRemote(meth) && isJMethodPublic
- ) && !(meth.throwsAnnotations contains RemoteExceptionClass)
+ ) && !hasThrowsRemoteException
)
if (needsAnnotation) {
val c = Constant(RemoteExceptionClass.tpe)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 833f25537c..747d20a441 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -71,7 +71,9 @@ abstract class Erasure extends AddInterfaces
}
override protected def verifyJavaErasure = settings.Xverify || settings.debug
- def needsJavaSig(tp: Type) = !settings.Ynogenericsig && NeedsSigCollector.collect(tp)
+ def needsJavaSig(tp: Type, throwsArgs: List[Type]) = !settings.Ynogenericsig && {
+ NeedsSigCollector.collect(tp) || throwsArgs.exists(NeedsSigCollector.collect)
+ }
// only refer to type params that will actually make it into the sig, this excludes:
// * higher-order type parameters
@@ -277,7 +279,7 @@ abstract class Erasure extends AddInterfaces
val preRebound = pre.baseType(sym.owner) // #2585
dotCleanup(
(
- if (needsJavaSig(preRebound)) {
+ if (needsJavaSig(preRebound, Nil)) {
val s = jsig(preRebound, existentiallyBound)
if (s.charAt(0) == 'L') s.substring(0, s.length - 1) + "." + sym.javaSimpleName
else fullNameInSig(sym)
@@ -356,8 +358,9 @@ abstract class Erasure extends AddInterfaces
else jsig(etp)
}
}
- if (needsJavaSig(info)) {
- try Some(jsig(info, toplevel = true))
+ val throwsArgs = sym0.annotations flatMap ThrownException.unapply
+ if (needsJavaSig(info, throwsArgs)) {
+ try Some(jsig(info, toplevel = true) + throwsArgs.map("^" + jsig(_, toplevel = true)).mkString(""))
catch { case ex: UnknownSig => None }
}
else None
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 45ebbd532d..510c83eb88 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3653,7 +3653,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val annType = annTpt.tpe
finish(
- if (typedFun.isErroneous)
+ if (typedFun.isErroneous || annType == null)
ErroneousAnnotation
else if (annType.typeSymbol isNonBottomSubClass ClassfileAnnotationClass) {
// annotation to be saved as java classfile annotation
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index b923541b56..207a66e360 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -30,12 +30,6 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
def staticAnnotations = annotations filter (_.isStatic)
- /** Symbols of any @throws annotations on this symbol.
- */
- def throwsAnnotations(): List[Symbol] = annotations collect {
- 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.")
@@ -406,24 +400,24 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
class ErroneousAnnotation() extends CompleteAnnotationInfo(ErrorType, Nil, Nil)
- /** Extracts symbol of thrown exception from AnnotationInfo.
+ /** Extracts the type of the thrown exception from an 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[Type] = {
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)
+ Some(tpe)
// new-style: @throws[Exception], @throws[Exception]("cause")
case AnnotationInfo(TypeRef(_, _, arg :: _), _, _) =>
- Some(arg.typeSymbol)
+ Some(arg)
case AnnotationInfo(TypeRef(_, _, Nil), _, _) =>
- Some(ThrowableClass)
+ Some(ThrowableTpe)
}
}
}
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index c3b2a8da08..ce93841567 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -2964,7 +2964,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
loop(info)
}
- override def exceptions = annotations flatMap ThrownException.unapply
+ override def exceptions = for (ThrownException(tp) <- annotations) yield tp.typeSymbol
}
implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol])