Skip to content

Commit 4af72b9

Browse files
committed
Add fakeSymbols to symbol section and don't hardlink fake syms
1 parent c3548a1 commit 4af72b9

File tree

5 files changed

+98
-45
lines changed

5 files changed

+98
-45
lines changed

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ class ExtractSemanticDB extends Phase:
4444

4545
override def run(using Context): Unit =
4646
val unit = ctx.compilationUnit
47-
val extract = Extractor()
48-
extract.traverse(unit.tpdTree)
49-
ExtractSemanticDB.write(unit.source, extract.occurrences.toList, extract.symbolInfos.toList)
47+
val extractor = Extractor()
48+
extractor.extract(unit.tpdTree)
49+
ExtractSemanticDB.write(unit.source, extractor.occurrences.toList, extractor.symbolInfos.toList)
5050

5151
/** Extractor of symbol occurrences from trees */
5252
class Extractor extends TreeTraverser:
@@ -68,6 +68,11 @@ class ExtractSemanticDB extends Phase:
6868
/** The symbol occurrences generated so far, as a set */
6969
private val generated = new mutable.HashSet[SymbolOccurrence]
7070

71+
def extract(tree: Tree)(using Context): Unit =
72+
traverse(tree)
73+
val fakeSyms = converter.fakeSymbols.map(_.symbolInfo(Set.empty)(using LinkMode.SymlinkChildren, converter))
74+
symbolInfos.appendAll(fakeSyms)
75+
7176
/** Definitions of this symbol should be excluded from semanticdb */
7277
private def excludeDef(sym: Symbol)(using Context): Boolean =
7378
!sym.exists

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ object Scala3:
3939

4040
case class TermParamRefSymbol(owner: Symbol, name: Name, tp: Type) extends FakeSymbol
4141
case class TypeParamRefSymbol(owner: Symbol, name: Name, tp: TypeBounds) extends FakeSymbol
42-
case class RefinementSymbol(name: Name, tp: Type) extends FakeSymbol
42+
case class RefinementSymbol(owner: Symbol, name: Name, tp: Type) extends FakeSymbol
4343
type SemanticSymbol = Symbol | FakeSymbol
4444
extension (sym: SemanticSymbol)
4545
def name(using Context): Name = sym match
@@ -68,26 +68,26 @@ object Scala3:
6868
language = Language.SCALA,
6969
kind = SymbolInformation.Kind.TYPE,
7070
displayName = nme.WILDCARD.show,
71-
signature = s.bounds.toSemanticSig(NoSymbol),
71+
signature = s.bounds.toSemanticSig(s.owner),
7272
)
7373
case s: TermParamRefSymbol =>
7474
SymbolInformation(
7575
symbol = symbolName,
7676
language = Language.SCALA,
7777
kind = SymbolInformation.Kind.PARAMETER,
7878
displayName = s.name.show.unescapeUnicode,
79-
signature = s.tp.toSemanticSig(NoSymbol),
79+
signature = s.tp.toSemanticSig(s.owner),
8080
)
8181
case s: TypeParamRefSymbol =>
8282
SymbolInformation(
8383
symbol = symbolName,
8484
language = Language.SCALA,
8585
kind = SymbolInformation.Kind.TYPE_PARAMETER,
8686
displayName = s.name.show.unescapeUnicode,
87-
signature = s.tp.toSemanticSig(NoSymbol),
87+
signature = s.tp.toSemanticSig(s.owner),
8888
)
8989
case s: RefinementSymbol =>
90-
val signature = s.tp.toSemanticSig(NoSymbol)
90+
val signature = s.tp.toSemanticSig(s.owner)
9191
val kind = signature match
9292
case _: TypeSignature => SymbolInformation.Kind.TYPE
9393
case _: MethodSignature => SymbolInformation.Kind.METHOD

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ class SemanticSymbolBuilder:
4848
b.toString
4949
case sym: RefinementSymbol =>
5050
val b = StringBuilder(20)
51-
val localIdx = nextLocalIdx
52-
nextLocalIdx += 1
53-
b.append(Symbols.LocalPrefix).append(localIdx)
51+
addLocalSymName(b)
5452
b.toString
5553

