Skip to content

Commit 0d5b775

Browse files
committed
fix: [SemanticDB] Emit symbol-info and occ for anon class
fix #15852 This commit enables ExtractSemanticDB to emit SymbolInformation and SymbolOccurrence of anonymous classes. e.g. ```scala trait Foo: def foo: String val foo1: Foo = new Foo { def foo: String = ??? } val foo2: Foo = new { def foo: String = ??? } ``` While Scala2 semanticdb-plugin emit symbols for the anonymous class. Lack of the symbol information / occurrence led Metals not being able to find those anonymous classes as implementations by `go-to-implementation` from `trait Foo`.
1 parent e560c2d commit 0d5b775

File tree

9 files changed

+63
-19
lines changed

9 files changed

+63
-19
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ class ExtractSemanticDB extends Phase:
8181
private def excludeDef(sym: Symbol)(using Context): Boolean =
8282
!sym.exists
8383
|| sym.isLocalDummy
84-
|| sym.is(Synthetic)
84+
// basically do not register synthetic symbols, except anonymous class
85+
// `new Foo { ... }`
86+
|| (sym.is(Synthetic) && !sym.isAnonymousClass)
8587
|| sym.isSetter
8688
|| sym.isOldStyleImplicitConversion(forImplicitClassOnly = true)
8789
|| sym.owner.isGivenInstanceSummoner
@@ -178,7 +180,7 @@ class ExtractSemanticDB extends Phase:
178180
if !excludeChildren(tree.symbol) then
179181
traverseChildren(tree)
180182
}
181-
if !excludeDef(tree.symbol) && tree.span.hasLength then
183+
if !excludeDef(tree.symbol) && (tree.span.hasLength || tree.symbol.isAnonymousClass) then
182184
registerDefinition(tree.symbol, tree.nameSpan, symbolKinds(tree), tree.source)
183185
val privateWithin = tree.symbol.privateWithin
184186
if privateWithin.exists then
@@ -355,7 +357,7 @@ class ExtractSemanticDB extends Phase:
355357
else
356358
Span(span.start)
357359

358-
if namePresentInSource(sym, span, treeSource) then
360+
if namePresentInSource(sym, span, treeSource) || sym.isAnonymousClass then
359361
registerOccurrence(sname, finalSpan, SymbolOccurrence.Role.DEFINITION, treeSource)
360362
if !sym.is(Package) then
361363
registerSymbol(sym, symkinds)

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ object Scala3:
4343
if content.lift(span.end - 1).exists(_ == '`') then
4444
(span.start + 1, span.end - 1)
4545
else (span.start, span.end)
46-
// println(s"${start}, $end")
4746
val nameInSource = content.slice(start, end).mkString
4847
// for secondary constructors `this`
4948
desig match

tests/semanticdb/expect/Advanced.expect.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ class C/*<-advanced::C#*/[T/*<-advanced::C#[T]*/] {
1111

1212
class Structural/*<-advanced::Structural#*/ {
1313
def s1/*<-advanced::Structural#s1().*/: { val x/*<-local0*/: Int/*->scala::Int#*/ } = ???/*->scala::Predef.`???`().*/
14-
def s2/*<-advanced::Structural#s2().*/: { val x/*<-local1*/: Int/*->scala::Int#*/ } = new { val x/*<-local2*/: Int/*->scala::Int#*/ = ???/*->scala::Predef.`???`().*/ }
15-
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.`???`().*/ }
14+
def s2/*<-advanced::Structural#s2().*/: { val x/*<-local1*/: Int/*->scala::Int#*/ } = /*<-local3*/new { val x/*<-local2*/: Int/*->scala::Int#*/ = ???/*->scala::Predef.`???`().*/ }
15+
def s3/*<-advanced::Structural#s3().*/: { def m/*<-local6*/(x/*<-local5*/: Int/*->scala::Int#*/): Int/*->scala::Int#*/ } = /*<-local9*/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.`???`().*/
1717
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
}

tests/semanticdb/expect/Anonymous.expect.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,10 @@ class Anonymous/*<-example::Anonymous#*/ {
1616
}
1717

