diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala index c13eede4d590..d3cb5865f4da 100644 --- a/compiler/src/dotty/tools/dotc/ast/Trees.scala +++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala @@ -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 diff --git a/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala b/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala index 5cff105cbaa4..e364bf15ca13 100644 --- a/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala +++ b/compiler/src/dotty/tools/dotc/semanticdb/ExtractSemanticDB.scala @@ -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 diff --git a/tests/semanticdb/expect/Givens.expect.scala b/tests/semanticdb/expect/Givens.expect.scala index 8ee82a419435..8cd1ee287096 100644 --- a/tests/semanticdb/expect/Givens.expect.scala +++ b/tests/semanticdb/expect/Givens.expect.scala @@ -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().*/ diff --git a/tests/semanticdb/expect/ImplicitConversion.expect.scala b/tests/semanticdb/expect/ImplicitConversion.expect.scala index 635ffb4d94c9..7c1708ee7617 100644 --- a/tests/semanticdb/expect/ImplicitConversion.expect.scala +++ b/tests/semanticdb/expect/ImplicitConversion.expect.scala @@ -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.*/ diff --git a/tests/semanticdb/expect/StructuralTypes.expect.scala b/tests/semanticdb/expect/StructuralTypes.expect.scala new file mode 100644 index 000000000000..96c7181d6f10 --- /dev/null +++ b/tests/semanticdb/expect/StructuralTypes.expect.scala @@ -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.*/ \ No newline at end of file diff --git a/tests/semanticdb/expect/StructuralTypes.scala b/tests/semanticdb/expect/StructuralTypes.scala new file mode 100644 index 000000000000..5d10dbe67224 --- /dev/null +++ b/tests/semanticdb/expect/StructuralTypes.scala @@ -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 \ No newline at end of file diff --git a/tests/semanticdb/metac.expect b/tests/semanticdb/metac.expect index 00727163fda4..8f875a050fd9 100644 --- a/tests/semanticdb/metac.expect +++ b/tests/semanticdb/metac.expect @@ -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# @@ -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#``(). [52:14..52:15): F <- advanced/HKClass#[F] @@ -1684,8 +1684,8 @@ 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) @@ -1693,11 +1693,11 @@ Occurrences: [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. @@ -1816,12 +1816,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# @@ -3326,6 +3326,73 @@ Occurrences: [13:17..13:17): <- selfs/C6#``(). [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 ---------------------- @@ -3924,7 +3991,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 -------------------