5654
def funParamSymbol(sym: Symbol)(using Context): Name => String =
@@ -66,6 +64,11 @@ class SemanticSymbolBuilder:
6664
if str.isJavaIdent then b append str
6765
else b append '`' append str append '`'
6866

67+
private def addLocalSymName(b: StringBuilder): Unit =
68+
val idx = nextLocalIdx
69+
nextLocalIdx += 1
70+
b.append(Symbols.LocalPrefix).append(idx)
71+
6972
/** Add semanticdb name of the given symbol to string builder */
7073
private def addSymName(b: StringBuilder, sym: Symbol)(using Context): Unit =
7174

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

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ import ast.tpd._
1414
import collection.mutable
1515

1616
import dotty.tools.dotc.{semanticdb => s}
17-
import Scala3.{SemanticSymbol, WildcardTypeSymbol, TypeParamRefSymbol, TermParamRefSymbol, RefinementSymbol}
17+
import Scala3.{FakeSymbol, SemanticSymbol, WildcardTypeSymbol, TypeParamRefSymbol, TermParamRefSymbol, RefinementSymbol}
1818

1919
class TypeOps:
2020
import SymbolScopeOps._
2121
import Scala3.given
2222
private val paramRefSymtab = mutable.Map[(LambdaType, Name), Symbol]()
2323
private val refinementSymtab = mutable.Map[(RefinedType, Name), Symbol]()
24+
25+
// save generated fake symbols so we can insert them into symbols section of SemanticDB
26+
val fakeSymbols = mutable.Set[FakeSymbol]()
2427
given typeOps: TypeOps = this
2528

2629
extension [T <: LambdaType | RefinedType](symtab: mutable.Map[(T, Name), Symbol])
@@ -56,6 +59,9 @@ class TypeOps:
5659
s"Internal error in extracting SemanticDB while compiling ${ctx.compilationUnit.source}: ${msg}"
5760
)
5861

