@@ -27,7 +27,7 @@ import scala.annotation.{ threadUnsafe => tu, tailrec }
27
27
* TODO: Also extract type information
28
28
*/
29
29
class ExtractSemanticDB extends Phase with
30
- import Scala .{_ , given }
30
+ import Scala3 .{_ , given }
31
31
import Symbols .given
32
32
33
33
override val phaseName : String = ExtractSemanticDB .name
@@ -68,6 +68,146 @@ class ExtractSemanticDB extends Phase with
68
68
/** The symbol occurrences generated so far, as a set */
69
69
private val generated = new mutable.HashSet [SymbolOccurrence ]
70
70
71
+ /** Definitions of this symbol should be excluded from semanticdb */
72
+ private def excludeDef (sym : Symbol )(given Context ): Boolean =
73
+ ! sym.exists
74
+ || sym.isLocalDummy
75
+ || sym.is(Synthetic )
76
+ || sym.isConstructor && sym.owner.is(ModuleClass )
77
+ || excludeDefStrict(sym)
78
+
79
+ private def excludeDefStrict (sym : Symbol )(given Context ): Boolean =
80
+ sym.name.is(NameKinds .DefaultGetterName )
81
+ || excludeSymbolStrict(sym)
82
+
83
+ private def excludeSymbolStrict (sym : Symbol )(given Context ): Boolean =
84
+ sym.name.isWildcard
85
+ || sym.isAnonymous
86
+ || sym.name.isEmptyNumbered
87
+
88
+ private def excludeChildren (sym : Symbol )(given Context ): Boolean =
89
+ sym.isAllOf(HigherKinded | Param )
90
+
91
+ /** Uses of this symbol where the reference has given span should be excluded from semanticdb */
92
+ private def excludeUseStrict (sym : Symbol , span : Span )(given Context ): Boolean =
93
+ excludeDefStrict(sym)
94
+ || excludeDef(sym) && span.zeroLength
95
+
96
+ override def traverse (tree : Tree )(given Context ): Unit =
97
+
98
+ inline def traverseCtorParamTpt (ctorSym : Symbol , tpt : Tree ): Unit =
99
+ val tptSym = tpt.symbol
100
+ if tptSym.owner == ctorSym
101
+ val found = matchingMemberType(tptSym, ctorSym.owner)
102
+ if ! excludeUseStrict(found, tpt.span) && tpt.span.hasLength
103
+ registerUse(found, tpt.span)
104
+ else
105
+ traverse(tpt)
106
+
107
+ for annot <- tree.symbol.annotations do
108
+ if annot.tree.span.exists
109
+ && annot.symbol.owner != defn.ScalaAnnotationInternal
110
+ then
111
+ traverse(annot.tree)
112
+
113
+ tree match
114
+ case tree : PackageDef =>
115
+ if ! excludeDef(tree.pid.symbol) && tree.pid.span.hasLength
116
+ tree.pid match
117
+ case tree @ Select (qual, name) =>
118
+ registerDefinition(tree.symbol, adjustSpanToName(tree.span, qual.span, name), Set .empty)
119
+ traverse(qual)
120
+ case tree => registerDefinition(tree.symbol, tree.span, Set .empty)
121
+ tree.stats.foreach(traverse)
122
+ case tree : NamedDefTree =>
123
+ if tree.symbol.isAllOf(ModuleValCreationFlags )
124
+ return
125
+ if ! excludeDef(tree.symbol) && tree.span.hasLength
126
+ registerDefinition(tree.symbol, tree.nameSpan, symbolKinds(tree))
127
+ val privateWithin = tree.symbol.privateWithin
128
+ if privateWithin.exists
129
+ registerUse(privateWithin, spanOfSymbol(privateWithin, tree.span))
130
+ else if ! excludeSymbolStrict(tree.symbol)
131
+ registerSymbol(tree.symbol, symbolName(tree.symbol), symbolKinds(tree))
132
+ tree match
133
+ case tree : ValDef if tree.symbol.isAllOf(EnumValue ) =>
134
+ tree.rhs match
135
+ case Block (TypeDef (_, template : Template ) :: _, _) => // simple case with specialised extends clause
136
+ template.parents.foreach(traverse)
137
+ case _ => // calls $new
138
+ case tree : ValDef if tree.symbol.isSelfSym =>
139
+ if tree.tpt.span.hasLength
140
+ traverse(tree.tpt)
141
+ case tree : DefDef if tree.symbol.isConstructor => // ignore typeparams for secondary ctors
142
+ tree.vparamss.foreach(_.foreach(traverse))
143
+ traverse(tree.rhs)
144
+ case tree : (DefDef | ValDef ) if tree.symbol.isSyntheticWithIdent =>
145
+ tree match
146
+ case tree : DefDef =>
147
+ tree.tparams.foreach(tparam => registerSymbolSimple(tparam.symbol))
148
+ tree.vparamss.foreach(_.foreach(vparam => registerSymbolSimple(vparam.symbol)))
149
+ case _ =>
150
+ // ignore rhs
151
+ case tree =>
152
+ if ! excludeChildren(tree.symbol)
153
+ traverseChildren(tree)
154
+ case tree : Template =>
155
+ val ctorSym = tree.constr.symbol
156
+ if ! excludeDef(ctorSym)
157
+ registerDefinition(ctorSym, tree.constr.span, Set .empty)
158
+ ctorParams(tree.constr.vparamss, tree.body)(traverseCtorParamTpt(ctorSym, _))
159
+ for parent <- tree.parentsOrDerived do
160
+ if
161
+ parent.symbol != defn.ObjectClass .primaryConstructor
162
+ && parent.tpe.dealias != defn.SerializableType
163
+ && parent.symbol != defn.ProductClass
164
+ then
165
+ traverse(parent)
166
+ val selfSpan = tree.self.span
167
+ if selfSpan.exists && selfSpan.hasLength then
168
+ traverse(tree.self)
169
+ if tree.symbol.owner.is(Enum , butNot= Case )
170
+ tree.body.foreachUntilImport(traverse).foreach(traverse) // the first import statement
171
+ else
172
+ tree.body.foreach(traverse)
173
+ case tree : Assign =>
174
+ if ! excludeUseStrict(tree.lhs.symbol, tree.lhs.span)
175
+ val lhs = tree.lhs.symbol
176
+ val setter = lhs.matchingSetter.orElse(lhs)
177
+ tree.lhs match
178
+ case tree @ Select (qual, name) => registerUse(setter, adjustSpanToName(tree.span, qual.span, name))
179
+ case tree => registerUse(setter, tree.span)
180
+ traverseChildren(tree.lhs)
181
+ traverse(tree.rhs)
182
+ case tree : Ident =>
183
+ if tree.name != nme.WILDCARD then
184
+ val sym = tree.symbol.adjustIfCtorTyparam
185
+ if ! excludeUseStrict(sym, tree.span) then
186
+ registerUse(sym, tree.span)
187
+ case tree : Select =>
188
+ val qualSpan = tree.qualifier.span
189
+ val sym = tree.symbol.adjustIfCtorTyparam
190
+ if ! excludeUseStrict(sym, tree.span) then
191
+ registerUse(sym, adjustSpanToName(tree.span, qualSpan, tree.name))
192
+ if qualSpan.exists && qualSpan.hasLength then
193
+ traverseChildren(tree)
194
+ case tree : Import =>
195
+ if tree.span.exists && tree.span.hasLength then
196
+ for sel <- tree.selectors do
197
+ val imported = sel.imported.name
198
+ if imported != nme.WILDCARD then
199
+ for alt <- tree.expr.tpe.member(imported).alternatives do
200
+ registerUse(alt.symbol, sel.imported.span)
201
+ if (alt.symbol.companionClass.exists)
202
+ registerUse(alt.symbol.companionClass, sel.imported.span)
203
+ traverseChildren(tree)
204
+ case tree : Inlined =>
205
+ traverse(tree.call)
206
+ case tree : Annotated => // skip the annotation (see `@param` in https://github.com/scalameta/scalameta/blob/633824474e99bbfefe12ad0cc73da1fe064b3e9b/tests/jvm/src/test/resources/example/Annotations.scala#L37)
207
+ traverse(tree.arg)
208
+ case _ =>
209
+ traverseChildren(tree)
210
+
71
211
/** Add semanticdb name of the given symbol to string builder */
72
212
private def addSymName (b : StringBuilder , sym : Symbol )(given ctx : Context ): Unit =
73
213
@@ -161,37 +301,10 @@ class ExtractSemanticDB extends Phase with
161
301
val (endLine, endCol) = lineCol(span.end)
162
302
Some (Range (startLine, startCol, endLine, endCol))
163
303
164
- /** Definitions of this symbol should be excluded from semanticdb */
165
- private def excludeDef (sym : Symbol )(given Context ): Boolean =
166
- ! sym.exists
167
- || sym.isLocalDummy
168
- || sym.is(Synthetic )
169
- || sym.owner.is(Synthetic ) && ! sym.owner.isAnonymous && ! sym.isAllOf(EnumCase )
170
- || sym.isConstructor && sym.owner.is(ModuleClass )
171
- || excludeDefStrict(sym)
172
-
173
- private def excludeDefStrict (sym : Symbol )(given Context ): Boolean =
174
- sym.name.is(NameKinds .DefaultGetterName )
175
- || excludeSymbolStrict(sym)
176
-
177
304
private inline def (name : Name ) isEmptyNumbered : Boolean = name match
178
305
case NameKinds .AnyNumberedName (nme.EMPTY , _) => true
179
306
case _ => false
180
307
181
- private def excludeSymbolStrict (sym : Symbol )(given Context ): Boolean =
182
- sym.name.isWildcard
183
- || sym.isAnonymous
184
- || sym.name.isEmptyNumbered
185
-
186
- private def excludeChildren (sym : Symbol )(given Context ): Boolean =
187
- sym.isAllOf(HigherKinded | Param )
188
- || ! sym.isAnonymous && sym.is(Synthetic , butNot= Module )
189
-
190
- /** Uses of this symbol where the reference has given span should be excluded from semanticdb */
191
- private def excludeUseStrict (sym : Symbol , span : Span )(given Context ): Boolean =
192
- excludeDefStrict(sym)
193
- || excludeDef(sym) && span.zeroLength
194
-
195
308
private def symbolKind (sym : Symbol , symkinds : Set [SymbolKind ])(given Context ): SymbolInformation .Kind =
196
309
if sym.isTypeParam
197
310
SymbolInformation .Kind .TYPE_PARAMETER
@@ -274,6 +387,9 @@ class ExtractSemanticDB extends Phase with
274
387
localNames += symbolName
275
388
symbolInfos += symbolInfo(sym, symbolName, symkinds)
276
389
390
+ private def registerSymbolSimple (sym : Symbol )(given Context ): Unit =
391
+ registerSymbol(sym, symbolName(sym), Set .empty)
392
+
277
393
private def registerOccurrence (symbol : String , span : Span , role : SymbolOccurrence .Role )(given Context ): Unit =
278
394
val occ = SymbolOccurrence (symbol, range(span), role)
279
395
if ! generated.contains(occ) && occ.symbol.nonEmpty then
@@ -386,114 +502,6 @@ class ExtractSemanticDB extends Phase with
386
502
registerSymbol(vparam.symbol, symbolName(vparam.symbol), symkinds)
387
503
traverseTpt(vparam.tpt)
388
504
389
- override def traverse (tree : Tree )(given Context ): Unit =
390
-
391
- inline def traverseCtorParamTpt (ctorSym : Symbol , tpt : Tree ): Unit =
392
- val tptSym = tpt.symbol
393
- if tptSym.owner == ctorSym
394
- val found = matchingMemberType(tptSym, ctorSym.owner)
395
- if ! excludeUseStrict(found, tpt.span) && tpt.span.hasLength
396
- registerUse(found, tpt.span)
397
- else
398
- traverse(tpt)
399
-
400
- for annot <- tree.symbol.annotations do
401
- if annot.tree.span.exists
402
- && annot.symbol.owner != defn.ScalaAnnotationInternal
403
- then
404
- traverse(annot.tree)
405
-
406
- tree match
407
- case tree : PackageDef =>
408
- if ! excludeDef(tree.pid.symbol) && tree.pid.span.hasLength
409
- tree.pid match
410
- case tree @ Select (qual, name) =>
411
- registerDefinition(tree.symbol, adjustSpanToName(tree.span, qual.span, name), Set .empty)
412
- traverse(qual)
413
- case tree => registerDefinition(tree.symbol, tree.span, Set .empty)
414
- tree.stats.foreach(traverse)
415
- case tree : NamedDefTree =>
416
- if tree.symbol.isAllOf(ModuleValCreationFlags )
417
- return
418
- if ! excludeDef(tree.symbol) && tree.span.hasLength
419
- registerDefinition(tree.symbol, tree.nameSpan, symbolKinds(tree))
420
- val privateWithin = tree.symbol.privateWithin
421
- if privateWithin.exists
422
- registerUse(privateWithin, spanOfSymbol(privateWithin, tree.span))
423
- else if ! excludeSymbolStrict(tree.symbol)
424
- registerSymbol(tree.symbol, symbolName(tree.symbol), symbolKinds(tree))
425
- tree match
426
- case tree : ValDef if tree.symbol.isAllOf(EnumValue ) =>
427
- tree.rhs match
428
- case Block (TypeDef (_, template : Template ) :: _, _) => // simple case with specialised extends clause
429
- template.parents.foreach(traverse)
430
- case _ => // calls $new
431
- case tree : ValDef if tree.symbol.isSelfSym =>
432
- if tree.tpt.span.hasLength
433
- traverse(tree.tpt)
434
- case tree : DefDef if tree.symbol.isConstructor => // ignore typeparams for secondary ctors
435
- tree.vparamss.foreach(_.foreach(traverse))
436
- traverse(tree.rhs)
437
- case tree =>
438
- if ! excludeChildren(tree.symbol)
439
- traverseChildren(tree)
440
- case tree : Template =>
441
- val ctorSym = tree.constr.symbol
442
- if ! excludeDef(ctorSym)
443
- registerDefinition(ctorSym, tree.constr.span, Set .empty)
444
- ctorParams(tree.constr.vparamss, tree.body)(traverseCtorParamTpt(ctorSym, _))
445
- for parent <- tree.parentsOrDerived do
446
- if
447
- parent.symbol != defn.ObjectClass .primaryConstructor
448
- && parent.tpe.dealias != defn.SerializableType
449
- && parent.symbol != defn.ProductClass
450
- then
451
- traverse(parent)
452
- val selfSpan = tree.self.span
453
- if selfSpan.exists && selfSpan.hasLength then
454
- traverse(tree.self)
455
- if tree.symbol.owner.is(Enum , butNot= Case )
456
- tree.body.foreachUntilImport(traverse).foreach(traverse) // the first import statement
457
- else
458
- tree.body.foreach(traverse)
459
- case tree : Assign =>
460
- if ! excludeUseStrict(tree.lhs.symbol, tree.lhs.span)
461
- val lhs = tree.lhs.symbol
462
- val setter = lhs.matchingSetter.orElse(lhs)
463
- tree.lhs match
464
- case tree @ Select (qual, name) => registerUse(setter, adjustSpanToName(tree.span, qual.span, name))
465
- case tree => registerUse(setter, tree.span)
466
- traverseChildren(tree.lhs)
467
- traverse(tree.rhs)
468
- case tree : Ident =>
469
- if tree.name != nme.WILDCARD then
470
- val sym = tree.symbol.adjustIfCtorTyparam
471
- if ! excludeUseStrict(sym, tree.span) then
472
- registerUse(sym, tree.span)
473
- case tree : Select =>
474
- val qualSpan = tree.qualifier.span
475
- val sym = tree.symbol.adjustIfCtorTyparam
476
- if ! excludeUseStrict(sym, tree.span) then
477
- registerUse(sym, adjustSpanToName(tree.span, qualSpan, tree.name))
478
- if qualSpan.exists && qualSpan.hasLength then
479
- traverseChildren(tree)
480
- case tree : Import =>
481
- if tree.span.exists && tree.span.hasLength then
482
- for sel <- tree.selectors do
483
- val imported = sel.imported.name
484
- if imported != nme.WILDCARD then
485
- for alt <- tree.expr.tpe.member(imported).alternatives do
486
- registerUse(alt.symbol, sel.imported.span)
487
- if (alt.symbol.companionClass.exists)
488
- registerUse(alt.symbol.companionClass, sel.imported.span)
489
- traverseChildren(tree)
490
- case tree : Inlined =>
491
- traverse(tree.call)
492
- case tree : Annotated => // skip the annotation (see `@param` in https://github.com/scalameta/scalameta/blob/633824474e99bbfefe12ad0cc73da1fe064b3e9b/tests/jvm/src/test/resources/example/Annotations.scala#L37)
493
- traverse(tree.arg)
494
- case _ =>
495
- traverseChildren(tree)
496
-
497
505
object ExtractSemanticDB with
498
506
import java .nio .file .Path
499
507
import scala .collection .JavaConverters ._
0 commit comments