1818
trait Foo/*<-example::Anonymous#Foo#*/
19-
val foo/*<-example::Anonymous#foo.*/ = new Foo/*->example::Anonymous#Foo#*/ {}
19+
val foo/*<-example::Anonymous#foo.*/ = /*<-local1*/new Foo/*->example::Anonymous#Foo#*/ {}
20+
21+
trait Bar/*<-example::Anonymous#Bar#*/:
22+
def bar/*<-example::Anonymous#Bar#bar().*/: String/*->scala::Predef.String#*/
23+
val bar1/*<-example::Anonymous#bar1.*/: Bar/*->example::Anonymous#Bar#*/ = /*<-local4*/new Bar/*->example::Anonymous#Bar#*/ { def bar/*<-local3*/: String/*->scala::Predef.String#*/ = ???/*->scala::Predef.`???`().*/ }
24+
val bar2/*<-example::Anonymous#bar2.*/: Bar/*->example::Anonymous#Bar#*/ = /*<-local7*/new { def bar/*<-local6*/: String/*->scala::Predef.String#*/ = ???/*->scala::Predef.`???`().*/ }
2025
}

tests/semanticdb/expect/Anonymous.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,9 @@ class Anonymous {
1717

1818
trait Foo
1919
val foo = new Foo {}
20+
21+
trait Bar:
22+
def bar: String
23+
val bar1: Bar = new Bar { def bar: String = ??? }
24+
val bar2: Bar = new { def bar: String = ??? }
2025
}

tests/semanticdb/expect/Classes.expect.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class C12/*<-classes::C12#*/ {
4646
}
4747

