aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/scala/async/internal/TransformUtils.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/scala/async/internal/TransformUtils.scala')
-rw-r--r--src/main/scala/scala/async/internal/TransformUtils.scala41
1 files changed, 33 insertions, 8 deletions
diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala
index 90419d3..c86540b 100644
--- a/src/main/scala/scala/async/internal/TransformUtils.scala
+++ b/src/main/scala/scala/async/internal/TransformUtils.scala
@@ -24,6 +24,7 @@ private[async] trait TransformUtils {
val ifRes = "ifres"
val await = "await"
val bindSuffix = "$bind"
+ val completed = newTermName("completed")
val state = newTermName("state")
val result = newTermName("result")
@@ -38,6 +39,9 @@ private[async] trait TransformUtils {
def fresh(name: String): String = c.freshName(name)
}
+ def isAsync(fun: Tree) =
+ fun.symbol == defn.Async_async
+
def isAwait(fun: Tree) =
fun.symbol == defn.Async_await
@@ -164,7 +168,8 @@ private[async] trait TransformUtils {
val NonFatalClass = rootMirror.staticModule("scala.util.control.NonFatal")
val ThrowableClass = rootMirror.staticClass("java.lang.Throwable")
- val Async_await = asyncBase.awaitMethod(c.universe)(c.macroApplication.symbol).ensuring(_ != NoSymbol)
+ lazy val Async_async = asyncBase.asyncMethod(c.universe)(c.macroApplication.symbol)
+ lazy val Async_await = asyncBase.awaitMethod(c.universe)(c.macroApplication.symbol)
val IllegalStateExceptionClass = rootMirror.staticClass("java.lang.IllegalStateException")
}
@@ -186,6 +191,10 @@ private[async] trait TransformUtils {
val LABEL = 1L << 17 // not in the public reflection API.
(internal.flags(sym).asInstanceOf[Long] & LABEL) != 0L
}
+ def isSynth(sym: Symbol): Boolean = {
+ val SYNTHETIC = 1 << 21 // not in the public reflection API.
+ (internal.flags(sym).asInstanceOf[Long] & SYNTHETIC) != 0L
+ }
def symId(sym: Symbol): Int = {
val symtab = this.c.universe.asInstanceOf[reflect.internal.SymbolTable]
sym.asInstanceOf[symtab.Symbol].id
@@ -281,6 +290,8 @@ private[async] trait TransformUtils {
override def traverse(tree: Tree) {
tree match {
+ case _ if isAsync(tree) =>
+ // Under -Ymacro-expand:discard, used in the IDE, nested async blocks will be visible to the outer blocks
case cd: ClassDef => nestedClass(cd)
case md: ModuleDef => nestedModule(md)
case dd: DefDef => nestedMethod(dd)
@@ -382,7 +393,7 @@ private[async] trait TransformUtils {
catch { case _: ScalaReflectionException => NoSymbol }
}
final def uncheckedBounds(tp: Type): Type = {
- if (tp.typeArgs.isEmpty || UncheckedBoundsClass == NoSymbol) tp
+ if ((tp.typeArgs.isEmpty && (tp match { case _: TypeRef => true; case _ => false}))|| UncheckedBoundsClass == NoSymbol) tp
else withAnnotation(tp, Annotation(UncheckedBoundsClass.asType.toType, Nil, ListMap()))
}
// =====================================
@@ -396,9 +407,11 @@ private[async] trait TransformUtils {
* in search of a sub tree that was decorated with the cached answer.
*/
final def containsAwaitCached(t: Tree): Tree => Boolean = {
+ if (c.macroApplication.symbol == null) return (t => false)
+
def treeCannotContainAwait(t: Tree) = t match {
case _: Ident | _: TypeTree | _: Literal => true
- case _ => false
+ case _ => isAsync(t)
}
def shouldAttach(t: Tree) = !treeCannotContainAwait(t)
val symtab = c.universe.asInstanceOf[scala.reflect.internal.SymbolTable]
@@ -417,11 +430,15 @@ private[async] trait TransformUtils {
override def traverse(tree: Tree): Unit = {
stack ::= tree
try {
- if (isAwait(tree))
- stack.foreach(attachContainsAwait)
- else
- attachNoAwait(tree)
- super.traverse(tree)
+ if (isAsync(tree)) {
+ ;
+ } else {
+ if (isAwait(tree))
+ stack.foreach(attachContainsAwait)
+ else
+ attachNoAwait(tree)
+ super.traverse(tree)
+ }
} finally stack = stack.tail
}
}
@@ -463,6 +480,14 @@ private[async] trait TransformUtils {
typingTransform(t, owner) {
(tree, api) =>
tree match {
+ case LabelDef(name, params, rhs) =>
+ val rhs1 = api.recur(rhs)
+ if (rhs1.tpe =:= UnitTpe) {
+ internal.setInfo(tree.symbol, internal.methodType(tree.symbol.info.paramLists.head, UnitTpe))
+ treeCopy.LabelDef(tree, name, params, rhs1)
+ } else {
+ treeCopy.LabelDef(tree, name, params, rhs1)
+ }
case Block(stats, expr) =>
val stats1 = stats map api.recur
val expr1 = api.recur(expr)