Skip to content

Commit e1c04a3

Browse files
committed
Improve positions of async-transformed code
Don't position the wrapping try / while trees at the position of the result expression anymore.
1 parent 1b0da54 commit e1c04a3

File tree

3 files changed

+14
-69
lines changed

3 files changed

+14
-69
lines changed

src/compiler/scala/tools/nsc/transform/async/ExprBuilder.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
3232
case ap @ Apply(i @ Ident(_), Nil) if isCaseLabel(i.symbol) || isMatchEndLabel(i.symbol) =>
3333
currentTransformState.labelDefStates.get(i.symbol) match {
3434
case Some(state) =>
35-
Block(StateTransitionStyle.UpdateAndContinue.trees(state, new StateSet), typed(literalUnit)).setType(definitions.UnitTpe)
35+
Block(StateTransitionStyle.UpdateAndContinue.trees(state, new StateSet), typedCurrentPos(literalUnit)).setType(definitions.UnitTpe)
3636
case None => ap
3737
}
3838
case tree => tree
@@ -60,7 +60,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
6060
val stats1 = mutable.ListBuffer[Tree]()
6161
def addNullAssigments(syms: Iterator[Symbol]): Unit = {
6262
for (fieldSym <- syms) {
63-
stats1 += typed(Assign(currentTransformState.memberRef(fieldSym), gen.mkZero(fieldSym.info)))
63+
stats1 += typedCurrentPos(Assign(currentTransformState.memberRef(fieldSym), gen.mkZero(fieldSym.info)))
6464
}
6565
}
6666
// Add pre-state null assigments at the beginning.
@@ -148,7 +148,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
148148
}
149149

150150
allNextStates += nextState
151-
stats += typed(Return(literalUnit).setSymbol(currentTransformState.applySym))
151+
stats += typedCurrentPos(Return(literalUnit).setSymbol(currentTransformState.applySym))
152152
}
153153
if (state == StateAssigner.Terminal) {
154154
// noop
@@ -462,7 +462,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
462462
val asyncStatesInit = asyncStates.init // drop the terminal state which has no code.
463463
val throww = Throw(Apply(Select(New(Ident(IllegalStateExceptionClass)), IllegalStateExceptionClass_NEW_String), List(gen.mkMethodCall(currentRun.runDefinitions.String_valueOf_Int, stateMemberRef :: Nil))))
464464
val body =
465-
typed(Match(stateMemberRef,
465+
typedBasePos(Match(stateMemberRef,
466466
asyncStatesInit.map(_.mkHandlerCaseForState) ++
467467
List(CaseDef(Ident(nme.WILDCARD), EmptyTree,
468468
throww))))
@@ -480,7 +480,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
480480
)
481481
), EmptyTree)
482482
}
483-
typed(LabelDef(transformState.whileLabel, Nil, Block(stateMatch :: Nil, Apply(Ident(transformState.whileLabel), Nil))))
483+
typedBasePos (LabelDef(transformState.whileLabel, Nil, Block(stateMatch :: Nil, Apply(Ident(transformState.whileLabel), Nil))))
484484
}
485485

