Skip to content

Commit be31d56

Browse files
committed
Resolve symbol occurrences of select type fields
1 parent 60c336e commit be31d56

File tree

5 files changed

+60
-36
lines changed

5 files changed

+60
-36
lines changed

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

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,16 @@ class ExtractSemanticDB extends Phase:
109109
|| sym.isOldStyleImplicitConversion(forImplicitClassOnly = true)
110110

111111
/** Uses of this symbol where the reference has given span should be excluded from semanticdb */
112-
private def excludeUse(qualifier: Option[Symbol], sym: Symbol)(using Context): Boolean =
113-
!sym.exists
114-
|| excludeDefOrUse(sym)
115-
|| sym.isConstructor && sym.owner.isAnnotation
116-
|| sym == defn.Any_typeCast
117-
|| sym.owner == defn.OpsPackageClass
118-
|| qualifier.exists(excludeQual)
112+
private def excludeUse(qualifier: Option[Symbol], sym: SemanticSymbol)(using Context): Boolean =
113+
sym match
114+
case sym: Symbol =>
115+
!sym.exists
116+
|| excludeDefOrUse(sym)
117+
|| sym.isConstructor && sym.owner.isAnnotation
118+
|| sym == defn.Any_typeCast
119+
|| sym.owner == defn.OpsPackageClass
120+
|| qualifier.exists(excludeQual)
121+
case fake: FakeSymbol => false // do not exclude fake symbols
119122

120123
private def traverseAnnotsOfDefinition(sym: Symbol)(using Context): Unit =
121124
for annot <- sym.annotations do
@@ -232,7 +235,12 @@ class ExtractSemanticDB extends Phase:
232235
val sym = tree.symbol.adjustIfCtorTyparam
233236
if qualSpan.exists && qualSpan.hasLength then
234237
traverse(qual)
235-
registerUseGuarded(qual.symbol.ifExists, sym, selectSpan(tree), tree.source)
238+
if (sym != NoSymbol)
239+
registerUseGuarded(qual.symbol.ifExists, sym, selectSpan(tree), tree.source)
240+
else
241+
qual.symbol.info.lookupSym(tree.name).foreach(sym =>
242+
registerUseGuarded(qual.symbol.ifExists, sym, selectSpan(tree), tree.source)
243+
)
236244
case tree: Import =>
237245
if tree.span.exists && tree.span.hasLength then
238246
traverseChildren(tree)
@@ -329,11 +337,11 @@ class ExtractSemanticDB extends Phase:
329337
occurrences += occ
330338
generated += occ
331339

332-
private def registerUseGuarded(qualSym: Option[Symbol], sym: Symbol, span: Span, treeSource: SourceFile)(using Context) =
340+
private def registerUseGuarded(qualSym: Option[Symbol], sym: SemanticSymbol, span: Span, treeSource: SourceFile)(using Context) =
333341
if !excludeUse(qualSym, sym) && !span.isZeroExtent then
334342
registerUse(sym, span, treeSource)
335343

336-
private def registerUse(sym: Symbol, span: Span, treeSource: SourceFile)(using Context): Unit =
344+
private def registerUse(sym: SemanticSymbol, span: Span, treeSource: SourceFile)(using Context): Unit =
337345
registerUse(sym.symbolName, span, treeSource)
338346

339347
private def registerUse(symbol: String, span: Span, treeSource: SourceFile)(using Context): Unit =

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

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import core.StdNames.nme
1212
import SymbolInformation.{Kind => k}
1313
import dotty.tools.dotc.util.SourceFile
1414
import dotty.tools.dotc.util.Spans.Span
15+
import dotty.tools.dotc.core.Names.Designator
1516

1617
import java.lang.Character.{isJavaIdentifierPart, isJavaIdentifierStart}
1718

@@ -34,23 +35,30 @@ object Scala3:
3435
val (endLine, endCol) = lineCol(span.end)
3536
Some(Range(startLine, startCol, endLine, endCol))
3637

