Skip to content

Commit 6e731a2

Browse files
committed
More definitions in Symbols section. Rename Scala to Scala3
1 parent 9bcf227 commit 6e731a2

File tree

4 files changed

+225
-168
lines changed

4 files changed

+225
-168
lines changed

compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala

Lines changed: 144 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import scala.annotation.{ threadUnsafe => tu, tailrec }
2727
* TODO: Also extract type information
2828
*/
2929
class ExtractSemanticDB extends Phase with
30-
import Scala.{_, given}
30+
import Scala3.{_, given}
3131
import Symbols.given
3232

3333
override val phaseName: String = ExtractSemanticDB.name
@@ -68,6 +68,146 @@ class ExtractSemanticDB extends Phase with
6868
/** The symbol occurrences generated so far, as a set */
6969
private val generated = new mutable.HashSet[SymbolOccurrence]
7070

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+
71211
/** Add semanticdb name of the given symbol to string builder */
72212
private def addSymName(b: StringBuilder, sym: Symbol)(given ctx: Context): Unit =
73213

@@ -161,37 +301,10 @@ class ExtractSemanticDB extends Phase with
161301
val (endLine, endCol) = lineCol(span.end)
162302
Some(Range(startLine, startCol, endLine, endCol))
163303

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-
177304
private inline def (name: Name) isEmptyNumbered: Boolean = name match
178305
case NameKinds.AnyNumberedName(nme.EMPTY, _) => true
179306
case _ => false
180307

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-
195308
private def symbolKind(sym: Symbol, symkinds: Set[SymbolKind])(given Context): SymbolInformation.Kind =
196309
if sym.isTypeParam
197310
SymbolInformation.Kind.TYPE_PARAMETER
@@ -274,6 +387,9 @@ class ExtractSemanticDB extends Phase with
274387
localNames += symbolName
275388
symbolInfos += symbolInfo(sym, symbolName, symkinds)
276389

390+
private def registerSymbolSimple(sym: Symbol)(given Context): Unit =
391+
registerSymbol(sym, symbolName(sym), Set.empty)
392+
277393
private def registerOccurrence(symbol: String, span: Span, role: SymbolOccurrence.Role)(given Context): Unit =
278394
val occ = SymbolOccurrence(symbol, range(span), role)
279395
if !generated.contains(occ) && occ.symbol.nonEmpty then
@@ -386,114 +502,6 @@ class ExtractSemanticDB extends Phase with
386502
registerSymbol(vparam.symbol, symbolName(vparam.symbol), symkinds)
387503
traverseTpt(vparam.tpt)
388504

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-
497505
object ExtractSemanticDB with
498506
import java.nio.file.Path
499507
import scala.collection.JavaConverters._

compiler/src/dotty/tools/dotc/semanticdb/Scala.scala renamed to compiler/src/dotty/tools/dotc/semanticdb/Scala3.scala

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import dotty.tools.dotc.core.StdNames.nme
1313
import scala.annotation.internal.sharable
1414
import scala.annotation.switch
1515

16-
object Scala with
16+
object Scala3 with
1717
import Symbols._
1818
import NameOps.given
1919

@@ -101,6 +101,10 @@ object Scala with
101101

102102
sym.owner.info.decls.find(s => s.name == setterName && s.info.matchingType)
103103

104+
105+
def isSyntheticWithIdent(given Context): Boolean =
106+
sym.is(Synthetic) && !sym.isAnonymous
107+
104108
end symbolOps
105109

106110
object LocalSymbol with
@@ -118,35 +122,26 @@ object Scala with
118122

119123
end LocalSymbol
120124

125+
private inline def (char: Char) `is/.#])` = (char: @switch) match
126+
case '/' | '.' | '#' | ']' | ')' => true
127+
case _ => false
128+
121129
given stringOps: (symbol: String) with
122130

123131
def isNoSymbol: Boolean = NoSymbol == symbol
124132
def isRootPackage: Boolean = RootPackage == symbol
125133
def isEmptyPackage: Boolean = EmptyPackage == symbol
126134

127-
def isGlobal: Boolean =
128-
!symbol.isNoSymbol
129-
&& !symbol.isMulti
130-
&& { (symbol.last: @switch) match
131-
case '.' | '#' | '/' | ')' | ']' => true
132-
case _ => false
133-
}
134-
135-
def isLocal: Boolean = !symbol.isGlobal
135+
def isGlobal: Boolean = !symbol.isNoSymbol && !symbol.isMulti && symbol.last.`is/.#])`
136+
def isLocal: Boolean = !symbol.isNoSymbol && !symbol.isMulti && !symbol.last.`is/.#])`
136137
def isMulti: Boolean = symbol startsWith ";"
137138

138-
def isConstructor: Boolean =
139-
ctor matches symbol
140-
def isTerm: Boolean =
141-
!symbol.isNoSymbol && !symbol.isMulti && symbol.last == '.'
142-
def isType: Boolean =
143-
!symbol.isNoSymbol && !symbol.isMulti && symbol.last == '#'
144-
def isPackage: Boolean =
145-
!symbol.isNoSymbol && !symbol.isMulti && symbol.last == '/'
146-
def isParameter: Boolean =
147-
!symbol.isNoSymbol && !symbol.isMulti && symbol.last == ')'
148-
def isTypeParameter: Boolean =
149-
!symbol.isNoSymbol && !symbol.isMulti && symbol.last == ']'
139+
def isConstructor: Boolean = ctor matches symbol
140+
def isPackage: Boolean = !symbol.isNoSymbol && !symbol.isMulti && symbol.last == '/'
141+
def isTerm: Boolean = !symbol.isNoSymbol && !symbol.isMulti && symbol.last == '.'
142+
def isType: Boolean = !symbol.isNoSymbol && !symbol.isMulti && symbol.last == '#'
143+
def isTypeParameter: Boolean = !symbol.isNoSymbol && !symbol.isMulti && symbol.last == ']'
144+
def isParameter: Boolean = !symbol.isNoSymbol && !symbol.isMulti && symbol.last == ')'
150145

151146
def unescapeUnicode =
152147
unicodeEscape.replaceAllIn(symbol, m => String.valueOf(Integer.parseInt(m.group(1), 16).toChar))
@@ -199,4 +194,4 @@ object Scala with
199194

200195
end infoOps
201196

202-
end Scala
197+
end Scala3

0 commit comments

Comments
 (0)