@@ -14,13 +14,16 @@ import ast.tpd._
1414import collection .mutable
1515
1616import dotty .tools .dotc .{semanticdb => s }
17- import Scala3 .{SemanticSymbol , WildcardTypeSymbol , TypeParamRefSymbol , TermParamRefSymbol , RefinementSymbol }
17+ import Scala3 .{FakeSymbol , SemanticSymbol , WildcardTypeSymbol , TypeParamRefSymbol , TermParamRefSymbol , RefinementSymbol }
1818
1919class 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