Skip to content

Commit 53794f1

Browse files
jkcieslukWojciechMazur
authored andcommitted
bugfix: Incorrect semanticdb span on Selectable
Semanticdb range on selectDynamic in `foo.bar` previously contained `.bar` instead of `bar` [Cherry-picked 5df5855]
1 parent bf4e4eb commit 53794f1

File tree

7 files changed

+132
-24
lines changed

7 files changed

+132
-24
lines changed

Diff for: compiler/src/dotty/tools/dotc/ast/Trees.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ object Trees {
455455
val point = span.point
456456
if name.toTermName == nme.ERROR then
457457
Span(point)
458-
else if qualifier.span.start > span.start then // right associative
458+
else if qualifier.span.start > span.point then // right associative
459459
val realName = name.stripModuleClassSuffix.lastPart
460460
Span(span.start, span.start + realName.length, point)
461461
else

Diff for: compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala

+4-7
Original file line numberDiff line numberDiff line change
@@ -392,15 +392,12 @@ class ExtractSemanticDB extends Phase:
392392
}).toMap
393393
end findGetters
394394

395-
private def selectSpan(tree: Select) =
395+
private def selectSpan(tree: Select)(using Context) =
396396
val end = tree.span.end
397397
val limit = tree.qualifier.span.end
398-
val start =
399-
if limit < end then
400-
val len = tree.name.toString.length
401-
if tree.source.content()(end - 1) == '`' then end - len - 2 else end - len
402-
else limit
403-
Span(start max limit, end)
398+
if limit < end then
399+
tree.nameSpan
400+
else Span(limit, end)
404401

405402
extension (span: Span)
406403
private def hasLength: Boolean = span.exists && !span.isZeroExtent

Diff for: tests/semanticdb/expect/Givens.expect.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ package b
44
object Givens/*<-a::b::Givens.*/:
55

66
extension [A/*<-a::b::Givens.sayHello().[A]*/](any/*<-a::b::Givens.sayHello().(any)*/: A/*->a::b::Givens.sayHello().[A]*/)
7-
def sayHello/*<-a::b::Givens.sayHello().*/ = s"Hello, I am $any/*->a::b::Givens.sayHello().(any)*/"/*->scala::StringContext#s().*/
7+
def sayHello/*<-a::b::Givens.sayHello().*/ = s/*->scala::StringContext#s().*/"Hello, I am $any/*->a::b::Givens.sayHello().(any)*/"
88

99
extension [B/*<-a::b::Givens.sayGoodbye().[B]*//*<-a::b::Givens.saySoLong().[B]*/](any/*<-a::b::Givens.sayGoodbye().(any)*//*<-a::b::Givens.saySoLong().(any)*/: B/*->a::b::Givens.sayGoodbye().[B]*//*->a::b::Givens.saySoLong().[B]*/)
10-
def sayGoodbye/*<-a::b::Givens.sayGoodbye().*/ = s"Goodbye, from $any/*->a::b::Givens.sayGoodbye().(any)*/"/*->scala::StringContext#s().*/
11-
def saySoLong/*<-a::b::Givens.saySoLong().*/ = s"So Long, from $any/*->a::b::Givens.saySoLong().(any)*/"/*->scala::StringContext#s().*/
10+
def sayGoodbye/*<-a::b::Givens.sayGoodbye().*/ = s/*->scala::StringContext#s().*/"Goodbye, from $any/*->a::b::Givens.sayGoodbye().(any)*/"
11+
def saySoLong/*<-a::b::Givens.saySoLong().*/ = s/*->scala::StringContext#s().*/"So Long, from $any/*->a::b::Givens.saySoLong().(any)*/"
1212

1313
val hello1/*<-a::b::Givens.hello1.*/ = 1.sayHello/*->a::b::Givens.sayHello().*/
1414
val goodbye1/*<-a::b::Givens.goodbye1.*/ = 1.sayGoodbye/*->a::b::Givens.sayGoodbye().*/

