Skip to content

Commit a7d8068

Browse files
committed
register usage for path parts of an import statement
1 parent 2c40921 commit a7d8068

31 files changed

+410
-81
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,13 @@ class ExtractSemanticDB extends Phase {
160160
registerOccurrence(sym, span, SymbolOccurrence.Role.REFERENCE)
161161

162162
override def traverse(tree: Tree)(given ctx: Context): Unit =
163+
def registerPath(expr: Tree): Unit = expr match
164+
case t @ Select(expr, _) =>
165+
registerUse(t.symbol, t.span)
166+
registerPath(expr)
167+
168+
case _ =>
169+
163170
tree match
164171
case tree: ValDef if tree.symbol.is(Module) => // skip module val
165172
case tree: NamedDefTree
@@ -185,6 +192,7 @@ class ExtractSemanticDB extends Phase {
185192
if imported != nme.WILDCARD then
186193
for alt <- tree.expr.tpe.member(imported).alternatives do
187194
registerUse(alt.symbol, sel.imported.span)
195+
registerPath(tree.expr)
188196
case tree: Inlined =>
189197
traverse(tree.call)
190198
case tree: PackageDef => tree.stats.foreach(traverse)

compiler/test/dotty/tools/dotc/semanticdb/Semanticdbs.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ object Semanticdbs {
6767
sourceFile.lineToOffset(range.endLine) + range.endCharacter
6868
)
6969
sb.append(doc.text.substring(offset, end))
70-
.append(" /*")
70+
.append("/*")
7171
.append(if (occ.role.isDefinition) "<<=" else "=>>")
7272
.append(occ.symbol.replace('/', '.'))
73-
.append("*/ ")
73+
.append("*/")
7474
offset = end
7575
}
7676
sb.append(doc.text.substring(offset))
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.TYPE)
10+
public @interface ClassAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.CONSTRUCTOR)
10+
public @interface ConstructorAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.FIELD)
10+
public @interface FieldAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.TYPE)
10+
public @interface InterfaceAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.LOCAL_VARIABLE)
10+
public @interface LocalAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.METHOD)
10+
public @interface MacroAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.METHOD)
10+
public @interface MethodAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.TYPE)
10+
public @interface ObjectAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.PACKAGE)
10+
public @interface PackageAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.PACKAGE)
10+
public @interface PackageObjectAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.PARAMETER)
10+
public @interface ParameterAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.PARAMETER)
10+
public @interface SelfParameterAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.TYPE)
10+
public @interface TraitAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.TYPE)
10+
public @interface TypeAnnotation{}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.javacp.annot;
2+
3+
import java.lang.annotation.Retention;
4+
import java.lang.annotation.RetentionPolicy;
5+
import java.lang.annotation.Target;
6+
import java.lang.annotation.ElementType;
7+
8+
@Retention(RetentionPolicy.CLASS)
9+
@Target(ElementType.TYPE_PARAMETER)
10+
public @interface TypeParameterAnnotation{}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.javacp.annot.usage;
2+
3+
@com.javacp.annot.InterfaceAnnotation
4+
public @interface AnnotatedInterface{}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// compiler crash
2+
// @annot.ParameterAnnotation
3+
package com.javacp.annot.usage;
4+
5+
public class AnnotatedPackage{}

tests/semanticdb/Access.expect.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package example
22

