Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport "bugfix: Incorrect semanticdb span on Selectable" to LTS #20618

Merged
merged 1 commit into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ object Trees {
val point = span.point
if name.toTermName == nme.ERROR then
Span(point)
else if qualifier.span.start > span.start then // right associative
else if qualifier.span.start > span.point then // right associative
val realName = name.stripModuleClassSuffix.lastPart
Span(span.start, span.start + realName.length, point)
else
Expand Down
11 changes: 4 additions & 7 deletions compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,12 @@ class ExtractSemanticDB extends Phase:
}).toMap
end findGetters

private def selectSpan(tree: Select) =
private def selectSpan(tree: Select)(using Context) =
val end = tree.span.end
val limit = tree.qualifier.span.end
val start =
if limit < end then
val len = tree.name.toString.length
if tree.source.content()(end - 1) == '`' then end - len - 2 else end - len
else limit
Span(start max limit, end)
if limit < end then
tree.nameSpan
else Span(limit, end)

extension (span: Span)
private def hasLength: Boolean = span.exists && !span.isZeroExtent
Expand Down
6 changes: 3 additions & 3 deletions tests/semanticdb/expect/Givens.expect.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ package b
object Givens/*<-a::b::Givens.*/:

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

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]*/)
def sayGoodbye/*<-a::b::Givens.sayGoodbye().*/ = s"Goodbye, from $any/*->a::b::Givens.sayGoodbye().(any)*/"/*->scala::StringContext#s().*/
def saySoLong/*<-a::b::Givens.saySoLong().*/ = s"So Long, from $any/*->a::b::Givens.saySoLong().(any)*/"/*->scala::StringContext#s().*/
def sayGoodbye/*<-a::b::Givens.sayGoodbye().*/ = s/*->scala::StringContext#s().*/"Goodbye, from $any/*->a::b::Givens.sayGoodbye().(any)*/"
def saySoLong/*<-a::b::Givens.saySoLong().*/ = s/*->scala::StringContext#s().*/"So Long, from $any/*->a::b::Givens.saySoLong().(any)*/"

