Skip to content

Commit f1e75e6

Browse files
author
Catherine Gasnier
committed
Populate SCIP field enclosing_range for definitions
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
1 parent 6c91f33 commit f1e75e6

File tree

28 files changed

+328
-12
lines changed

28 files changed

+328
-12
lines changed

scip-java/src/main/scala/com/sourcegraph/scip_java/ScipPrinters.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,13 @@ object ScipPrinters {
199199
.append(info.getEnclosingSymbol)
200200
.append("\n")
201201
}
202+
if (occ.getEnclosingRangeCount > 0) {
203+
out
204+
.append(prefix)
205+
.append("enclosing_range ")
206+
.append(occ.getEnclosingRangeList.asScala.mkString(" "))
207+
.append("\n")
208+
}
202209
if (info.getKind != Scip.SymbolInformation.Kind.UnspecifiedKind) {
203210
out.append(prefix).append("kind ").append(info.getKind).append("\n")
204211
}

scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdb.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,30 @@ private void processTypedDocument(
179179
occ.getRange().getEndLine(),
180180
occ.getRange().getEndCharacter());
181181
Package pkg = packages.packageForSymbol(occ.getSymbol()).orElse(Package.EMPTY);
182-
tdoc.addOccurrences(
182+
Scip.Occurrence.Builder occBuilder =
183183
Scip.Occurrence.newBuilder()
184184
.addAllRange(range)
185185
.setSymbol(typedSymbol(occ.getSymbol(), pkg))
186-
.setSymbolRoles(role));
186+
.setSymbolRoles(role);
187+
// Add enclosing_range if it exists
188+
if (occ.hasEnclosingRange()) {
189+
Semanticdb.Range enclosingRange = occ.getEnclosingRange();
190+
boolean isEnclosingSingleLine =
191+
enclosingRange.getStartLine() == enclosingRange.getEndLine();
192+
Iterable<Integer> enclosingRangeInts =
193+
isEnclosingSingleLine
194+
? Arrays.asList(
195+
enclosingRange.getStartLine(),
196+
enclosingRange.getStartCharacter(),
197+
enclosingRange.getEndCharacter())
198+
: Arrays.asList(
199+
enclosingRange.getStartLine(),
200+
enclosingRange.getStartCharacter(),
201+
enclosingRange.getEndLine(),
202+
enclosingRange.getEndCharacter());
203+
occBuilder.addAllEnclosingRange(enclosingRangeInts);
204+
}
205+
tdoc.addOccurrences(occBuilder);
187206
}
188207
Symtab symtab = new Symtab(doc.semanticdb);
189208
for (SymbolInformation info : doc.semanticdb.getSymbolsList()) {

semanticdb-java/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbBuilders.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ public static Semanticdb.Signature signature(Semanticdb.TypeSignature.Builder si
5252
// SemanticDB Symbols
5353

5454
public static Semanticdb.SymbolOccurrence symbolOccurrence(
55-
String symbol, Semanticdb.Range range, Semanticdb.SymbolOccurrence.Role role) {
56-
return Semanticdb.SymbolOccurrence.newBuilder()
55+
String symbol, Semanticdb.Range range, Semanticdb.SymbolOccurrence.Role role,
56+
java.util.Optional<Semanticdb.Range> enclosingRange) {
57+
Semanticdb.SymbolOccurrence.Builder builder = Semanticdb.SymbolOccurrence.newBuilder()
5758
.setSymbol(symbol)
5859
.setRange(range)
59-
.setRole(role)
60-
.build();
60+
.setRole(role);
61+
enclosingRange.ifPresent(builder::setEnclosingRange);
62+
return builder.build();
6163
}
6264

6365
public static Semanticdb.SymbolInformation.Builder symbolInformation(String symbol) {

semanticdb-java/src/main/protobuf/semanticdb.proto

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ message SymbolOccurrence {
182182
Range range = 1;
183183
string symbol = 2;
184184
Role role = 3;
185+
// NOTE: this field does not exist in the upstream SemanticDB spec.
186+
// It is added to support SCIP's enclosing_range field.
187+
// This is the range of the nearest non-trivial enclosing AST node.
188+
optional Range enclosing_range = 4;
185189
}
186190

187191
message Scope {

semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,18 @@ private Optional<Semanticdb.Range> emitSymbolOccurrence(
110110
Element sym, Tree tree, Name name, Role role, CompilerRange kind) {
111111
if (sym == null || name == null) return Optional.empty();
112112
Optional<Semanticdb.Range> range = semanticdbRange(tree, kind, sym, name.toString());
113-
emitSymbolOccurrence(sym, range, role);
113+
Optional<Semanticdb.Range> enclosingRange = computeEnclosingRange(tree);
114+
emitSymbolOccurrence(sym, range, role, enclosingRange);
114115
if (role == Role.DEFINITION) {
115116
// Only emit SymbolInformation for symbols that are defined in this compilation unit.
116117
emitSymbolInformation(sym, tree);
117118
}
118119
return range;
119120
}
120121

121-
private void emitSymbolOccurrence(Element sym, Optional<Semanticdb.Range> range, Role role) {
122+
private void emitSymbolOccurrence(Element sym, Optional<Semanticdb.Range> range, Role role, Optional<Semanticdb.Range> enclosingRange) {
122123
if (sym == null) return;
123-
Optional<Semanticdb.SymbolOccurrence> occ = semanticdbOccurrence(sym, range, role);
124+
Optional<Semanticdb.SymbolOccurrence> occ = semanticdbOccurrence(sym, range, role, enclosingRange);
124125
occ.ifPresent(occurrences::add);
125126
}
126127

@@ -298,7 +299,7 @@ private void resolveVariableTree(VariableTree node, TreePath treePath) {
298299
if (sym.getKind() == ElementKind.ENUM_CONSTANT) {
299300
TreePath typeTreePath = nodes.get(node.getInitializer());
300301
Element typeSym = trees.getElement(typeTreePath);
301-
if (typeSym != null) emitSymbolOccurrence(typeSym, range, Role.REFERENCE);
302+
if (typeSym != null) emitSymbolOccurrence(typeSym, range, Role.REFERENCE, Optional.empty());
302303
}
303304
}
304305
}
@@ -462,11 +463,11 @@ private Semanticdb.Range correctForTabs(Semanticdb.Range range, LineMap lineMap,
462463
}
463464

464465
private Optional<Semanticdb.SymbolOccurrence> semanticdbOccurrence(
465-
Element sym, Optional<Semanticdb.Range> range, Role role) {
466+
Element sym, Optional<Semanticdb.Range> range, Role role, Optional<Semanticdb.Range> enclosingRange) {
466467
if (range.isPresent()) {
467468
String ssym = semanticdbSymbol(sym);
468469
if (!ssym.equals(SemanticdbSymbols.NONE)) {
469-
Semanticdb.SymbolOccurrence occ = symbolOccurrence(ssym, range.get(), role);
470+
Semanticdb.SymbolOccurrence occ = symbolOccurrence(ssym, range.get(), role, enclosingRange);
470471
return Optional.of(occ);
471472
} else {
472473
return Optional.empty();
@@ -476,6 +477,51 @@ private Optional<Semanticdb.SymbolOccurrence> semanticdbOccurrence(
476477
}
477478
}
478479

480+
/**
481+
* Computes the enclosing range for the given tree node.
482+
* Returns the range of the nearest non-trivial enclosing AST node.
483+
* For definition occurrences, this includes the entire definition including documentation.
484+
* For reference occurrences, this includes the parent expression bounds.
485+
*/
486+
private Optional<Semanticdb.Range> computeEnclosingRange(Tree tree) {
487+
if (tree == null) return Optional.empty();
488+
489+
TreePath path = nodes.get(tree);
490+
if (path == null) return Optional.empty();
491+
492+
// For method, class, and variable definitions, use the tree itself as the enclosing range
493+
// since we're processing the definition node
494+
Tree enclosingTree = tree;
495+
if (!(tree instanceof MethodTree || tree instanceof ClassTree || tree instanceof VariableTree)) {
496+
// For non-definition nodes (like references), use the parent
497+
TreePath parentPath = path.getParentPath();
498+
if (parentPath == null) return Optional.empty();
499+
enclosingTree = parentPath.getLeaf();
500+
if (enclosingTree == null || enclosingTree == compUnitTree) return Optional.empty();
501+
}
502+
503+
SourcePositions sourcePositions = trees.getSourcePositions();
504+
int start = (int) sourcePositions.getStartPosition(compUnitTree, enclosingTree);
505+
int end = (int) sourcePositions.getEndPosition(compUnitTree, enclosingTree);
506+
507+
if (start != Diagnostic.NOPOS && end != Diagnostic.NOPOS && end > start) {
508+
LineMap lineMap = compUnitTree.getLineMap();
509+
Semanticdb.Range range =
510+
Semanticdb.Range.newBuilder()
511+
.setStartLine((int) lineMap.getLineNumber(start) - 1)
512+
.setStartCharacter((int) lineMap.getColumnNumber(start) - 1)
513+
.setEndLine((int) lineMap.getLineNumber(end) - 1)
514+
.setEndCharacter((int) lineMap.getColumnNumber(end) - 1)
515+
.build();
516+
517+
range = correctForTabs(range, lineMap, start);
518+
519+
return Optional.of(range);
520+
}
521+
522+
return Optional.empty();
523+
}
524+
479525
private String semanticdbText() {
480526
if (source != null) return source;
481527
try {

tests/snapshots/src/main/generated/tests/minimized/src/main/java/minimized/AbstractClasses.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ public abstract class AbstractClasses {
44
// ^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#
55
// display_name AbstractClasses
66
// signature_documentation java public abstract class AbstractClasses
7+
// enclosing_range 2 0 8 1
78
// kind Class
89
// ^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#`<init>`().
910
// display_name <init>
@@ -14,6 +15,7 @@ public String defaultImplementation() {
1415
// ^^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#defaultImplementation().
1516
// display_name defaultImplementation
1617
// signature_documentation java public String defaultImplementation()
18+
// enclosing_range 3 2 5 3
1719
// kind Method
1820
return "";
1921
}
@@ -23,6 +25,7 @@ public String defaultImplementation() {
2325
// ^^^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#abstractImplementation().
2426
// display_name abstractImplementation
2527
// signature_documentation java public abstract String abstractImplementation()
28+
// enclosing_range 7 2 50
2629
// kind AbstractMethod
2730
// relationship is_reference is_implementation semanticdb maven . . minimized/SubClasses#abstractImplementation().
2831
}

tests/snapshots/src/main/generated/tests/minimized/src/main/java/minimized/AnnotationParameters.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,45 @@
44
// ^^^ definition semanticdb maven . . minimized/Bar#
55
// display_name Bar
66
// signature_documentation java @interface Bar
7+
// enclosing_range 2 0 4 1
78
// kind Interface
89
// relationship is_implementation semanticdb maven jdk 11 java/lang/annotation/Annotation#
910
double value();
1011
// ^^^^^ definition semanticdb maven . . minimized/Bar#value().
1112
// display_name value
1213
// signature_documentation java public abstract double value()
14+
// enclosing_range 3 1 16
1315
// kind AbstractMethod
1416
}
1517

1618
@interface BarB {
1719
// ^^^^ definition semanticdb maven . . minimized/BarB#
1820
// display_name BarB
1921
// signature_documentation java @interface BarB
22+
// enclosing_range 6 0 8 1
2023
// kind Interface
2124
// relationship is_implementation semanticdb maven jdk 11 java/lang/annotation/Annotation#
2225
boolean value();
2326
// ^^^^^ definition semanticdb maven . . minimized/BarB#value().
2427
// display_name value
2528
// signature_documentation java public abstract boolean value()
29+
// enclosing_range 7 1 17
2630
// kind AbstractMethod
2731
}
2832

2933
@interface Nullable {
3034
// ^^^^^^^^ definition semanticdb maven . . minimized/Nullable#
3135
// display_name Nullable
3236
// signature_documentation java @interface Nullable
37+
// enclosing_range 10 0 12 1
3338
// kind Interface
3439
// relationship is_implementation semanticdb maven jdk 11 java/lang/annotation/Annotation#
3540
String value() default "";
3641
//^^^^^ reference semanticdb maven jdk 11 java/lang/String#
3742
// ^^^^^ definition semanticdb maven . . minimized/Nullable#value().
3843
// display_name value
3944
// signature_documentation java public abstract String value()
45+
// enclosing_range 11 1 27
4046
// kind AbstractMethod
4147
}
4248

@@ -45,27 +51,31 @@
4551
// ^^^^^^ definition semanticdb maven . . minimized/BarRef#
4652
// display_name BarRef
4753
// signature_documentation java @interface BarRef
54+
// enclosing_range 15 0 17 1
4855
// kind Interface
4956
// relationship is_implementation semanticdb maven jdk 11 java/lang/annotation/Annotation#
5057
SuppressWarnings value();
5158
//^^^^^^^^^^^^^^^ reference semanticdb maven jdk 11 java/lang/SuppressWarnings#
5259
// ^^^^^ definition semanticdb maven . . minimized/BarRef#value().
5360
// display_name value
5461
// signature_documentation java public abstract SuppressWarnings value()
62+
// enclosing_range 16 1 26
5563
// kind AbstractMethod
5664
}
5765

5866
interface Foo {
5967
// ^^^ definition semanticdb maven . . minimized/Foo#
6068
// display_name Foo
6169
// signature_documentation java interface Foo
70+
// enclosing_range 19 0 35 1
6271
// kind Interface
6372
@Bar(-1d)
6473
//^^^ reference semanticdb maven . . minimized/Bar#
6574
double test();
6675
// ^^^^ definition semanticdb maven . . minimized/Foo#test().
6776
// display_name test
6877
// signature_documentation java @Bar(-1.0)\npublic abstract double test()
78+
// enclosing_range 20 1 21 15
6979
// kind AbstractMethod
7080

7181
@Bar(~5)
@@ -77,6 +87,7 @@ interface Foo {
7787
// ^^^^^ definition semanticdb maven . . minimized/Foo#test2().
7888
// display_name test2
7989
// signature_documentation java @Bar(~5)\n@SuppressWarnings("unchecked")\npublic abstract double test2()
90+
// enclosing_range 23 1 25 16
8091
// kind AbstractMethod
8192

8293
@BarB(!true)
@@ -85,6 +96,7 @@ interface Foo {
8596
// ^^^^^ definition semanticdb maven . . minimized/Foo#test3().
8697
// display_name test3
8798
// signature_documentation java @BarB(!true)\npublic abstract double test3()
99+
// enclosing_range 27 1 28 16
88100
// kind AbstractMethod
89101

90102
@Nullable(("what"))
@@ -94,6 +106,7 @@ interface Foo {
94106
// ^^^^^ definition semanticdb maven . . minimized/Foo#test4().
95107
// display_name test4
96108
// signature_documentation java @Nullable("what")\npublic abstract Foo test4()
109+
// enclosing_range 30 1 31 13
97110
// kind AbstractMethod
98111

99112
@Bar((double) -1)
@@ -102,13 +115,15 @@ interface Foo {
102115
// ^^^^^^^^ definition semanticdb maven . . minimized/Foo#testCast().
103116
// display_name testCast
104117
// signature_documentation java @Bar((double) -1)\npublic abstract double testCast()
118+
// enclosing_range 33 1 34 19
105119
// kind AbstractMethod
106120
}
107121

108122
interface TestRef {
109123
// ^^^^^^^ definition semanticdb maven . . minimized/TestRef#
110124
// display_name TestRef
111125
// signature_documentation java interface TestRef
126+
// enclosing_range 37 0 40 1
112127
// kind Interface
113128
@BarRef(@SuppressWarnings(value = "unchecked"))
114129
//^^^^^^ reference semanticdb maven . . minimized/BarRef#
@@ -118,5 +133,6 @@ interface TestRef {
118133
// ^^^^^^^^ definition semanticdb maven . . minimized/TestRef#testCase().
119134
// display_name testCase
120135
// signature_documentation java @BarRef(@SuppressWarnings("unchecked"))\npublic abstract double testCase()
136+
// enclosing_range 38 1 39 28
121137
// kind AbstractMethod
122138
}

tests/snapshots/src/main/generated/tests/minimized/src/main/java/minimized/Annotations.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
// ^^^^^^^^^^^ definition semanticdb maven . . minimized/Annotations#
5555
// display_name Annotations
5656
// signature_documentation java @Documented\n@Retention(RetentionPolicy.RUNTIME)\n@Target({CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})\npublic @interface Annotations
57+
// enclosing_range 9 0 24 1
5758
// kind Interface
5859
// relationship is_implementation semanticdb maven jdk 11 java/lang/annotation/Annotation#
5960

@@ -62,12 +63,14 @@
6263
// ^^^^^ definition semanticdb maven . . minimized/Annotations#value().
6364
// display_name value
6465
// signature_documentation java public abstract String value()
66+
// enclosing_range 21 2 28
6567
// kind AbstractMethod
6668

6769
String format() default "";
6870
//^^^^^^ reference semanticdb maven jdk 11 java/lang/String#
6971
// ^^^^^^ definition semanticdb maven . . minimized/Annotations#format().
7072
// display_name format
7173
// signature_documentation java public abstract String format()
74+
// enclosing_range 23 2 29
7275
// kind AbstractMethod
7376
}

0 commit comments

Comments
 (0)