@@ -64,7 +64,7 @@ class ExtractSemanticDB extends Phase:
64
64
val occurrences = new mutable.ListBuffer [SymbolOccurrence ]()
65
65
66
66
/** The extracted symbol infos */
67
- val symbolInfos = new mutable.HashSet [SymbolInformation ]()
67
+ val symbolInfos = new mutable.ListBuffer [SymbolInformation ]()
68
68
69
69
/** A cache of localN names */
70
70
val localNames = new mutable.HashSet [String ]()
@@ -81,30 +81,36 @@ class ExtractSemanticDB extends Phase:
81
81
|| excludeDefOrUse(sym)
82
82
83
83
private def excludeDefOrUse (sym : Symbol )(using Context ): Boolean =
84
- sym.name.is(NameKinds .DefaultGetterName )
84
+ ! sym.exists
85
+ || sym.name.is(NameKinds .DefaultGetterName )
85
86
|| sym.isConstructor && (sym.owner.is(ModuleClass ) || ! sym.isGlobal)
86
87
|| excludeSymbol(sym)
87
88
88
89
private def excludeSymbol (sym : Symbol )(using Context ): Boolean =
89
- sym.name.isWildcard
90
+ ! sym.exists
91
+ || sym.name.isWildcard
90
92
|| excludeQual(sym)
91
93
92
94
private def excludeQual (sym : Symbol )(using Context ): Boolean =
93
- sym.isAnonymousFunction
95
+ ! sym.exists
96
+ || sym.isAnonymousFunction
94
97
|| sym.isAnonymousModuleVal
95
98
|| sym.name.isEmptyNumbered
96
99
97
100
private def excludeChildren (sym : Symbol )(using Context ): Boolean =
98
- sym.isAllOf(HigherKinded | Param )
101
+ ! sym.exists
102
+ || sym.isAllOf(HigherKinded | Param )
99
103
100
104
/** Uses of this symbol where the reference has given span should be excluded from semanticdb */
101
105
private def excludeUse (qualifier : Option [Symbol ], sym : Symbol )(using Context ): Boolean =
102
- excludeDefOrUse(sym)
106
+ ! sym.exists
107
+ || excludeDefOrUse(sym)
103
108
|| sym.isConstructor && sym.owner.isAnnotation
104
109
|| sym == defn.Any_typeCast
110
+ || sym.owner == defn.OpsPackageClass
105
111
|| qualifier.exists(excludeQual)
106
112
107
- private def traverseAnnotsOf (sym : Symbol )(using Context ): Unit =
113
+ private def traverseAnnotsOfDefinition (sym : Symbol )(using Context ): Unit =
108
114
for annot <- sym.annotations do
109
115
if annot.tree.span.exists
110
116
&& annot.tree.span.hasLength
@@ -114,36 +120,31 @@ class ExtractSemanticDB extends Phase:
114
120
115
121
override def traverse (tree : Tree )(using Context ): Unit =
116
122
117
- inline def traverseCtorParamTpt (ctorSym : Symbol , tpt : Tree ): Unit =
118
- val tptSym = tpt.symbol
119
- if tptSym.owner == ctorSym
120
- val found = matchingMemberType(tptSym, ctorSym.owner)
121
- if tpt.span.hasLength
122
- registerUseGuarded(None , found, tpt.span)
123
- else
124
- traverse(tpt)
125
-
126
- traverseAnnotsOf(tree.symbol)
123
+ tree match
124
+ case tree : DefTree if tree.symbol.exists =>
125
+ traverseAnnotsOfDefinition(tree.symbol)
126
+ case _ =>
127
+ ()
127
128
128
129
tree match
129
130
case tree : PackageDef =>
130
131
if ! excludeDef(tree.pid.symbol)
131
132
&& tree.pid.span.hasLength
132
133
tree.pid match
133
- case tree @ Select (qual, name) =>
134
- registerDefinition(tree.symbol, adjustSpanToName (tree.span, qual.span, name ), Set .empty)
135
- traverse(qual )
136
- case tree => registerDefinition(tree.symbol, tree.span, Set .empty)
134
+ case tree : Select =>
135
+ registerDefinition(tree.symbol, selectSpan (tree), Set .empty, tree.source )
136
+ traverse(tree.qualifier )
137
+ case tree => registerDefinition(tree.symbol, tree.span, Set .empty, tree.source )
137
138
tree.stats.foreach(traverse)
138
139
case tree : NamedDefTree =>
139
140
if tree.symbol.isAllOf(ModuleValCreationFlags )
140
141
return
141
142
if ! excludeDef(tree.symbol)
142
143
&& tree.span.hasLength
143
- registerDefinition(tree.symbol, tree.adjustedNameSpan, symbolKinds(tree))
144
+ registerDefinition(tree.symbol, tree.adjustedNameSpan, symbolKinds(tree), tree.source )
144
145
val privateWithin = tree.symbol.privateWithin
145
146
if privateWithin.exists
146
- registerUseGuarded(None , privateWithin, spanOfSymbol(privateWithin, tree.span) )
147
+ registerUseGuarded(None , privateWithin, spanOfSymbol(privateWithin, tree.span, tree.source), tree.source )
147
148
else if ! excludeSymbol(tree.symbol)
148
149
registerSymbol(tree.symbol, symbolName(tree.symbol), symbolKinds(tree))
149
150
tree match
@@ -180,8 +181,9 @@ class ExtractSemanticDB extends Phase:
180
181
case tree : Template =>
181
182
val ctorSym = tree.constr.symbol
182
183
if ! excludeDef(ctorSym)
183
- registerDefinition(ctorSym, tree.constr.span, Set .empty)
184
- ctorParams(tree.constr.vparamss, tree.body)(traverseCtorParamTpt(ctorSym, _))
184
+ traverseAnnotsOfDefinition(ctorSym)
185
+ registerDefinition(ctorSym, tree.constr.span, Set .empty, tree.source)
186
+ ctorParams(tree.constr.vparamss, tree.body)
185
187
for parent <- tree.parentsOrDerived if parent.span.hasLength do
186
188
traverse(parent)
187
189
val selfSpan = tree.self.span
@@ -196,39 +198,40 @@ class ExtractSemanticDB extends Phase:
196
198
traverse(tree.fun)
197
199
for arg <- tree.args do
198
200
arg match
199
- case arg @ NamedArg (name, value ) =>
200
- registerUse(genParamSymbol(name), arg .span.startPos.withEnd(arg .span.start + name.toString.length))
201
- traverse(localBodies.get(value .symbol).getOrElse(value ))
201
+ case tree @ NamedArg (name, arg ) =>
202
+ registerUse(genParamSymbol(name), tree .span.startPos.withEnd(tree .span.start + name.toString.length), tree.source )
203
+ traverse(localBodies.get(arg .symbol).getOrElse(arg ))
202
204
case _ => traverse(arg)
203
205
case tree : Assign =>
204
206
val qualSym = condOpt(tree.lhs) { case Select (qual, _) if qual.symbol.exists => qual.symbol }
205
207
if ! excludeUse(qualSym, tree.lhs.symbol)
206
208
val lhs = tree.lhs.symbol
207
209
val setter = lhs.matchingSetter.orElse(lhs)
208
210
tree.lhs match
209
- case tree @ Select (qual, name) => registerUse(setter, adjustSpanToName (tree.span, qual.span, name) )
210
- case tree => registerUse(setter, tree.span)
211
+ case tree : Select => registerUse(setter, selectSpan (tree), tree.source )
212
+ case tree => registerUse(setter, tree.span, tree.source )
211
213
traverseChildren(tree.lhs)
212
214
traverse(tree.rhs)
213
215
case tree : Ident =>
214
216
if tree.name != nme.WILDCARD then
215
217
val sym = tree.symbol.adjustIfCtorTyparam
216
- registerUseGuarded(None , sym, tree.span)
218
+ registerUseGuarded(None , sym, tree.span, tree.source )
217
219
case tree : Select =>
218
- val qualSpan = tree.qualifier.span
220
+ val qual = tree.qualifier
221
+ val qualSpan = qual.span
219
222
val sym = tree.symbol.adjustIfCtorTyparam
220
- registerUseGuarded(tree.qualifier. symbol.ifExists, sym, adjustSpanToName (tree.span, qualSpan, tree.name) )
223
+ registerUseGuarded(qual. symbol.ifExists, sym, selectSpan (tree), tree.source )
221
224
if qualSpan.exists && qualSpan.hasLength then
222
- traverse(tree.qualifier )
225
+ traverse(qual )
223
226
case tree : Import =>
224
227
if tree.span.exists && tree.span.hasLength then
225
228
for sel <- tree.selectors do
226
229
val imported = sel.imported.name
227
230
if imported != nme.WILDCARD then
228
231
for alt <- tree.expr.tpe.member(imported).alternatives do
229
- registerUseGuarded(None , alt.symbol, sel.imported.span)
232
+ registerUseGuarded(None , alt.symbol, sel.imported.span, tree.source )
230
233
if (alt.symbol.companionClass.exists)
231
- registerUseGuarded(None , alt.symbol.companionClass, sel.imported.span)
234
+ registerUseGuarded(None , alt.symbol.companionClass, sel.imported.span, tree.source )
232
235
traverseChildren(tree)
233
236
case tree : Inlined =>
234
237
traverse(tree.call)
@@ -302,12 +305,15 @@ class ExtractSemanticDB extends Phase:
302
305
else
303
306
decls0
304
307
end decls
305
- val alts = decls.filter(_.is(Method )).toList.reverse
306
- alts match
307
- case notSym :: rest if sym != notSym =>
308
- val idx = rest.indexOf(sym).ensuring(_ >= 0 )
309
- b.append('+' ).append(idx + 1 )
310
- case _ =>
308
+ val alts = decls.filter(_.isOneOf(Method | Mutable )).toList.reverse
309
+ def find (filter : Symbol => Boolean ) = alts match
310
+ case notSym :: rest if ! filter(notSym) =>
311
+ val idx = rest.indexWhere(filter).ensuring(_ >= 0 )
312
+ b.append('+' ).append(idx + 1 )
313
+ case _ =>
314
+ end find
315
+ val sig = sym.signature
316
+ find(_.signature == sig)
311
317
312
318
def addDescriptor (sym : Symbol ): Unit =
313
319
if sym.is(ModuleClass ) then
@@ -335,16 +341,23 @@ class ExtractSemanticDB extends Phase:
335
341
* the same starting position have the same index.
336
342
*/
337
343
def localIdx (sym : Symbol )(using Context ): Int =
338
- def computeLocalIdx (): Int =
339
- symsAtOffset(sym.span.start).find(_.name == sym.name) match
340
- case Some (other) => localIdx(other)
344
+ val startPos =
345
+ assert(sym.span.exists, s " $sym should have a span " )
346
+ sym.span.start
347
+ @ tailrec
348
+ def computeLocalIdx (sym : Symbol ): Int = locals get sym match
349
+ case Some (idx) => idx
350
+ case None => symsAtOffset(startPos).find(_.name == sym.name) match
351
+ case Some (other) => computeLocalIdx(other)
341
352
case None =>
342
353
val idx = nextLocalIdx
343
354
nextLocalIdx += 1
344
355
locals(sym) = idx
345
- symsAtOffset(sym.span.start ) += sym
356
+ symsAtOffset(startPos ) += sym
346
357
idx
347
- locals.getOrElseUpdate(sym, computeLocalIdx())
358
+ end computeLocalIdx
359
+ computeLocalIdx(sym)
360
+ end localIdx
348
361
349
362
if sym.exists then
350
363
if sym.isGlobal then
@@ -360,10 +373,8 @@ class ExtractSemanticDB extends Phase:
360
373
addSymName(b, sym)
361
374
b.toString
362
375
363
- inline private def source (using Context ) = ctx.compilationUnit.source
364
-
365
- private def range (span : Span )(using Context ): Option [Range ] =
366
- def lineCol (offset : Int ) = (source.offsetToLine(offset), source.column(offset))
376
+ private def range (span : Span , treeSource : SourceFile )(using Context ): Option [Range ] =
377
+ def lineCol (offset : Int ) = (treeSource.offsetToLine(offset), treeSource.column(offset))
367
378
val (startLine, startCol) = lineCol(span.start)
368
379
val (endLine, endCol) = lineCol(span.end)
369
380
Some (Range (startLine, startCol, endLine, endCol))
@@ -455,30 +466,30 @@ class ExtractSemanticDB extends Phase:
455
466
private def registerSymbolSimple (sym : Symbol )(using Context ): Unit =
456
467
registerSymbol(sym, symbolName(sym), Set .empty)
457
468
458
- private def registerOccurrence (symbol : String , span : Span , role : SymbolOccurrence .Role )(using Context ): Unit =
459
- val occ = SymbolOccurrence (symbol, range(span), role)
469
+ private def registerOccurrence (symbol : String , span : Span , role : SymbolOccurrence .Role , treeSource : SourceFile )(using Context ): Unit =
470
+ val occ = SymbolOccurrence (symbol, range(span, treeSource ), role)
460
471
if ! generated.contains(occ) && occ.symbol.nonEmpty then
461
472
occurrences += occ
462
473
generated += occ
463
474
464
- private def registerUseGuarded (qualSym : Option [Symbol ], sym : Symbol , span : Span )(using Context ) =
475
+ private def registerUseGuarded (qualSym : Option [Symbol ], sym : Symbol , span : Span , treeSource : SourceFile )(using Context ) =
465
476
if ! excludeUse(qualSym, sym) then
466
- registerUse(sym, span)
477
+ registerUse(sym, span, treeSource )
467
478
468
- private def registerUse (sym : Symbol , span : Span )(using Context ): Unit =
469
- registerUse(symbolName(sym), span)
479
+ private def registerUse (sym : Symbol , span : Span , treeSource : SourceFile )(using Context ): Unit =
480
+ registerUse(symbolName(sym), span, treeSource )
470
481
471
- private def registerUse (symbol : String , span : Span )(using Context ): Unit =
472
- registerOccurrence(symbol, span, SymbolOccurrence .Role .REFERENCE )
482
+ private def registerUse (symbol : String , span : Span , treeSource : SourceFile )(using Context ): Unit =
483
+ registerOccurrence(symbol, span, SymbolOccurrence .Role .REFERENCE , treeSource )
473
484
474
- private def registerDefinition (sym : Symbol , span : Span , symkinds : Set [SymbolKind ])(using Context ) =
485
+ private def registerDefinition (sym : Symbol , span : Span , symkinds : Set [SymbolKind ], treeSource : SourceFile )(using Context ) =
475
486
val symbol = symbolName(sym)
476
- registerOccurrence(symbol, span, SymbolOccurrence .Role .DEFINITION )
487
+ registerOccurrence(symbol, span, SymbolOccurrence .Role .DEFINITION , treeSource )
477
488
if ! sym.is(Package )
478
489
registerSymbol(sym, symbol, symkinds)
479
490
480
- private def spanOfSymbol (sym : Symbol , span : Span )(using Context ): Span =
481
- val contents = if source .exists then source .content() else Array .empty[Char ]
491
+ private def spanOfSymbol (sym : Symbol , span : Span , treeSource : SourceFile )(using Context ): Span =
492
+ val contents = if treeSource .exists then treeSource .content() else Array .empty[Char ]
482
493
val idx = contents.indexOfSlice(sym.name.show, span.start)
483
494
val start = if idx >= 0 then idx else span.start
484
495
Span (start, start + sym.name.show.length, start)
@@ -502,13 +513,13 @@ class ExtractSemanticDB extends Phase:
502
513
}).toMap
503
514
end findGetters
504
515
505
- private def adjustSpanToName ( span : Span , qualSpan : Span , name : Name )( using Context ) =
506
- val end = span.end
507
- val limit = qualSpan .end
516
+ private def selectSpan ( tree : Select ) =
517
+ val end = tree. span.end
518
+ val limit = tree.qualifier.span .end
508
519
val start =
509
520
if limit < end then
510
- val len = name.toString.length
511
- if source.content()(end - 1 ) == '`' then end - len - 2 else end - len
521
+ val len = tree. name.toString.length
522
+ if tree. source.content()(end - 1 ) == '`' then end - len - 2 else end - len
512
523
else limit
513
524
Span (start max limit, end)
514
525
@@ -559,20 +570,20 @@ class ExtractSemanticDB extends Phase:
559
570
case _ =>
560
571
symkinds.toSet
561
572
562
- private inline def ctorParams (
563
- vparamss : List [List [ValDef ]], body : List [Tree ])(traverseTpt : => Tree => Unit )( using Context ): Unit =
573
+ private def ctorParams (
574
+ vparamss : List [List [ValDef ]], body : List [Tree ])(using Context ): Unit =
564
575
@ tu lazy val getters = findGetters(vparamss.flatMap(_.map(_.name)).toSet, body)
565
576
for
566
577
vparams <- vparamss
567
578
vparam <- vparams
568
579
do
569
- traverseAnnotsOf(vparam.symbol)
570
580
if ! excludeSymbol(vparam.symbol)
581
+ traverseAnnotsOfDefinition(vparam.symbol)
571
582
val symkinds =
572
583
getters.get(vparam.name).fold(SymbolKind .emptySet)(getter =>
573
584
if getter.mods.is(Mutable ) then SymbolKind .VarSet else SymbolKind .ValSet )
574
585
registerSymbol(vparam.symbol, symbolName(vparam.symbol), symkinds)
575
- traverseTpt (vparam.tpt)
586
+ traverse (vparam.tpt)
576
587
577
588
object ExtractSemanticDB :
578
589
import java .nio .file .Path
0 commit comments