diff options
author | Philipp Haller <hallerp@gmail.com> | 2012-11-26 10:32:37 -0800 |
---|---|---|
committer | Philipp Haller <hallerp@gmail.com> | 2012-11-26 10:32:37 -0800 |
commit | 54c97691f78dcd811cd5dad66d0b7d9406fb9ed6 (patch) | |
tree | 31fd1d999bd88275d1202c0ef7f7c8a7fa4f0928 /src/main/scala/scala/async/ExprBuilder.scala | |
parent | 4518c96f9b54a1b7ca14d82b3ed31d7014a67f57 (diff) | |
parent | 6c3c0f0a37d337aa297f5b2481d4727ea2a20434 (diff) | |
download | scala-async-54c97691f78dcd811cd5dad66d0b7d9406fb9ed6.tar.gz scala-async-54c97691f78dcd811cd5dad66d0b7d9406fb9ed6.tar.bz2 scala-async-54c97691f78dcd811cd5dad66d0b7d9406fb9ed6.zip |
Merge pull request #41 from phaller/ticket/35-synth-object-2
Ticket/35 synth object 2
Diffstat (limited to 'src/main/scala/scala/async/ExprBuilder.scala')
-rw-r--r-- | src/main/scala/scala/async/ExprBuilder.scala | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/src/main/scala/scala/async/ExprBuilder.scala b/src/main/scala/scala/async/ExprBuilder.scala index d9faad5..7b4ccb8 100644 --- a/src/main/scala/scala/async/ExprBuilder.scala +++ b/src/main/scala/scala/async/ExprBuilder.scala @@ -6,11 +6,12 @@ package scala.async import scala.reflect.macros.Context import scala.collection.mutable.ListBuffer import collection.mutable +import language.existentials /* * @author Philipp Haller */ -private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c: C, futureSystem: FS) { +private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c: C, futureSystem: FS, origTree: C#Tree) { builder => val utils = TransformUtils[c.type](c) @@ -70,7 +71,7 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c: override def mkHandlerCaseForState: CaseDef = { val callOnComplete = futureSystemOps.onComplete(c.Expr(awaitable.expr), - c.Expr(Ident(name.onCompleteHandler)), c.Expr(Ident(name.execContext))).tree + c.Expr(This(tpnme.EMPTY)), c.Expr(Ident(name.execContext))).tree mkHandlerCase(state, stats :+ callOnComplete) } @@ -96,12 +97,13 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c: /** The state of the target of a LabelDef application (while loop jump) */ private var nextJumpState: Option[Int] = None - private def renameReset(tree: Tree) = resetDuplicate(substituteNames(tree, nameMap)) + private def renameReset(tree: Tree) = resetInternalAttrs(substituteNames(tree, nameMap)) def +=(stat: c.Tree): this.type = { assert(nextJumpState.isEmpty, s"statement appeared after a label jump: $stat") def addStat() = stats += renameReset(stat) stat match { + case _: DefDef => // these have been lifted. case Apply(fun, Nil) => labelDefStates get fun.symbol match { case Some(nextState) => nextJumpState = Some(nextState) @@ -146,7 +148,12 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c: def resultWithMatch(scrutTree: c.Tree, cases: List[CaseDef], caseStates: List[Int]): AsyncState = { // 1. build list of changed cases val newCases = for ((cas, num) <- cases.zipWithIndex) yield cas match { - case CaseDef(pat, guard, rhs) => CaseDef(pat, guard, Block(mkStateTree(caseStates(num)), mkResumeApply)) + case CaseDef(pat, guard, rhs) => + val bindAssigns = rhs.children.takeWhile(isSyntheticBindVal).map { + case ValDef(_, name, _, rhs) => Assign(Ident(name), rhs) + case t => sys.error(s"Unexpected tree. Expected ValDef, found: $t") + } + CaseDef(pat, guard, Block(bindAssigns :+ mkStateTree(caseStates(num)), mkResumeApply)) } // 2. insert changed match tree at the end of the current state this += Match(renameReset(scrutTree), newCases) @@ -237,7 +244,9 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c: stateBuilder.resultWithMatch(scrutinee, cases, caseStates) for ((cas, num) <- cases.zipWithIndex) { - val builder = nestedBlockBuilder(cas.body, caseStates(num), afterMatchState) + val (stats, expr) = statsAndExpr(cas.body) + val stats1 = stats.dropWhile(isSyntheticBindVal) + val builder = nestedBlockBuilder(Block(stats1, expr), caseStates(num), afterMatchState) asyncStates ++= builder.asyncStates } @@ -302,19 +311,16 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c: val initStates = asyncStates.init /** - * lazy val onCompleteHandler = (tr: Try[Any]) => state match { + * // assumes tr: Try[Any] is in scope. + * // + * state match { * case 0 => { * x11 = tr.get.asInstanceOf[Double]; * state = 1; * resume() * } */ - val onCompleteHandler: Tree = { - val onCompleteHandlers = initStates.flatMap(_.mkOnCompleteHandler).toList - Function( - List(ValDef(Modifiers(Flag.PARAM), name.tr, TypeTree(defn.TryAnyType), EmptyTree)), - Match(Ident(name.state), onCompleteHandlers)) - } + val onCompleteHandler: Tree = Match(Ident(name.state), initStates.flatMap(_.mkOnCompleteHandler).toList) /** * def resume(): Unit = { @@ -346,9 +352,18 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](c: } } + private def isSyntheticBindVal(tree: Tree) = tree match { + case vd@ValDef(_, lname, _, Ident(rname)) => lname.toString.contains(name.bindSuffix) + case _ => false + } + private final case class Awaitable(expr: Tree, resultName: TermName, resultType: Type) - private def resetDuplicate(tree: Tree) = c.resetAllAttrs(tree.duplicate) + private val internalSyms = origTree.collect { + case dt: DefTree => dt.symbol + } + + private def resetInternalAttrs(tree: Tree) = utils.resetInternalAttrs(tree, internalSyms) private def mkResumeApply = Apply(Ident(name.resume), Nil) |