diff options
Diffstat (limited to 'src/main/scala')
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 |