Skip to content

Commit f36c68a

Browse files
authored
Merge pull request #566 from sourcegraph/olafurpg/reference-bijection
Emit inverse relationships
2 parents b847cd1 + ef1e175 commit f36c68a

29 files changed

+276
-6
lines changed

scip-java/src/main/scala/com/sourcegraph/scip_java/commands/IndexSemanticdbCommand.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ final case class IndexSemanticdbCommand(
3636
@Description(
3737
"Whether to infer the location of SemanticDB files based as produced by Bazel"
3838
) bazel: Boolean = true,
39+
@Description(
40+
"Whether to emit parent->child relationships for 'Find references' and 'Find implementations'. " +
41+
"This flag exists as a workaround for the issue https://github.com/sourcegraph/sourcegraph/issues/50927"
42+
) emitInverseRelationships: Boolean = true,
3943
@Description("URL to a PackageHub instance")
4044
@Hidden
4145
packagehub: Option[String] = None,
@@ -85,7 +89,8 @@ final case class IndexSemanticdbCommand(
8589
format,
8690
parallel,
8791
packages.map(_.toPackageInformation).asJava,
88-
buildKind
92+
buildKind,
93+
emitInverseRelationships
8994
)
9095
ScipSemanticdb.run(options)
9196
postPackages(packages)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import java.nio.file.Files;
99
import java.nio.file.Path;
1010
import java.nio.file.PathMatcher;
11-
import java.sql.Array;
1211
import java.util.*;
1312
import java.util.stream.Collectors;
1413
import java.util.stream.Stream;
@@ -48,7 +47,8 @@ public void error(Throwable e) {
4847
ScipOutputFormat.TYPED_PROTOBUF,
4948
options.parallel,
5049
mavenPackages,
51-
"");
50+
"",
51+
true);
5252
ScipSemanticdb.run(scipOptions);
5353
if (!scipOptions.reporter.hasErrors()) {
5454
System.out.println("done: " + scipOptions.output);

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

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ private void run() throws IOException {
6565

6666
private void runTyped(List<Path> files, PackageTable packages) {
6767
writer.emitTyped(typedMetadata());
68-
filesStream(files).forEach(document -> processTypedDocument(document, packages));
68+
InverseReferenceRelationships references = inverseReferenceRelationships(files);
69+
filesStream(files).forEach(document -> processTypedDocument(document, packages, references));
6970
}
7071

7172
private String typedSymbol(String symbol, Package pkg) {
@@ -82,7 +83,8 @@ public static boolean isDefinitionRole(Role role) {
8283
return role == Role.DEFINITION || role == Role.SYNTHETIC_DEFINITION;
8384
}
8485

85-
private void processTypedDocument(Path path, PackageTable packages) {
86+
private void processTypedDocument(
87+
Path path, PackageTable packages, InverseReferenceRelationships references) {
8688
for (ScipTextDocument doc : parseTextDocument(path).collect(Collectors.toList())) {
8789
if (doc.semanticdb.getOccurrencesCount() == 0) {
8890
continue;
@@ -130,6 +132,19 @@ private void processTypedDocument(Path path, PackageTable packages) {
130132
Scip.SymbolInformation.Builder scipInfo =
131133
Scip.SymbolInformation.newBuilder().setSymbol(typedSymbol(info.getSymbol(), pkg));
132134

135+
// TODO: this can be removed once https://github.com/sourcegraph/sourcegraph/issues/50927 is
136+
// fixed.
137+
ArrayList<String> inverseReferences = references.map.get(info.getSymbol());
138+
if (inverseReferences != null) {
139+
for (String inverseReference : inverseReferences) {
140+
scipInfo.addRelationships(
141+
Scip.Relationship.newBuilder()
142+
.setSymbol(inverseReference)
143+
.setIsImplementation(true)
144+
.setIsReference(true));
145+
}
146+
}
147+
133148
for (int i = 0; i < info.getDefinitionRelationshipsCount(); i++) {
134149
String definitionSymbol = info.getDefinitionRelationships(i);
135150
if (definitionSymbol.isEmpty()) {
@@ -245,6 +260,50 @@ private Stream<Path> filesStream(List<Path> files) {
245260
return options.parallel ? files.parallelStream() : files.stream();
246261
}
247262

263+
private static class InverseReferenceRelationships {
264+
public final Map<String, ArrayList<String>> map;
265+
266+
private InverseReferenceRelationships(Map<String, ArrayList<String>> map) {
267+
this.map = map;
268+
}
269+
}
270+
271+
private InverseReferenceRelationships inverseReferenceRelationships(List<Path> files) {
272+
if (!options.emitInverseRelationships) {
273+
return new InverseReferenceRelationships(Collections.emptyMap());
274+
}
275+
return new InverseReferenceRelationships(
276+
filesStream(files)
277+
.flatMap(this::parseTextDocument)
278+
.flatMap(this::referenceRelationships)
279+
.collect(
280+
Collectors.groupingBy(
281+
SymbolRelationship::getTo,
282+
Collectors.mapping(
283+
SymbolRelationship::getFrom, Collectors.toCollection(ArrayList::new)))));
284+
}
285+
286+
private Stream<SymbolRelationship> referenceRelationships(ScipTextDocument document) {
287+
ArrayList<SymbolRelationship> relationships = new ArrayList<>();
288+
for (int i = 0; i < document.semanticdb.getSymbolsCount(); i++) {
289+
SymbolInformation info = document.semanticdb.getSymbols(i);
290+
if (!supportsReferenceRelationship(info)) {
291+
continue;
292+
}
293+
if (info.getSymbol().isEmpty() || SemanticdbSymbols.isLocal(info.getSymbol())) {
294+
continue;
295+
}
296+
for (int j = 0; j < info.getOverriddenSymbolsCount(); j++) {
297+
String overriddenSymbol = info.getOverriddenSymbols(j);
298+
if (SemanticdbSymbols.isLocal(overriddenSymbol)) {
299+
continue;
300+
}
301+
relationships.add(new SymbolRelationship(info.getSymbol(), overriddenSymbol));
302+
}
303+
}
304+
return relationships.stream();
305+
}
306+
248307
private Set<String> exportSymbols(List<Path> files) {
249308
return filesStream(files)
250309
.flatMap(this::parseTextDocument)

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class ScipSemanticdbOptions {
1717
public final boolean parallel;
1818
public final List<MavenPackage> packages;
1919
public final String buildKind;
20+
public final boolean emitInverseRelationships;
2021

2122
public ScipSemanticdbOptions(
2223
List<Path> targetroots,
@@ -28,7 +29,8 @@ public ScipSemanticdbOptions(
2829
ScipOutputFormat format,
2930
boolean parallel,
3031
List<MavenPackage> packages,
31-
String buildKind) {
32+
String buildKind,
33+
boolean emitInverseRelationships) {
3234
this.targetroots = targetroots;
3335
this.output = output;
3436
this.sourceroot = sourceroot;
@@ -39,5 +41,6 @@ public ScipSemanticdbOptions(
3941
this.parallel = parallel;
4042
this.packages = packages;
4143
this.buildKind = buildKind;
44+
this.emitInverseRelationships = emitInverseRelationships;
4245
}
4346
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.sourcegraph.scip_semanticdb;
2+
3+
public class SymbolRelationship {
4+
public final String from;
5+
public final String to;
6+
7+
public SymbolRelationship(String from, String to) {
8+
this.from = from;
9+
this.to = to;
10+
}
11+
12+
public String getFrom() {
13+
return from;
14+
}
15+
16+
public String getTo() {
17+
return to;
18+
}
19+
}

tests/snapshots/src/main/generated/ByteParser.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ abstract class ByteParser[J] extends upickle.core.BufferingByteParser{
107107
protected[this] def close(): Unit
108108
// ^^^^^ definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/ByteParser#close().
109109
// documentation ```scala\ndef close(): Unit\n```
110+
// relationship is_reference is_implementation ujson/ByteArrayParser#close().
111+
// relationship is_reference is_implementation ujson/ByteBufferParser#close().
112+
// relationship is_reference is_implementation ujson/InputStreamParser#close().
110113
// ^^^^ reference semanticdb maven maven/org.scala-lang/scala-library 2.13.10 scala/Unit#
111114

112115
/**

tests/snapshots/src/main/generated/CharParser.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ abstract class CharParser[J] extends upickle.core.BufferingCharParser{
107107
protected[this] def close(): Unit
108108
// ^^^^^ definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/CharParser#close().
109109
// documentation ```scala\ndef close(): Unit\n```
110+
// relationship is_reference is_implementation ujson/CharSequenceParser#close().
111+
// relationship is_reference is_implementation ujson/StringParser#close().
110112
// ^^^^ reference semanticdb maven maven/org.scala-lang/scala-library 2.13.10 scala/Unit#
111113

112114
/**

tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyDiffer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ interface ResultCallback {
6060
void onResult(@NonNull DiffResult result);
6161
// ^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/AsyncEpoxyDiffer#ResultCallback#onResult().
6262
// documentation ```java\npublic abstract void onResult(DiffResult result)\n```
63+
// relationship is_reference is_implementation com/airbnb/epoxy/EpoxyControllerAdapter#onResult().
6364
// ^^^^^^^ reference semanticdb maven maven/androidx.annotation/annotation 1.1.0 androidx/annotation/NonNull#
6465
// ^^^^^^^^^^ reference semanticdb maven . . com/airbnb/epoxy/DiffResult#
6566
// ^^^^^^ definition local 0

0 commit comments

Comments
 (0)