summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2014-01-28 10:27:59 +0300
committerEugene Burmako <xeno.by@gmail.com>2014-02-14 13:24:48 +0100
commitedadc01df2cbac2c8a00c2e0cc520713690418b9 (patch)
tree5a7211dca95674f85460ee52f167766f0df9348c
parentad7983b70a43ba9033a491c00ad22691e7a0a7b4 (diff)
downloadscala-edadc01df2cbac2c8a00c2e0cc520713690418b9.tar.gz
scala-edadc01df2cbac2c8a00c2e0cc520713690418b9.tar.bz2
scala-edadc01df2cbac2c8a00c2e0cc520713690418b9.zip
SI-6379 adds MethodSymbol.exception
Following Simon’s request, this commit introduces a dedicated API that can be used to acquire the list of exceptions thrown by a method, abstracting away from whether it’s a Java or a Scala artifact.
-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)
+}