Skip to content

Various clean-ups and docs #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 18, 2013
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ difficult to understand.
- Logging of the transform can be enabled with `scalac -Dscala.async.debug=true`.
- Tracing of the ANF transform: `scalac -Dscala.async.trace=true`
- Debug the macro expansion by checking out the project and executing the application
[`TreeInterrogation`](https://github.com/scala/async/blob/master/src/test/scala/scala/async/TreeInterrogation.scala#L59)
[`scala.async.TreeInterrogation`](https://github.com/scala/async/blob/master/src/test/scala/scala/async/TreeInterrogation.scala#L59)

## Limitations
- See the [neg](https://github.com/scala/async/tree/master/src/test/scala/scala/async/neg) test cases for
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
scalaVersion := "2.10.3-RC1"
scalaVersion := "2.10.3"

// Uncomment to test with a locally built copy of Scala.
// scalaHome := Some(file("/code/scala2/build/pack"))
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=0.13.0-RC5
sbt.version=0.13.0
4 changes: 2 additions & 2 deletions src/main/scala/scala/async/internal/AsyncTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ trait AsyncTransform {

// We annotate the type of the whole expression as `T @uncheckedBounds` so as not to introduce
// warnings about non-conformant LUBs. See SI-7694
// This implicit propatages the annotated type in the type tag.
// This implicit propagates the annotated type in the type tag.
implicit val uncheckedBoundsResultTag: WeakTypeTag[T] = WeakTypeTag[T](rootMirror, FixedMirrorTypeCreator(rootMirror, uncheckedBounds(resultType.tpe)))

reportUnsupportedAwaits(body, report = !cpsFallbackEnabled)

// Transform to A-normal form:
// Transform to A-normal form:
// - no await calls in qualifiers or arguments,
// - if/match only used in statement position.
val anfTree: Block = anfTransform(body)
Expand Down
73 changes: 44 additions & 29 deletions src/main/scala/scala/async/internal/ExprBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ trait ExprBuilder {
}
}

/** A sequence of statements the concludes with a unconditional transition to `nextState` */
/** A sequence of statements that concludes with a unconditional transition to `nextState` */
final class SimpleAsyncState(val stats: List[Tree], val state: Int, nextState: Int, symLookup: SymLookup)
extends AsyncState {

Expand All @@ -65,7 +65,7 @@ trait ExprBuilder {
}

/** A sequence of statements that concludes with an `await` call. The `onComplete`
* handler will unconditionally transition to `nestState`.``
* handler will unconditionally transition to `nextState`.
*/
final class AsyncStateWithAwait(val stats: List[Tree], val state: Int, nextState: Int,
val awaitable: Awaitable, symLookup: SymLookup)
Expand Down Expand Up @@ -110,7 +110,7 @@ trait ExprBuilder {
}

/*
* Builder for a single state of an async method.
* Builder for a single state of an async expression.
*/
final class AsyncStateBuilder(state: Int, private val symLookup: SymLookup) {
/* Statements preceding an await call. */
Expand All @@ -123,9 +123,10 @@ trait ExprBuilder {
def addStat() = stats += stat
stat match {
case Apply(fun, Nil) =>
// labelDefStates belongs to the current ExprBuilder
labelDefStates get fun.symbol match {
case Some(nextState) => nextJumpState = Some(nextState)
case None => addStat()
case opt @ Some(nextState) => nextJumpState = opt // re-use object
case None => addStat()
}
case _ => addStat()
}
Expand Down Expand Up @@ -258,7 +259,7 @@ trait ExprBuilder {
currState = afterMatchState
stateBuilder = new AsyncStateBuilder(currState, symLookup)

case ld@LabelDef(name, params, rhs) if rhs exists isAwait =>
case ld @ LabelDef(name, params, rhs) if rhs exists isAwait =>
val startLabelState = nextState()
val afterLabelState = nextState()
asyncStates += stateBuilder.resultWithLabel(startLabelState, symLookup)
Expand All @@ -268,7 +269,8 @@ trait ExprBuilder {

currState = afterLabelState
stateBuilder = new AsyncStateBuilder(currState, symLookup)
case _ =>

case _ =>
checkForUnsupportedAwait(stat)
stateBuilder += stat
}
Expand All @@ -293,6 +295,13 @@ trait ExprBuilder {
gen.mkAttributedRef(stateMachineMember(name))
}

/**
* Uses `AsyncBlockBuilder` to create an instance of `AsyncBlock`.
*
* @param block a `Block` tree in ANF
* @param symLookup helper for looking up members of the state machine class
* @return an `AsyncBlock`
*/
def buildAsyncBlock(block: Block, symLookup: SymLookup): AsyncBlock = {
val Block(stats, expr) = block
val startState = stateAssigner.nextState()
Expand Down Expand Up @@ -323,19 +332,23 @@ trait ExprBuilder {
val initStates = asyncStates.init

/**
* def resume(): Unit = {
* try {
* state match {
* case 0 => {
* f11 = exprReturningFuture
* f11.onComplete(onCompleteHandler)(context)
* Builds the definition of the `resume` method.
*
* The resulting tree has the following shape:
*
* def resume(): Unit = {
* try {
* state match {
* case 0 => {
* f11 = exprReturningFuture
* f11.onComplete(onCompleteHandler)(context)
* }
* ...
* }
* } catch {
* case NonFatal(t) => result.failure(t)
* }
* ...
* }
* } catch {
* case NonFatal(t) => result.failure(t)
* }
* }
*/
def resumeFunTree[T: WeakTypeTag]: DefDef =
DefDef(Modifiers(), name.resume, Nil, List(Nil), Ident(definitions.UnitClass),
Expand All @@ -344,22 +357,23 @@ trait ExprBuilder {
List(
CaseDef(
Bind(name.t, Ident(nme.WILDCARD)),
Apply(Ident(defn.NonFatalClass), List(Ident(name.t))),
Block(List({
Apply(Ident(defn.NonFatalClass), List(Ident(name.t))), {
val t = Expr[Throwable](Ident(name.t))
futureSystemOps.completeProm[T](
Expr[futureSystem.Prom[T]](symLookup.memberRef(name.result)), reify(scala.util.Failure(t.splice))).tree
}), literalUnit))), EmptyTree))
})), EmptyTree))

/**
* assumes tr: Try[Any] is in scope.
* Builds a `match` expression used as an onComplete handler.
*
* state match {
* case 0 =>
* x11 = tr.get.asInstanceOf[Double]
* state = 1
* resume()
* }
* Assumes `tr: Try[Any]` is in scope. The resulting tree has the following shape:
*
* state match {
* 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)
Expand All @@ -373,7 +387,8 @@ trait ExprBuilder {

case class Awaitable(expr: Tree, resultName: Symbol, resultType: Type, resultValDef: ValDef)

private def mkResumeApply(symLookup: SymLookup) = Apply(symLookup.memberRef(name.resume), Nil)
private def mkResumeApply(symLookup: SymLookup) =
Apply(symLookup.memberRef(name.resume), Nil)

private def mkStateTree(nextState: Int, symLookup: SymLookup): Tree =
Assign(symLookup.memberRef(name.state), Literal(Constant(nextState)))
Expand Down