diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-07-02 15:55:34 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-07-03 10:04:55 +0200 |
commit | 82232ec47effb4a6b67b3a0792e1c7600e2d31b7 (patch) | |
tree | ed9925418aa0a631d1d25fd1be30f5d508e81b24 /src/main/scala/scala/async/FutureSystem.scala | |
parent | d63b63f536aafa494c70835526174be1987050de (diff) | |
download | scala-async-82232ec47effb4a6b67b3a0792e1c7600e2d31b7.tar.gz scala-async-82232ec47effb4a6b67b3a0792e1c7600e2d31b7.tar.bz2 scala-async-82232ec47effb4a6b67b3a0792e1c7600e2d31b7.zip |
An overdue overhaul of macro internals.
- Avoid reset + retypecheck, instead hang onto the original types/symbols
- Eliminated duplication between AsyncDefinitionUseAnalyzer and ExprBuilder
- Instead, decide what do lift *after* running ExprBuilder
- Account for transitive references local classes/objects and lift them
as needed.
- Make the execution context an regular implicit parameter of the macro
- Fixes interaction with existential skolems and singleton types
Fixes #6, #13, #16, #17, #19, #21.
Diffstat (limited to 'src/main/scala/scala/async/FutureSystem.scala')
-rw-r--r-- | src/main/scala/scala/async/FutureSystem.scala | 50 |
1 files changed, 23 insertions, 27 deletions
diff --git a/src/main/scala/scala/async/FutureSystem.scala b/src/main/scala/scala/async/FutureSystem.scala index a050bec..0c04296 100644 --- a/src/main/scala/scala/async/FutureSystem.scala +++ b/src/main/scala/scala/async/FutureSystem.scala @@ -6,6 +6,7 @@ package scala.async import scala.language.higherKinds import scala.reflect.macros.Context +import scala.reflect.internal.SymbolTable /** * An abstraction over a future system. @@ -26,12 +27,10 @@ trait FutureSystem { type ExecContext trait Ops { - val context: reflect.macros.Context + val universe: reflect.internal.SymbolTable - import context.universe._ - - /** Lookup the execution context, typically with an implicit search */ - def execContext: Expr[ExecContext] + import universe._ + def Expr[T: WeakTypeTag](tree: Tree): Expr[T] = universe.Expr[T](rootMirror, universe.FixedMirrorTreeCreator(rootMirror, tree)) def promType[A: WeakTypeTag]: Type def execContextType: Type @@ -52,15 +51,17 @@ trait FutureSystem { /** Complete a promise with a value */ def completeProm[A](prom: Expr[Prom[A]], value: Expr[scala.util.Try[A]]): Expr[Unit] - def spawn(tree: context.Tree): context.Tree = - future(context.Expr[Unit](tree))(execContext).tree + def spawn(tree: Tree, execContext: Tree): Tree = + future(Expr[Unit](tree))(Expr[ExecContext](execContext)).tree + // TODO Why is this needed? def castTo[A: WeakTypeTag](future: Expr[Fut[Any]]): Expr[Fut[A]] } - def mkOps(c: Context): Ops { val context: c.type } + def mkOps(c: SymbolTable): Ops { val universe: c.type } } + object ScalaConcurrentFutureSystem extends FutureSystem { import scala.concurrent._ @@ -69,18 +70,13 @@ object ScalaConcurrentFutureSystem extends FutureSystem { type Fut[A] = Future[A] type ExecContext = ExecutionContext - def mkOps(c: Context): Ops {val context: c.type} = new Ops { - val context: c.type = c - - import context.universe._ + def mkOps(c: SymbolTable): Ops {val universe: c.type} = new Ops { + val universe: c.type = c - def execContext: Expr[ExecContext] = c.Expr(c.inferImplicitValue(c.weakTypeOf[ExecutionContext]) match { - case EmptyTree => c.abort(c.macroApplication.pos, "Unable to resolve implicit ExecutionContext") - case context => context - }) + import universe._ - def promType[A: WeakTypeTag]: Type = c.weakTypeOf[Promise[A]] - def execContextType: Type = c.weakTypeOf[ExecutionContext] + def promType[A: WeakTypeTag]: Type = weakTypeOf[Promise[A]] + def execContextType: Type = weakTypeOf[ExecutionContext] def createProm[A: WeakTypeTag]: Expr[Prom[A]] = reify { Promise[A]() @@ -101,7 +97,7 @@ object ScalaConcurrentFutureSystem extends FutureSystem { def completeProm[A](prom: Expr[Prom[A]], value: Expr[scala.util.Try[A]]): Expr[Unit] = reify { prom.splice.complete(value.splice) - context.literalUnit.splice + Expr[Unit](Literal(Constant(()))).splice } def castTo[A: WeakTypeTag](future: Expr[Fut[Any]]): Expr[Fut[A]] = reify { @@ -121,15 +117,15 @@ object IdentityFutureSystem extends FutureSystem { type Fut[A] = A type ExecContext = Unit - def mkOps(c: Context): Ops {val context: c.type} = new Ops { - val context: c.type = c + def mkOps(c: SymbolTable): Ops {val universe: c.type} = new Ops { + val universe: c.type = c - import context.universe._ + import universe._ - def execContext: Expr[ExecContext] = c.literalUnit + def execContext: Expr[ExecContext] = Expr[Unit](Literal(Constant(()))) - def promType[A: WeakTypeTag]: Type = c.weakTypeOf[Prom[A]] - def execContextType: Type = c.weakTypeOf[Unit] + def promType[A: WeakTypeTag]: Type = weakTypeOf[Prom[A]] + def execContextType: Type = weakTypeOf[Unit] def createProm[A: WeakTypeTag]: Expr[Prom[A]] = reify { new Prom(null.asInstanceOf[A]) @@ -144,12 +140,12 @@ object IdentityFutureSystem extends FutureSystem { def onComplete[A, U](future: Expr[Fut[A]], fun: Expr[scala.util.Try[A] => U], execContext: Expr[ExecContext]): Expr[Unit] = reify { fun.splice.apply(util.Success(future.splice)) - context.literalUnit.splice + Expr[Unit](Literal(Constant(()))).splice } def completeProm[A](prom: Expr[Prom[A]], value: Expr[scala.util.Try[A]]): Expr[Unit] = reify { prom.splice.a = value.splice.get - context.literalUnit.splice + Expr[Unit](Literal(Constant(()))).splice } def castTo[A: WeakTypeTag](future: Expr[Fut[Any]]): Expr[Fut[A]] = ??? |