val hello1/*<-a::b::Givens.hello1.*/ = 1.sayHello/*->a::b::Givens.sayHello().*/
val goodbye1/*<-a::b::Givens.goodbye1.*/ = 1.sayGoodbye/*->a::b::Givens.sayGoodbye().*/
Expand Down
6 changes: 3 additions & 3 deletions tests/semanticdb/expect/ImplicitConversion.expect.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ class ImplicitConversion/*<-example::ImplicitConversion#*/ {
val x/*<-example::ImplicitConversion#x.*/: Int/*->scala::Int#*/ = message/*->example::ImplicitConversion#message.*/

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

val a/*<-example::ImplicitConversion#a.*/: Int/*->scala::Int#*/ = char/*->example::ImplicitConversion#char.*/
val b/*<-example::ImplicitConversion#b.*/: Long/*->scala::Long#*/ = char/*->example::ImplicitConversion#char.*/
Expand Down
22 changes: 22 additions & 0 deletions tests/semanticdb/expect/StructuralTypes.expect.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package example

import reflect.Selectable/*->scala::reflect::Selectable.*/.reflectiveSelectable/*->scala::reflect::Selectable.reflectiveSelectable().*/

object StructuralTypes/*<-example::StructuralTypes.*/:
type User/*<-example::StructuralTypes.User#*/ = {
def name/*<-local0*/: String/*->scala::Predef.String#*/
def age/*<-local1*/: Int/*->scala::Int#*/
def foo/*<-local3*/(x/*<-local2*/: Int/*->scala::Int#*/): Int/*->scala::Int#*/
}

val user/*<-example::StructuralTypes.user.*/ = null.asInstanceOf/*->scala::Any#asInstanceOf().*/[User/*->example::StructuralTypes.User#*/]
user/*->example::StructuralTypes.user.*/.name/*->scala::reflect::Selectable#selectDynamic().*/
user/*->example::StructuralTypes.user.*/.age/*->scala::reflect::Selectable#selectDynamic().*/
val fooBar/*<-example::StructuralTypes.fooBar.*/ = user/*->example::StructuralTypes.user.*/ foo/*->scala::reflect::Selectable#applyDynamic().*/ 123

val V/*<-example::StructuralTypes.V.*/: Object/*->java::lang::Object#*/ {
def scalameta/*<-local4*/: String/*->scala::Predef.String#*/
} = /*<-local6*/new:
def scalameta/*<-local5*/ = "4.0"
V/*->example::StructuralTypes.V.*/.scalameta/*->scala::reflect::Selectable#selectDynamic().*/
end StructuralTypes/*->example::StructuralTypes.*/
22 changes: 22 additions & 0 deletions tests/semanticdb/expect/StructuralTypes.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package example

import reflect.Selectable.reflectiveSelectable

object StructuralTypes:
type User = {
def name: String
def age: Int
def foo(x: Int): Int
}

val user = null.asInstanceOf[User]
user.name
user.age
val fooBar = user foo 123

val V: Object {
def scalameta: String
} = new:
def scalameta = "4.0"
V.scalameta
end StructuralTypes
87 changes: 77 additions & 10 deletions tests/semanticdb/metac.expect
Original file line number Diff line number Diff line change
Expand Up @@ -193,21 +193,21 @@ Occurrences:
[27:6..27:9): s1x <- advanced/Test.s1x.
[27:12..27:13): s -> advanced/Test.s.
[27:14..27:16): s1 -> advanced/Structural#s1().
[27:16..27:18): .x -> scala/reflect/Selectable#selectDynamic().
[27:17..27:18): x -> scala/reflect/Selectable#selectDynamic().
[28:6..28:8): s2 <- advanced/Test.s2.
[28:11..28:12): s -> advanced/Test.s.
[28:13..28:15): s2 -> advanced/Structural#s2().
[29:6..29:9): s2x <- advanced/Test.s2x.
[29:12..29:13): s -> advanced/Test.s.
[29:14..29:16): s2 -> advanced/Structural#s2().
[29:16..29:18): .x -> scala/reflect/Selectable#selectDynamic().
[29:17..29:18): x -> scala/reflect/Selectable#selectDynamic().
[30:6..30:8): s3 <- advanced/Test.s3.
[30:11..30:12): s -> advanced/Test.s.
[30:13..30:15): s3 -> advanced/Structural#s3().
[31:6..31:9): s3x <- advanced/Test.s3x.
[31:12..31:13): s -> advanced/Test.s.
[31:14..31:16): s3 -> advanced/Structural#s3().
[31:16..31:18): .m -> scala/reflect/Selectable#applyDynamic().
[31:17..31:18): m -> scala/reflect/Selectable#applyDynamic().
[31:19..31:22): ??? -> scala/Predef.`???`().
[33:6..33:7): e <- advanced/Test.e.
[33:14..33:23): Wildcards -> advanced/Wildcards#
Expand Down Expand Up @@ -242,7 +242,7 @@ Occurrences:
[47:11..47:14): foo -> advanced/Test.foo.
[47:15..47:16): A -> local17
[47:19..47:22): foo -> advanced/Test.foo.
[47:22..47:24): .a -> scala/reflect/Selectable#selectDynamic().
[47:23..47:24): a -> scala/reflect/Selectable#selectDynamic().
[52:6..52:13): HKClass <- advanced/HKClass#
[52:13..52:13): <- advanced/HKClass#`<init>`().
[52:14..52:15): F <- advanced/HKClass#[F]
Expand Down Expand Up @@ -1704,20 +1704,20 @@ Occurrences:
[5:16..5:19): any <- a/b/Givens.sayHello().(any)
[5:21..5:22): A -> a/b/Givens.sayHello().[A]
[6:8..6:16): sayHello <- a/b/Givens.sayHello().
[6:19..6:20): s -> scala/StringContext#s().
[6:34..6:37): any -> a/b/Givens.sayHello().(any)
[6:37..6:38): " -> scala/StringContext#s().
[8:13..8:14): B <- a/b/Givens.sayGoodbye().[B]
[8:13..8:14): B <- a/b/Givens.saySoLong().[B]
[8:16..8:19): any <- a/b/Givens.sayGoodbye().(any)
[8:16..8:19): any <- a/b/Givens.saySoLong().(any)
[8:21..8:22): B -> a/b/Givens.sayGoodbye().[B]
[8:21..8:22): B -> a/b/Givens.saySoLong().[B]
[9:8..9:18): sayGoodbye <- a/b/Givens.sayGoodbye().
[9:21..9:22): s -> scala/StringContext#s().
[9:38..9:41): any -> a/b/Givens.sayGoodbye().(any)
[9:41..9:42): " -> scala/StringContext#s().
[10:8..10:17): saySoLong <- a/b/Givens.saySoLong().
[10:20..10:21): s -> scala/StringContext#s().
[10:37..10:40): any -> a/b/Givens.saySoLong().(any)
[10:40..10:41): " -> scala/StringContext#s().
[12:6..12:12): hello1 <- a/b/Givens.hello1.
[12:17..12:25): sayHello -> a/b/Givens.sayHello().
[13:6..13:14): goodbye1 <- a/b/Givens.goodbye1.
Expand Down Expand Up @@ -1836,12 +1836,12 @@ Occurrences:
[20:6..20:7): x <- example/ImplicitConversion#x.
[20:9..20:12): Int -> scala/Int#
[20:15..20:22): message -> example/ImplicitConversion#message.
[23:2..23:3): s -> scala/StringContext#s().
[23:11..23:18): message -> example/ImplicitConversion#message.
[23:20..23:26): number -> example/ImplicitConversion#number.
[23:26..23:27): " -> scala/StringContext#s().
[24:2..24:3): s -> scala/StringContext#s().
[25:7..25:14): message -> example/ImplicitConversion#message.
[26:7..26:13): number -> example/ImplicitConversion#number.
[26:15..26:16): " -> scala/StringContext#s().
[26:17..26:28): stripMargin -> scala/collection/StringOps#stripMargin(+1).
[28:6..28:7): a <- example/ImplicitConversion#a.
[28:9..28:12): Int -> scala/Int#
Expand Down Expand Up @@ -3346,6 +3346,73 @@ Occurrences:
[13:17..13:17): <- selfs/C6#`<init>`().
[13:27..13:28): B -> selfs/B#

expect/StructuralTypes.scala
----------------------------

Summary:
Schema => SemanticDB v4
Uri => StructuralTypes.scala
Text => empty
Language => Scala
Symbols => 12 entries
Occurrences => 33 entries
Synthetics => 4 entries

Symbols:
example/StructuralTypes. => final object StructuralTypes extends Object { self: StructuralTypes.type => +5 decls }
example/StructuralTypes.User# => type User = Object { abstract method foo (param x: Int): Int; abstract method age => Int; abstract method name => String }
example/StructuralTypes.V. => val method V Object { abstract method scalameta => String }
example/StructuralTypes.fooBar. => val method fooBar Int
example/StructuralTypes.user. => val method user User
local0 => abstract method name => String
local1 => abstract method age => Int
local2 => param x: Int
local3 => abstract method foo (param x: Int): Int
local4 => abstract method scalameta => String
local5 => method scalameta => String
local6 => final class $anon extends Object { self: $anon => +2 decls }

Occurrences:
[0:8..0:15): example <- example/
[2:7..2:14): reflect -> scala/reflect/
[2:15..2:25): Selectable -> scala/reflect/Selectable.
[2:26..2:46): reflectiveSelectable -> scala/reflect/Selectable.reflectiveSelectable().
[4:7..4:22): StructuralTypes <- example/StructuralTypes.
[5:7..5:11): User <- example/StructuralTypes.User#
[6:8..6:12): name <- local0
[6:14..6:20): String -> scala/Predef.String#
[7:8..7:11): age <- local1
[7:13..7:16): Int -> scala/Int#
[8:8..8:11): foo <- local3
[8:12..8:13): x <- local2
[8:15..8:18): Int -> scala/Int#
[8:21..8:24): Int -> scala/Int#
[11:6..11:10): user <- example/StructuralTypes.user.
[11:18..11:30): asInstanceOf -> scala/Any#asInstanceOf().
[11:31..11:35): User -> example/StructuralTypes.User#
[12:2..12:6): user -> example/StructuralTypes.user.
[12:7..12:11): name -> scala/reflect/Selectable#selectDynamic().
[13:2..13:6): user -> example/StructuralTypes.user.
[13:7..13:10): age -> scala/reflect/Selectable#selectDynamic().
[14:6..14:12): fooBar <- example/StructuralTypes.fooBar.
[14:15..14:19): user -> example/StructuralTypes.user.
[14:20..14:23): foo -> scala/reflect/Selectable#applyDynamic().
[16:6..16:7): V <- example/StructuralTypes.V.
[16:9..16:15): Object -> java/lang/Object#
[17:8..17:17): scalameta <- local4
[17:19..17:25): String -> scala/Predef.String#
[18:6..18:6): <- local6
[19:8..19:17): scalameta <- local5
[20:2..20:3): V -> example/StructuralTypes.V.
[20:4..20:13): scalameta -> scala/reflect/Selectable#selectDynamic().
[21:4..21:19): StructuralTypes -> example/StructuralTypes.

Synthetics:
[12:2..12:6):user => reflectiveSelectable(*)
[13:2..13:6):user => reflectiveSelectable(*)
[14:15..14:19):user => reflectiveSelectable(*)
[20:2..20:3):V => reflectiveSelectable(*)

expect/Synthetic.scala
----------------------

Expand Down Expand Up @@ -3944,7 +4011,7 @@ Occurrences:
[48:18..48:19): v -> example/ValUsages.v.
[48:20..48:23): yim -> example/Vals#yim().
[49:2..49:3): v -> example/ValUsages.v.
[49:3..49:18): .explicitSetter -> example/Vals#`explicitSetter_=`().
[49:4..49:18): explicitSetter -> example/Vals#`explicitSetter_=`().

expect/Vararg.scala
-------------------
Expand Down
Loading