From bc51a19ab4c7fccfa64554dce5098481aec8cdac Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 15 Feb 2014 01:29:03 +0100 Subject: AsyncMacro.global is gone --- .../scala/scala/async/internal/AnfTransform.scala | 16 ++++---- .../scala/scala/async/internal/AsyncAnalysis.scala | 2 +- .../scala/scala/async/internal/AsyncBase.scala | 5 +-- .../scala/scala/async/internal/AsyncMacro.scala | 18 +++------ .../scala/async/internal/AsyncTransform.scala | 14 +++---- .../scala/scala/async/internal/ExprBuilder.scala | 1 + src/main/scala/scala/async/internal/Lifter.scala | 24 ++++++----- .../scala/scala/async/internal/LiveVariables.scala | 2 +- .../scala/async/internal/TransformUtils.scala | 47 +++++++++++++++++----- 9 files changed, 76 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/main/scala/scala/async/internal/AnfTransform.scala b/src/main/scala/scala/async/internal/AnfTransform.scala index dc52683..0e58fa7 100644 --- a/src/main/scala/scala/async/internal/AnfTransform.scala +++ b/src/main/scala/scala/async/internal/AnfTransform.scala @@ -5,13 +5,13 @@ package scala.async.internal -import scala.tools.nsc.Global import scala.Predef._ +import scala.reflect.internal.util.Collections.map2 private[async] trait AnfTransform { self: AsyncMacro => - import c.universe.{gen => _, _} + import c.universe._ import Flag._ import c.internal._ import decorators._ @@ -61,7 +61,7 @@ private[async] trait AnfTransform { } else { val varDef = defineVar(name.ifRes, expr.tpe, tree.pos) def branchWithAssign(orig: Tree) = api.typecheck(atPos(orig.pos) { - def cast(t: Tree) = mkAttributedCastPreservingAnnotations(t, varDef.symbol.tpe) + def cast(t: Tree) = mkAttributedCastPreservingAnnotations(t, tpe(varDef.symbol)) orig match { case Block(thenStats, thenExpr) => Block(thenStats, Assign(Ident(varDef.symbol), cast(thenExpr))) case _ => Assign(Ident(varDef.symbol), cast(orig)) @@ -82,7 +82,7 @@ private[async] trait AnfTransform { else { val varDef = defineVar(name.matchRes, expr.tpe, tree.pos) def typedAssign(lhs: Tree) = - api.typecheck(atPos(lhs.pos)(Assign(Ident(varDef.symbol), mkAttributedCastPreservingAnnotations(lhs, varDef.symbol.tpe)))) + api.typecheck(atPos(lhs.pos)(Assign(Ident(varDef.symbol), mkAttributedCastPreservingAnnotations(lhs, tpe(varDef.symbol))))) val casesWithAssign = cases map { case cd@CaseDef(pat, guard, body) => val newBody = body match { @@ -102,7 +102,7 @@ private[async] trait AnfTransform { private def defineVar(prefix: String, tp: Type, pos: Position): ValDef = { val sym = api.currentOwner.newTermSymbol(name.fresh(prefix), pos, MUTABLE | SYNTHETIC).setInfo(uncheckedBounds(tp)) - ValDef(sym, gen.mkZero(uncheckedBounds(tp))).setType(NoType).setPos(pos) + valDef(sym, gen.mkZero(uncheckedBounds(tp))).setType(NoType).setPos(pos) } } @@ -129,7 +129,7 @@ private[async] trait AnfTransform { def defineVal(prefix: String, lhs: Tree, pos: Position): ValDef = { val sym = api.currentOwner.newTermSymbol(name.fresh(prefix), pos, SYNTHETIC).setInfo(uncheckedBounds(lhs.tpe)) lhs.changeOwner(api.currentOwner, sym) - ValDef(sym, lhs.changeOwner(api.currentOwner, sym)).setType(NoType).setPos(pos) + valDef(sym, lhs.changeOwner(api.currentOwner, sym)).setType(NoType).setPos(pos) } object anf { @@ -161,7 +161,7 @@ private[async] trait AnfTransform { val stats :+ expr1 = linearize.transformToList(expr) stats :+ treeCopy.Typed(tree, expr1, tpt) - case treeInfo.Applied(fun, targs, argss) if argss.nonEmpty => + case q"$fun[..$targs](...$argss)" if argss.nonEmpty => // we can assume that no await call appears in a by-name argument position, // this has already been checked. val funStats :+ simpleFun = linearize.transformToList(fun) @@ -271,7 +271,7 @@ private[async] trait AnfTransform { case _: ValDef | _: DefDef | _: Function | _: ClassDef | _: TypeDef => api.atOwner(tree.symbol)(anfLinearize(tree)) case _: ModuleDef => - api.atOwner(tree.symbol.moduleClass orElse tree.symbol)(anfLinearize(tree)) + api.atOwner(tree.symbol.asModule.moduleClass orElse tree.symbol)(anfLinearize(tree)) case _ => anfLinearize(tree) } diff --git a/src/main/scala/scala/async/internal/AsyncAnalysis.scala b/src/main/scala/scala/async/internal/AsyncAnalysis.scala index 4339653..ffbc04d 100644 --- a/src/main/scala/scala/async/internal/AsyncAnalysis.scala +++ b/src/main/scala/scala/async/internal/AsyncAnalysis.scala @@ -28,7 +28,7 @@ trait AsyncAnalysis { var hasUnsupportedAwaits = false override def nestedClass(classDef: ClassDef) { - val kind = if (classDef.symbol.isTrait) "trait" else "class" + val kind = if (classDef.symbol.asClass.isTrait) "trait" else "class" reportUnsupportedAwait(classDef, s"nested ${kind}") } diff --git a/src/main/scala/scala/async/internal/AsyncBase.scala b/src/main/scala/scala/async/internal/AsyncBase.scala index 3d4810b..7464c42 100644 --- a/src/main/scala/scala/async/internal/AsyncBase.scala +++ b/src/main/scala/scala/async/internal/AsyncBase.scala @@ -45,10 +45,7 @@ abstract class AsyncBase { import c.universe._, c.internal._, decorators._ val asyncMacro = AsyncMacro(c, self) - 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] + val code = asyncMacro.asyncTransform[T](body.tree, execContext.tree)(c.weakTypeTag[T]) AsyncUtils.vprintln(s"async state machine transform expands to:\n ${code}") // Mark range positions for synthetic code as transparent to allow some wiggle room for overlapping ranges diff --git a/src/main/scala/scala/async/internal/AsyncMacro.scala b/src/main/scala/scala/async/internal/AsyncMacro.scala index 30aa1dd..e969f9b 100644 --- a/src/main/scala/scala/async/internal/AsyncMacro.scala +++ b/src/main/scala/scala/async/internal/AsyncMacro.scala @@ -1,19 +1,14 @@ package scala.async.internal -import scala.tools.nsc.Global -import scala.tools.nsc.transform.TypingTransformers - object AsyncMacro { - def apply(c0: reflect.macros.Context, base: AsyncBase): AsyncMacro = { + def apply(c0: reflect.macros.Context, base: AsyncBase): AsyncMacro { val c: c0.type } = { import language.reflectiveCalls - val powerContext = c0.asInstanceOf[c0.type { val universe: Global; val callsiteTyper: universe.analyzer.Typer }] new AsyncMacro { self => - val c: scala.reflect.macros.Context { val universe: global.type } = c0.asInstanceOf[scala.reflect.macros.Context { val universe: global.type }] - val global: powerContext.universe.type = powerContext.universe + val c: c0.type = c0 // This member is required by `AsyncTransform`: - val asyncBase: AsyncBase = base + val asyncBase: AsyncBase = base // These members are required by `ExprBuilder`: - val futureSystem: FutureSystem = base.futureSystem + val futureSystem: FutureSystem = base.futureSystem val futureSystemOps: futureSystem.Ops {val c: self.c.type} = futureSystem.mkOps(c) } } @@ -23,9 +18,8 @@ private[async] trait AsyncMacro extends AnfTransform with TransformUtils with Lifter with ExprBuilder with AsyncTransform with AsyncAnalysis with LiveVariables { - val c: scala.reflect.macros.Context { val universe: global.type } - val global: Global + val c: scala.reflect.macros.Context lazy val macroPos = c.macroApplication.pos.makeTransparent - def atMacroPos(t: global.Tree) = c.universe.atPos(macroPos)(t) + def atMacroPos(t: c.Tree) = c.universe.atPos(macroPos)(t) } diff --git a/src/main/scala/scala/async/internal/AsyncTransform.scala b/src/main/scala/scala/async/internal/AsyncTransform.scala index f66644f..cf9dd1c 100644 --- a/src/main/scala/scala/async/internal/AsyncTransform.scala +++ b/src/main/scala/scala/async/internal/AsyncTransform.scala @@ -3,7 +3,7 @@ package scala.async.internal trait AsyncTransform { self: AsyncMacro => - import c.universe.{gen => _, _} + import c.universe._ import c.internal._ import decorators._ @@ -15,7 +15,7 @@ trait AsyncTransform { // We annotate the type of the whole expression as `T @uncheckedBounds` so as not to introduce // warnings about non-conformant LUBs. See SI-7694 // This implicit propagates the annotated type in the type tag. - implicit val uncheckedBoundsResultTag: WeakTypeTag[T] = WeakTypeTag[T](rootMirror, FixedMirrorTypeCreator(rootMirror, uncheckedBounds(resultType.tpe))) + implicit val uncheckedBoundsResultTag: WeakTypeTag[T] = c.WeakTypeTag[T](uncheckedBounds(resultType.tpe)) reportUnsupportedAwaits(body) @@ -82,7 +82,7 @@ trait AsyncTransform { List( asyncBase.nullOut(c.universe)(c.Expr[String](Literal(Constant(fieldSym.name.toString))), c.Expr[Any](Ident(fieldSym))).tree ), - Assign(gen.mkAttributedStableRef(fieldSym.owner.thisType, fieldSym), gen.mkZero(fieldSym.info)) + Assign(gen.mkAttributedStableRef(thisType(fieldSym.owner), fieldSym), gen.mkZero(fieldSym.info)) ) } val asyncState = asyncBlock.asyncStates.find(_.state == state).get @@ -143,9 +143,9 @@ trait AsyncTransform { liftedSyms.foreach { sym => if (sym != null) { - sym.owner = stateMachineClass + sym.setOwner(stateMachineClass) if (sym.isModule) - sym.moduleClass.owner = stateMachineClass + sym.asModule.moduleClass.setOwner(stateMachineClass) } } // Replace the ValDefs in the splicee with Assigns to the corresponding lifted @@ -158,7 +158,7 @@ trait AsyncTransform { case ValDef(_, _, _, rhs) if liftedSyms(tree.symbol) => api.atOwner(api.currentOwner) { val fieldSym = tree.symbol - val set = Assign(gen.mkAttributedStableRef(fieldSym.owner.thisType, fieldSym), api.recur(rhs)) + val set = Assign(gen.mkAttributedStableRef(thisType(fieldSym.owner.asClass), fieldSym), api.recur(rhs)) set.changeOwner(tree.symbol, api.currentOwner) api.typecheck(atPos(tree.pos)(set)) } @@ -167,7 +167,7 @@ trait AsyncTransform { case Ident(name) if liftedSyms(tree.symbol) => val fieldSym = tree.symbol atPos(tree.pos) { - gen.mkAttributedStableRef(fieldSym.owner.thisType, fieldSym).setType(tree.tpe) + gen.mkAttributedStableRef(thisType(fieldSym.owner.asClass), fieldSym).setType(tree.tpe) } case _ => api.default(tree) diff --git a/src/main/scala/scala/async/internal/ExprBuilder.scala b/src/main/scala/scala/async/internal/ExprBuilder.scala index 893556f..2e31347 100644 --- a/src/main/scala/scala/async/internal/ExprBuilder.scala +++ b/src/main/scala/scala/async/internal/ExprBuilder.scala @@ -15,6 +15,7 @@ trait ExprBuilder { import c.universe._ import defn._ + import c.internal._ val futureSystem: FutureSystem val futureSystemOps: futureSystem.Ops { val c: builder.c.type } diff --git a/src/main/scala/scala/async/internal/Lifter.scala b/src/main/scala/scala/async/internal/Lifter.scala index 024b036..bf7bdbd 100644 --- a/src/main/scala/scala/async/internal/Lifter.scala +++ b/src/main/scala/scala/async/internal/Lifter.scala @@ -4,6 +4,8 @@ trait Lifter { self: AsyncMacro => import c.universe._ import Flag._ + import c.internal._ + import decorators._ /** * Identify which DefTrees are used (including transitively) which are declared @@ -88,7 +90,7 @@ trait Lifter { // Only mark transitive references of defs, modules and classes. The RHS of lifted vals/vars // stays in its original location, so things that it refers to need not be lifted. - if (!(sym.isVal || sym.isVar)) + if (!(sym.isTerm && (sym.asTerm.isVal || sym.asTerm.isVar))) defSymToReferenced(sym).foreach(sym2 => markForLift(sym2)) } } @@ -111,35 +113,35 @@ trait Lifter { val treeLifted = t match { case vd@ValDef(_, _, tpt, rhs) => sym.setFlag(MUTABLE | STABLE | PRIVATE | LOCAL) - sym.name = name.fresh(sym.name.toTermName) - sym.modifyInfo(_.deconst) + sym.setName(name.fresh(sym.name.toTermName)) + sym.setInfo(deconst(sym.info)) 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) + treeCopy.ValDef(vd, Modifiers(sym.flags), sym.name, TypeTree(tpe(sym)).setPos(t.pos), zeroRhs) case dd@DefDef(_, _, tparams, vparamss, tpt, rhs) => - sym.name = this.name.fresh(sym.name.toTermName) + sym.setName(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) + sym.setName(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 + moduleSymbol.setName(sym.name.toTermName) + moduleSymbol.asModule.moduleClass.setName(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 + sym.setName(name.fresh(sym.name.toTermName)) + sym.asModule.moduleClass.setName(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) + sym.setName(newTypeName(name.fresh(sym.name.toString).toString)) treeCopy.TypeDef(td, Modifiers(sym.flags), sym.name, tparams, rhs) } atPos(t.pos)(treeLifted) diff --git a/src/main/scala/scala/async/internal/LiveVariables.scala b/src/main/scala/scala/async/internal/LiveVariables.scala index 5a7a3e4..6c67e99 100644 --- a/src/main/scala/scala/async/internal/LiveVariables.scala +++ b/src/main/scala/scala/async/internal/LiveVariables.scala @@ -55,7 +55,7 @@ trait LiveVariables { // determine which fields should be live also at the end (will not be nulled out) val noNull: Set[Symbol] = liftedSyms.filter { sym => - sym.tpe.typeSymbol.isPrimitiveValueClass || liftables.exists { tree => + tpe(sym).typeSymbol.asClass.isPrimitive || liftables.exists { tree => !liftedSyms.contains(tree.symbol) && tree.exists(_.symbol == sym) } } diff --git a/src/main/scala/scala/async/internal/TransformUtils.scala b/src/main/scala/scala/async/internal/TransformUtils.scala index c44b2c8..5d0a96f 100644 --- a/src/main/scala/scala/async/internal/TransformUtils.scala +++ b/src/main/scala/scala/async/internal/TransformUtils.scala @@ -5,6 +5,7 @@ package scala.async.internal import scala.reflect.macros.Context import reflect.ClassTag +import scala.collection.immutable.ListMap /** * Utilities used in both `ExprBuilder` and `AnfTransform`. @@ -12,8 +13,9 @@ import reflect.ClassTag private[async] trait TransformUtils { self: AsyncMacro => - import c.universe.{gen => _, _} + import c.universe._ import c.internal._ + import decorators._ object name { val resume = newTermName("resume") @@ -51,7 +53,7 @@ private[async] trait TransformUtils { if (Boolean_ShortCircuits contains fun.symbol) (i, j) => true else { val paramss = fun.tpe.paramss - val byNamess = paramss.map(_.map(_.isByNameParam)) + val byNamess = paramss.map(_.map(_.asTerm.isByNameParam)) (i, j) => util.Try(byNamess(i)(j)).getOrElse(false) } } @@ -86,10 +88,6 @@ private[async] trait TransformUtils { val Async_await = asyncBase.awaitMethod(c.universe)(c.macroApplication.symbol).ensuring(_ != NoSymbol) } - def isSafeToInline(tree: Tree) = { - treeInfo.isExprSafeToInline(tree) - } - // `while(await(x))` ... or `do { await(x); ... } while(...)` contain an `If` that loops; // we must break that `If` into states so that it convert the label jump into a state machine // transition @@ -192,7 +190,7 @@ private[async] trait TransformUtils { case dd: DefDef => nestedMethod(dd) case fun: Function => function(fun) case m@Match(EmptyTree, _) => patMatFunction(m) // Pattern matching anonymous function under -Xoldpatmat of after `restorePatternMatchingFunctions` - case treeInfo.Applied(fun, targs, argss) if argss.nonEmpty => + case q"$fun[..$targs](...$argss)" if argss.nonEmpty => val isInByName = isByName(fun) for ((args, i) <- argss.zipWithIndex) { for ((arg, j) <- args.zipWithIndex) { @@ -219,11 +217,42 @@ private[async] trait TransformUtils { // Attributed version of `TreeGen#mkCastPreservingAnnotations` def mkAttributedCastPreservingAnnotations(tree: Tree, tp: Type): Tree = { atPos(tree.pos) { - val casted = c.typecheck(gen.mkCast(tree, uncheckedBounds(tp.withoutAnnotations).dealias)) + val casted = c.typecheck(gen.mkCast(tree, uncheckedBounds(withoutAnnotations(tp)).dealias)) Typed(casted, TypeTree(tp)).setType(tp) } } + def deconst(tp: Type): Type = tp match { + case AnnotatedType(anns, underlying) => annotatedType(anns, deconst(underlying)) + case ExistentialType(quants, underlying) => existentialType(quants, deconst(underlying)) + case ConstantType(value) => deconst(value.tpe) + case _ => tp + } + + def withAnnotation(tp: Type, ann: Annotation): Type = withAnnotations(tp, List(ann)) + + def withAnnotations(tp: Type, anns: List[Annotation]): Type = tp match { + case AnnotatedType(existingAnns, underlying) => annotatedType(anns ::: existingAnns, underlying) + case ExistentialType(quants, underlying) => existentialType(quants, withAnnotations(underlying, anns)) + case _ => annotatedType(anns, tp) + } + + def withoutAnnotations(tp: Type): Type = tp match { + case AnnotatedType(anns, underlying) => withoutAnnotations(underlying) + case ExistentialType(quants, underlying) => existentialType(quants, withoutAnnotations(underlying)) + case _ => tp + } + + def tpe(sym: Symbol): Type = { + if (sym.isType) sym.asType.toType + else sym.info + } + + def thisType(sym: Symbol): Type = { + if (sym.isClass) sym.asClass.thisPrefix + else NoPrefix + } + // ===================================== // Copy/Pasted from Scala 2.10.3. See SI-7694. private lazy val UncheckedBoundsClass = { @@ -232,7 +261,7 @@ private[async] trait TransformUtils { } final def uncheckedBounds(tp: Type): Type = { if (tp.typeArgs.isEmpty || UncheckedBoundsClass == NoSymbol) tp - else tp.withAnnotation(AnnotationInfo marker UncheckedBoundsClass.tpe) + else withAnnotation(tp, Annotation(UncheckedBoundsClass.asType.toType, Nil, ListMap())) } // ===================================== } -- cgit v1.2.3