3-
class /*=>>java.lang.Object#`<init>`().*/ Access /*<<=example.Access#*/ {
4-
private def m1 /*<<=example.Access#m1().*/ = ??? /*=>>scala.Predef.`???`().*/
5-
private[this] def m2 /*<<=example.Access#m2().*/ = ??? /*=>>scala.Predef.`???`().*/
6-
private[Access] def m3 /*<<=example.Access#m3().*/ = ??? /*=>>scala.Predef.`???`().*/
7-
protected def m4 /*<<=example.Access#m4().*/ = ??? /*=>>scala.Predef.`???`().*/
8-
protected[this] def m5 /*<<=example.Access#m5().*/ = ??? /*=>>scala.Predef.`???`().*/
9-
protected[example] def m6 /*<<=example.Access#m6().*/ = ??? /*=>>scala.Predef.`???`().*/
10-
def m7 /*<<=example.Access#m7().*/ = ??? /*=>>scala.Predef.`???`().*/
3+
class /*=>>java.lang.Object#`<init>`().*/Access/*<<=example.Access#*/ {
4+
private def m1/*<<=example.Access#m1().*/ = ???/*=>>scala.Predef.`???`().*/
5+
private[this] def m2/*<<=example.Access#m2().*/ = ???/*=>>scala.Predef.`???`().*/
6+
private[Access] def m3/*<<=example.Access#m3().*/ = ???/*=>>scala.Predef.`???`().*/
7+
protected def m4/*<<=example.Access#m4().*/ = ???/*=>>scala.Predef.`???`().*/
8+
protected[this] def m5/*<<=example.Access#m5().*/ = ???/*=>>scala.Predef.`???`().*/
9+
protected[example] def m6/*<<=example.Access#m6().*/ = ???/*=>>scala.Predef.`???`().*/
10+
def m7/*<<=example.Access#m7().*/ = ???/*=>>scala.Predef.`???`().*/
1111
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package advanced
2+
3+
import scala.language/*=>>scalaShadowing.language.*/.higherKinds/*=>>scalaShadowing.language.higherKinds.*/
4+
import scala.language/*=>>scalaShadowing.language.*/.reflectiveCalls/*=>>scalaShadowing.language.reflectiveCalls.*/
5+
6+
import scala.reflect/*=>>scala.reflect.*/.Selectable/*=>>scala.reflect.Selectable.*/.reflectiveSelectable/*=>>scala.reflect.Selectable.reflectiveSelectable().*/
7+
8+
class /*=>>java.lang.Object#`<init>`().*/C/*<<=advanced.C#*/[T] {
9+
/*<<=advanced.C#`<init>`().*//*<<=advanced.C#`<init>`().(T)*//*<<=advanced.C#(T)*/ def t/*<<=advanced.C#t().*/: T/*=>>advanced.C#(T)*/ = ???/*=>>scala.Predef.`???`().*/
10+
}
11+
12+
class /*=>>java.lang.Object#`<init>`().*/Structural/*<<=advanced.Structural#*/ {
13+
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#*/ } = /*=>>java.lang.Object#`<init>`().*/new {/*<<=local2*/ val x/*<<=local3*/: Int/*=>>scala.Int#*/ = ???/*=>>scala.Predef.`???`().*/ }/*=>>local4*//*=>>local2*/
15+
def s3/*<<=advanced.Structural#s3().*/: { def m/*<<=local5*/(x/*<<=local6*/: Int/*=>>scala.Int#*/): Int/*=>>scala.Int#*/ } = /*=>>java.lang.Object#`<init>`().*/new {/*<<=local7*/ def m/*<<=local8*/(x/*<<=local9*/: Int/*=>>scala.Int#*/): Int/*=>>scala.Int#*/ = ???/*=>>scala.Predef.`???`().*/ }/*=>>local10*//*=>>local7*/
16+
}
17+
18+
class /*=>>java.lang.Object#`<init>`().*/Wildcards/*<<=advanced.Wildcards#*/ {
19+
def e1/*<<=advanced.Wildcards#e1().*/: List/*=>>scala.package.List#*/[_] = ???/*=>>scala.Predef.`???`().*/
20+
}
21+
22+
object /*=>>java.lang.Object#`<init>`().*/Test/*<<=advanced.Test.*/ {
23+
/*=>>scala.package.Serializable#*//*=>>scala.*//*=>>_root_*//*=>>advanced.Test.*/val s/*<<=advanced.Test.s.*/ = new Structural/*=>>advanced.Structural#*//*=>>advanced.Structural#`<init>`().*/
24+
val s1/*<<=advanced.Test.s1.*/ = s/*=>>advanced.Test.s.*/.s1/*=>>advanced.Structural#s1().*/
25+
val s1x/*<<=advanced.Test.s1x.*/ = /*=>>scala.reflect.Selectable.reflectiveSelectable().*/s/*=>>advanced.Test.s.*/.s1/*=>>advanced.Structural#s1().*//*=>>scala.Selectable#selectDynamic().*/.x
26+
val s2/*<<=advanced.Test.s2.*/ = s/*=>>advanced.Test.s.*/.s2/*=>>advanced.Structural#s2().*/
27+
val s2x/*<<=advanced.Test.s2x.*/ = /*=>>scala.reflect.Selectable.reflectiveSelectable().*/s/*=>>advanced.Test.s.*/.s2/*=>>advanced.Structural#s2().*//*=>>scala.Selectable#selectDynamic().*/.x
28+
val s3/*<<=advanced.Test.s3.*/ = s/*=>>advanced.Test.s.*/.s3/*=>>advanced.Structural#s3().*/
29+
val s3x/*<<=advanced.Test.s3x.*/ = /*=>>scala.reflect.Selectable.reflectiveSelectable().*/s/*=>>advanced.Test.s.*/.s3/*=>>advanced.Structural#s3().*//*=>>scala.Selectable#applyDynamic().*/.m/*=>>scala.reflect.ClassTag.apply().*//*=>>scala.reflect.ClassTag.*//*=>>java.lang.Integer.TYPE.*//*=>>java.lang.Integer.*/(???/*=>>scala.Predef.`???`().*/)
30+
31+
val e/*<<=advanced.Test.e.*/ = new Wildcards/*=>>advanced.Wildcards#*//*=>>advanced.Wildcards#`<init>`().*/
32+
val e1/*<<=advanced.Test.e1.*/ = e/*=>>advanced.Test.e.*/.e1/*=>>advanced.Wildcards#e1().*/
33+
val e1x/*<<=advanced.Test.e1x.*/ = e/*=>>advanced.Test.e.*/.e1/*=>>advanced.Wildcards#e1().*/.head/*=>>scala.collection.IterableOps#head().*/
34+
35+
{
36+
(???/*=>>scala.Predef.`???`().*/ : Any/*=>>scala.Any#*/) match {
37+
case e3/*<<=local11*/: List/*=>>scala.package.List#*/[_/*<<=local12*/] =>
38+
val e3x/*<<=local13*/ = e3/*=>>local11*/.head/*=>>scala.collection.IterableOps#head().*/
39+
()
40+
}
41+
}
42+
}

tests/semanticdb/Advanced.scala

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package advanced
2+
3+
import scala.language.higherKinds
4+
import scala.language.reflectiveCalls
5+
6+
import scala.reflect.Selectable.reflectiveSelectable
7+
8+
class C[T] {
9+
def t: T = ???
10+
}
11+
12+
class Structural {
13+
def s1: { val x: Int } = ???
14+
def s2: { val x: Int } = new { val x: Int = ??? }
15+
def s3: { def m(x: Int): Int } = new { def m(x: Int): Int = ??? }
16+
}
17+
18+
class Wildcards {
19+
def e1: List[_] = ???
20+
}
21+
22+
object Test {
23+
val s = new Structural
24+
val s1 = s.s1
25+
val s1x = s.s1.x
26+
val s2 = s.s2
27+
val s2x = s.s2.x
28+
val s3 = s.s3
29+
val s3x = s.s3.m(???)
30+
31+
val e = new Wildcards
32+
val e1 = e.e1
33+
val e1x = e.e1.head
34+
35+
{
36+
(??? : Any) match {
37+
case e3: List[_] =>
38+
val e3x = e3.head
39+
()
40+
}
41+
}
42+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package annot
2+
3+
import com.javacp.annot._
4+
import scala.annotation.meta._
5+
import scala.language/*=>>scalaShadowing.language.*/.experimental/*=>>scalaShadowing.language.experimental.*/.macros/*=>>scalaShadowing.language.experimental.macros.*/
6+
7+
@ClassAnnotation
8+
class /*=>>java.lang.Object#`<init>`().*/Annotations/*<<=annot.Annotations#*/[@Type/*<<=annot.Annotations#`<init>`().*/ParameterAnnotation T/*<<=annot.Annotations#`<init>`().(T)*//*<<=annot.Annotations#(T)*/](@ParameterAnnotation x/*<<=annot.Annotations#`<init>`().(x)*//*<<=annot.Annotations#(x)*/: T/*=>>annot.Annotations#`<init>`().(T)*/) { self/*<<=annot.Annotations#self.*/: AnyRef/*=>>scala.AnyRef#*/ =>
9+
@FieldAnnotation
10+
val field/*<<=annot.Annotations#field.*/ = 42
11+
12+
@MethodAnnotation
13+
def method/*<<=annot.Annotations#method().*/ = {
14+
@LocalAnnotation
15+
val local/*<<=local0*/ = 42
16+
local/*=>>local0*/
17+
}
18+
@TypeAnnotation
19+
type S/*<<=annot.Annotations#S#*/
20+
}
21+
22+
class /*=>>java.lang.Object#`<init>`().*/B/*<<=annot.B#*/ @Cons/*<<=annot.B#`<init>`().*/tructorAnnotation()(x/*<<=annot.B#`<init>`().(x)*//*<<=annot.B#(x)*/: Int/*=>>scala.Int#*/) {
23+
@ConstructorAnnotation
24+
def this()/*<<=annot.B#`<init>`(+1).*/ = this(/*=>>annot.B#`<init>`().*/42)
25+
}
26+
27+
@ObjectAnnotation
28+
object /*=>>java.lang.Object#`<init>`().*/M/*<<=annot.M.*/ {
29+
/*=>>scala.package.Serializable#*//*=>>scala.*//*=>>_root_*//*=>>annot.M.*/@MacroAnnotation
30+
def m/*<<=annot.M.m().*/[TT/*<<=annot.M.m().(TT)*/]: Int/*=>>scala.Int#*//*=>>scala.Predef.`???`().*//*=>>scala.Predef.*//*=>>scala.*//*=>>_root_*/ = macro ???
31+
}
32+
33+
@TraitAnnotation
34+
trait T/*<<=annot.T#*/
35+
36+
object /*=>>java.lang.Object#`<init>`().*/Alias/*<<=annot.Alias.*/ {
37+
/*=>>scala.package.Serializable#*//*=>>scala.*//*=>>_root_*//*=>>annot.Alias.*/type A/*<<=annot.Alias.A#*/ = ClassAnnotation/*=>>com.javacp.annot.ClassAnnotation#*/ @param/*=>>scala.annotation.meta.param#*//*=>>scala.annotation.meta.param#`<init>`().*/
38+
}

tests/semanticdb/Annotations.scala

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package annot
2+
3+
import com.javacp.annot._
4+
import scala.annotation.meta._
5+
import scala.language.experimental.macros
6+
7+
@ClassAnnotation
8+
class Annotations[@TypeParameterAnnotation T](@ParameterAnnotation x: T) { self: AnyRef =>
9+
@FieldAnnotation
10+
val field = 42
11+
12+
@MethodAnnotation
13+
def method = {
14+
@LocalAnnotation
15+
val local = 42
16+
local
17+
}
18+
@TypeAnnotation
19+
type S
20+
}
21+
22+
class B @ConstructorAnnotation()(x: Int) {
23+
@ConstructorAnnotation
24+
def this() = this(42)
25+
}
26+
27+
@ObjectAnnotation
28+
object M {
29+
@MacroAnnotation
30+
def m[TT]: Int = macro ???
31+
}
32+
33+
@TraitAnnotation
34+
trait T
35+
36+
object Alias {
37+
type A = ClassAnnotation @param
38+
}

0 commit comments

Comments
 (0)