From 5a2acf110233669e1cf1124ac54b28a526d37858 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Fri, 23 Nov 2012 12:08:59 +0100 Subject: Ensure unique names for definitions in the async block. - transform the provided tree using reflect.internal.Symbols#Symbol.name_= and treeCopy.{Ident, Select}. - not sure if this is possible within the public Symbol API. - move checking for unsupported nested module/class to AsyncAnalysis. - make block merging selective (only do so if there are nested await calls.) --- src/main/scala/scala/async/AsyncAnalysis.scala | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'src/main/scala/scala/async/AsyncAnalysis.scala') diff --git a/src/main/scala/scala/async/AsyncAnalysis.scala b/src/main/scala/scala/async/AsyncAnalysis.scala index 1b00620..c7db44d 100644 --- a/src/main/scala/scala/async/AsyncAnalysis.scala +++ b/src/main/scala/scala/async/AsyncAnalysis.scala @@ -32,11 +32,17 @@ private[async] final class AsyncAnalysis[C <: Context](override val c: C) extend private class UnsupportedAwaitAnalyzer extends super.AsyncTraverser { override def nestedClass(classDef: ClassDef) { val kind = if (classDef.symbol.asClass.isTrait) "trait" else "class" - reportUnsupportedAwait(classDef, s"nested $kind") + if (!reportUnsupportedAwait(classDef, s"nested $kind")) { + // do not allow local class definitions, because of SI-5467 (specific to case classes, though) + c.error(classDef.pos, s"Local class ${classDef.name.decoded} illegal within `async` block") + } } override def nestedModule(module: ModuleDef) { - reportUnsupportedAwait(module, "nested object") + if (!reportUnsupportedAwait(module, "nested object")) { + // local object definitions lead to spurious type errors (because of resetAllAttrs?) + c.error(module.pos, s"Local object ${module.name.decoded} illegal within `async` block") + } } override def byNameArgument(arg: Tree) { @@ -47,14 +53,18 @@ private[async] final class AsyncAnalysis[C <: Context](override val c: C) extend reportUnsupportedAwait(function, "nested function") } - private def reportUnsupportedAwait(tree: Tree, whyUnsupported: String) { - val badAwaits = tree collect { + /** + * @return true, if the tree contained an unsupported await. + */ + private def reportUnsupportedAwait(tree: Tree, whyUnsupported: String): Boolean = { + val badAwaits: List[RefTree] = tree collect { case rt: RefTree if isAwait(rt) => rt } badAwaits foreach { tree => c.error(tree.pos, s"await must not be used under a $whyUnsupported.") } + badAwaits.nonEmpty } } -- cgit v1.2.3