@@ -125,20 +125,20 @@ class ExtractSemanticDB extends Phase:
125125 if ! excludeDef(tree.pid.symbol)
126126 && tree.pid.span.hasLength
127127 tree.pid match
128- case tree @ Select (qual, name) =>
129- registerDefinition(tree.symbol, adjustSpanToName (tree.span, qual.span, name, tree.source), Set .empty )
130- traverse(qual )
131- case tree => registerDefinition(tree.symbol, tree.span, Set .empty)
128+ case tree : Select =>
129+ registerDefinition(tree.symbol, selectSpan (tree), Set .empty, tree.source)
130+ traverse(tree.qualifier )
131+ case tree => registerDefinition(tree.symbol, tree.span, Set .empty, tree.source )
132132 tree.stats.foreach(traverse)
133133 case tree : NamedDefTree =>
134134 if tree.symbol.isAllOf(ModuleValCreationFlags )
135135 return
136136 if ! excludeDef(tree.symbol)
137137 && tree.span.hasLength
138- registerDefinition(tree.symbol, tree.adjustedNameSpan, symbolKinds(tree))
138+ registerDefinition(tree.symbol, tree.adjustedNameSpan, symbolKinds(tree), tree.source )
139139 val privateWithin = tree.symbol.privateWithin
140140 if privateWithin.exists
141- registerUseGuarded(None , privateWithin, spanOfSymbol(privateWithin, tree.span) )
141+ registerUseGuarded(None , privateWithin, spanOfSymbol(privateWithin, tree.span, tree.source), tree.source )
142142 else if ! excludeSymbol(tree.symbol)
143143 registerSymbol(tree.symbol, symbolName(tree.symbol), symbolKinds(tree))
144144 tree match
@@ -176,7 +176,7 @@ class ExtractSemanticDB extends Phase:
176176 val ctorSym = tree.constr.symbol
177177 if ! excludeDef(ctorSym)
178178 traverseAnnotsOfDefinition(ctorSym)
179- registerDefinition(ctorSym, tree.constr.span, Set .empty)
179+ registerDefinition(ctorSym, tree.constr.span, Set .empty, tree.source )
180180 ctorParams(tree.constr.vparamss, tree.body)
181181 for parent <- tree.parentsOrDerived if parent.span.hasLength do
182182 traverse(parent)
@@ -192,39 +192,40 @@ class ExtractSemanticDB extends Phase:
192192 traverse(tree.fun)
193193 for arg <- tree.args do
194194 arg match
195- case arg @ NamedArg (name, value ) =>
196- registerUse(genParamSymbol(name), arg .span.startPos.withEnd(arg .span.start + name.toString.length))
197- traverse(localBodies.get(value .symbol).getOrElse(value ))
195+ case tree @ NamedArg (name, arg ) =>
196+ registerUse(genParamSymbol(name), tree .span.startPos.withEnd(tree .span.start + name.toString.length), tree.source )
197+ traverse(localBodies.get(arg .symbol).getOrElse(arg ))
198198 case _ => traverse(arg)
199199 case tree : Assign =>
200200 val qualSym = condOpt(tree.lhs) { case Select (qual, _) if qual.symbol.exists => qual.symbol }
201201 if ! excludeUse(qualSym, tree.lhs.symbol)
202202 val lhs = tree.lhs.symbol
203203 val setter = lhs.matchingSetter.orElse(lhs)
204204 tree.lhs match
205- case tree @ Select (qual, name) => registerUse(setter, adjustSpanToName (tree.span, qual.span, name, tree.source) )
206- case tree => registerUse(setter, tree.span)
205+ case tree : Select => registerUse(setter, selectSpan (tree), tree.source)
206+ case tree => registerUse(setter, tree.span, tree.source )
207207 traverseChildren(tree.lhs)
208208 traverse(tree.rhs)
209209 case tree : Ident =>
210210 if tree.name != nme.WILDCARD then
211211 val sym = tree.symbol.adjustIfCtorTyparam
212- registerUseGuarded(None , sym, tree.span)
212+ registerUseGuarded(None , sym, tree.span, tree.source )
213213 case tree : Select =>
214- val qualSpan = tree.qualifier.span
214+ val qual = tree.qualifier
215+ val qualSpan = qual.span
215216 val sym = tree.symbol.adjustIfCtorTyparam
216- registerUseGuarded(tree.qualifier. symbol.ifExists, sym, adjustSpanToName (tree.span, qualSpan, tree.name, tree. source) )
217+ registerUseGuarded(qual. symbol.ifExists, sym, selectSpan (tree), tree.source)
217218 if qualSpan.exists && qualSpan.hasLength then
218- traverse(tree.qualifier )
219+ traverse(qual )
219220 case tree : Import =>
220221 if tree.span.exists && tree.span.hasLength then
221222 for sel <- tree.selectors do
222223 val imported = sel.imported.name
223224 if imported != nme.WILDCARD then
224225 for alt <- tree.expr.tpe.member(imported).alternatives do
225- registerUseGuarded(None , alt.symbol, sel.imported.span)
226+ registerUseGuarded(None , alt.symbol, sel.imported.span, tree.source )
226227 if (alt.symbol.companionClass.exists)
227- registerUseGuarded(None , alt.symbol.companionClass, sel.imported.span)
228+ registerUseGuarded(None , alt.symbol.companionClass, sel.imported.span, tree.source )
228229 traverseChildren(tree)
229230 case tree : Inlined =>
230231 traverse(tree.call)
@@ -334,18 +335,23 @@ class ExtractSemanticDB extends Phase:
334335 * the same starting position have the same index.
335336 */
336337 def localIdx (sym : Symbol )(using Context ): Int =
337- def startPos (sym : Symbol ) =
338- if sym.span.exists then sym.span.start else - 1
339- def computeLocalIdx (): Int =
340- symsAtOffset(startPos(sym)).find(_.name == sym.name) match
341- case Some (other) => localIdx(other)
338+ val startPos =
339+ assert(sym.span.exists, s " $sym should have a span " )
340+ sym.span.start
341+ @ tailrec
342+ def computeLocalIdx (sym : Symbol ): Int = locals get sym match
343+ case Some (idx) => idx
344+ case None => symsAtOffset(startPos).find(_.name == sym.name) match
345+ case Some (other) => computeLocalIdx(other)
342346 case None =>
343347 val idx = nextLocalIdx
344348 nextLocalIdx += 1
345349 locals(sym) = idx
346- symsAtOffset(startPos(sym) ) += sym
350+ symsAtOffset(startPos) += sym
347351 idx
348- locals.getOrElseUpdate(sym, computeLocalIdx())
352+ end computeLocalIdx
353+ computeLocalIdx(sym)
354+ end localIdx
349355
350356 if sym.exists then
351357 if sym.isGlobal then
@@ -361,10 +367,8 @@ class ExtractSemanticDB extends Phase:
361367 addSymName(b, sym)
362368 b.toString
363369
364- inline private def source (using Context ) = ctx.compilationUnit.source
365-
366- private def range (span : Span )(using Context ): Option [Range ] =
367- def lineCol (offset : Int ) = (source.offsetToLine(offset), source.column(offset))
370+ private def range (span : Span , treeSource : SourceFile )(using Context ): Option [Range ] =
371+ def lineCol (offset : Int ) = (treeSource.offsetToLine(offset), treeSource.column(offset))
368372 val (startLine, startCol) = lineCol(span.start)
369373 val (endLine, endCol) = lineCol(span.end)
370374 Some (Range (startLine, startCol, endLine, endCol))
@@ -456,30 +460,30 @@ class ExtractSemanticDB extends Phase:
456460 private def registerSymbolSimple (sym : Symbol )(using Context ): Unit =
457461 registerSymbol(sym, symbolName(sym), Set .empty)
458462
459- private def registerOccurrence (symbol : String , span : Span , role : SymbolOccurrence .Role )(using Context ): Unit =
460- val occ = SymbolOccurrence (symbol, range(span), role)
463+ private def registerOccurrence (symbol : String , span : Span , role : SymbolOccurrence .Role , treeSource : SourceFile )(using Context ): Unit =
464+ val occ = SymbolOccurrence (symbol, range(span, treeSource ), role)
461465 if ! generated.contains(occ) && occ.symbol.nonEmpty then
462466 occurrences += occ
463467 generated += occ
464468
465- private def registerUseGuarded (qualSym : Option [Symbol ], sym : Symbol , span : Span )(using Context ) =
469+ private def registerUseGuarded (qualSym : Option [Symbol ], sym : Symbol , span : Span , treeSource : SourceFile )(using Context ) =
466470 if ! excludeUse(qualSym, sym) then
467- registerUse(sym, span)
471+ registerUse(sym, span, treeSource )
468472
469- private def registerUse (sym : Symbol , span : Span )(using Context ): Unit =
470- registerUse(symbolName(sym), span)
473+ private def registerUse (sym : Symbol , span : Span , treeSource : SourceFile )(using Context ): Unit =
474+ registerUse(symbolName(sym), span, treeSource )
471475
472- private def registerUse (symbol : String , span : Span )(using Context ): Unit =
473- registerOccurrence(symbol, span, SymbolOccurrence .Role .REFERENCE )
476+ private def registerUse (symbol : String , span : Span , treeSource : SourceFile )(using Context ): Unit =
477+ registerOccurrence(symbol, span, SymbolOccurrence .Role .REFERENCE , treeSource )
474478
475- private def registerDefinition (sym : Symbol , span : Span , symkinds : Set [SymbolKind ])(using Context ) =
479+ private def registerDefinition (sym : Symbol , span : Span , symkinds : Set [SymbolKind ], treeSource : SourceFile )(using Context ) =
476480 val symbol = symbolName(sym)
477- registerOccurrence(symbol, span, SymbolOccurrence .Role .DEFINITION )
481+ registerOccurrence(symbol, span, SymbolOccurrence .Role .DEFINITION , treeSource )
478482 if ! sym.is(Package )
479483 registerSymbol(sym, symbol, symkinds)
480484
481- private def spanOfSymbol (sym : Symbol , span : Span )(using Context ): Span =
482- val contents = if source .exists then source .content() else Array .empty[Char ]
485+ private def spanOfSymbol (sym : Symbol , span : Span , treeSource : SourceFile )(using Context ): Span =
486+ val contents = if treeSource .exists then treeSource .content() else Array .empty[Char ]
483487 val idx = contents.indexOfSlice(sym.name.show, span.start)
484488 val start = if idx >= 0 then idx else span.start
485489 Span (start, start + sym.name.show.length, start)
@@ -503,13 +507,13 @@ class ExtractSemanticDB extends Phase:
503507 }).toMap
504508 end findGetters
505509
506- private def adjustSpanToName ( span : Span , qualSpan : Span , name : Name , source : SourceFile ) =
507- val end = span.end
508- val limit = qualSpan .end
510+ private def selectSpan ( tree : Select ) =
511+ val end = tree. span.end
512+ val limit = tree.qualifier.span .end
509513 val start =
510514 if limit < end then
511- val len = name.toString.length
512- if source.content()(end - 1 ) == '`' then end - len - 2 else end - len
515+ val len = tree. name.toString.length
516+ if tree. source.content()(end - 1 ) == '`' then end - len - 2 else end - len
513517 else limit
514518 Span (start max limit, end)
515519
0 commit comments