Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,13 @@ object ScipPrinters {
.append(info.getEnclosingSymbol)
.append("\n")
}
if (occ.getEnclosingRangeCount > 0) {
out
.append(prefix)
.append("enclosing_range ")
.append(occ.getEnclosingRangeList.asScala.mkString(" "))
.append("\n")
}
if (info.getKind != Scip.SymbolInformation.Kind.UnspecifiedKind) {
out.append(prefix).append("kind ").append(info.getKind).append("\n")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,11 +179,30 @@ private void processTypedDocument(
occ.getRange().getEndLine(),
occ.getRange().getEndCharacter());
Package pkg = packages.packageForSymbol(occ.getSymbol()).orElse(Package.EMPTY);
tdoc.addOccurrences(
Scip.Occurrence.Builder occBuilder =
Scip.Occurrence.newBuilder()
.addAllRange(range)
.setSymbol(typedSymbol(occ.getSymbol(), pkg))
.setSymbolRoles(role));
.setSymbolRoles(role);
// Add enclosing_range if it exists
if (occ.hasEnclosingRange()) {
Semanticdb.Range enclosingRange = occ.getEnclosingRange();
boolean isEnclosingSingleLine =
enclosingRange.getStartLine() == enclosingRange.getEndLine();
Iterable<Integer> enclosingRangeInts =
isEnclosingSingleLine
? Arrays.asList(
enclosingRange.getStartLine(),
enclosingRange.getStartCharacter(),
enclosingRange.getEndCharacter())
: Arrays.asList(
enclosingRange.getStartLine(),
enclosingRange.getStartCharacter(),
enclosingRange.getEndLine(),
enclosingRange.getEndCharacter());
occBuilder.addAllEnclosingRange(enclosingRangeInts);
}
tdoc.addOccurrences(occBuilder);
}
Symtab symtab = new Symtab(doc.semanticdb);
for (SymbolInformation info : doc.semanticdb.getSymbolsList()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,14 @@ public static Semanticdb.Signature signature(Semanticdb.TypeSignature.Builder si
// SemanticDB Symbols

public static Semanticdb.SymbolOccurrence symbolOccurrence(
String symbol, Semanticdb.Range range, Semanticdb.SymbolOccurrence.Role role) {
return Semanticdb.SymbolOccurrence.newBuilder()
String symbol, Semanticdb.Range range, Semanticdb.SymbolOccurrence.Role role,
java.util.Optional<Semanticdb.Range> enclosingRange) {
Semanticdb.SymbolOccurrence.Builder builder = Semanticdb.SymbolOccurrence.newBuilder()
.setSymbol(symbol)
.setRange(range)
.setRole(role)
.build();
.setRole(role);
enclosingRange.ifPresent(builder::setEnclosingRange);
return builder.build();
}

public static Semanticdb.SymbolInformation.Builder symbolInformation(String symbol) {
Expand Down
4 changes: 4 additions & 0 deletions semanticdb-java/src/main/protobuf/semanticdb.proto
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ message SymbolOccurrence {
Range range = 1;
string symbol = 2;
Role role = 3;
// NOTE: this field does not exist in the upstream SemanticDB spec.
// It is added to support SCIP's enclosing_range field.
// This is the range of the nearest non-trivial enclosing AST node.
optional Range enclosing_range = 4;
}

message Scope {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,18 @@ private Optional<Semanticdb.Range> emitSymbolOccurrence(
Element sym, Tree tree, Name name, Role role, CompilerRange kind) {
if (sym == null || name == null) return Optional.empty();
Optional<Semanticdb.Range> range = semanticdbRange(tree, kind, sym, name.toString());
emitSymbolOccurrence(sym, range, role);
Optional<Semanticdb.Range> enclosingRange = computeEnclosingRange(tree);
emitSymbolOccurrence(sym, range, role, enclosingRange);
if (role == Role.DEFINITION) {
// Only emit SymbolInformation for symbols that are defined in this compilation unit.
emitSymbolInformation(sym, tree);
}
return range;
}

private void emitSymbolOccurrence(Element sym, Optional<Semanticdb.Range> range, Role role) {
private void emitSymbolOccurrence(Element sym, Optional<Semanticdb.Range> range, Role role, Optional<Semanticdb.Range> enclosingRange) {
if (sym == null) return;
Optional<Semanticdb.SymbolOccurrence> occ = semanticdbOccurrence(sym, range, role);
Optional<Semanticdb.SymbolOccurrence> occ = semanticdbOccurrence(sym, range, role, enclosingRange);
occ.ifPresent(occurrences::add);
}

Expand Down Expand Up @@ -298,7 +299,7 @@ private void resolveVariableTree(VariableTree node, TreePath treePath) {
if (sym.getKind() == ElementKind.ENUM_CONSTANT) {
TreePath typeTreePath = nodes.get(node.getInitializer());
Element typeSym = trees.getElement(typeTreePath);
if (typeSym != null) emitSymbolOccurrence(typeSym, range, Role.REFERENCE);
if (typeSym != null) emitSymbolOccurrence(typeSym, range, Role.REFERENCE, Optional.empty());
}
}
}
Expand Down Expand Up @@ -462,11 +463,11 @@ private Semanticdb.Range correctForTabs(Semanticdb.Range range, LineMap lineMap,
}

private Optional<Semanticdb.SymbolOccurrence> semanticdbOccurrence(
Element sym, Optional<Semanticdb.Range> range, Role role) {
Element sym, Optional<Semanticdb.Range> range, Role role, Optional<Semanticdb.Range> enclosingRange) {
if (range.isPresent()) {
String ssym = semanticdbSymbol(sym);
if (!ssym.equals(SemanticdbSymbols.NONE)) {
Semanticdb.SymbolOccurrence occ = symbolOccurrence(ssym, range.get(), role);
Semanticdb.SymbolOccurrence occ = symbolOccurrence(ssym, range.get(), role, enclosingRange);
return Optional.of(occ);
} else {
return Optional.empty();
Expand All @@ -476,6 +477,51 @@ private Optional<Semanticdb.SymbolOccurrence> semanticdbOccurrence(
}
}

/**
* Computes the enclosing range for the given tree node.
* Returns the range of the nearest non-trivial enclosing AST node.
* For definition occurrences, this includes the entire definition including documentation.
* For reference occurrences, this includes the parent expression bounds.
*/
private Optional<Semanticdb.Range> computeEnclosingRange(Tree tree) {
if (tree == null) return Optional.empty();

TreePath path = nodes.get(tree);
if (path == null) return Optional.empty();

// For method, class, and variable definitions, use the tree itself as the enclosing range
// since we're processing the definition node
Tree enclosingTree = tree;
if (!(tree instanceof MethodTree || tree instanceof ClassTree || tree instanceof VariableTree)) {
// For non-definition nodes (like references), use the parent
TreePath parentPath = path.getParentPath();
if (parentPath == null) return Optional.empty();
enclosingTree = parentPath.getLeaf();
if (enclosingTree == null || enclosingTree == compUnitTree) return Optional.empty();
}

SourcePositions sourcePositions = trees.getSourcePositions();
int start = (int) sourcePositions.getStartPosition(compUnitTree, enclosingTree);
int end = (int) sourcePositions.getEndPosition(compUnitTree, enclosingTree);

if (start != Diagnostic.NOPOS && end != Diagnostic.NOPOS && end > start) {
LineMap lineMap = compUnitTree.getLineMap();
Semanticdb.Range range =
Semanticdb.Range.newBuilder()
.setStartLine((int) lineMap.getLineNumber(start) - 1)
.setStartCharacter((int) lineMap.getColumnNumber(start) - 1)
.setEndLine((int) lineMap.getLineNumber(end) - 1)
.setEndCharacter((int) lineMap.getColumnNumber(end) - 1)
.build();

range = correctForTabs(range, lineMap, start);

return Optional.of(range);
}

return Optional.empty();
}

private String semanticdbText() {
if (source != null) return source;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public abstract class AbstractClasses {
// ^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#
// display_name AbstractClasses
// signature_documentation java public abstract class AbstractClasses
// enclosing_range 2 0 8 1
// kind Class
// ^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#`<init>`().
// display_name <init>
Expand All @@ -14,6 +15,7 @@ public String defaultImplementation() {
// ^^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#defaultImplementation().
// display_name defaultImplementation
// signature_documentation java public String defaultImplementation()
// enclosing_range 3 2 5 3
// kind Method
return "";
}
Expand All @@ -23,6 +25,7 @@ public String defaultImplementation() {
// ^^^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#abstractImplementation().
// display_name abstractImplementation
// signature_documentation java public abstract String abstractImplementation()
// enclosing_range 7 2 50
// kind AbstractMethod
// relationship is_reference is_implementation semanticdb maven . . minimized/SubClasses#abstractImplementation().
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,45 @@
// ^^^ definition semanticdb maven . . minimized/Bar#
// display_name Bar
// signature_documentation java @interface Bar
// enclosing_range 2 0 4 1
// kind Interface
// relationship is_implementation semanticdb maven jdk 11 java/lang/annotation/Annotation#
→double value();
// ^^^^^ definition semanticdb maven . . minimized/Bar#value().
// display_name value
// signature_documentation java public abstract double value()
// enclosing_range 3 1 16
// kind AbstractMethod
}

@interface BarB {
// ^^^^ definition semanticdb maven . . minimized/BarB#
// display_name BarB
// signature_documentation java @interface BarB
// enclosing_range 6 0 8 1
// kind Interface
// relationship is_implementation semanticdb maven jdk 11 java/lang/annotation/Annotation#
→boolean value();
// ^^^^^ definition semanticdb maven . . minimized/BarB#value().
// display_name value
// signature_documentation java public abstract boolean value()
// enclosing_range 7 1 17
// kind AbstractMethod
}

@interface Nullable {
// ^^^^^^^^ definition semanticdb maven . . minimized/Nullable#
// display_name Nullable
// signature_documentation java @interface Nullable
// enclosing_range 10 0 12 1
// kind Interface
// relationship is_implementation semanticdb maven jdk 11 java/lang/annotation/Annotation#
→String value() default "";
//^^^^^ reference semanticdb maven jdk 11 java/lang/String#
// ^^^^^ definition semanticdb maven . . minimized/Nullable#value().
// display_name value
// signature_documentation java public abstract String value()
// enclosing_range 11 1 27
// kind AbstractMethod
}

Expand All @@ -45,27 +51,31 @@
// ^^^^^^ definition semanticdb maven . . minimized/BarRef#
// display_name BarRef
// signature_documentation java @interface BarRef
// enclosing_range 15 0 17 1
// kind Interface
// relationship is_implementation semanticdb maven jdk 11 java/lang/annotation/Annotation#
→SuppressWarnings value();
//^^^^^^^^^^^^^^^ reference semanticdb maven jdk 11 java/lang/SuppressWarnings#
// ^^^^^ definition semanticdb maven . . minimized/BarRef#value().
// display_name value
// signature_documentation java public abstract SuppressWarnings value()
// enclosing_range 16 1 26
// kind AbstractMethod
}

interface Foo {
// ^^^ definition semanticdb maven . . minimized/Foo#
// display_name Foo
// signature_documentation java interface Foo
// enclosing_range 19 0 35 1
// kind Interface
→@Bar(-1d)
//^^^ reference semanticdb maven . . minimized/Bar#
→double test();
// ^^^^ definition semanticdb maven . . minimized/Foo#test().
// display_name test
// signature_documentation java @Bar(-1.0)\npublic abstract double test()
// enclosing_range 20 1 21 15
// kind AbstractMethod

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

→@BarB(!true)
Expand All @@ -85,6 +96,7 @@ interface Foo {
// ^^^^^ definition semanticdb maven . . minimized/Foo#test3().
// display_name test3
// signature_documentation java @BarB(!true)\npublic abstract double test3()
// enclosing_range 27 1 28 16
// kind AbstractMethod

→@Nullable(("what"))
Expand All @@ -94,6 +106,7 @@ interface Foo {
// ^^^^^ definition semanticdb maven . . minimized/Foo#test4().
// display_name test4
// signature_documentation java @Nullable("what")\npublic abstract Foo test4()
// enclosing_range 30 1 31 13
// kind AbstractMethod

→@Bar((double) -1)
Expand All @@ -102,13 +115,15 @@ interface Foo {
// ^^^^^^^^ definition semanticdb maven . . minimized/Foo#testCast().
// display_name testCast
// signature_documentation java @Bar((double) -1)\npublic abstract double testCast()
// enclosing_range 33 1 34 19
// kind AbstractMethod
}

interface TestRef {
// ^^^^^^^ definition semanticdb maven . . minimized/TestRef#
// display_name TestRef
// signature_documentation java interface TestRef
// enclosing_range 37 0 40 1
// kind Interface
→@BarRef(@SuppressWarnings(value = "unchecked"))
//^^^^^^ reference semanticdb maven . . minimized/BarRef#
Expand All @@ -118,5 +133,6 @@ interface TestRef {
// ^^^^^^^^ definition semanticdb maven . . minimized/TestRef#testCase().
// display_name testCase
// signature_documentation java @BarRef(@SuppressWarnings("unchecked"))\npublic abstract double testCase()
// enclosing_range 38 1 39 28
// kind AbstractMethod
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
// ^^^^^^^^^^^ definition semanticdb maven . . minimized/Annotations#
// display_name Annotations
// signature_documentation java @Documented\n@Retention(RetentionPolicy.RUNTIME)\n@Target({CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})\npublic @interface Annotations
// enclosing_range 9 0 24 1
// kind Interface
// relationship is_implementation semanticdb maven jdk 11 java/lang/annotation/Annotation#

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

String format() default "";
//^^^^^^ reference semanticdb maven jdk 11 java/lang/String#
// ^^^^^^ definition semanticdb maven . . minimized/Annotations#format().
// display_name format
// signature_documentation java public abstract String format()
// enclosing_range 23 2 29
// kind AbstractMethod
}
Loading