Skip to content
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 MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ maven.install(
artifacts = [
"com.google.protobuf:protobuf-java-util:4.34.2",
"org.projectlombok:lombok:1.18.46",
"org.scip-code:scip-java-bindings:0.8.0",
"org.scip-code:scip-java-bindings:0.9.0",
],
known_contributing_modules = ["protobuf"],
repositories = ["https://repo1.maven.org/maven2"],
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ maven-plugin-api = "3.6.3"
maven-project = "2.2.1"
protobuf = "4.34.2"
protobuf-plugin = "0.10.0"
scip-bindings = "0.8.0"
scip-bindings = "0.9.0"
shadow = "9.4.3"
spotless = "8.7.0"
vanniktech-maven-publish = "0.35.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,20 @@ private Document rewriteDocument(
for (Occurrence occ : shard.getOccurrencesList()) {
Occurrence.Builder rebuilt =
Occurrence.newBuilder()
.addAllRange(occ.getRangeList())
.setSymbol(rewriter.rewrite(occ.getSymbol()))
.setSymbolRoles(occ.getSymbolRoles());
if (occ.getEnclosingRangeCount() > 0) {
rebuilt.addAllEnclosingRange(occ.getEnclosingRangeList());
switch (occ.getTypedRangeCase()) {
case SINGLE_LINE_RANGE -> rebuilt.setSingleLineRange(occ.getSingleLineRange());
case MULTI_LINE_RANGE -> rebuilt.setMultiLineRange(occ.getMultiLineRange());
case TYPEDRANGE_NOT_SET ->
throw new IllegalArgumentException("expected SCIP 0.9 typed occurrence range");
}
switch (occ.getTypedEnclosingRangeCase()) {
case SINGLE_LINE_ENCLOSING_RANGE ->
rebuilt.setSingleLineEnclosingRange(occ.getSingleLineEnclosingRange());
case MULTI_LINE_ENCLOSING_RANGE ->
rebuilt.setMultiLineEnclosingRange(occ.getMultiLineEnclosingRange());
case TYPEDENCLOSINGRANGE_NOT_SET -> {}
}
out.addOccurrences(rebuilt);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.sourcegraph.scip.LocalSymbolsCache;
import com.sourcegraph.scip.ScipDocumentBuilder;
import com.sourcegraph.scip.ScipRange;
import com.sourcegraph.scip.ScipSymbols;
import com.sun.source.tree.AnnotatedTypeTree;
import com.sun.source.tree.ClassTree;
Expand Down Expand Up @@ -182,7 +183,7 @@ private void resolveMethodTree(MethodTree node, TreePath treePath) {
private void resolveVariableTree(VariableTree node, TreePath treePath) {
Element sym = trees.getElement(treePath);
if (sym == null) return;
int[] range =
ScipRange range =
emitDefinition(sym, node, sym.getSimpleName(), CompilerRange.FROM_POINT_WITH_TEXT_SEARCH);
if (sym.getKind() == ElementKind.ENUM_CONSTANT) {
TreePath typeTreePath = nodes.get(node.getInitializer());
Expand Down Expand Up @@ -246,8 +247,8 @@ private void resolveNewClassTree(NewClassTree node, TreePath treePath) {
// =======================================
// Occurrence + SymbolInformation emission
// =======================================
private int[] emitDefinition(Element sym, Tree tree, Name name, CompilerRange kind) {
int[] range = computeRange(tree, kind, sym, name == null ? null : name.toString());
private ScipRange emitDefinition(Element sym, Tree tree, Name name, CompilerRange kind) {
ScipRange range = computeRange(tree, kind, sym, name == null ? null : name.toString());
if (range == null) return null;
emitOccurrence(sym, range, SymbolRole.Definition_VALUE, computeEnclosingRange(tree));
declTrees.put(sym, tree);
Expand All @@ -256,18 +257,26 @@ private int[] emitDefinition(Element sym, Tree tree, Name name, CompilerRange ki
}

private void emitReference(Element sym, Tree tree, Name name, CompilerRange kind) {
int[] range = computeRange(tree, kind, sym, name == null ? null : name.toString());
ScipRange range = computeRange(tree, kind, sym, name == null ? null : name.toString());
if (range == null) return;
emitOccurrence(sym, range, 0 /* reference */, null);
}

private void emitOccurrence(Element sym, int[] range, int role, int[] enclosingRange) {
private void emitOccurrence(Element sym, ScipRange range, int role, ScipRange enclosingRange) {
String symbol = scipSymbol(sym);
if (symbol.isEmpty()) return;
Occurrence.Builder b = Occurrence.newBuilder().setSymbol(symbol).setSymbolRoles(role);
for (int v : range) b.addRange(v);
if (range.isSingleLine()) {
b.setSingleLineRange(range.toSingleLineRange());
} else {
b.setMultiLineRange(range.toMultiLineRange());
}
if (enclosingRange != null) {
for (int v : enclosingRange) b.addEnclosingRange(v);
if (enclosingRange.isSingleLine()) {
b.setSingleLineEnclosingRange(enclosingRange.toSingleLineRange());
} else {
b.setMultiLineEnclosingRange(enclosingRange.toMultiLineRange());
}
}
documentBuilder.addOccurrence(b.build());
}
Expand Down Expand Up @@ -360,7 +369,7 @@ private SymbolInformation.Kind scipKind(Element sym) {
// =======================================
// Source position / range computation
// =======================================
private int[] computeRange(Tree tree, CompilerRange kind, Element sym, String name) {
private ScipRange computeRange(Tree tree, CompilerRange kind, Element sym, String name) {
if (sym == null) return null;
SourcePositions sourcePositions = trees.getSourcePositions();
int start = (int) sourcePositions.getStartPosition(compUnitTree, tree);
Expand Down Expand Up @@ -394,7 +403,7 @@ private int[] computeRange(Tree tree, CompilerRange kind, Element sym, String na
return lineMapRange(start, end);
}

private int[] computeEnclosingRange(Tree tree) {
private ScipRange computeEnclosingRange(Tree tree) {
if (tree == null) return null;
TreePath path = nodes.get(tree);
if (path == null) return null;
Expand All @@ -413,7 +422,7 @@ private int[] computeEnclosingRange(Tree tree) {
return lineMapRange(start, end);
}

private int[] lineMapRange(int start, int end) {
private ScipRange lineMapRange(int start, int end) {
if (start == Diagnostic.NOPOS || end == Diagnostic.NOPOS || end <= start) return null;
LineMap lineMap = compUnitTree.getLineMap();
int startLine = (int) lineMap.getLineNumber(start) - 1;
Expand All @@ -431,8 +440,8 @@ private int[] lineMapRange(int start, int end) {
endChar -= count * 7;
}

if (startLine == endLine) return new int[] {startLine, startChar, endChar};
return new int[] {startLine, startChar, endLine, endChar};
if (startLine == endLine) return ScipRange.singleLine(startLine, startChar, endChar);
return ScipRange.range(startLine, startChar, endLine, endChar);
}

// =======================================
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sourcegraph.scip_kotlinc

import com.sourcegraph.scip.ScipDocumentBuilder
import com.sourcegraph.scip.ScipRange
import com.sourcegraph.scip.ScipShardPaths
import java.nio.file.Path
import java.nio.file.Paths
Expand All @@ -22,7 +23,6 @@ import org.scip_code.scip.Document
import org.scip_code.scip.Occurrence
import org.scip_code.scip.SymbolInformation
import org.scip_code.scip.SymbolRole
import org.scip_code.scip.occurrence
import org.scip_code.scip.relationship
import org.scip_code.scip.signature
import org.scip_code.scip.symbolInformation
Expand Down Expand Up @@ -98,29 +98,36 @@ class ScipTextDocumentBuilder(
element: KtSourceElement,
isDefinition: Boolean,
enclosingSource: KtSourceElement?,
): Occurrence = occurrence {
this.symbol = symbol.toString()
if (isDefinition) symbolRoles = SymbolRole.Definition.number
range += range(element).asIterable()
): Occurrence {
val builder = Occurrence.newBuilder().setSymbol(symbol.toString())
if (isDefinition) builder.setSymbolRoles(SymbolRole.Definition.number)
val range = range(element)
if (range.isSingleLine) builder.singleLineRange = range.toSingleLineRange()
else builder.multiLineRange = range.toMultiLineRange()
if (enclosingSource != null) {
enclosingRange += enclosingRange(enclosingSource).asIterable()
val enclosingRange = enclosingRange(enclosingSource)
if (enclosingRange.isSingleLine) {
builder.singleLineEnclosingRange = enclosingRange.toSingleLineRange()
} else {
builder.multiLineEnclosingRange = enclosingRange.toMultiLineRange()
}
}
return builder.build()
}

private fun range(element: KtSourceElement): IntArray {
private fun range(element: KtSourceElement): ScipRange {
val line = lineMap.lineNumber(element) - 1
val startCol = lineMap.startCharacter(element)
val endCol = lineMap.endCharacter(element)
return intArrayOf(line, startCol, endCol)
return ScipRange.singleLine(line, startCol, endCol)
}

private fun enclosingRange(element: KtSourceElement): IntArray {
private fun enclosingRange(element: KtSourceElement): ScipRange {
val startLine = lineMap.lineNumber(element) - 1
val startCol = lineMap.startCharacter(element)
val endLine = lineMap.lineNumberForOffset(element.endOffset) - 1
val endCol = lineMap.columnForOffset(element.endOffset)
return if (startLine == endLine) intArrayOf(startLine, startCol, endCol)
else intArrayOf(startLine, startCol, endLine, endCol)
return ScipRange.range(startLine, startCol, endLine, endCol)
}

private fun relativePath(): String =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.sourcegraph.scip_kotlinc.test

import com.sourcegraph.scip.ScipRange
import org.scip_code.scip.Occurrence
import org.scip_code.scip.SymbolInformation
import org.scip_code.scip.SymbolRole
import org.scip_code.scip.occurrence
import org.scip_code.scip.relationship
import org.scip_code.scip.signature
import org.scip_code.scip.symbolInformation
Expand Down Expand Up @@ -38,33 +38,38 @@ class ScipRangeBuilder {
var endLine: Int = -1
var endCharacter: Int = 0

internal fun toIntList(): List<Int> {
internal fun toScipRange(): ScipRange {
val line = if (endLine < 0) startLine else endLine
return if (line == startLine) listOf(startLine, startCharacter, endCharacter)
else listOf(startLine, startCharacter, line, endCharacter)
return ScipRange.range(startLine, startCharacter, line, endCharacter)
}
}

@ScipBuilderDsl
class ScipOccurrenceBuilder {
var role: Int = REFERENCE
var symbol: String = ""
private var range: List<Int>? = null
private var enclosingRange: List<Int>? = null
private var range: ScipRange? = null
private var enclosingRange: ScipRange? = null

fun range(block: ScipRangeBuilder.() -> Unit) {
range = ScipRangeBuilder().apply(block).toIntList()
range = ScipRangeBuilder().apply(block).toScipRange()
}

fun enclosingRange(block: ScipRangeBuilder.() -> Unit) {
enclosingRange = ScipRangeBuilder().apply(block).toIntList()
enclosingRange = ScipRangeBuilder().apply(block).toScipRange()
}

internal fun build(): Occurrence = occurrence {
symbol = this@ScipOccurrenceBuilder.symbol
symbolRoles = role
this@ScipOccurrenceBuilder.range?.let { range += it }
this@ScipOccurrenceBuilder.enclosingRange?.let { enclosingRange += it }
internal fun build(): Occurrence {
val builder = Occurrence.newBuilder().setSymbol(symbol).setSymbolRoles(role)
range?.let {
if (it.isSingleLine) builder.singleLineRange = it.toSingleLineRange()
else builder.multiLineRange = it.toMultiLineRange()
}
enclosingRange?.let {
if (it.isSingleLine) builder.singleLineEnclosingRange = it.toSingleLineRange()
else builder.multiLineEnclosingRange = it.toMultiLineRange()
}
return builder.build()
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.sourcegraph.scip;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
Expand All @@ -21,8 +20,8 @@
*/
public final class ScipDocumentBuilder {
private static final Comparator<Occurrence> OCCURRENCE_ORDER =
Comparator.<Occurrence>comparingInt(o -> rangeStartLine(o))
.thenComparingInt(o -> rangeStartCharacter(o));
Comparator.<Occurrence>comparingInt(o -> ScipRange.from(o).startLine())
.thenComparingInt(o -> ScipRange.from(o).startCharacter());

private final Map<OccurrenceKey, Occurrence> occurrences = new LinkedHashMap<>();
private final Map<String, SymbolInformation> symbols = new LinkedHashMap<>();
Expand All @@ -49,21 +48,13 @@ public Document build(String language, String relativePath, String text) {
.build();
}

private static int rangeStartLine(Occurrence occurrence) {
return occurrence.getRangeCount() > 0 ? occurrence.getRange(0) : 0;
}

private static int rangeStartCharacter(Occurrence occurrence) {
return occurrence.getRangeCount() > 1 ? occurrence.getRange(1) : 0;
}

private static final class OccurrenceKey {
private final List<Integer> range;
private final ScipRange range;
private final String symbol;
private final int roles;

OccurrenceKey(Occurrence occurrence) {
this.range = Collections.unmodifiableList(new ArrayList<>(occurrence.getRangeList()));
this.range = ScipRange.from(occurrence);
this.symbol = occurrence.getSymbol();
this.roles = occurrence.getSymbolRoles();
}
Expand Down
65 changes: 65 additions & 0 deletions scip-shared/src/main/java/com/sourcegraph/scip/ScipRange.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.sourcegraph.scip;

import org.scip_code.scip.MultiLineRange;
import org.scip_code.scip.Occurrence;
import org.scip_code.scip.SingleLineRange;

/** A normalized source range that can be serialized to SCIP's typed range oneofs. */
public record ScipRange(int startLine, int startCharacter, int endLine, int endCharacter) {

public static ScipRange singleLine(int line, int startCharacter, int endCharacter) {
return new ScipRange(line, startCharacter, line, endCharacter);
}

public static ScipRange range(int startLine, int startCharacter, int endLine, int endCharacter) {
return new ScipRange(startLine, startCharacter, endLine, endCharacter);
}

public static ScipRange from(Occurrence occurrence) {
switch (occurrence.getTypedRangeCase()) {
case SINGLE_LINE_RANGE:
return from(occurrence.getSingleLineRange());
case MULTI_LINE_RANGE:
return from(occurrence.getMultiLineRange());
case TYPEDRANGE_NOT_SET:
throw new IllegalArgumentException("expected SCIP 0.9 typed occurrence range");
}
throw new IllegalArgumentException("expected SCIP 0.9 typed occurrence range");
}

private static ScipRange from(SingleLineRange range) {
return new ScipRange(
range.getLine(), range.getStartCharacter(), range.getLine(), range.getEndCharacter());
}

private static ScipRange from(MultiLineRange range) {
return new ScipRange(
range.getStartLine(),
range.getStartCharacter(),
range.getEndLine(),
range.getEndCharacter());
}

public boolean isSingleLine() {
return startLine == endLine;
}

public SingleLineRange toSingleLineRange() {
if (!isSingleLine()) throw new IllegalStateException("expected single-line range");
return SingleLineRange.newBuilder()
.setLine(startLine)
.setStartCharacter(startCharacter)
.setEndCharacter(endCharacter)
.build();
}

public MultiLineRange toMultiLineRange() {
if (isSingleLine()) throw new IllegalStateException("expected multi-line range");
return MultiLineRange.newBuilder()
.setStartLine(startLine)
.setStartCharacter(startCharacter)
.setEndLine(endLine)
.setEndCharacter(endCharacter)
.build();
}
}
Loading