summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorMirco Dotta <mirco.dotta@typesafe.com>2013-12-12 17:15:48 +0100
committerMirco Dotta <mirco.dotta@typesafe.com>2014-01-08 12:59:47 +0100
commit4936c43c137e8e4d133dde397a121288490f78f9 (patch)
tree464ff2b2c279d6d8ddb4a602e5586075428b5e51 /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parentbdb0ac0fe55260d5ee5e14a963b73bf7d9166430 (diff)
downloadscala-4936c43c137e8e4d133dde397a121288490f78f9.tar.gz
scala-4936c43c137e8e4d133dde397a121288490f78f9.tar.bz2
scala-4936c43c137e8e4d133dde397a121288490f78f9.zip
SI-4827 Corrected positions assigned to constructor's default arg
* Default arguments are always retained on the <init> method (i.e., the class' constructor). Therefore, when the <init> parameters are created, we need to use `duplicateAndKeepPositions` to make sure that if a default argument is present, its opaque position is retained as well. This is necessary because when parameter accessors (i.e., `fieldDefs`) are created, all default arguments are discared ( as you can see in the code, the right-hand-side of a `field` is always an `EmptyTree`) - see changes in TreeGen.scala * When constructing the `fieldDefs`, it is important to adapt their range position to avoid overlappings with the positions of default arguments. It is worth noting that updating the field's end position to `vd.rhs.pos.start` would be incorrect, because `askTypeAt(pos)` could return the incorrect tree when the position is equal to `vd.rhs.pos.start` (because two nodes including that point position would exist in the tree, and `CompilerControl.locateTree(pos)` would return the first tree that includes the passed `pos`). This is why `1` is subtracted to `vd.rhs.pos.start`. Alternatively, we could have used `vd.tpt.pos.end` with similar results. However the logic would have become slightly more complex as we would need to handle the case where `vd.tpt` doesn't have a range position (for instance, this can happen if `-Yinfer-argument-types` is enabled). Therefore, subtracting `1` from `vd.rhs.pos.start` seemed the cleanest solution at the moment. - see changes in TreeGen.scala. * If the synthetic constructor contains trees with an opaque range position (see point above), it must have a transparent position. This can only happen if the constructor's parameters' positions are considered, which is why we are now passing `vparamss1` to `wrappingPos` - see changes in TreeGen.scala. * The derived primary constructor should have a transparent position as it may contain trees with an opaque range position. Hence, the `primaryCtor` position is considered for computing the position of the derived constructor - see change in Typers.scala. Finally, below follows the printing of the tree for test t4287, which you should compare with the one attached with the previous commit message: ``` [[syntax trees at end of typer]] // Foo.scala [0:63]package [0:0]<empty> { [0:37]class Baz extends [9:37][39]scala.AnyRef { [10:20]<paramaccessor> private[this] val f: [14]Int = _; [14]<stable> <accessor> <paramaccessor> def f: [14]Int = [14][14]Baz.this.f; <10:31>def <init>(<10:31>f: [17]<type: [17]scala.Int> = [23:31]B.a): [9]Baz = <10:31>{ <10:31><10:31><10:31>Baz.super.<init>(); <10:31>() } }; [6]<synthetic> object Baz extends [6][6]AnyRef { [6]def <init>(): [9]Baz.type = [6]{ [6][6][6]Baz.super.<init>(); [9]() }; [14]<synthetic> def <init>$default$1: [14]Int = [30]B.a }; [39:63]object B extends [48:63][63]scala.AnyRef { [63]def <init>(): [48]B.type = [63]{ [63][63][63]B.super.<init>(); [48]() }; [52:61]private[this] val a: [56]Int = [60:61]2; [56]<stable> <accessor> def a: [56]Int = [56][56]B.this.a } } ``` You should notice that the default arg of `Baz` constructor now has a range position. And that explains why the associated test now returns the right tree when asking hyperlinking at the location of the default argument.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 520b55400c..98706d9ea6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1918,7 +1918,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val primaryCtor1 = primaryCtor match {
case DefDef(_, _, _, _, _, Block(earlyVals :+ global.pendingSuperCall, unit)) =>
val argss = superArgs(parents1.head) getOrElse Nil
- val pos = wrappingPos(parents1.head.pos, argss.flatten)
+ val pos = wrappingPos(parents1.head.pos, primaryCtor :: argss.flatten).makeTransparent
val superCall = atPos(pos)(PrimarySuperCall(argss))
deriveDefDef(primaryCtor)(block => Block(earlyVals :+ superCall, unit) setPos pos) setPos pos
case _ => primaryCtor