Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 5 additions & 14 deletions src/main/scala/scala/async/internal/AnfTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ private[async] trait AnfTransform {
private object trace {
private var indent = -1

def indentString = " " * indent
private def indentString = " " * indent

def apply[T](args: Any)(t: => T): T = {
def prefix = mode.toString.toLowerCase
indent += 1
def oneLine(s: Any) = s.toString.replaceAll( """\n""", "\\\\n").take(127)
def oneLine(s: Any) = s.toString.replaceAll("""\n""", "\\\\n").take(127)
try {
AsyncUtils.trace(s"${indentString}$prefix(${oneLine(args)})")
val result = t
Expand Down Expand Up @@ -173,7 +173,7 @@ private[async] trait AnfTransform {
stats :+ treeCopy.Typed(tree, expr1, tpt)

case treeInfo.Applied(fun, targs, argss) if argss.nonEmpty =>
// we an assume that no await call appears in a by-name argument position,
// we can assume that no await call appears in a by-name argument position,
// this has already been checked.
val funStats :+ simpleFun = linearize.transformToList(fun)
val (argStatss, argExprss): (List[List[List[Tree]]], List[List[Tree]]) =
Expand Down Expand Up @@ -221,14 +221,7 @@ private[async] trait AnfTransform {
val condStats :+ condExpr = linearize.transformToList(cond)
val thenBlock = linearize.transformToBlock(thenp)
val elseBlock = linearize.transformToBlock(elsep)
// Typechecking with `condExpr` as the condition fails if the condition
// contains an await. `ifTree.setType(tree.tpe)` also fails; it seems
// we rely on this call to `typeCheck` descending into the branches.
// But, we can get away with typechecking a throwaway `If` tree with the
// original scrutinee and the new branches, and setting that type on
// the real `If` tree.
val iff = treeCopy.If(tree, condExpr, thenBlock, elseBlock)
condStats :+ iff
condStats :+ treeCopy.If(tree, condExpr, thenBlock, elseBlock)

case Match(scrut, cases) =>
val scrutStats :+ scrutExpr = linearize.transformToList(scrut)
Expand All @@ -248,9 +241,7 @@ private[async] trait AnfTransform {
val newBlock = treeCopy.Block(b, valDefs ++ stats1, expr1)
treeCopy.CaseDef(tree, pat, guard, newBlock)
}
// Refer to comments the translation of `If` above.
val typedMatch = treeCopy.Match(tree, scrutExpr, caseDefs)
scrutStats :+ typedMatch
scrutStats :+ treeCopy.Match(tree, scrutExpr, caseDefs)

case LabelDef(name, params, rhs) =>
List(LabelDef(name, params, Block(linearize.transformToList(rhs), Literal(Constant(())))).setSymbol(tree.symbol))
Expand Down
1 change: 1 addition & 0 deletions src/main/scala/scala/async/internal/AsyncBase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ abstract class AsyncBase {
execContext.tree.asInstanceOf[asyncMacro.global.Tree],
fallbackEnabled)(implicitly[c.WeakTypeTag[T]].asInstanceOf[asyncMacro.global.WeakTypeTag[T]]).asInstanceOf[Tree]

// Mark range positions for synthetic code as transparent to allow some wiggle room for overlapping ranges
for (t <- code)
t.pos = t.pos.makeTransparent

Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/scala/async/internal/AsyncMacro.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import scala.tools.nsc.transform.TypingTransformers
object AsyncMacro {
def apply(c: reflect.macros.Context, futureSystem0: FutureSystem): AsyncMacro = {
import language.reflectiveCalls
val powerContext = c.asInstanceOf[c.type {val universe: Global; val callsiteTyper: universe.analyzer.Typer}]
val powerContext = c.asInstanceOf[c.type { val universe: Global; val callsiteTyper: universe.analyzer.Typer }]
new AsyncMacro {
val global: powerContext.universe.type = powerContext.universe
val callSiteTyper: global.analyzer.Typer = powerContext.callsiteTyper
Expand All @@ -26,7 +26,7 @@ private[async] trait AsyncMacro
val callSiteTyper: global.analyzer.Typer
val macroApplication: global.Tree

def macroPos = macroApplication.pos.makeTransparent
lazy val macroPos = macroApplication.pos.makeTransparent
def atMacroPos(t: global.Tree) = global.atPos(macroPos)(t)

}
41 changes: 21 additions & 20 deletions src/main/scala/scala/async/internal/ExprBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import collection.mutable
import language.existentials
import scala.reflect.api.Universe
import scala.reflect.api
import scala.Some

trait ExprBuilder {
builder: AsyncMacro =>
Expand Down Expand Up @@ -290,7 +289,8 @@ trait ExprBuilder {
case class SymLookup(stateMachineClass: Symbol, applyTrParam: Symbol) {
def stateMachineMember(name: TermName): Symbol =
stateMachineClass.info.member(name)
def memberRef(name: TermName) = gen.mkAttributedRef(stateMachineMember(name))
def memberRef(name: TermName): Tree =
gen.mkAttributedRef(stateMachineMember(name))
}

def buildAsyncBlock(block: Block, symLookup: SymLookup): AsyncBlock = {
Expand Down Expand Up @@ -324,17 +324,17 @@ trait ExprBuilder {

/**
* def resume(): Unit = {
* try {
* state match {
* case 0 => {
* f11 = exprReturningFuture
* f11.onComplete(onCompleteHandler)(context)
* }
* ...
* }
* } catch {
* case NonFatal(t) => result.failure(t)
* }
* try {
* state match {
* case 0 => {
* f11 = exprReturningFuture
* f11.onComplete(onCompleteHandler)(context)
* }
* ...
* }
* } catch {
* case NonFatal(t) => result.failure(t)
* }
* }
*/
def resumeFunTree[T]: DefDef =
Expand All @@ -352,16 +352,17 @@ trait ExprBuilder {
}), literalUnit))), EmptyTree))

/**
* // assumes tr: Try[Any] is in scope.
* //
* assumes tr: Try[Any] is in scope.
*
* state match {
* case 0 => {
* x11 = tr.get.asInstanceOf[Double];
* state = 1;
* resume()
* case 0 =>
* x11 = tr.get.asInstanceOf[Double]
* state = 1
* resume()
* }
*/
def onCompleteHandler[T: WeakTypeTag]: Tree = Match(symLookup.memberRef(name.state), initStates.flatMap(_.mkOnCompleteHandler[T]).toList)
def onCompleteHandler[T: WeakTypeTag]: Tree =
Match(symLookup.memberRef(name.state), initStates.flatMap(_.mkOnCompleteHandler[T]).toList)
}
}

Expand Down
4 changes: 1 addition & 3 deletions src/main/scala/scala/async/internal/FutureSystem.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
package scala.async.internal

import scala.language.higherKinds

import scala.reflect.macros.Context
import scala.reflect.internal.SymbolTable

/**
Expand Down Expand Up @@ -54,7 +52,7 @@ trait FutureSystem {
def spawn(tree: Tree, execContext: Tree): Tree =
future(Expr[Unit](tree))(Expr[ExecContext](execContext)).tree

// TODO Why is this needed?
// This is only needed in `AsyncBaseWithCPSFallback` and should be removed once CPS fall-back support is dropped.
def castTo[A: WeakTypeTag](future: Expr[Fut[Any]]): Expr[Fut[A]]
}

Expand Down
1 change: 0 additions & 1 deletion src/test/scala/scala/async/TreeInterrogation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ object TreeInterrogation extends App {
import scala.async.Async._
val tree = tb.parse(
""" import _root_.scala.async.internal.AsyncId.{async, await}
| import reflect.runtime.universe._
| async {
| implicit def view(a: Int): String = ""
| await(0).length
Expand Down