aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/scala/async/internal/AsyncBase.scala20
-rw-r--r--src/main/scala/scala/async/internal/AsyncMacro.scala17
-rw-r--r--src/main/scala/scala/async/internal/Lifter.scala73
-rw-r--r--src/main/scala/scala/async/internal/TransformUtils.scala1
4 files changed, 67 insertions, 44 deletions
diff --git a/src/main/scala/scala/async/internal/AsyncBase.scala b/src/main/scala/scala/async/internal/AsyncBase.scala
index 8cacb40..3bb3b99 100644
--- a/src/main/scala/scala/async/internal/AsyncBase.scala
+++ b/src/main/scala/scala/async/internal/AsyncBase.scala
@@ -43,20 +43,26 @@ abstract class AsyncBase {
(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]
-
- // Mark range positions for synthetic code as transparent to allow some wiggle room for overlapping ranges
- for (t <- code)
- t.pos = t.pos.makeTransparent
+ )(implicitly[c.WeakTypeTag[T]].asInstanceOf[asyncMacro.global.WeakTypeTag[T]]).asInstanceOf[Tree]
AsyncUtils.vprintln(s"async state machine transform expands to:\n ${code}")
- c.Expr[futureSystem.Fut[T]](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 = {
diff --git a/src/main/scala/scala/async/internal/AsyncMacro.scala b/src/main/scala/scala/async/internal/AsyncMacro.scala
index ee49923..d030367 100644
--- a/src/main/scala/scala/async/internal/AsyncMacro.scala
+++ b/src/main/scala/scala/async/internal/AsyncMacro.scala
@@ -32,4 +32,21 @@ private[async] trait AsyncMacro
lazy val macroPos = macroApplication.pos.makeTransparent
def atMacroPos(t: global.Tree) = global.atPos(macroPos)(t)
+ def suppressExpansion() {
+ // Have your cake : Scala IDE sees original trees and hyperlinking, etc within async blocks "Just Works"
+ // Eat it too : (domain specific errors like "unsupported use of await"
+ //
+ // TODO roll this idea back into scala/scala
+ def suppress(globalOrAnalzer: Any) = {
+ type Suppress = { def suppressMacroExpansion(a: Object): Object }
+ globalOrAnalzer.asInstanceOf[Suppress].suppressMacroExpansion(macroApplication)
+ }
+ try {
+ suppress(global) // 2.10.x
+ } catch {
+ case _: NoSuchMethodException =>
+ suppress(global.analyzer) // 2.11
+ }
+ }
+
}
diff --git a/src/main/scala/scala/async/internal/Lifter.scala b/src/main/scala/scala/async/internal/Lifter.scala
index f49dcbb..7b102d1 100644
--- a/src/main/scala/scala/async/internal/Lifter.scala
+++ b/src/main/scala/scala/async/internal/Lifter.scala
@@ -2,6 +2,7 @@ package scala.async.internal
trait Lifter {
self: AsyncMacro =>
+ import scala.reflect.internal.Flags._
import global._
/**
@@ -105,45 +106,43 @@ trait Lifter {
}
val lifted = liftableSyms.map(symToTree).toList.map {
- case vd@ValDef(_, _, tpt, rhs) =>
- import reflect.internal.Flags._
- val sym = vd.symbol
- sym.setFlag(MUTABLE | STABLE | PRIVATE | LOCAL)
- sym.name = name.fresh(sym.name.toTermName)
- sym.modifyInfo(_.deconst)
- ValDef(vd.symbol, gen.mkZero(vd.symbol.info)).setPos(vd.pos)
- case dd@DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- import reflect.internal.Flags._
- val sym = dd.symbol
- sym.name = this.name.fresh(sym.name.toTermName)
- sym.setFlag(PRIVATE | LOCAL)
- DefDef(dd.symbol, rhs).setPos(dd.pos)
- case cd@ClassDef(_, _, _, impl) =>
- import reflect.internal.Flags._
- val sym = cd.symbol
- sym.name = newTypeName(name.fresh(sym.name.toString).toString)
- companionship.companionOf(cd.symbol) match {
- case NoSymbol =>
- case moduleSymbol =>
- moduleSymbol.name = sym.name.toTermName
- moduleSymbol.moduleClass.name = moduleSymbol.name.toTypeName
- }
- ClassDef(cd.symbol, impl).setPos(cd.pos)
- case md@ModuleDef(_, _, impl) =>
- import reflect.internal.Flags._
- val sym = md.symbol
- companionship.companionOf(md.symbol) match {
- case NoSymbol =>
+ t =>
+ val sym = t.symbol
+ val treeLifted = t match {
+ case vd@ValDef(_, _, tpt, rhs) =>
+ sym.setFlag(MUTABLE | STABLE | PRIVATE | LOCAL)
sym.name = name.fresh(sym.name.toTermName)
- sym.moduleClass.name = sym.name.toTypeName
- case classSymbol => // will be renamed by `case ClassDef` above.
+ sym.modifyInfo(_.deconst)
+ val zeroRhs = atPos(t.pos)(gen.mkZero(vd.symbol.info))
+ treeCopy.ValDef(vd, Modifiers(sym.flags), sym.name, TypeTree(sym.tpe).setPos(t.pos), zeroRhs)
+ case dd@DefDef(_, _, tparams, vparamss, tpt, rhs) =>
+ sym.name = this.name.fresh(sym.name.toTermName)
+ sym.setFlag(PRIVATE | LOCAL)
+ // Was `DefDef(sym, rhs)`, but this ran afoul of `ToughTypeSpec.nestedMethodWithInconsistencyTreeAndInfoParamSymbols`
+ // due to the handling of type parameter skolems in `thisMethodType` in `Namers`
+ treeCopy.DefDef(dd, Modifiers(sym.flags), sym.name, tparams, vparamss, tpt, rhs)
+ case cd@ClassDef(_, _, tparams, impl) =>
+ sym.name = newTypeName(name.fresh(sym.name.toString).toString)
+ companionship.companionOf(cd.symbol) match {
+ case NoSymbol =>
+ case moduleSymbol =>
+ moduleSymbol.name = sym.name.toTermName
+ moduleSymbol.moduleClass.name = moduleSymbol.name.toTypeName
+ }
+ treeCopy.ClassDef(cd, Modifiers(sym.flags), sym.name, tparams, impl)
+ case md@ModuleDef(_, _, impl) =>
+ companionship.companionOf(md.symbol) match {
+ case NoSymbol =>
+ sym.name = name.fresh(sym.name.toTermName)
+ sym.moduleClass.name = sym.name.toTypeName
+ case classSymbol => // will be renamed by `case ClassDef` above.
+ }
+ treeCopy.ModuleDef(md, Modifiers(sym.flags), sym.name, impl)
+ case td@TypeDef(_, _, tparams, rhs) =>
+ sym.name = newTypeName(name.fresh(sym.name.toString).toString)
+ treeCopy.TypeDef(td, Modifiers(sym.flags), sym.name, tparams, rhs)
}
- ModuleDef(md.symbol, impl).setPos(md.pos)
- case td@TypeDef(_, _, _, rhs) =>
- import reflect.internal.Flags._
- val sym = td.symbol
- sym.name = newTypeName(name.fresh(sym.name.toString).toString)
- TypeDef(td.symbol, rhs).setPos(td.pos)
+ atPos(t.pos)(treeLifted)
}
lifted
}
diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala
index 92c9a4f..71fddaa 100644
--- a/src/main/scala/scala/async/internal/TransformUtils.scala
+++ b/src/main/scala/scala/async/internal/TransformUtils.scala
@@ -203,6 +203,7 @@ private[async] trait TransformUtils {
abstract class MacroTypingTransformer extends TypingTransformer(callSiteTyper.context.unit) {
currentOwner = callSiteTyper.context.owner
+ curTree = EmptyTree
def currOwner: Symbol = currentOwner