@@ -23,6 +23,7 @@ import scala.annotation.{ threadUnsafe => tu, tailrec }
23
23
import scala .PartialFunction .condOpt
24
24
25
25
import dotty .tools .dotc .semanticdb .SemanticSymbolBuilder
26
+ import dotty .tools .dotc .semanticdb .{TypeOps => TOps }
26
27
27
28
/** Extract symbol references and uses to semanticdb files.
28
29
* See https://scalameta.org/docs/semanticdb/specification.html#symbol-1
@@ -50,6 +51,7 @@ class ExtractSemanticDB extends Phase:
50
51
/** Extractor of symbol occurrences from trees */
51
52
class Extractor extends TreeTraverser :
52
53
given builder : SemanticSymbolBuilder = SemanticSymbolBuilder ()
54
+ given typeOps : TOps = TOps ()
53
55
54
56
/** The bodies of synthetic locals */
55
57
private val localBodies = mutable.HashMap [Symbol , Tree ]()
@@ -123,61 +125,52 @@ class ExtractSemanticDB extends Phase:
123
125
124
126
tree match
125
127
case tree : PackageDef =>
126
- if ! excludeDef(tree.pid.symbol)
127
- && tree.pid.span.hasLength then
128
- tree.pid match
129
- case tree : Select =>
130
- registerDefinition(tree.symbol, selectSpan(tree), Set .empty, tree.source)
131
- traverse(tree.qualifier)
132
- case tree => registerDefinition(tree.symbol, tree.span, Set .empty, tree.source)
133
128
tree.stats.foreach(traverse)
129
+ if ! excludeDef(tree.pid.symbol) && tree.pid.span.hasLength then
130
+ tree.pid match
131
+ case tree : Select =>
132
+ traverse(tree.qualifier)
133
+ registerDefinition(tree.symbol, selectSpan(tree), Set .empty, tree.source)
134
+ case tree => registerDefinition(tree.symbol, tree.span, Set .empty, tree.source)
134
135
case tree : NamedDefTree =>
135
136
if ! tree.symbol.isAllOf(ModuleValCreationFlags ) then
136
- if ! excludeDef(tree.symbol)
137
- && tree.span.hasLength then
137
+ tree match {
138
+ case tree : ValDef if tree.symbol.isAllOf(EnumValue ) =>
139
+ tree.rhs match
140
+ case Block (TypeDef (_, template : Template ) :: _, _) => // simple case with specialised extends clause
141
+ template.parents.filter(! _.span.isZeroExtent).foreach(traverse)
142
+ case _ => // calls $new
143
+ case tree : ValDef if tree.symbol.isSelfSym =>
144
+ if tree.tpt.span.hasLength then
145
+ traverse(tree.tpt)
146
+ case tree : DefDef if tree.symbol.isConstructor => // ignore typeparams for secondary ctors
147
+ tree.trailingParamss.foreach(_.foreach(traverse))
148
+ traverse(tree.rhs)
149
+ case tree : (DefDef | ValDef ) if tree.symbol.isSyntheticWithIdent =>
150
+ tree match
151
+ case tree : DefDef =>
152
+ tree.paramss.foreach(_.foreach(param => registerSymbolSimple(param.symbol)))
153
+ case tree : ValDef if tree.symbol.is(Given ) => traverse(tree.tpt)
154
+ case _ =>
155
+ if ! tree.symbol.isGlobal then
156
+ localBodies(tree.symbol) = tree.rhs
157
+ // ignore rhs
158
+ case PatternValDef (pat, rhs) =>
159
+ traverse(rhs)
160
+ PatternValDef .collectPats(pat).foreach(traverse)
161
+ case tree =>
162
+ if ! excludeChildren(tree.symbol) then
163
+ traverseChildren(tree)
164
+ }
165
+ if ! excludeDef(tree.symbol) && tree.span.hasLength then
138
166
registerDefinition(tree.symbol, tree.nameSpan, symbolKinds(tree), tree.source)
139
167
val privateWithin = tree.symbol.privateWithin
140
168
if privateWithin.exists then
141
169
registerUseGuarded(None , privateWithin, spanOfSymbol(privateWithin, tree.span, tree.source), tree.source)
142
170
else if ! excludeSymbol(tree.symbol) then
143
171
registerSymbol(tree.symbol, symbolKinds(tree))
144
- tree match
145
- case tree : ValDef
146
- if tree.symbol.isAllOf(EnumValue ) =>
147
- tree.rhs match
148
- case Block (TypeDef (_, template : Template ) :: _, _) => // simple case with specialised extends clause
149
- template.parents.filter(! _.span.isZeroExtent).foreach(traverse)
150
- case _ => // calls $new
151
- case tree : ValDef
152
- if tree.symbol.isSelfSym =>
153
- if tree.tpt.span.hasLength then
154
- traverse(tree.tpt)
155
- case tree : DefDef
156
- if tree.symbol.isConstructor => // ignore typeparams for secondary ctors
157
- tree.trailingParamss.foreach(_.foreach(traverse))
158
- traverse(tree.rhs)
159
- case tree : (DefDef | ValDef )
160
- if tree.symbol.isSyntheticWithIdent =>
161
- tree match
162
- case tree : DefDef =>
163
- tree.paramss.foreach(_.foreach(param => registerSymbolSimple(param.symbol)))
164
- case tree : ValDef if tree.symbol.is(Given ) => traverse(tree.tpt)
165
- case _ =>
166
- if ! tree.symbol.isGlobal then
167
- localBodies(tree.symbol) = tree.rhs
168
- // ignore rhs
169
- case PatternValDef (pat, rhs) =>
170
- traverse(rhs)
171
- PatternValDef .collectPats(pat).foreach(traverse)
172
- case tree =>
173
- if ! excludeChildren(tree.symbol) then
174
- traverseChildren(tree)
175
172
case tree : Template =>
176
173
val ctorSym = tree.constr.symbol
177
- if ! excludeDef(ctorSym) then
178
- traverseAnnotsOfDefinition(ctorSym)
179
- registerDefinition(ctorSym, tree.constr.nameSpan.startPos, Set .empty, tree.source)
180
- ctorParams(tree.constr.termParamss, tree.body)
181
174
for parent <- tree.parentsOrDerived if parent.span.hasLength do
182
175
traverse(parent)
183
176
val selfSpan = tree.self.span
@@ -187,14 +180,18 @@ class ExtractSemanticDB extends Phase:
187
180
tree.body.foreachUntilImport(traverse).foreach(traverse) // the first import statement
188
181
else
189
182
tree.body.foreach(traverse)
183
+ if ! excludeDef(ctorSym) then
184
+ traverseAnnotsOfDefinition(ctorSym)
185
+ ctorParams(tree.constr.termParamss, tree.body)
186
+ registerDefinition(ctorSym, tree.constr.nameSpan.startPos, Set .empty, tree.source)
190
187
case tree : Apply =>
191
188
@ tu lazy val genParamSymbol : Name => String = tree.fun.symbol.funParamSymbol
192
189
traverse(tree.fun)
193
190
for arg <- tree.args do
194
191
arg match
195
192
case tree @ NamedArg (name, arg) =>
196
- registerUse(genParamSymbol(name), tree.span.startPos.withEnd(tree.span.start + name.toString.length), tree.source)
197
193
traverse(localBodies.get(arg.symbol).getOrElse(arg))
194
+ registerUse(genParamSymbol(name), tree.span.startPos.withEnd(tree.span.start + name.toString.length), tree.source)
198
195
case _ => traverse(arg)
199
196
case tree : Assign =>
200
197
val qualSym = condOpt(tree.lhs) { case Select (qual, _) if qual.symbol.exists => qual.symbol }
@@ -214,19 +211,19 @@ class ExtractSemanticDB extends Phase:
214
211
val qual = tree.qualifier
215
212
val qualSpan = qual.span
216
213
val sym = tree.symbol.adjustIfCtorTyparam
217
- registerUseGuarded(qual.symbol.ifExists, sym, selectSpan(tree), tree.source)
218
214
if qualSpan.exists && qualSpan.hasLength then
219
215
traverse(qual)
216
+ registerUseGuarded(qual.symbol.ifExists, sym, selectSpan(tree), tree.source)
220
217
case tree : Import =>
221
218
if tree.span.exists && tree.span.hasLength then
219
+ traverseChildren(tree)
222
220
for sel <- tree.selectors do
223
221
val imported = sel.imported.name
224
222
if imported != nme.WILDCARD then
225
223
for alt <- tree.expr.tpe.member(imported).alternatives do
226
224
registerUseGuarded(None , alt.symbol, sel.imported.span, tree.source)
227
225
if (alt.symbol.companionClass.exists)
228
226
registerUseGuarded(None , alt.symbol.companionClass, sel.imported.span, tree.source)
229
- traverseChildren(tree)
230
227
case tree : Inlined =>
231
228
traverse(tree.call)
232
229
case _ =>
@@ -416,13 +413,13 @@ class ExtractSemanticDB extends Phase:
416
413
vparams <- vparamss
417
414
vparam <- vparams
418
415
do
416
+ traverse(vparam.tpt)
419
417
if ! excludeSymbol(vparam.symbol) then
420
418
traverseAnnotsOfDefinition(vparam.symbol)
421
419
val symkinds =
422
420
getters.get(vparam.name).fold(SymbolKind .emptySet)(getter =>
423
421
if getter.mods.is(Mutable ) then SymbolKind .VarSet else SymbolKind .ValSet )
424
422
registerSymbol(vparam.symbol, symkinds)
425
- traverse(vparam.tpt)
426
423
427
424
object ExtractSemanticDB :
428
425
import java .nio .file .Path
0 commit comments