62+
private def registerFakeSymbol(sym: FakeSymbol)(using Context, SemanticSymbolBuilder): Unit =
63+
fakeSymbols.add(sym)
64+
5965
extension (tpe: Type)
6066
def toSemanticSig(using LinkMode, Context, SemanticSymbolBuilder)(sym: Symbol): s.Signature =
6167
def enterParamRef(tpe: Type): Unit =
@@ -146,16 +152,20 @@ class TypeOps:
146152
): (Type, List[List[SemanticSymbol]], List[SemanticSymbol]) = t match {
147153
case mt: MethodType =>
148154
val syms: List[SemanticSymbol] = mt.paramNames.zip(mt.paramInfos).map { (name, info) =>
149-
paramRefSymtab.lookup(mt, name).getOrElse(
150-
TermParamRefSymbol(sym, name, info)
151-
)
155+
paramRefSymtab.lookup(mt, name).getOrElse {
156+
val fakeSym = TermParamRefSymbol(sym, name, info)
157+
registerFakeSymbol(fakeSym)
158+
fakeSym
159+
}
152160
}
153161
flatten(mt.resType, paramss :+ syms, tparams)
154162
case pt: PolyType =>
155163
val syms: List[SemanticSymbol] = pt.paramNames.zip(pt.paramInfos).map { (name, info) =>
156-
paramRefSymtab.lookup(pt, name).getOrElse(
157-
TypeParamRefSymbol(sym, name, info)
158-
)
164+
paramRefSymtab.lookup(pt, name).getOrElse {
165+
val fakeSym = TypeParamRefSymbol(sym, name, info)
166+
registerFakeSymbol(fakeSym)
167+
fakeSym
168+
}
159169
}
160170
flatten(pt.resType, paramss, tparams ++ syms)
161171
case other =>
@@ -185,11 +195,15 @@ class TypeOps:
185195
val paramSyms: List[SemanticSymbol] = lambda.paramNames.zip(lambda.paramInfos).map { (paramName, bounds) =>
186196
// def x[T[_]] = ???
187197
if paramName.isWildcard then
188-
WildcardTypeSymbol(sym, bounds)
198+
val fakeSym = WildcardTypeSymbol(sym, bounds)
199+
registerFakeSymbol(fakeSym)
200+
fakeSym
189201
else
190-
paramRefSymtab.lookup(lambda, paramName).getOrElse(
191-
TypeParamRefSymbol(sym, paramName, bounds)
192-
)
202+
paramRefSymtab.lookup(lambda, paramName).getOrElse {
203+
val fakeSym = TypeParamRefSymbol(sym, paramName, bounds)
204+
registerFakeSymbol(fakeSym)
205+
fakeSym
206+
}
193207
}
194208
(lambda.resType, paramSyms)
195209
case _ => (tpe, Nil)
@@ -245,7 +259,9 @@ class TypeOps:
245259
tref.binder.typeParams.find(param => param.paramName == tref.paramName) match
246260
case Some(param) =>
247261
val info = param.paramInfo
248-
Some(TypeParamRefSymbol(sym, tref.paramName, info))
262+
val fakeSym = TypeParamRefSymbol(sym, tref.paramName, info)
263+
registerFakeSymbol(fakeSym)
264+
Some(fakeSym)
249265
case None =>
250266
symbolNotFound(tref.binder, tref.paramName, sym)
251267
None
@@ -300,9 +316,11 @@ class TypeOps:
300316
val stpe = s.IntersectionType(flattenParent(parent))
301317

302318
val decls: List[SemanticSymbol] = refinedInfos.map { (name, info) =>
303-
refinementSymtab.lookup(rt, name).getOrElse(
304-
RefinementSymbol(name, info)
305-
)
319+
refinementSymtab.lookup(rt, name).getOrElse {
320+
val fakeSym = RefinementSymbol(sym, name, info)
321+
registerFakeSymbol(fakeSym)
322+
fakeSym
323+
}
306324
}
307325
val sdecls = decls.sscopeOpt(using LinkMode.HardlinkChildren)
308326
s.StructuralType(stpe, sdecls)
@@ -348,6 +366,7 @@ class TypeOps:
348366
// signature: type_signature(..., lo = <Nothing>, hi = <T>)
349367
case bounds: TypeBounds =>
350368
val wildcardSym = WildcardTypeSymbol(sym, bounds)
369+
registerFakeSymbol(wildcardSym)
351370
val ssym = wildcardSym.symbolName
352371
(Some(wildcardSym), s.TypeRef(s.Type.Empty, ssym, Seq.empty))
353372
case other =>
@@ -419,13 +438,11 @@ object SymbolScopeOps:
419438
import Scala3.{_, given}
420439
extension (syms: List[SemanticSymbol])
421440
def sscope(using linkMode: LinkMode)(using SemanticSymbolBuilder, TypeOps, Context): s.Scope =
422-
// if syms contains FakeSymbol, hardlink those symbols
423-
// because fake symbols don't appear in Symbols section.
424-
// If we symlink those fake symbols, we always fail to lookup those symlinked symbols.
425-
if syms.exists(s => s.isInstanceOf[FakeSymbol]) || linkMode == LinkMode.HardlinkChildren then
426-
s.Scope(hardlinks = syms.map(_.symbolInfo(Set.empty)(using LinkMode.HardlinkChildren)))
427-
else
428-
s.Scope(symlinks = syms.map(_.symbolName))
429-
430-
def sscopeOpt(using linkMode: LinkMode)(using SemanticSymbolBuilder, TypeOps, Context): Option[s.Scope] =
441+
linkMode match
442+
case LinkMode.SymlinkChildren =>
443+
s.Scope(symlinks = syms.map(_.symbolName))
444+
case LinkMode.HardlinkChildren =>
445+
s.Scope(hardlinks = syms.map(_.symbolInfo(Set.empty)))
446+
447+
def sscopeOpt(using LinkMode, SemanticSymbolBuilder, TypeOps, Context): Option[s.Scope] =
431448
if syms.nonEmpty then Some(syms.sscope) else None

0 commit comments

Comments
 (0)