@@ -18,8 +18,8 @@ abstract class Positioned(implicit @transientParam src: SourceInfo) extends Prod
18
18
/** A unique identifier. Among other things, used for determining the source file
19
19
* component of the position.
20
20
*/
21
- private var myUniqueId : Int = _
22
- private [this ] var mySpan : Span = _
21
+ private var myUniqueId : Int = - 1
22
+ private [this ] var mySpan : Span = NoSpan
23
23
24
24
/** The span part of the item's position */
25
25
def span : Span = mySpan
@@ -30,8 +30,8 @@ abstract class Positioned(implicit @transientParam src: SourceInfo) extends Prod
30
30
def source : SourceFile = SourceFile .fromId(uniqueId)
31
31
def sourcePos (implicit ctx : Context ): SourcePosition = source.atSpan(span)
32
32
33
- setId(initialSource(src).nextId)
34
- setPos(initialSpan(), source)
33
+ // setId(initialSource(src).nextId)
34
+ setPos(initialSpan(src ), source)
35
35
36
36
protected def setId (id : Int ): Unit = {
37
37
myUniqueId = id
@@ -155,66 +155,49 @@ abstract class Positioned(implicit @transientParam src: SourceInfo) extends Prod
155
155
newpd
156
156
}
157
157
158
- /** The source of the first element of this node that has a position */
159
- def elemsSource : SourceFile = {
160
- def firstSource (x : Any ): SourceFile = x match {
161
- case x : Positioned if x.span.exists =>
162
- x.source
163
- case x1 :: xs1 =>
164
- val f = firstSource(x1)
165
- if (f.exists) f else firstSource(xs1)
166
- case _ =>
167
- NoSource
168
- }
169
- def firstElemSource (n : Int ): SourceFile =
170
- if (n == productArity) NoSource
171
- else {
172
- val f = firstSource(productElement(n))
173
- if (f.exists) f else firstElemSource(n + 1 )
174
- }
175
- firstElemSource(0 )
176
- }
177
-
178
- /** The source file to use for the `id` of this node. This is
179
- * `elemsSource` if it exists, or the source file indicated by
180
- * `src` otherwise
181
- */
182
- private def initialSource (src : SourceInfo ): SourceFile = {
183
- val f = elemsSource
184
- if (f.exists) f else src.source
185
- }
186
-
187
158
/** The initial, synthetic span. This is usually the union of all positioned children's spans.
188
- * @param ignoreTypeTrees If true, TypeTree children are not counted for the span.
189
- * This is important for predicting whether a position entry is
190
- * needed for pickling, since TypeTrees are pickled as types, so
191
- * their position is lost.
192
159
*/
193
- def initialSpan (ignoreTypeTrees : Boolean = false ): Span = {
160
+ def initialSpan (si : SourceInfo ): Span = {
194
161
195
- def include (p1 : Span , p2 : Positioned ) = p2 match {
196
- case _ : Trees .TypeTree [_] if ignoreTypeTrees => p1
197
- case _ => p1.union(p2.span)
162
+ def include (span1 : Span , p2 : Positioned ): Span = {
163
+ val span2 = p2.span
164
+ if (span2.exists) {
165
+ var src = if (uniqueId == - 1 ) NoSource else source
166
+ val src2 = p2.source
167
+ if (src `eq` src2) span1.union(span2)
168
+ else if (! src.exists) {
169
+ setId(src2.nextId)
170
+ if (span1.exists) initialSpan(si) // we might have some mis-classified children; re-run everything
171
+ else span2
172
+ }
173
+ else span1 // sources differ: ignore child span
174
+ }
175
+ else span1
198
176
}
199
177
200
178
def includeAll (span : Span , xs : List [_]): Span = xs match {
201
- case (p : Positioned ) :: xs1 if sameSource(p) => includeAll(include(span, p), xs1)
179
+ case Nil => span
180
+ case (p : Positioned ) :: xs1 => includeAll(include(span, p), xs1)
202
181
case (xs0 : List [_]) :: xs1 => includeAll(includeAll(span, xs0), xs1)
203
182
case _ :: xs1 => includeAll(span, xs1)
204
- case _ => span
205
183
}
206
184
207
- var n = productArity
185
+ val limit = relevantElemCount
186
+ var n = 0
208
187
var span = NoSpan
209
- while (n > 0 ) {
210
- n -= 1
188
+ while (n < limit) {
211
189
productElement(n) match {
212
- case p : Positioned if sameSource(p) => span = include(span, p)
213
- case m : untpd.Modifiers => span = includeAll(includeAll(span, m.mods), m.annotations)
214
- case xs : List [_] => span = includeAll(span, xs)
190
+ case p : Positioned =>
191
+ span = include(span, p)
192
+ case m : untpd.Modifiers =>
193
+ span = includeAll(includeAll(span, m.mods), m.annotations)
194
+ case xs : :: [_] =>
195
+ span = includeAll(span, xs)
215
196
case _ =>
216
197
}
198
+ n += 1
217
199
}
200
+ if (uniqueId == - 1 ) setId(si.source.nextId)
218
201
span.toSynthetic
219
202
}
220
203
@@ -223,8 +206,6 @@ abstract class Positioned(implicit @transientParam src: SourceInfo) extends Prod
223
206
*/
224
207
def relevantElemCount = productArity
225
208
226
- private def sameSource (that : Positioned ) = source `eq` that.source
227
-
228
209
def contains (that : Positioned ): Boolean = {
229
210
def isParent (x : Any ): Boolean = x match {
230
211
case x : Positioned =>
0 commit comments