diff options
author | Philipp Haller <hallerp@gmail.com> | 2012-11-12 06:21:35 -0800 |
---|---|---|
committer | Philipp Haller <hallerp@gmail.com> | 2012-11-12 06:21:35 -0800 |
commit | 415d277d931033d00b96f78d9a8f3e06c6df79c2 (patch) | |
tree | 2c85470d5fdb248157b21551bb537e353662712a | |
parent | 7a27951f47635f8badcabfee2f315dd6183ac8ce (diff) | |
parent | 35e62f929df44ff83ed2296352a9db9df889af17 (diff) | |
download | scala-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.scala | 8 | ||||
-rw-r--r-- | src/test/scala/scala/async/TreeInterrogation.scala | 2 | ||||
-rw-r--r-- | src/test/scala/scala/async/neg/LocalClasses0Spec.scala | 121 |
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 + } + } + +} |