summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala8
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala2
-rw-r--r--test/files/run/t6379.check14
-rw-r--r--test/files/run/t6379/Macros_1.scala26
-rw-r--r--test/files/run/t6379/Test_2.scala22
5 files changed, 72 insertions, 0 deletions
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index 562129d893..6fff965de1 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -824,6 +824,14 @@ trait Symbols { self: Universe =>
* @group Method
*/
def returnType: Type
+
+ /** Exceptions that this method is known to throw.
+ * For Scala methods, the list is calculated from [[throws]] annotations present on a method.
+ * For Java methods, the list is calculated from `throws` clauses attached to the method and stored in bytecode.
+ *
+ * @group Method
+ */
+ def exceptions: List[Symbol]
}
/** The API of module symbols.
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index f2b3d52c6f..dae9eba878 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -2817,6 +2817,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
loop(info)
}
+
+ override def exceptions = annotations flatMap ThrownException.unapply
}
implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol])
diff --git a/test/files/run/t6379.check b/test/files/run/t6379.check
new file mode 100644
index 0000000000..3e5dfec623
--- /dev/null
+++ b/test/files/run/t6379.check
@@ -0,0 +1,14 @@
+compile-time
+uninitialized close: List(class IOException)
+initialized close: List(class IOException)
+uninitialized productElement: List(class IndexOutOfBoundsException)
+initialized productElement: List(class IndexOutOfBoundsException)
+uninitialized read: List(class IOException)
+initialized read: List(class IOException)
+runtime
+uninitialized close: List(class IOException)
+initialized close: List(class IOException)
+uninitialized productElement: List(class IndexOutOfBoundsException)
+initialized productElement: List(class IndexOutOfBoundsException)
+uninitialized read: List(class IOException)
+initialized read: List(class IOException)
diff --git a/test/files/run/t6379/Macros_1.scala b/test/files/run/t6379/Macros_1.scala
new file mode 100644
index 0000000000..a866438f7d
--- /dev/null
+++ b/test/files/run/t6379/Macros_1.scala
@@ -0,0 +1,26 @@
+import scala.reflect.macros.whitebox._
+import scala.language.experimental.macros
+import java.io._
+
+object Macros {
+ def impl(c: Context) = {
+ var messages = List[String]()
+ def println(msg: String) = messages :+= msg
+
+ import c.universe._
+ def test(sym: MethodSymbol): Unit = {
+ println(s"uninitialized ${sym.name}: ${sym.exceptions}")
+ sym.typeSignature
+ println(s"initialized ${sym.name}: ${sym.exceptions}")
+ }
+
+ println("compile-time")
+ test(typeOf[Closeable].declaration(TermName("close")).asMethod)
+ test(typeOf[Product1[_]].declaration(TermName("productElement")).asMethod)
+ test(c.mirror.staticClass("Reader").typeSignature.declaration(TermName("read")).asMethod)
+
+ q"..${messages.map(msg => q"println($msg)")}"
+ }
+
+ def foo: Any = macro impl
+} \ No newline at end of file
diff --git a/test/files/run/t6379/Test_2.scala b/test/files/run/t6379/Test_2.scala
new file mode 100644
index 0000000000..af4ec7c6d0
--- /dev/null
+++ b/test/files/run/t6379/Test_2.scala
@@ -0,0 +1,22 @@
+import java.io._
+import scala.reflect.runtime.universe._
+
+class Reader(fname: String) {
+ private val in = new BufferedReader(new FileReader(fname))
+ @throws[IOException]("if the file doesn't exist")
+ def read() = in.read()
+}
+
+object Test extends App {
+ def test(sym: MethodSymbol): Unit = {
+ println(s"uninitialized ${sym.name}: ${sym.exceptions}")
+ sym.typeSignature
+ println(s"initialized ${sym.name}: ${sym.exceptions}")
+ }
+
+ Macros.foo
+ println("runtime")
+ test(typeOf[Closeable].declaration(TermName("close")).asMethod)
+ test(typeOf[Product1[_]].declaration(TermName("productElement")).asMethod)
+ test(typeOf[Reader].declaration(TermName("read")).asMethod)
+}