@@ -64,7 +64,7 @@ class ExtractSemanticDB extends Phase:
6464 val occurrences = new mutable.ListBuffer [SymbolOccurrence ]()
6565
6666 /** The extracted symbol infos */
67- val symbolInfos = new mutable.HashSet [SymbolInformation ]()
67+ val symbolInfos = new mutable.ListBuffer [SymbolInformation ]()
6868
6969 /** A cache of localN names */
7070 val localNames = new mutable.HashSet [String ]()
@@ -81,30 +81,36 @@ class ExtractSemanticDB extends Phase:
8181 || excludeDefOrUse(sym)
8282
8383 private def excludeDefOrUse (sym : Symbol )(using Context ): Boolean =
84- sym.name.is(NameKinds .DefaultGetterName )
84+ ! sym.exists
85+ || sym.name.is(NameKinds .DefaultGetterName )
8586 || sym.isConstructor && (sym.owner.is(ModuleClass ) || ! sym.isGlobal)
8687 || excludeSymbol(sym)
8788
8889 private def excludeSymbol (sym : Symbol )(using Context ): Boolean =
89- sym.name.isWildcard
90+ ! sym.exists
91+ || sym.name.isWildcard
9092 || excludeQual(sym)
9193
9294 private def excludeQual (sym : Symbol )(using Context ): Boolean =
93- sym.isAnonymousFunction
95+ ! sym.exists
96+ || sym.isAnonymousFunction
9497 || sym.isAnonymousModuleVal
9598 || sym.name.isEmptyNumbered
9699
97100 private def excludeChildren (sym : Symbol )(using Context ): Boolean =
98- sym.isAllOf(HigherKinded | Param )
101+ ! sym.exists
102+ || sym.isAllOf(HigherKinded | Param )
99103
100104 /** Uses of this symbol where the reference has given span should be excluded from semanticdb */
101105 private def excludeUse (qualifier : Option [Symbol ], sym : Symbol )(using Context ): Boolean =
102- excludeDefOrUse(sym)
106+ ! sym.exists
107+ || excludeDefOrUse(sym)
103108 || sym.isConstructor && sym.owner.isAnnotation
104109 || sym == defn.Any_typeCast
110+ || sym.owner == defn.OpsPackageClass
105111 || qualifier.exists(excludeQual)
106112
107- private def traverseAnnotsOf (sym : Symbol )(using Context ): Unit =
113+ private def traverseAnnotsOfDefinition (sym : Symbol )(using Context ): Unit =
108114 for annot <- sym.annotations do
109115 if annot.tree.span.exists
110116 && annot.tree.span.hasLength
@@ -114,36 +120,31 @@ class ExtractSemanticDB extends Phase:
114120
115121 override def traverse (tree : Tree )(using Context ): Unit =
116122
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+ ()
127128
128129 tree match
129130 case tree : PackageDef =>
130131 if ! excludeDef(tree.pid.symbol)
131132 && tree.pid.span.hasLength
132133 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 )
137138 tree.stats.foreach(traverse)
138139 case tree : NamedDefTree =>
139140 if tree.symbol.isAllOf(ModuleValCreationFlags )
140141 return
141142 if ! excludeDef(tree.symbol)
142143 && tree.span.hasLength
143- registerDefinition(tree.symbol, tree.adjustedNameSpan, symbolKinds(tree))
144+ registerDefinition(tree.symbol, tree.adjustedNameSpan, symbolKinds(tree), tree.source )
144145 val privateWithin = tree.symbol.privateWithin
145146 if privateWithin.exists
146- registerUseGuarded(None , privateWithin, spanOfSymbol(privateWithin, tree.span) )
147+ registerUseGuarded(None , privateWithin, spanOfSymbol(privateWithin, tree.span, tree.source), tree.source )
147148 else if ! excludeSymbol(tree.symbol)
148149 registerSymbol(tree.symbol, symbolName(tree.symbol), symbolKinds(tree))
149150 tree match
@@ -180,8 +181,9 @@ class ExtractSemanticDB extends Phase:
180181 case tree : Template =>
181182 val ctorSym = tree.constr.symbol
182183 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)
185187 for parent <- tree.parentsOrDerived if parent.span.hasLength do
186188 traverse(parent)
187189 val selfSpan = tree.self.span
@@ -196,39 +198,40 @@ class ExtractSemanticDB extends Phase:
196198 traverse(tree.fun)
197199 for arg <- tree.args do
198200 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 ))
202204 case _ => traverse(arg)
203205 case tree : Assign =>
204206 val qualSym = condOpt(tree.lhs) { case Select (qual, _) if qual.symbol.exists => qual.symbol }
205207 if ! excludeUse(qualSym, tree.lhs.symbol)
206208 val lhs = tree.lhs.symbol
207209 val setter = lhs.matchingSetter.orElse(lhs)
208210 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 )
211213 traverseChildren(tree.lhs)
212214 traverse(tree.rhs)
213215 case tree : Ident =>
214216 if tree.name != nme.WILDCARD then
215217 val sym = tree.symbol.adjustIfCtorTyparam
216- registerUseGuarded(None , sym, tree.span)
218+ registerUseGuarded(None , sym, tree.span, tree.source )
217219 case tree : Select =>
218- val qualSpan = tree.qualifier.span
220+ val qual = tree.qualifier
221+ val qualSpan = qual.span
219222 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 )
221224 if qualSpan.exists && qualSpan.hasLength then
222- traverse(tree.qualifier )
225+ traverse(qual )
223226 case tree : Import =>
224227 if tree.span.exists && tree.span.hasLength then
225228 for sel <- tree.selectors do
226229 val imported = sel.imported.name
227230 if imported != nme.WILDCARD then
228231 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 )
230233 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 )
232235 traverseChildren(tree)
233236 case tree : Inlined =>
234237 traverse(tree.call)
@@ -302,12 +305,15 @@ class ExtractSemanticDB extends Phase:
302305 else
303306 decls0
304307 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)
311317
312318 def addDescriptor (sym : Symbol ): Unit =
313319 if sym.is(ModuleClass ) then
@@ -335,16 +341,23 @@ class ExtractSemanticDB extends Phase:
335341 * the same starting position have the same index.
336342 */
337343 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)
341352 case None =>
342353 val idx = nextLocalIdx
343354 nextLocalIdx += 1
344355 locals(sym) = idx
345- symsAtOffset(sym.span.start ) += sym
356+ symsAtOffset(startPos ) += sym
346357 idx
347- locals.getOrElseUpdate(sym, computeLocalIdx())
358+ end computeLocalIdx
359+ computeLocalIdx(sym)
360+ end localIdx
348361
349362 if sym.exists then
350363 if sym.isGlobal then
@@ -360,10 +373,8 @@ class ExtractSemanticDB extends Phase:
360373 addSymName(b, sym)
361374 b.toString
362375
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))
367378 val (startLine, startCol) = lineCol(span.start)
368379 val (endLine, endCol) = lineCol(span.end)
369380 Some (Range (startLine, startCol, endLine, endCol))
@@ -455,30 +466,30 @@ class ExtractSemanticDB extends Phase:
455466 private def registerSymbolSimple (sym : Symbol )(using Context ): Unit =
456467 registerSymbol(sym, symbolName(sym), Set .empty)
457468
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)
460471 if ! generated.contains(occ) && occ.symbol.nonEmpty then
461472 occurrences += occ
462473 generated += occ
463474
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 ) =
465476 if ! excludeUse(qualSym, sym) then
466- registerUse(sym, span)
477+ registerUse(sym, span, treeSource )
467478
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 )
470481
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 )
473484
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 ) =
475486 val symbol = symbolName(sym)
476- registerOccurrence(symbol, span, SymbolOccurrence .Role .DEFINITION )
487+ registerOccurrence(symbol, span, SymbolOccurrence .Role .DEFINITION , treeSource )
477488 if ! sym.is(Package )
478489 registerSymbol(sym, symbol, symkinds)
479490
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 ]
482493 val idx = contents.indexOfSlice(sym.name.show, span.start)
483494 val start = if idx >= 0 then idx else span.start
484495 Span (start, start + sym.name.show.length, start)
@@ -502,13 +513,13 @@ class ExtractSemanticDB extends Phase:
502513 }).toMap
503514 end findGetters
504515
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
508519 val start =
509520 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
512523 else limit
513524 Span (start max limit, end)
514525
@@ -559,20 +570,20 @@ class ExtractSemanticDB extends Phase:
559570 case _ =>
560571 symkinds.toSet
561572
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 =
564575 @ tu lazy val getters = findGetters(vparamss.flatMap(_.map(_.name)).toSet, body)
565576 for
566577 vparams <- vparamss
567578 vparam <- vparams
568579 do
569- traverseAnnotsOf(vparam.symbol)
570580 if ! excludeSymbol(vparam.symbol)
581+ traverseAnnotsOfDefinition(vparam.symbol)
571582 val symkinds =
572583 getters.get(vparam.name).fold(SymbolKind .emptySet)(getter =>
573584 if getter.mods.is(Mutable ) then SymbolKind .VarSet else SymbolKind .ValSet )
574585 registerSymbol(vparam.symbol, symbolName(vparam.symbol), symkinds)
575- traverseTpt (vparam.tpt)
586+ traverse (vparam.tpt)
576587
577588object ExtractSemanticDB :
578589 import java .nio .file .Path
0 commit comments