blob: ebedcbd5f0b6e9ddc7877ad68a0d68205588c3d5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
/*
* Copyright (C) 2012-2014 Typesafe Inc. <http://www.typesafe.com>
*/
package scala.async.internal
import scala.reflect.internal.annotations.compileTimeOnly
import scala.reflect.macros.Context
import scala.reflect.api.Universe
/**
* A base class for the `async` macro. Subclasses must provide:
*
* - Concrete types for a given future system
* - Tree manipulations to create and complete the equivalent of Future and Promise
* in that system.
* - The `async` macro declaration itself, and a forwarder for the macro implementation.
* (The latter is temporarily needed to workaround bug SI-6650 in the macro system)
*
* The default implementation, [[scala.async.Async]], binds the macro to `scala.concurrent._`.
*/
abstract class AsyncBase {
self =>
type FS <: FutureSystem
val futureSystem: FS
/**
* A call to `await` must be nested in an enclosing `async` block.
*
* A call to `await` does not block the current thread, rather it is a delimiter
* used by the enclosing `async` macro. Code following the `await`
* call is executed asynchronously, when the argument of `await` has been completed.
*
* @param awaitable the future from which a value is awaited.
* @tparam T the type of that value.
* @return the value.
*/
@compileTimeOnly("`await` must be enclosed in an `async` block")
def await[T](awaitable: futureSystem.Fut[T]): T = ???
def asyncImpl[T: c.WeakTypeTag](c: Context)
(body: c.Expr[T])
(execContext: c.Expr[futureSystem.ExecContext]): c.Expr[futureSystem.Fut[T]] = {
import c.universe._
val asyncMacro = AsyncMacro(c, self)
val isPresentationCompiler = asyncMacro.global.forInteractive
val code = asyncMacro.asyncTransform[T](
body.tree.asInstanceOf[asyncMacro.global.Tree],
execContext.tree.asInstanceOf[asyncMacro.global.Tree]
)(implicitly[c.WeakTypeTag[T]].asInstanceOf[asyncMacro.global.WeakTypeTag[T]]).asInstanceOf[Tree]
AsyncUtils.vprintln(s"async state machine transform expands to:\n ${code}")
val result = if (isPresentationCompiler) {
asyncMacro.suppressExpansion()
c.macroApplication
} else {
// Mark range positions for synthetic code as transparent to allow some wiggle room for overlapping ranges
for (t <- code)
t.pos = t.pos.makeTransparent
code
}
c.Expr[futureSystem.Fut[T]](result)
}
protected[async] def awaitMethod(u: Universe)(asyncMacroSymbol: u.Symbol): u.Symbol = {
import u._
asyncMacroSymbol.owner.typeSignature.member(newTermName("await"))
}
protected[async] def nullOut(u: Universe)(name: u.Expr[String], v: u.Expr[Any]): u.Expr[Unit] =
u.reify { () }
}
|