Skip to content

Commit 5f9ce74

Browse files
committed
Do not create newSymbol for wildcard type symbol
instead, create a proxy data that will be converted to semanticdb symbol who represents wildcard symbol
1 parent c111a49 commit 5f9ce74

File tree

3 files changed

+55
-14
lines changed

3 files changed

+55
-14
lines changed

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

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import core.Symbols.{ Symbol , defn, NoSymbol }
55
import core.Contexts._
66
import core.Names
77
import core.Names.Name
8-
import core.Types.Type
8+
import core.Types.{Type, TypeBounds}
99
import core.Flags._
1010
import core.NameKinds
1111
import core.StdNames.nme
@@ -26,6 +26,42 @@ object Scala3:
2626

2727
private val WILDCARDTypeName = nme.WILDCARD.toTypeName
2828

29+
/** Fake symbol that represents wildcard symbol which will be converted to
30+
* semanticdb symbol with
31+
* - name: local...
32+
* - SymbolInformation with signature TypeSignature of given type bound.
33+
*/
34+
case class WildcardTypeSymbol(bounds: TypeBounds) {
35+
private[Scala3] var sname: Option[String] = None
36+
}
37+
type SemanticSymbol = Symbol | WildcardTypeSymbol
38+
extension (sym: SemanticSymbol)
39+
def name(using Context): Name = sym match
40+
case s: Symbol => s.name
41+
case s: WildcardTypeSymbol => nme.WILDCARD
42+
43+
def symbolName(using builder: SemanticSymbolBuilder)(using Context): String =
44+
sym match
45+
case s: Symbol => SymbolOps.symbolName(s)
46+
case s: WildcardTypeSymbol =>
47+
s.sname.getOrElse {
48+
val sname = builder.symbolName(s)
49+
s.sname = Some(sname)
50+
sname
51+
}
52+
53+
def symbolInfo(symkinds: Set[SymbolKind])(using LinkMode, TypeOps, SemanticSymbolBuilder, Context): SymbolInformation =
54+
sym match
55+
case s: Symbol => SymbolOps.symbolInfo(s)(symkinds)
56+
case s: WildcardTypeSymbol =>
57+
SymbolInformation(
58+
symbol = symbolName,
59+
language = Language.SCALA,
60+
kind = SymbolInformation.Kind.TYPE,
61+
displayName = nme.WILDCARD.toString,
62+
signature = s.bounds.toSemanticSig(NoSymbol),
63+
)
64+
2965
enum SymbolKind derives CanEqual:
3066
kind =>
3167

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,15 @@ class SemanticSymbolBuilder:
2323
private val symsAtOffset = new mutable.HashMap[Int, Set[Symbol]]():
2424
override def default(key: Int) = Set[Symbol]()
2525

26+
2627
def symbolName(sym: Symbol)(using Context): String =
2728
val b = StringBuilder(20)
2829
addSymName(b, sym)
2930
b.toString
31+
def symbolName(sym: WildcardTypeSymbol): String =
32+
val idx = nextLocalIdx
33+
nextLocalIdx += 1
34+
s"${Symbols.LocalPrefix}${idx}"
3035

3136
def funParamSymbol(sym: Symbol)(using Context): Name => String =
3237
if sym.isGlobal then

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

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

1616
import dotty.tools.dotc.{semanticdb => s}
17+
import Scala3.{SemanticSymbol, WildcardTypeSymbol}
1718

1819
class TypeOps:
1920
import SymbolScopeOps._
@@ -38,9 +39,9 @@ class TypeOps:
3839
// e.g. `class HKClass[F <: [T] =>> [U] =>> (U, T)]`
3940
// and if the binder is HKTypeLambda, fallback to create fake symbol
4041
case lam: HKTypeLambda =>
41-
lam.paramNames.zip(lam.paramInfos).toMap.get(name) match
42+
lam.paramNames.zip(lam.paramInfos).find(t => t._1 == name) match
4243
case Some(info) =>
43-
Some(newSymbol(parent, name, Flags.TypeParam, info))
44+
Some(newSymbol(parent, name, Flags.TypeParam, info._2))
4445
case None =>
4546
symbolNotFound(binder, name, parent)
4647
None
@@ -131,8 +132,9 @@ class TypeOps:
131132
enterRefined(m.resType)
132133
case _ => ()
133134
}
134-
enterParamRef(sym.owner.info)
135-
enterRefined(sym.owner.info)
135+
if sym.exists && sym.owner.exists then
136+
enterParamRef(sym.owner.info)
137+
enterRefined(sym.owner.info)
136138

137139
def loop(tpe: Type): s.Signature = tpe match {
138140
case mp: MethodOrPoly =>
@@ -173,13 +175,12 @@ class TypeOps:
173175

174176
case TypeBounds(lo, hi) =>
175177
// for `type X[T] = T` is equivalent to `[T] =>> T`
176-
def tparams(tpe: Type): (Type, List[Symbol]) = tpe match {
178+
def tparams(tpe: Type): (Type, List[SemanticSymbol]) = tpe match {
177179
case lambda: HKTypeLambda =>
178-
val paramSyms = lambda.paramNames.zip(lambda.paramInfos).flatMap { (paramName, bounds) =>
180+
val paramSyms: List[SemanticSymbol] = lambda.paramNames.zip(lambda.paramInfos).flatMap { (paramName, bounds) =>
179181
// def x[T[_]] = ???
180182
if paramName.isWildcard then
181-
val wildcardSym = newSymbol(NoSymbol, tpnme.WILDCARD, Flags.EmptyFlags, bounds)
182-
Some(wildcardSym)
183+
Some(WildcardTypeSymbol(bounds))
183184
else
184185
paramRefSymtab.getOrErr(lambda, paramName, sym)
185186
}
@@ -188,10 +189,9 @@ class TypeOps:
188189
}
189190
val (loRes, loParams) = tparams(lo)
190191
val (hiRes, hiParams) = tparams(hi)
191-
val params = (loParams ++ hiParams).distinctBy(_.name)
192+
val stparams = (loParams ++ hiParams).distinctBy(_.name).sscopeOpt
192193
val slo = loRes.toSemanticType(sym)
193194
val shi = hiRes.toSemanticType(sym)
194-
val stparams = params.sscopeOpt
195195
s.TypeSignature(stparams, slo, shi)
196196

197197
case other =>
@@ -320,7 +320,7 @@ class TypeOps:
320320
// display_name: "_" and,
321321
// signature: type_signature(..., lo = <Nothing>, hi = <T>)
322322
case bounds: TypeBounds =>
323-
val wildcardSym = newSymbol(NoSymbol, tpnme.WILDCARD, Flags.EmptyFlags, bounds)
323+
val wildcardSym = WildcardTypeSymbol(bounds)
324324
val ssym = wildcardSym.symbolName
325325
(Some(wildcardSym), s.TypeRef(s.Type.Empty, ssym, Seq.empty))
326326
case other =>
@@ -379,8 +379,8 @@ class TypeOps:
379379

380380

381381
object SymbolScopeOps:
382-
import Scala3.given
383-
extension (syms: List[Symbol])
382+
import Scala3.{_, given}
383+
extension (syms: List[SemanticSymbol])
384384
def sscope(using linkMode: LinkMode)(using SemanticSymbolBuilder, TypeOps, Context): s.Scope =
385385
linkMode match {
386386
case LinkMode.SymlinkChildren =>

0 commit comments

Comments
 (0)