From d301bea1ca478652ae86397ee3655bc6e4332589 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 24 Nov 2012 12:26:32 +0100 Subject: Favouring composition over inheritance. --- src/main/scala/scala/async/AnfTransform.scala | 4 +++- src/main/scala/scala/async/Async.scala | 11 +++++------ src/main/scala/scala/async/AsyncAnalysis.scala | 9 ++++++--- src/main/scala/scala/async/ExprBuilder.scala | 24 ++++++++++-------------- src/main/scala/scala/async/TransformUtils.scala | 14 +++++++------- 5 files changed, 31 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/main/scala/scala/async/AnfTransform.scala b/src/main/scala/scala/async/AnfTransform.scala index 12b3f26..0836634 100644 --- a/src/main/scala/scala/async/AnfTransform.scala +++ b/src/main/scala/scala/async/AnfTransform.scala @@ -7,9 +7,11 @@ package scala.async import scala.reflect.macros.Context -private[async] final case class AnfTransform[C <: Context](override val c: C) extends TransformUtils(c) { +private[async] final case class AnfTransform[C <: Context](val c: C) { import c.universe._ + val utils = TransformUtils[c.type](c) + import utils._ def apply(tree: Tree): List[Tree] = { val unique = uniqueNames(tree) diff --git a/src/main/scala/scala/async/Async.scala b/src/main/scala/scala/async/Async.scala index 0a8ea1b..8c956f1 100644 --- a/src/main/scala/scala/async/Async.scala +++ b/src/main/scala/scala/async/Async.scala @@ -68,9 +68,8 @@ abstract class AsyncBase { val builder = ExprBuilder[c.type, futureSystem.type](c, self.futureSystem) val anaylzer = AsyncAnalysis[c.type](c) - - import builder.defn._ - import builder.name + val utils = TransformUtils[c.type](c) + import utils.{name, defn} import builder.futureSystemOps anaylzer.reportUnsupportedAwaits(body.tree) @@ -91,7 +90,7 @@ abstract class AsyncBase { val renameMap: Map[Symbol, TermName] = { anaylzer.valDefsUsedInSubsequentStates(anfTree).map { vd => - (vd.symbol, builder.name.fresh(vd.name)) + (vd.symbol, name.fresh(vd.name)) }.toMap } @@ -121,7 +120,7 @@ abstract class AsyncBase { val onCompleteHandler = { val onCompleteHandlers = initStates.flatMap(_.mkOnCompleteHandler()).toList Function( - List(ValDef(Modifiers(PARAM), name.tr, TypeTree(TryAnyType), EmptyTree)), + List(ValDef(Modifiers(PARAM), name.tr, TypeTree(defn.TryAnyType), EmptyTree)), Match(Ident(name.state), onCompleteHandlers)) } @@ -145,7 +144,7 @@ abstract class AsyncBase { Match(Ident(name.state), handlerCases), List( CaseDef( - Apply(Ident(NonFatalClass), List(Bind(name.tr, Ident(nme.WILDCARD)))), + Apply(Ident(defn.NonFatalClass), List(Bind(name.tr, Ident(nme.WILDCARD)))), EmptyTree, Block(List({ val t = c.Expr[Throwable](Ident(name.tr)) diff --git a/src/main/scala/scala/async/AsyncAnalysis.scala b/src/main/scala/scala/async/AsyncAnalysis.scala index fa6ab58..4f5bf8d 100644 --- a/src/main/scala/scala/async/AsyncAnalysis.scala +++ b/src/main/scala/scala/async/AsyncAnalysis.scala @@ -7,9 +7,12 @@ package scala.async import scala.reflect.macros.Context import collection.mutable -private[async] final case class AsyncAnalysis[C <: Context](override val c: C) extends TransformUtils(c) { +private[async] final case class AsyncAnalysis[C <: Context](val c: C) { import c.universe._ + val utils = TransformUtils[c.type](c) + import utils._ + /** * Analyze the contents of an `async` block in order to: * - Report unsupported `await` calls under nested templates, functions, by-name arguments. @@ -33,7 +36,7 @@ private[async] final case class AsyncAnalysis[C <: Context](override val c: C) e analyzer.valDefsToLift.toList } - private class UnsupportedAwaitAnalyzer extends super.AsyncTraverser { + private class UnsupportedAwaitAnalyzer extends AsyncTraverser { override def nestedClass(classDef: ClassDef) { val kind = if (classDef.symbol.asClass.isTrait) "trait" else "class" if (!reportUnsupportedAwait(classDef, s"nested $kind")) { @@ -92,7 +95,7 @@ private[async] final case class AsyncAnalysis[C <: Context](override val c: C) e } } - private class AsyncDefinitionUseAnalyzer extends super.AsyncTraverser { + private class AsyncDefinitionUseAnalyzer extends AsyncTraverser { private var chunkId = 0 private def nextChunk() = chunkId += 1 diff --git a/src/main/scala/scala/async/ExprBuilder.scala b/src/main/scala/scala/async/ExprBuilder.scala index 0a2a09d..a3ba53e 100644 --- a/src/main/scala/scala/async/ExprBuilder.scala +++ b/src/main/scala/scala/async/ExprBuilder.scala @@ -10,11 +10,13 @@ import collection.mutable /* * @author Philipp Haller */ -private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](override val c: C, val futureSystem: FS) - extends TransformUtils(c) { +private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](val c: C, val futureSystem: FS) { builder => + val utils = TransformUtils[c.type](c) + import c.universe._ + import utils._ import defn._ lazy val futureSystemOps = futureSystem.mkOps(c) @@ -81,17 +83,12 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](ov s"AsyncStateWithIf #$state, next = $nextState" } - abstract class AsyncStateWithAwait(stats: List[c.Tree], state: Int, nextState: Int) + final class AsyncStateWithAwait(stats: List[c.Tree], state: Int, nextState: Int, + awaitable: c.Tree, val resultName: TermName, val resultType: Type) extends AsyncState(stats, state, nextState) { - val awaitable : c.Tree - val resultName: TermName - val resultType: Type protected def tryType = appliedType(TryClass.toType, List(resultType)) - override val toString: String = - s"AsyncStateWithAwait #$state, next = $nextState" - private def mkOnCompleteTree: c.Tree = { futureSystemOps.onComplete(c.Expr(awaitable), c.Expr(Ident(name.onCompleteHandler)), c.Expr(Ident(name.execContext))).tree } @@ -100,6 +97,9 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](ov assert(awaitable != null) mkHandlerCase(state, stats :+ mkOnCompleteTree) } + + override val toString: String = + s"AsyncStateWithAwait #$state, next = $nextState" } /* @@ -157,11 +157,7 @@ private[async] final case class ExprBuilder[C <: Context, FS <: FutureSystem](ov if (awaitable == null) new AsyncState(stats.toList, state, effectiveNestState) else - new AsyncStateWithAwait(stats.toList, state, effectiveNestState) { - val awaitable = self.awaitable - val resultName = self.resultName - val resultType = self.resultType - } + new AsyncStateWithAwait(stats.toList, state, effectiveNestState, awaitable, resultName, resultType) } /* Result needs to be created as a var at the beginning of the transformed method body, so that diff --git a/src/main/scala/scala/async/TransformUtils.scala b/src/main/scala/scala/async/TransformUtils.scala index 0eca5db..b7bb2ce 100644 --- a/src/main/scala/scala/async/TransformUtils.scala +++ b/src/main/scala/scala/async/TransformUtils.scala @@ -9,11 +9,11 @@ import reflect.ClassTag /** * Utilities used in both `ExprBuilder` and `AnfTransform`. */ -private[async] class TransformUtils[C <: Context](val c: C) { +private[async] final case class TransformUtils[C <: Context](val c: C) { import c.universe._ - private[async] object name { + object name { def suffix(string: String) = string + "$async" def suffixedName(prefix: String) = newTermName(suffix(prefix)) @@ -37,7 +37,7 @@ private[async] class TransformUtils[C <: Context](val c: C) { def fresh(name: String): String = if (name.toString.contains("$")) name else c.fresh("" + name + "$") } - protected def defaultValue(tpe: Type): Literal = { + def defaultValue(tpe: Type): Literal = { val defaultValue: Any = if (tpe <:< definitions.BooleanTpe) false else if (definitions.ScalaNumericValueClasses.exists(tpe <:< _.toType)) 0 @@ -46,7 +46,7 @@ private[async] class TransformUtils[C <: Context](val c: C) { Literal(Constant(defaultValue)) } - protected def isAwait(fun: Tree) = + def isAwait(fun: Tree) = fun.symbol == defn.Async_await /** Descends into the regions of the tree that are subject to the @@ -96,7 +96,7 @@ private[async] class TransformUtils[C <: Context](val c: C) { Set(Boolean_&&, Boolean_||) } - protected def isByName(fun: Tree): (Int => Boolean) = { + def isByName(fun: Tree): (Int => Boolean) = { if (Boolean_ShortCircuits contains fun.symbol) i => true else fun.tpe match { case MethodType(params, _) => @@ -106,12 +106,12 @@ private[async] class TransformUtils[C <: Context](val c: C) { } } - protected def statsAndExpr(tree: Tree): (List[Tree], Tree) = tree match { + def statsAndExpr(tree: Tree): (List[Tree], Tree) = tree match { case Block(stats, expr) => (stats, expr) case _ => (List(tree), Literal(Constant(()))) } - private[async] object defn { + object defn { def mkList_apply[A](args: List[Expr[A]]): Expr[List[A]] = { c.Expr(Apply(Ident(definitions.List_apply), args.map(_.tree))) } -- cgit v1.2.3