4848
object N/*<-classes::N.*/ {
49-
val anonClass/*<-classes::N.anonClass.*/ = new C7/*->classes::C7#*/(42) {
49+
val anonClass/*<-classes::N.anonClass.*/ = /*<-local1*/new C7/*->classes::C7#*/(42) {
5050
val local/*<-local0*/ = ???/*->scala::Predef.`???`().*/
5151
}
5252
val anonFun/*<-classes::N.anonFun.*/ = List/*->scala::package.List.*/(1).map/*->scala::collection::immutable::List#map().*/ { i/*<-local3*/ =>

tests/semanticdb/expect/Traits.expect.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ trait T/*<-traits::T#*/ {
66

77
sealed trait U/*<-traits::U#*/
88
object U/*<-traits::U.*/ {
9-
def u/*<-traits::U.u().*/: U/*->traits::U#*/ = new U/*->traits::U#*/ {}
9+
def u/*<-traits::U.u().*/: U/*->traits::U#*/ = /*<-local0*/new U/*->traits::U#*/ {}
1010
}
1111

1212
class C/*<-traits::C#*/

tests/semanticdb/expect/semanticdb-Types.expect.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ object Test/*<-types::Test.*/ {
6262
val compoundType1/*<-types::Test.C#compoundType1.*/: { def k/*<-local0*/: Int/*->scala::Int#*/ } = ???/*->scala::Predef.`???`().*/
6363
val compoundType2/*<-types::Test.C#compoundType2.*/: M/*->types::Test.M#*/ with N/*->types::Test.N#*/ = ???/*->scala::Predef.`???`().*/
6464
val compoundType3/*<-types::Test.C#compoundType3.*/: M/*->types::Test.M#*/ with N/*->types::Test.N#*/ { def k/*<-local1*/: Int/*->scala::Int#*/ } = ???/*->scala::Predef.`???`().*/
65-
val compoundType4/*<-types::Test.C#compoundType4.*/ = new { def k/*<-local2*/: Int/*->scala::Int#*/ = ???/*->scala::Predef.`???`().*/ }
66-
val compoundType5/*<-types::Test.C#compoundType5.*/ = new M/*->types::Test.M#*/ with N/*->types::Test.N#*/
67-
val compoundType6/*<-types::Test.C#compoundType6.*/ = new M/*->types::Test.M#*/ with N/*->types::Test.N#*/ { def k/*<-local7*/: Int/*->scala::Int#*/ = ???/*->scala::Predef.`???`().*/ }
65+
val compoundType4/*<-types::Test.C#compoundType4.*/ = /*<-local3*/new { def k/*<-local2*/: Int/*->scala::Int#*/ = ???/*->scala::Predef.`???`().*/ }
66+
val compoundType5/*<-types::Test.C#compoundType5.*/ = /*<-local5*/new M/*->types::Test.M#*/ with N/*->types::Test.N#*/
67+
val compoundType6/*<-types::Test.C#compoundType6.*/ = /*<-local8*/new M/*->types::Test.M#*/ with N/*->types::Test.N#*/ { def k/*<-local7*/: Int/*->scala::Int#*/ = ???/*->scala::Predef.`???`().*/ }
6868

6969
val annType1/*<-types::Test.C#annType1.*/: T/*->types::T#*/ @ann(42) = ???/*->scala::Predef.`???`().*/
7070
val annType2/*<-types::Test.C#annType2.*/: T/*->types::T#*/ @ann1/*->types::ann1#*/ @ann2/*->types::ann2#*/ = ???/*->scala::Predef.`???`().*/

tests/semanticdb/metac.expect

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

5555
Symbols:
@@ -139,6 +139,7 @@ Occurrences:
139139
[13:6..13:8): s2 <- advanced/Structural#s2().
140140
[13:16..13:17): x <- local1
141141
[13:19..13:22): Int -> scala/Int#
142+
[13:27..13:27): <- local3
142143
[13:37..13:38): x <- local2
143144
[13:40..13:43): Int -> scala/Int#
144145
[13:46..13:49): ??? -> scala/Predef.`???`().
@@ -147,6 +148,7 @@ Occurrences:
147148
[14:18..14:19): x <- local5
148149
[14:21..14:24): Int -> scala/Int#
149150
[14:27..14:30): Int -> scala/Int#
151+
[14:35..14:35): <- local9
150152
[14:45..14:46): m <- local8
151153
[14:47..14:48): x <- local7
152154
[14:50..14:53): Int -> scala/Int#
@@ -357,15 +359,20 @@ Schema => SemanticDB v4
357359
Uri => Anonymous.scala
358360
Text => empty
359361
Language => Scala
360-
Symbols => 14 entries
361-
Occurrences => 30 entries
362+
Symbols => 23 entries
363+
Occurrences => 47 entries
362364
Synthetics => 2 entries
363365

364366
Symbols:
365-
example/Anonymous# => class Anonymous extends Object { self: Anonymous & Anonymous => +6 decls }
367+
example/Anonymous# => class Anonymous extends Object { self: Anonymous & Anonymous => +9 decls }
368+
example/Anonymous#Bar# => trait Bar extends Object { self: Bar => +2 decls }
369+
example/Anonymous#Bar#`<init>`(). => primary ctor <init> (): Bar
370+
example/Anonymous#Bar#bar(). => abstract method bar => String
366371
example/Anonymous#Foo# => trait Foo extends Object { self: Foo => +1 decls }
367372
example/Anonymous#Foo#`<init>`(). => primary ctor <init> (): Foo
368373
example/Anonymous#`<init>`(). => primary ctor <init> (): Anonymous
374+
example/Anonymous#bar1. => val method bar1 Bar
375+
example/Anonymous#bar2. => val method bar2 Bar
369376
example/Anonymous#foo. => val method foo Foo
370377
example/Anonymous#locally(). => method locally [typeparam A ](param x: A): A
371378
example/Anonymous#locally().(x) => param x: A
@@ -376,6 +383,10 @@ example/Anonymous#m1().[T][_] => type _
376383
example/Anonymous#m2(). => method m2 => Map[_, List[_] forSome { type _ }] forSome { type _ }
377384
local0 => val local x: Function1[Int, Int]
378385
local1 => final class $anon extends Object with Foo { self: $anon => +1 decls }
386+
local3 => method bar => String <: example/Anonymous#Bar#bar().
387+
local4 => final class $anon extends Object with Bar { self: $anon => +2 decls }
388+
local6 => method bar => String <: example/Anonymous#Bar#bar().
389+
local7 => final class $anon extends Object with Bar { self: $anon => +2 decls }
379390

380391
Occurrences:
381392
[0:8..0:15): example <- example/
@@ -407,7 +418,24 @@ Occurrences:
407418
[14:29..14:32): ??? -> scala/Predef.`???`().
408419
[17:8..17:11): Foo <- example/Anonymous#Foo#
409420
[18:6..18:9): foo <- example/Anonymous#foo.
421+
[18:12..18:12): <- local1
410422
[18:16..18:19): Foo -> example/Anonymous#Foo#
423+
[20:8..20:11): Bar <- example/Anonymous#Bar#
424+
[21:8..21:11): bar <- example/Anonymous#Bar#bar().
425+
[21:13..21:19): String -> scala/Predef.String#
426+
[22:6..22:10): bar1 <- example/Anonymous#bar1.
427+
[22:12..22:15): Bar -> example/Anonymous#Bar#
428+
[22:18..22:18): <- local4
429+
[22:22..22:25): Bar -> example/Anonymous#Bar#
430+
[22:32..22:35): bar <- local3
431+
[22:37..22:43): String -> scala/Predef.String#
432+
[22:46..22:49): ??? -> scala/Predef.`???`().
433+
[23:6..23:10): bar2 <- example/Anonymous#bar2.
434+
[23:12..23:15): Bar -> example/Anonymous#Bar#
435+
[23:18..23:18): <- local7
436+
[23:28..23:31): bar <- local6
437+
[23:33..23:39): String -> scala/Predef.String#
438+
[23:42..23:45): ??? -> scala/Predef.`???`().
411439

412440
Synthetics:
413441
[10:2..10:9):locally => *[Unit]
@@ -446,7 +474,7 @@ Uri => Classes.scala
446474
Text => empty
447475
Language => Scala
448476
Symbols => 109 entries
449-
Occurrences => 113 entries
477+
Occurrences => 114 entries
450478
Synthetics => 2 entries
451479

452480
Symbols:
@@ -664,6 +692,7 @@ Occurrences:
664692
[43:101..43:104): ??? -> scala/Predef.`???`().
665693
[47:7..47:8): N <- classes/N.
666694
[48:6..48:15): anonClass <- classes/N.anonClass.
695+
[48:18..48:18): <- local1
667696
[48:22..48:24): C7 -> classes/C7#
668697
[49:8..49:13): local <- local0
669698
[49:16..49:19): ??? -> scala/Predef.`???`().
@@ -3430,7 +3459,7 @@ Uri => Traits.scala
34303459
Text => empty
34313460
Language => Scala
34323461
Symbols => 13 entries
3433-
Occurrences => 12 entries
3462+
Occurrences => 13 entries
34343463

34353464
Symbols:
34363465
local0 => final class $anon extends Object with U { self: $anon => +1 decls }
@@ -3455,6 +3484,7 @@ Occurrences:
34553484
[7:7..7:8): U <- traits/U.
34563485
[8:6..8:7): u <- traits/U.u().
34573486
[8:9..8:10): U -> traits/U#
3487+
[8:13..8:13): <- local0
34583488
[8:17..8:18): U -> traits/U#
34593489
[11:6..11:7): C <- traits/C#
34603490
[12:6..12:7): V <- traits/V#
@@ -4522,7 +4552,7 @@ Uri => semanticdb-Types.scala
45224552
Text => empty
45234553
Language => Scala
45244554
Symbols => 144 entries
4525-
Occurrences => 225 entries
4555+
Occurrences => 228 entries
45264556
Synthetics => 1 entries
45274557

45284558
Symbols:
@@ -4780,13 +4810,16 @@ Occurrences:
47804810
[63:41..63:44): Int -> scala/Int#
47814811
[63:49..63:52): ??? -> scala/Predef.`???`().
47824812
[64:8..64:21): compoundType4 <- types/Test.C#compoundType4.
4813+
[64:24..64:24): <- local3
47834814
[64:34..64:35): k <- local2
47844815
[64:37..64:40): Int -> scala/Int#
47854816
[64:43..64:46): ??? -> scala/Predef.`???`().
47864817
[65:8..65:21): compoundType5 <- types/Test.C#compoundType5.
4818+
[65:24..65:24): <- local5
47874819
[65:28..65:29): M -> types/Test.M#
47884820
[65:35..65:36): N -> types/Test.N#
47894821
[66:8..66:21): compoundType6 <- types/Test.C#compoundType6.
4822+
[66:24..66:24): <- local8
47904823
[66:28..66:29): M -> types/Test.M#
47914824
[66:35..66:36): N -> types/Test.N#
47924825
[66:43..66:44): k <- local7

0 commit comments

Comments
 (0)