37-
def namePresentInSource(sym: Symbol, span: Span, source:SourceFile)(using Context): Boolean =
38+
def namePresentInSource(desig: Designator, span: Span, source:SourceFile)(using Context): Boolean =
3839
if !span.exists then false
3940
else
4041
val content = source.content()
4142
val (start, end) =
4243
if content.lift(span.end - 1).exists(_ == '`') then
4344
(span.start + 1, span.end - 1)
4445
else (span.start, span.end)
46+
// println(s"${start}, $end")
4547
val nameInSource = content.slice(start, end).mkString
4648
// for secondary constructors `this`
47-
if sym.isConstructor && nameInSource == nme.THISkw.toString then
48-
true
49-
else
50-
val target =
51-
if sym.isPackageObject then sym.owner
52-
else sym
53-
nameInSource == target.name.stripModuleClassSuffix.lastPart.toString
49+
desig match
50+
case sym: Symbol =>
51+
if sym.isConstructor && nameInSource == nme.THISkw.toString then
52+
true
53+
else
54+
val target =
55+
if sym.isPackageObject then sym.owner
56+
else sym
57+
nameInSource == target.name.stripModuleClassSuffix.lastPart.toString
58+
case name: Name =>
59+
// println(nameInSource)
60+
// println(name.mangledString)
61+
nameInSource == name.mangledString
5462

