diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2015-10-09 15:34:59 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2015-10-09 15:34:59 +1000 |
commit | 01b36eae1da662763d969a9c312832a4e7ea1f84 (patch) | |
tree | d3bc4adb923e1b47765d0b929942559f078a869c /src/main/scala/scala/async/internal/AsyncAnalysis.scala | |
parent | 7263aaad02a75978a0a48f90bf171c66cda4328c (diff) | |
download | scala-async-01b36eae1da662763d969a9c312832a4e7ea1f84.tar.gz scala-async-01b36eae1da662763d969a9c312832a4e7ea1f84.tar.bz2 scala-async-01b36eae1da662763d969a9c312832a4e7ea1f84.zip |
Avoid spurious "illegal await" error in IDE with nesting
The presentation compiler runs with `-Ymacro-expand:discard`, which
retains the macro expandee in the typechecked trees, rather than
substituting in the expansion. This mode was motivated as a means
to keep IDE functionality working (e.g. completion, navigation,
refactoring) inside macro applications.
However, if one has nested async macro applications, as reported in
the IDE ticket:
https://www.assembla.com/spaces/scala-ide/tickets/1002561
... the expansion of the outer async application was reporting
await calls enclosed by the inner async application.
This change tweaks the traversers used for this analysis to
stop whenever it sees an async.
Diffstat (limited to 'src/main/scala/scala/async/internal/AsyncAnalysis.scala')
-rw-r--r-- | src/main/scala/scala/async/internal/AsyncAnalysis.scala | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/src/main/scala/scala/async/internal/AsyncAnalysis.scala b/src/main/scala/scala/async/internal/AsyncAnalysis.scala index 6540bdb..6b75493 100644 --- a/src/main/scala/scala/async/internal/AsyncAnalysis.scala +++ b/src/main/scala/scala/async/internal/AsyncAnalysis.scala @@ -4,6 +4,7 @@ package scala.async.internal +import scala.collection.mutable.ListBuffer import scala.reflect.macros.Context import scala.collection.mutable @@ -53,14 +54,13 @@ trait AsyncAnalysis { } override def traverse(tree: Tree) { - def containsAwait = tree exists isAwait tree match { - case Try(_, _, _) if containsAwait => + case Try(_, _, _) if containsAwait(tree) => reportUnsupportedAwait(tree, "try/catch") super.traverse(tree) case Return(_) => c.abort(tree.pos, "return is illegal within a async block") - case DefDef(mods, _, _, _, _, _) if mods.hasFlag(Flag.LAZY) && containsAwait => + case DefDef(mods, _, _, _, _, _) if mods.hasFlag(Flag.LAZY) && containsAwait(tree) => reportUnsupportedAwait(tree, "lazy val initializer") case CaseDef(_, guard, _) if guard exists isAwait => // TODO lift this restriction @@ -74,9 +74,19 @@ trait AsyncAnalysis { * @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 + val badAwaits = ListBuffer[Tree]() + object traverser extends Traverser { + override def traverse(tree: Tree): Unit = { + if (!isAsync(tree)) + super.traverse(tree) + tree match { + case rt: RefTree if isAwait(rt) => + badAwaits += rt + case _ => + } + } } + traverser(tree) badAwaits foreach { tree => reportError(tree.pos, s"await must not be used under a $whyUnsupported.") |