@@ -14,13 +14,16 @@ import ast.tpd._
14
14
import collection .mutable
15
15
16
16
import dotty .tools .dotc .{semanticdb => s }
17
- import Scala3 .{SemanticSymbol , WildcardTypeSymbol , TypeParamRefSymbol , TermParamRefSymbol , RefinementSymbol }
17
+ import Scala3 .{FakeSymbol , SemanticSymbol , WildcardTypeSymbol , TypeParamRefSymbol , TermParamRefSymbol , RefinementSymbol }
18
18
19
19
class TypeOps :
20
20
import SymbolScopeOps ._
21
21
import Scala3 .given
22
22
private val paramRefSymtab = mutable.Map [(LambdaType , Name ), Symbol ]()
23
23
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 ]()
24
27
given typeOps : TypeOps = this
25
28
26
29
extension [T <: LambdaType | RefinedType ](symtab : mutable.Map [(T , Name ), Symbol ])
@@ -56,6 +59,9 @@ class TypeOps:
56
59
s " Internal error in extracting SemanticDB while compiling ${ctx.compilationUnit.source}: ${msg}"
57
60
)
58
61
62
+ private def registerFakeSymbol (sym : FakeSymbol )(using Context , SemanticSymbolBuilder ): Unit =
63
+ fakeSymbols.add(sym)
64
+
59
65
extension (tpe : Type )
60
66
def toSemanticSig (using LinkMode , Context , SemanticSymbolBuilder )(sym : Symbol ): s.Signature =
61
67
def enterParamRef (tpe : Type ): Unit =
@@ -146,16 +152,20 @@ class TypeOps:
146
152
): (Type , List [List [SemanticSymbol ]], List [SemanticSymbol ]) = t match {
147
153
case mt : MethodType =>
148
154
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
+ }
152
160
}
153
161
flatten(mt.resType, paramss :+ syms, tparams)
154
162
case pt : PolyType =>
155
163
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
+ }
159
169
}
160
170
flatten(pt.resType, paramss, tparams ++ syms)
161
171
case other =>
@@ -185,11 +195,15 @@ class TypeOps:
185
195
val paramSyms : List [SemanticSymbol ] = lambda.paramNames.zip(lambda.paramInfos).map { (paramName, bounds) =>
186
196
// def x[T[_]] = ???
187
197
if paramName.isWildcard then
188
- WildcardTypeSymbol (sym, bounds)
198
+ val fakeSym = WildcardTypeSymbol (sym, bounds)
199
+ registerFakeSymbol(fakeSym)
200
+ fakeSym
189
201
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
+ }
193
207
}
194
208
(lambda.resType, paramSyms)
195
209
case _ => (tpe, Nil )
@@ -245,7 +259,9 @@ class TypeOps:
245
259
tref.binder.typeParams.find(param => param.paramName == tref.paramName) match
246
260
case Some (param) =>
247
261
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)
249
265
case None =>
250
266
symbolNotFound(tref.binder, tref.paramName, sym)
251
267
None
@@ -300,9 +316,11 @@ class TypeOps:
300
316
val stpe = s.IntersectionType (flattenParent(parent))
301
317
302
318
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
+ }
306
324
}
307
325
val sdecls = decls.sscopeOpt(using LinkMode .HardlinkChildren )
308
326
s.StructuralType (stpe, sdecls)
@@ -348,6 +366,7 @@ class TypeOps:
348
366
// signature: type_signature(..., lo = <Nothing>, hi = <T>)
349
367
case bounds : TypeBounds =>
350
368
val wildcardSym = WildcardTypeSymbol (sym, bounds)
369
+ registerFakeSymbol(wildcardSym)
351
370
val ssym = wildcardSym.symbolName
352
371
(Some (wildcardSym), s.TypeRef (s.Type .Empty , ssym, Seq .empty))
353
372
case other =>
@@ -419,13 +438,11 @@ object SymbolScopeOps:
419
438
import Scala3 .{_ , given }
420
439
extension (syms : List [SemanticSymbol ])
421
440
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 ] =
431
448
if syms.nonEmpty then Some (syms.sscope) else None
0 commit comments