5563
sealed trait FakeSymbol {
5664
private[Scala3] var sname: Option[String] = None

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

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class TypeOps:
5454

5555
private def symbolNotFound(binder: Type, name: Name, parent: Symbol)(using ctx: Context): Unit =
5656
warn(s"Ignoring ${name} of symbol ${parent}, type ${binder}")
57+
private def symbolNotFound(name: Name, parent: Symbol)(using ctx: Context): Unit =
58+
warn(s"Ignoring ${name} of symbol ${parent}")
5759

5860
private def warn(msg: String)(using ctx: Context): Unit =
5961
report.warning(
@@ -64,6 +66,24 @@ class TypeOps:
6466
fakeSymbols.add(sym)
6567

6668
extension (tpe: Type)
69+
def lookupSym(name: Name)(using Context): Option[SemanticSymbol] = {
70+
def loop(ty: Type): Option[SemanticSymbol] = ty match
71+
case rt: RefinedType =>
72+
refinementSymtab.lookup(rt, name).orElse(
73+
loop(rt.parent)
74+
)
75+
case rec: RecType =>
76+
loop(rec.parent)
77+
case AndType(tp1, tp2) =>
78+
loop(tp1).orElse(loop(tp2))
79+
case OrType(tp1, tp2) =>
80+
loop(tp1).orElse(loop(tp2))
81+
case _ =>
82+
symbolNotFound(name, tpe.typeSymbol)
83+
None
84+
loop(tpe)
85+
}
86+
6787
def toSemanticSig(using LinkMode, Context, SemanticSymbolBuilder)(sym: Symbol): s.Signature =
6888
def enterParamRef(tpe: Type): Unit =
6989
tpe match {
@@ -241,22 +261,8 @@ class TypeOps:
241261
// when TypeRef refers the refinement of RefinedType e.g.
242262
// TypeRef for `foo.B` in `trait T[A] { val foo: { type B = A } = ???; def bar(b: foo.B) = () }` has NoSymbol
243263
case TypeRef(pre, name: Name) =>
244-
def lookupSym(tpe: Type): Option[SemanticSymbol] = {
245-
tpe match {
246-
case rt: RefinedType =>
247-
refinementSymtab.lookupOrErr(rt, name, rt.typeSymbol)
248-
case rec: RecType =>
249-
lookupSym(rec.parent)
250-
case AndType(tp1, tp2) =>
251-
lookupSym(tp1).orElse(lookupSym(tp2))
252-
case OrType(tp1, tp2) =>
253-
lookupSym(tp1).orElse(lookupSym(tp2))
254-
case _ =>
255-
None
256-
}
257-
}
258264
val spre = if tpe.hasTrivialPrefix then s.Type.Empty else loop(pre)
259-
val maybeSym = lookupSym(pre.widen.dealias)
265+
val maybeSym = pre.widen.dealias.lookupSym(name)
260266
maybeSym match
261267
case Some(sym) =>
262268
s.TypeRef(spre, sym.symbolName, Seq.empty)

tests/semanticdb/expect/Advanced.expect.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Structural/*<-advanced::Structural#*/ {
1414
def s2/*<-advanced::Structural#s2().*/: { val x/*<-local1*/: Int/*->scala::Int#*/ } = new { val x/*<-local2*/: Int/*->scala::Int#*/ = ???/*->scala::Predef.`???`().*/ }
1515
def s3/*<-advanced::Structural#s3().*/: { def m/*<-local6*/(x/*<-local5*/: Int/*->scala::Int#*/): Int/*->scala::Int#*/ } = new { def m/*<-local8*/(x/*<-local7*/: Int/*->scala::Int#*/): Int/*->scala::Int#*/ = ???/*->scala::Predef.`???`().*/ }
1616
def s4/*<-advanced::Structural#s4().*/(a/*<-advanced::Structural#s4().(a)*/: Int/*->scala::Int#*/): { val x/*<-local11*/: Int/*->scala::Int#*/ } = ???/*->scala::Predef.`???`().*/
17-
trait T/*<-advanced::Structural#T#*/[A/*<-advanced::Structural#T#[A]*/] { val foo/*<-advanced::Structural#T#foo.*/: { type B/*<-local12*/ = A/*->advanced::Structural#T#[A]*/ } = ???/*->scala::Predef.`???`().*/; def bar/*<-advanced::Structural#T#bar().*/(b/*<-advanced::Structural#T#bar().(b)*/: foo/*->advanced::Structural#T#foo.*/.B) = () } // from tests/pos/t8177e.scala
17+
trait T/*<-advanced::Structural#T#*/[A/*<-advanced::Structural#T#[A]*/] { val foo/*<-advanced::Structural#T#foo.*/: { type B/*<-local12*/ = A/*->advanced::Structural#T#[A]*/ } = ???/*->scala::Predef.`???`().*/; def bar/*<-advanced::Structural#T#bar().*/(b/*<-advanced::Structural#T#bar().(b)*/: foo/*->advanced::Structural#T#foo.*/.B/*->local12*/) = () } // from tests/pos/t8177e.scala
1818
}
1919

2020
class Wildcards/*<-advanced::Wildcards#*/ {
@@ -45,7 +45,7 @@ object Test/*<-advanced::Test.*/ {
4545

4646
// see: https://github.com/lampepfl/dotty/pull/14608#discussion_r835642563
4747
lazy val foo/*<-advanced::Test.foo.*/: (reflect.Selectable/*->scala::reflect::Selectable#*/ { type A/*<-local16*/ = Int/*->scala::Int#*/ }) &/*->scala::`&`#*/ (reflect.Selectable/*->scala::reflect::Selectable#*/ { type A/*<-local17*/ = Int/*->scala::Int#*/; val a/*<-local18*/: A/*->local17*/ }) = ???/*->scala::Predef.`???`().*/
48-
def bar/*<-advanced::Test.bar().*/: foo/*->advanced::Test.foo.*/.A = foo/*->advanced::Test.foo.*/.a
48+
def bar/*<-advanced::Test.bar().*/: foo/*->advanced::Test.foo.*/.A/*->local19*/ = foo/*->advanced::Test.foo.*/.a
4949
}
5050

5151

tests/semanticdb/metac.expect

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Uri => Advanced.scala
4949
Text => empty
5050
Language => Scala
5151
Symbols => 62 entries
52-
Occurrences => 130 entries
52+
Occurrences => 132 entries
5353
Synthetics => 4 entries
5454

5555
Symbols:
@@ -169,6 +169,7 @@ Occurrences:
169169
[16:50..16:53): bar <- advanced/Structural#T#bar().
170170
[16:54..16:55): b <- advanced/Structural#T#bar().(b)
171171
[16:57..16:60): foo -> advanced/Structural#T#foo.
172+
[16:61..16:62): B -> local12
172173
[19:6..19:15): Wildcards <- advanced/Wildcards#
173174
[20:6..20:8): e1 <- advanced/Wildcards#e1().
174175
[20:10..20:14): List -> scala/package.List#
@@ -230,6 +231,7 @@ Occurrences:
230231
[46:106..46:109): ??? -> scala/Predef.`???`().
231232
[47:6..47:9): bar <- advanced/Test.bar().
232233
[47:11..47:14): foo -> advanced/Test.foo.
234+
[47:15..47:16): A -> local19
233235
[47:19..47:22): foo -> advanced/Test.foo.
234236
[52:6..52:13): HKClass <- advanced/HKClass#
235237
[52:14..52:15): F <- advanced/HKClass#[F]

0 commit comments

Comments
 (0)