486486
private def compactStates = true
@@ -557,7 +557,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
557557
} else {
558558
val temp = awaitableResult.symbol.newTermSymbol(nme.trGetResult).setInfo(definitions.ObjectTpe)
559559
val tempVd = ValDef(temp, gen.mkMethodCall(currentTransformState.memberRef(currentTransformState.stateTryGet), tryyReference :: Nil))
560-
typed(Block(
560+
typedCurrentPos(Block(
561561
tempVd :: Nil,
562562
If(Apply(gen.mkAttributedSelect(currentTransformState.stateMachineRef(), definitions.Object_eq), gen.mkAttributedIdent(temp) :: Nil),
563563
Return(literalUnit),
@@ -571,7 +571,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
571571
// Comlete the Promise in the `result` field with the final successful result of this async block.
572572
private def completeSuccess(expr: Tree): Tree = {
573573
deriveTree(expr, definitions.UnitTpe) { expr =>
574-
typed(Apply(currentTransformState.memberRef(currentTransformState.stateCompleteSuccess), expr :: Nil))
574+
typedCurrentPos(Apply(currentTransformState.memberRef(currentTransformState.stateCompleteSuccess), expr :: Nil))
575575
}
576576
}
577577

@@ -581,7 +581,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
581581
protected def mkStateTree(nextState: Int): Tree = {
582582
val transformState = currentTransformState
583583
val callSetter = Apply(transformState.memberRef(transformState.stateSetter), Literal(Constant(nextState)) :: Nil)
584-
typed(callSetter.updateAttachment(StateTransitionTree))
584+
typedCurrentPos(callSetter.updateAttachment(StateTransitionTree))
585585
}
586586
}
587587

@@ -625,9 +625,9 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
625625
If(Apply(null_ne, Ident(transformState.applyTrParam) :: Nil),
626626
Apply(Ident(transformState.whileLabel), Nil),
627627
Block(toStats(callOnComplete(gen.mkAttributedIdent(tempAwaitableSym))), Return(literalUnit).setSymbol(transformState.applySym)))
628-
typed(initAwaitableTemp) :: typed(initTempCompleted) :: mkStateTree(nextState) :: typed(ifTree) :: Nil
628+
typedCurrentPos(initAwaitableTemp) :: typedCurrentPos(initTempCompleted) :: mkStateTree(nextState) :: typedCurrentPos(ifTree) :: Nil
629629
} else {
630-
mkStateTree(nextState) :: toStats(typed(callOnComplete(awaitable))) ::: typed(Return(literalUnit)) :: Nil
630+
mkStateTree(nextState) :: toStats(typedCurrentPos(callOnComplete(awaitable))) ::: typedCurrentPos(Return(literalUnit)) :: Nil
631631
}
632632
}
633633
}
@@ -636,7 +636,7 @@ trait ExprBuilder extends TransformUtils with AsyncAnalysis {
636636
case object UpdateAndContinue extends StateTransitionStyle {
637637
def trees(nextState: Int, stateSet: StateSet): List[Tree] = {
638638
stateSet += nextState
639-
List(mkStateTree(nextState), typed(Apply(Ident(currentTransformState.whileLabel), Nil)))
639+
List(mkStateTree(nextState), typedCurrentPos(Apply(Ident(currentTransformState.whileLabel), Nil)))
640640
}
641641
}
642642
}

src/compiler/scala/tools/nsc/transform/async/TransformUtils.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ private[async] trait TransformUtils extends AsyncTransformStates {
2424
private[async] val asyncNames: AsyncNames[global.type]
2525

2626
def typedPos(pos: Position)(tree: Tree): Tree = currentTransformState.localTyper.typedPos(pos)(tree: Tree)
27-
def typed(tree: Tree): Tree = typedPos(currentTransformState.currentPos)(tree)
27+
def typedCurrentPos(tree: Tree): Tree = typedPos(currentTransformState.currentPos)(tree)
28+
def typedBasePos(tree: Tree): Tree = typedPos(currentTransformState.applySym.pos)(tree)
2829

2930
lazy val IllegalStateExceptionClass: Symbol = rootMirror.staticClass("java.lang.IllegalStateException")
3031
lazy val IllegalStateExceptionClass_NEW_String: Symbol = IllegalStateExceptionClass.info.decl(nme.CONSTRUCTOR).suchThat(

test/junit/scala/tools/nsc/async/AnnotationDrivenAsyncTest.scala

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -414,63 +414,7 @@ class AnnotationDrivenAsyncTest {
414414
val actual = posMap.toList.mkString("\n")
415415
val expected =
416416
"""(val x = id(1),self.x)
417-
|(x.$plus(y),while$(){
418-
| try {
419-
| self.state() match {
420-
| case 0 => {
421-
| val awaitable$async: scala.tools.nsc.async.CustomFuture = scala.tools.nsc.async.CustomFuture._successful(scala.Int.box(Test.this.id(1)));
422-
| tr = self.getCompleted(awaitable$async);
423-
| self.state_=(1);
424-
| if (null.!=(tr))
425-
| while$()
426-
| else
427-
| {
428-
| self.onComplete(awaitable$async);
429-
| return ()
430-
| }
431-
| }
432-
| case 1 => {
433-
| <synthetic> val await$1: Object = {
434-
| val tryGetResult$async: Object = self.tryGet(tr);
435-
| if (self.eq(tryGetResult$async))
436-
| return ()
437-
| else
438-
| tryGetResult$async.$asInstanceOf[Object]()
439-
| };
440-
| self.x = scala.Int.unbox(await$1);
441-
| val awaitable$async: scala.tools.nsc.async.CustomFuture = scala.tools.nsc.async.CustomFuture._successful(scala.Int.box(Test.this.id(2)));
442-
| tr = self.getCompleted(awaitable$async);
443-
| self.state_=(2);
444-
| if (null.!=(tr))
445-
| while$()
446-
| else
447-
| {
448-
| self.onComplete(awaitable$async);
449-
| return ()
450-
| }
451-
| }
452-
| case 2 => {
453-
| <synthetic> val await$2: Object = {
454-
| val tryGetResult$async: Object = self.tryGet(tr);
455-
| if (self.eq(tryGetResult$async))
456-
| return ()
457-
| else
458-
| tryGetResult$async.$asInstanceOf[Object]()
459-
| };
460-
| val y: Int = scala.Int.unbox(await$2);
461-
| self.completeSuccess(scala.Int.box(self.x.+(y)));
462-
| return ()
463-
| }
464-
| case _ => throw new IllegalStateException(java.lang.String.valueOf(self.state()))
465-
| }
466-
| } catch {
467-
| case (throwable$async @ (_: Throwable)) => {
468-
| self.completeFailure(throwable$async);
469-
| return ()
470-
| }
471-
| };
472-
| while$()
473-
|})
417+
|(x.$plus(y),self.completeSuccess(scala.Int.box(self.x.+(y))))
474418
|(val y = id(2),val y: Int = scala.Int.unbox(await$2))""".stripMargin
475419
assertEquals(
476420
expected, actual)

0 commit comments

Comments
 (0)