aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Haller <hallerp@gmail.com>2012-11-12 06:21:35 -0800
committerPhilipp Haller <hallerp@gmail.com>2012-11-12 06:21:35 -0800
commit415d277d931033d00b96f78d9a8f3e06c6df79c2 (patch)
tree2c85470d5fdb248157b21551bb537e353662712a
parent7a27951f47635f8badcabfee2f315dd6183ac8ce (diff)
parent35e62f929df44ff83ed2296352a9db9df889af17 (diff)
downloadscala-async-415d277d931033d00b96f78d9a8f3e06c6df79c2.tar.gz
scala-async-415d277d931033d00b96f78d9a8f3e06c6df79c2.tar.bz2
scala-async-415d277d931033d00b96f78d9a8f3e06c6df79c2.zip
Merge pull request #9 from phaller/topic/local-classes
#8 - Clean compilation error when defining local class inside async block
-rw-r--r--src/main/scala/scala/async/ExprBuilder.scala8
-rw-r--r--src/test/scala/scala/async/TreeInterrogation.scala2
-rw-r--r--src/test/scala/scala/async/neg/LocalClasses0Spec.scala121
3 files changed, 130 insertions, 1 deletions
diff --git a/src/main/scala/scala/async/ExprBuilder.scala b/src/main/scala/scala/async/ExprBuilder.scala
index 1a3f866..56274ec 100644
--- a/src/main/scala/scala/async/ExprBuilder.scala
+++ b/src/main/scala/scala/async/ExprBuilder.scala
@@ -368,6 +368,14 @@ final class ExprBuilder[C <: Context, FS <: FutureSystem](val c: C, val futureSy
currState = currState + matchBudget
stateBuilder = new builder.AsyncStateBuilder(currState, toRename)
+ case ClassDef(_, name, _, _) =>
+ // do not allow local class definitions, because of SI-5467 (specific to case classes, though)
+ c.error(stat.pos, s"Local class ${name.decoded} illegal within `async` block")
+
+ case ModuleDef(_, name, _) =>
+ // local object definitions lead to spurious type errors (because of resetAllAttrs?)
+ c.error(stat.pos, s"Local object ${name.decoded} illegal within `async` block")
+
case _ =>
checkForUnsupportedAwait(stat)
stateBuilder += stat
diff --git a/src/test/scala/scala/async/TreeInterrogation.scala b/src/test/scala/scala/async/TreeInterrogation.scala
index 7c277b1..1293bdf 100644
--- a/src/test/scala/scala/async/TreeInterrogation.scala
+++ b/src/test/scala/scala/async/TreeInterrogation.scala
@@ -10,7 +10,7 @@ class TreeInterrogation {
@Test
def `a minimal set of vals are lifted to vars`() {
val cm = reflect.runtime.currentMirror
- val tb = mkToolbox()
+ val tb = mkToolbox("-cp target/scala-2.10/classes")
val tree = mkToolbox().parse(
"""| import _root_.scala.async.AsyncId._
| async {
diff --git a/src/test/scala/scala/async/neg/LocalClasses0Spec.scala b/src/test/scala/scala/async/neg/LocalClasses0Spec.scala
new file mode 100644
index 0000000..7932744
--- /dev/null
+++ b/src/test/scala/scala/async/neg/LocalClasses0Spec.scala
@@ -0,0 +1,121 @@
+package scala.async
+package neg
+
+/**
+ * Copyright (C) 2012 Typesafe Inc. <http://www.typesafe.com>
+ */
+
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.Test
+
+@RunWith(classOf[JUnit4])
+class LocalClasses0Spec {
+
+ @Test
+ def `reject a local class`() {
+ expectError("Local class Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") {
+ """
+ | import scala.concurrent.ExecutionContext.Implicits.global
+ | import scala.async.Async._
+ |
+ | async {
+ | case class Person(name: String)
+ | }
+ """.stripMargin
+ }
+ }
+
+ @Test
+ def `reject a local class 2`() {
+ expectError("Local class Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") {
+ """
+ | import scala.concurrent.{Future, ExecutionContext}
+ | import ExecutionContext.Implicits.global
+ | import scala.async.Async._
+ |
+ | async {
+ | case class Person(name: String)
+ | val fut = Future { 5 }
+ | val x = await(fut)
+ | x
+ | }
+ """.stripMargin
+ }
+ }
+
+ @Test
+ def `reject a local class 3`() {
+ expectError("Local class Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") {
+ """
+ | import scala.concurrent.{Future, ExecutionContext}
+ | import ExecutionContext.Implicits.global
+ | import scala.async.Async._
+ |
+ | async {
+ | val fut = Future { 5 }
+ | val x = await(fut)
+ | case class Person(name: String)
+ | x
+ | }
+ """.stripMargin
+ }
+ }
+
+ @Test
+ def `reject a local class with symbols in its name`() {
+ expectError("Local class :: illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") {
+ """
+ | import scala.concurrent.{Future, ExecutionContext}
+ | import ExecutionContext.Implicits.global
+ | import scala.async.Async._
+ |
+ | async {
+ | val fut = Future { 5 }
+ | val x = await(fut)
+ | case class ::(name: String)
+ | x
+ | }
+ """.stripMargin
+ }
+ }
+
+ @Test
+ def `reject a nested local class`() {
+ expectError("Local class Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") {
+ """
+ | import scala.concurrent.{Future, ExecutionContext}
+ | import ExecutionContext.Implicits.global
+ | import scala.async.Async._
+ |
+ | async {
+ | val fut = Future { 5 }
+ | val x = 2 + 2
+ | var y = 0
+ | if (x > 0) {
+ | case class Person(name: String)
+ | y = await(fut)
+ | } else {
+ | y = x
+ | }
+ | y
+ | }
+ """.stripMargin
+ }
+ }
+
+ @Test
+ def `reject a local singleton object`() {
+ expectError("Local object Person illegal within `async` block", "-cp target/scala-2.10/classes -deprecation -Xfatal-warnings") {
+ """
+ | import scala.concurrent.ExecutionContext.Implicits.global
+ | import scala.async.Async._
+ |
+ | async {
+ | object Person { val name = "Joe" }
+ | }
+ """.stripMargin
+ }
+ }
+
+}