Diff for: tests/semanticdb/expect/ImplicitConversion.expect.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ class ImplicitConversion/*<-example::ImplicitConversion#*/ {
2121
val x/*<-example::ImplicitConversion#x.*/: Int/*->scala::Int#*/ = message/*->example::ImplicitConversion#message.*/
2222

2323
// interpolators
24-
s"Hello $message/*->example::ImplicitConversion#message.*/ $number/*->example::ImplicitConversion#number.*/"/*->scala::StringContext#s().*/
25-
s"""Hello
24+
s/*->scala::StringContext#s().*/"Hello $message/*->example::ImplicitConversion#message.*/ $number/*->example::ImplicitConversion#number.*/"
25+
s/*->scala::StringContext#s().*/"""Hello
2626
|$message/*->example::ImplicitConversion#message.*/
27-
|$number/*->example::ImplicitConversion#number.*/"""/*->scala::StringContext#s().*/.stripMargin/*->scala::collection::StringOps#stripMargin(+1).*/
27+
|$number/*->example::ImplicitConversion#number.*/""".stripMargin/*->scala::collection::StringOps#stripMargin(+1).*/
2828

2929
val a/*<-example::ImplicitConversion#a.*/: Int/*->scala::Int#*/ = char/*->example::ImplicitConversion#char.*/
3030
val b/*<-example::ImplicitConversion#b.*/: Long/*->scala::Long#*/ = char/*->example::ImplicitConversion#char.*/

Diff for: tests/semanticdb/expect/StructuralTypes.expect.scala

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package example
2+
3+
import reflect.Selectable/*->scala::reflect::Selectable.*/.reflectiveSelectable/*->scala::reflect::Selectable.reflectiveSelectable().*/
4+
5+
object StructuralTypes/*<-example::StructuralTypes.*/:
6+
type User/*<-example::StructuralTypes.User#*/ = {
7+
def name/*<-local0*/: String/*->scala::Predef.String#*/
8+
def age/*<-local1*/: Int/*->scala::Int#*/
9+
def foo/*<-local3*/(x/*<-local2*/: Int/*->scala::Int#*/): Int/*->scala::Int#*/
10+
}
11+
12+
val user/*<-example::StructuralTypes.user.*/ = null.asInstanceOf/*->scala::Any#asInstanceOf().*/[User/*->example::StructuralTypes.User#*/]
13+
user/*->example::StructuralTypes.user.*/.name/*->scala::reflect::Selectable#selectDynamic().*/
14+
user/*->example::StructuralTypes.user.*/.age/*->scala::reflect::Selectable#selectDynamic().*/
15+
val fooBar/*<-example::StructuralTypes.fooBar.*/ = user/*->example::StructuralTypes.user.*/ foo/*->scala::reflect::Selectable#applyDynamic().*/ 123
16+
17+
val V/*<-example::StructuralTypes.V.*/: Object/*->java::lang::Object#*/ {
18+
def scalameta/*<-local4*/: String/*->scala::Predef.String#*/
19+
} = /*<-local6*/new:
20+
def scalameta/*<-local5*/ = "4.0"
21+
V/*->example::StructuralTypes.V.*/.scalameta/*->scala::reflect::Selectable#selectDynamic().*/
22+
end StructuralTypes/*->example::StructuralTypes.*/

Diff for: tests/semanticdb/expect/StructuralTypes.scala

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package example
2+
3+
import reflect.Selectable.reflectiveSelectable
4+
5+
object StructuralTypes:
6+
type User = {
7+
def name: String
8+
def age: Int
9+
def foo(x: Int): Int
10+
}
11+
12+
val user = null.asInstanceOf[User]
13+
user.name
14+
user.age
15+
val fooBar = user foo 123
16+
17+
val V: Object {
18+
def scalameta: String
19+
} = new:
20+
def scalameta = "4.0"
21+
V.scalameta
22+
end StructuralTypes

Diff for: tests/semanticdb/metac.expect

+77-10
Original file line numberDiff line numberDiff line change
@@ -193,21 +193,21 @@ Occurrences:
193193
[27:6..27:9): s1x <- advanced/Test.s1x.
194194
[27:12..27:13): s -> advanced/Test.s.
195195
[27:14..27:16): s1 -> advanced/Structural#s1().
196-
[27:16..27:18): .x -> scala/reflect/Selectable#selectDynamic().
196+
[27:17..27:18): x -> scala/reflect/Selectable#selectDynamic().
197197
[28:6..28:8): s2 <- advanced/Test.s2.
198198
[28:11..28:12): s -> advanced/Test.s.
199199
[28:13..28:15): s2 -> advanced/Structural#s2().
200200
[29:6..29:9): s2x <- advanced/Test.s2x.
201201
[29:12..29:13): s -> advanced/Test.s.
202202
[29:14..29:16): s2 -> advanced/Structural#s2().
203-
[29:16..29:18): .x -> scala/reflect/Selectable#selectDynamic().
203+
[29:17..29:18): x -> scala/reflect/Selectable#selectDynamic().
204204
[30:6..30:8): s3 <- advanced/Test.s3.
205205
[30:11..30:12): s -> advanced/Test.s.
206206
[30:13..30:15): s3 -> advanced/Structural#s3().
207207
[31:6..31:9): s3x <- advanced/Test.s3x.
208208
[31:12..31:13): s -> advanced/Test.s.
209209
[31:14..31:16): s3 -> advanced/Structural#s3().
210-
[31:16..31:18): .m -> scala/reflect/Selectable#applyDynamic().
210+
[31:17..31:18): m -> scala/reflect/Selectable#applyDynamic().
211211
[31:19..31:22): ??? -> scala/Predef.`???`().
212212
[33:6..33:7): e <- advanced/Test.e.
213213
[33:14..33:23): Wildcards -> advanced/Wildcards#
@@ -242,7 +242,7 @@ Occurrences:
242242
[47:11..47:14): foo -> advanced/Test.foo.
243243
[47:15..47:16): A -> local17
244244
[47:19..47:22): foo -> advanced/Test.foo.
245-
[47:22..47:24): .a -> scala/reflect/Selectable#selectDynamic().
245+
[47:23..47:24): a -> scala/reflect/Selectable#selectDynamic().
246246
[52:6..52:13): HKClass <- advanced/HKClass#
247247
[52:13..52:13): <- advanced/HKClass#`<init>`().
248248
[52:14..52:15): F <- advanced/HKClass#[F]
@@ -1704,20 +1704,20 @@ Occurrences:
17041704
[5:16..5:19): any <- a/b/Givens.sayHello().(any)
17051705
[5:21..5:22): A -> a/b/Givens.sayHello().[A]
17061706
[6:8..6:16): sayHello <- a/b/Givens.sayHello().
1707+
[6:19..6:20): s -> scala/StringContext#s().
17071708
[6:34..6:37): any -> a/b/Givens.sayHello().(any)
1708-
[6:37..6:38): " -> scala/StringContext#s().
17091709
[8:13..8:14): B <- a/b/Givens.sayGoodbye().[B]
17101710
[8:13..8:14): B <- a/b/Givens.saySoLong().[B]
17111711
[8:16..8:19): any <- a/b/Givens.sayGoodbye().(any)
17121712
[8:16..8:19): any <- a/b/Givens.saySoLong().(any)
17131713
[8:21..8:22): B -> a/b/Givens.sayGoodbye().[B]
17141714
[8:21..8:22): B -> a/b/Givens.saySoLong().[B]
17151715
[9:8..9:18): sayGoodbye <- a/b/Givens.sayGoodbye().
1716+
[9:21..9:22): s -> scala/StringContext#s().
17161717
[9:38..9:41): any -> a/b/Givens.sayGoodbye().(any)
1717-
[9:41..9:42): " -> scala/StringContext#s().
17181718
[10:8..10:17): saySoLong <- a/b/Givens.saySoLong().
1719+
[10:20..10:21): s -> scala/StringContext#s().
17191720
[10:37..10:40): any -> a/b/Givens.saySoLong().(any)
1720-
[10:40..10:41): " -> scala/StringContext#s().
17211721
[12:6..12:12): hello1 <- a/b/Givens.hello1.
17221722
[12:17..12:25): sayHello -> a/b/Givens.sayHello().
17231723
[13:6..13:14): goodbye1 <- a/b/Givens.goodbye1.
@@ -1836,12 +1836,12 @@ Occurrences:
18361836
[20:6..20:7): x <- example/ImplicitConversion#x.
18371837
[20:9..20:12): Int -> scala/Int#
18381838
[20:15..20:22): message -> example/ImplicitConversion#message.
1839+
[23:2..23:3): s -> scala/StringContext#s().
18391840
[23:11..23:18): message -> example/ImplicitConversion#message.
18401841
[23:20..23:26): number -> example/ImplicitConversion#number.
1841-
[23:26..23:27): " -> scala/StringContext#s().
1842+
[24:2..24:3): s -> scala/StringContext#s().
18421843
[25:7..25:14): message -> example/ImplicitConversion#message.
18431844
[26:7..26:13): number -> example/ImplicitConversion#number.
1844-
[26:15..26:16): " -> scala/StringContext#s().
18451845
[26:17..26:28): stripMargin -> scala/collection/StringOps#stripMargin(+1).
18461846
[28:6..28:7): a <- example/ImplicitConversion#a.
18471847
[28:9..28:12): Int -> scala/Int#
@@ -3346,6 +3346,73 @@ Occurrences:
33463346
[13:17..13:17): <- selfs/C6#`<init>`().
33473347
[13:27..13:28): B -> selfs/B#
33483348

3349+
expect/StructuralTypes.scala
3350+
----------------------------
3351+
3352+
Summary:
3353+
Schema => SemanticDB v4
3354+
Uri => StructuralTypes.scala
3355+
Text => empty
3356+
Language => Scala
3357+
Symbols => 12 entries
3358+
Occurrences => 33 entries
3359+
Synthetics => 4 entries
3360+
3361+
Symbols:
3362+
example/StructuralTypes. => final object StructuralTypes extends Object { self: StructuralTypes.type => +5 decls }
3363+
example/StructuralTypes.User# => type User = Object { abstract method foo (param x: Int): Int; abstract method age => Int; abstract method name => String }
3364+
example/StructuralTypes.V. => val method V Object { abstract method scalameta => String }
3365+
example/StructuralTypes.fooBar. => val method fooBar Int
3366+
example/StructuralTypes.user. => val method user User
3367+
local0 => abstract method name => String
3368+
local1 => abstract method age => Int
3369+
local2 => param x: Int
3370+
local3 => abstract method foo (param x: Int): Int
3371+
local4 => abstract method scalameta => String
3372+
local5 => method scalameta => String
3373+
local6 => final class $anon extends Object { self: $anon => +2 decls }
3374+
3375+
Occurrences:
3376+
[0:8..0:15): example <- example/
3377+
[2:7..2:14): reflect -> scala/reflect/
3378+
[2:15..2:25): Selectable -> scala/reflect/Selectable.
3379+
[2:26..2:46): reflectiveSelectable -> scala/reflect/Selectable.reflectiveSelectable().
3380+
[4:7..4:22): StructuralTypes <- example/StructuralTypes.
3381+
[5:7..5:11): User <- example/StructuralTypes.User#
3382+
[6:8..6:12): name <- local0
3383+
[6:14..6:20): String -> scala/Predef.String#
3384+
[7:8..7:11): age <- local1
3385+
[7:13..7:16): Int -> scala/Int#
3386+
[8:8..8:11): foo <- local3
3387+
[8:12..8:13): x <- local2
3388+
[8:15..8:18): Int -> scala/Int#
3389+
[8:21..8:24): Int -> scala/Int#
3390+
[11:6..11:10): user <- example/StructuralTypes.user.
3391+
[11:18..11:30): asInstanceOf -> scala/Any#asInstanceOf().
3392+
[11:31..11:35): User -> example/StructuralTypes.User#
3393+
[12:2..12:6): user -> example/StructuralTypes.user.
3394+
[12:7..12:11): name -> scala/reflect/Selectable#selectDynamic().
3395+
[13:2..13:6): user -> example/StructuralTypes.user.
3396+
[13:7..13:10): age -> scala/reflect/Selectable#selectDynamic().
3397+
[14:6..14:12): fooBar <- example/StructuralTypes.fooBar.
3398+
[14:15..14:19): user -> example/StructuralTypes.user.
3399+
[14:20..14:23): foo -> scala/reflect/Selectable#applyDynamic().
3400+
[16:6..16:7): V <- example/StructuralTypes.V.
3401+
[16:9..16:15): Object -> java/lang/Object#
3402+
[17:8..17:17): scalameta <- local4
3403+
[17:19..17:25): String -> scala/Predef.String#
3404+
[18:6..18:6): <- local6
3405+
[19:8..19:17): scalameta <- local5
3406+
[20:2..20:3): V -> example/StructuralTypes.V.
3407+
[20:4..20:13): scalameta -> scala/reflect/Selectable#selectDynamic().
3408+
[21:4..21:19): StructuralTypes -> example/StructuralTypes.
3409+
3410+
Synthetics:
3411+
[12:2..12:6):user => reflectiveSelectable(*)
3412+
[13:2..13:6):user => reflectiveSelectable(*)
3413+
[14:15..14:19):user => reflectiveSelectable(*)
3414+
[20:2..20:3):V => reflectiveSelectable(*)
3415+
33493416
expect/Synthetic.scala
33503417
----------------------
33513418

@@ -3944,7 +4011,7 @@ Occurrences:
39444011
[48:18..48:19): v -> example/ValUsages.v.
39454012
[48:20..48:23): yim -> example/Vals#yim().
39464013
[49:2..49:3): v -> example/ValUsages.v.
3947-
[49:3..49:18): .explicitSetter -> example/Vals#`explicitSetter_=`().
4014+
[49:4..49:18): explicitSetter -> example/Vals#`explicitSetter_=`().
39484015

39494016
expect/Vararg.scala
39504017
-------------------

0 commit comments

Comments
 (0)