Skip to content

Commit b847cd1

Browse files
authored
Add is_reference relationships between synthetic case class symbols (#561)
* Add `is_reference` relationships between synthetic case class symbols Previously, doing "Find references" on a synthetic case class symbol (for example, named parameter of a `copy` method) then it only showed usages of that symbol and the non-synthetic symbol (for example, the case class field that matches the `copy` parameter). It didn't return usages of other synthetic symbols that also relate to the case class field (for example, the `apply` parameter). This PR fixes the issue by adding `is_reference` relationships between all synthetic symbols that relate to the same non-synthetic symbol. * Always upload SCIP to Sourcegraph Previously, it only ran `src code-intel upload` on git tags and master branch. * Add explicit JSR 305 dependency for Bazel build Needed to use `Nullable` annotation
1 parent 8964623 commit b847cd1

20 files changed

+497
-11
lines changed

.github/workflows/sourcegraph.yml

+2-4
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ jobs:
1717

1818
- uses: actions/setup-java@v3
1919
with:
20-
distribution: 'temurin'
20+
distribution: "temurin"
2121
java-version: 8
22-
cache: 'sbt'
22+
cache: "sbt"
2323

2424
- name: Publish CLI locally
2525
run: sbt publishLocal dumpScipJavaVersion
@@ -35,11 +35,9 @@ jobs:
3535
if-no-files-found: error
3636

3737
- name: Install src
38-
if: startsWith(github.ref, 'refs/tags/v') || (github.ref == 'refs/heads/main')
3938
run: yarn global add @sourcegraph/src
4039

4140
- name: Upload sourcegraph data
42-
if: startsWith(github.ref, 'refs/tags/v') || (github.ref == 'refs/heads/main')
4341
run: sbt -Dscip-java-version=$(cat VERSION) sourcegraphUpload
4442
env:
4543
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

scip-semanticdb/BUILD

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ java_library(
2121
"//scip-java-proto/src/main/protobuf:scip_java_proto",
2222
"//semanticdb-java",
2323
"//semanticdb-java/src/main/protobuf:semanticdb_java_proto",
24+
"@maven//:com_google_code_findbugs_jsr305",
2425
"@maven//:com_google_protobuf_protobuf_java",
2526
"@maven//:com_google_protobuf_protobuf_java_util",
2627
],

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

+42-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.sourcegraph.semanticdb_javac.SemanticdbSymbols;
1010
import com.sourcegraph.Scip;
1111

12+
import javax.annotation.Nullable;
1213
import java.io.IOException;
1314
import java.net.URI;
1415
import java.nio.file.*;
@@ -126,7 +127,7 @@ private void processTypedDocument(Path path, PackageTable packages) {
126127
continue;
127128
}
128129
Package pkg = packages.packageForSymbol(info.getSymbol()).orElse(Package.EMPTY);
129-
Scip.SymbolInformation.Builder tinfo =
130+
Scip.SymbolInformation.Builder scipInfo =
130131
Scip.SymbolInformation.newBuilder().setSymbol(typedSymbol(info.getSymbol(), pkg));
131132

132133
for (int i = 0; i < info.getDefinitionRelationshipsCount(); i++) {
@@ -137,15 +138,23 @@ private void processTypedDocument(Path path, PackageTable packages) {
137138
Package definitionSymbolPkg =
138139
packages.packageForSymbol(definitionSymbol).orElse(Package.EMPTY);
139140
SymbolInformation definitionInfo = symtab.symbols.get(definitionSymbol);
140-
tinfo.addRelationships(
141+
142+
scipInfo.addRelationships(
141143
Scip.Relationship.newBuilder()
142144
.setSymbol(typedSymbol(definitionSymbol, definitionSymbolPkg))
143145
.setIsDefinition(true)
144146
.setIsReference(
145147
definitionInfo != null
146148
&& definitionInfo.getDisplayName().equals(info.getDisplayName())
147149
&& supportsReferenceRelationship(info)));
150+
151+
addReferenceRelationships(
152+
symtab, info, scipInfo, doc.definitionCliques.get(definitionSymbol), packages);
148153
}
154+
155+
addReferenceRelationships(
156+
symtab, info, scipInfo, doc.definitionCliques.get(info.getSymbol()), packages);
157+
149158
for (int i = 0; i < info.getOverriddenSymbolsCount(); i++) {
150159
String overriddenSymbol = info.getOverriddenSymbols(i);
151160
if (overriddenSymbol.isEmpty()) {
@@ -156,7 +165,7 @@ private void processTypedDocument(Path path, PackageTable packages) {
156165
}
157166
Package overriddenSymbolPkg =
158167
packages.packageForSymbol(overriddenSymbol).orElse(Package.EMPTY);
159-
tinfo.addRelationships(
168+
scipInfo.addRelationships(
160169
Scip.Relationship.newBuilder()
161170
.setSymbol(typedSymbol(overriddenSymbol, overriddenSymbolPkg))
162171
.setIsImplementation(true)
@@ -166,18 +175,45 @@ private void processTypedDocument(Path path, PackageTable packages) {
166175
String language =
167176
doc.semanticdb.getLanguage().toString().toLowerCase(Locale.ROOT).intern();
168177
String signature = new SignatureFormatter(info, symtab).formatSymbol();
169-
tinfo.addDocumentation("```" + language + "\n" + signature + "\n```");
178+
scipInfo.addDocumentation("```" + language + "\n" + signature + "\n```");
170179
}
171180
String documentation = info.getDocumentation().getMessage();
172181
if (!documentation.isEmpty()) {
173-
tinfo.addDocumentation(documentation);
182+
scipInfo.addDocumentation(documentation);
174183
}
175-
tdoc.addSymbols(tinfo);
184+
tdoc.addSymbols(scipInfo);
176185
}
177186
writer.emitTyped(Scip.Index.newBuilder().addDocuments(tdoc).build());
178187
}
179188
}
180189

190+
private void addReferenceRelationships(
191+
Symtab symtab,
192+
SymbolInformation info,
193+
Scip.SymbolInformation.Builder scipInfo,
194+
@Nullable ArrayList<String> clique,
195+
PackageTable packages) {
196+
if (clique == null) {
197+
return;
198+
}
199+
for (String symbol : clique) {
200+
if (symbol.equals(info.getSymbol())) {
201+
continue;
202+
}
203+
SymbolInformation otherInfo = symtab.symbols.get(symbol);
204+
if (otherInfo == null) {
205+
continue;
206+
}
207+
if (!symbol.endsWith(".apply().")
208+
&& !otherInfo.getDisplayName().equals(info.getDisplayName())) {
209+
continue;
210+
}
211+
Package pkg = packages.packageForSymbol(symbol).orElse(Package.EMPTY);
212+
scipInfo.addRelationships(
213+
Scip.Relationship.newBuilder().setSymbol(typedSymbol(symbol, pkg)).setIsReference(true));
214+
}
215+
}
216+
181217
private Scip.Index typedMetadata() {
182218
return Scip.Index.newBuilder()
183219
.setMetadata(

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

+14-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ public class ScipTextDocument {
1313
public int id;
1414
public final Map<String, Semanticdb.SymbolInformation> symbols;
1515
public final Map<String, ResultIds> localSymbols;
16+
// Map from symbols that have a definition occurrence to the list of symbols that have
17+
// `is_definition` relationships to that symbol.
18+
// This map is used to add `is_reference` relationships between all symbols in the list so that
19+
// doing "Find references"
20+
// on any of those symbols returns occurrences for all of the symbols in the "clique" (per
21+
// https://en.wikipedia.org/wiki/Clique_(graph_theory)).
22+
// See https://github.com/sourcegraph/sourcegraph/issues/50927 for more details.
23+
public final Map<String, ArrayList<String>> definitionCliques = new HashMap<>();
1624

1725
public ScipTextDocument(
1826
Path semanticdbPath, Semanticdb.TextDocument semanticdb, Path sourceroot) {
@@ -79,7 +87,7 @@ private void setSemanticdb(Semanticdb.TextDocument semanticdb) {
7987
}
8088
}
8189

82-
public static Semanticdb.TextDocument manifestOccurrencesForSyntheticSymbols(
90+
public Semanticdb.TextDocument manifestOccurrencesForSyntheticSymbols(
8391
Semanticdb.TextDocument semanticdb) {
8492
if (semanticdb.getLanguage() != Semanticdb.Language.SCALA) {
8593
// It's only semanticdb-scalac that emits SymbolInformation for symbols that have no
@@ -98,13 +106,18 @@ public static Semanticdb.TextDocument manifestOccurrencesForSyntheticSymbols(
98106
Semanticdb.SymbolInformation.Builder newInfo = Semanticdb.SymbolInformation.newBuilder(info);
99107
Semanticdb.SymbolOccurrence definition = definitionOccurrences.get(info.getSymbol());
100108
if (definition != null) {
109+
// This symbol has a definition so it doesn't need an is_definition relationship.
101110
builder.addSymbols(newInfo);
102111
continue;
103112
}
104113
for (Semanticdb.SymbolOccurrence alternativeSymbol : alternativeSymbols(info)) {
105114
Semanticdb.SymbolOccurrence alternativeDefinition =
106115
definitionOccurrences.get(alternativeSymbol.getSymbol());
107116
if (alternativeDefinition != null) {
117+
ArrayList<String> clique =
118+
this.definitionCliques.computeIfAbsent(
119+
alternativeSymbol.getSymbol(), k -> new ArrayList<>());
120+
clique.add(info.getSymbol());
108121
newInfo.addDefinitionRelationships(alternativeDefinition.getSymbol());
109122
break;
110123
}

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

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import upickle.core.{ArrVisitor, ObjVisitor}
2424
class BaseByteRenderer[T <: upickle.core.ByteOps.Output]
2525
// ^^^^^^^^^^^^^^^^ definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#
2626
// documentation ```scala\nclass BaseByteRenderer[T <: Output]\n```
27+
// relationship is_reference semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer.
2728
// ________________ synthetic_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer.
2829
// documentation ```scala\nobject BaseByteRenderer\n```
2930
// relationship is_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#
@@ -36,20 +37,23 @@ class BaseByteRenderer[T <: upickle.core.ByteOps.Output]
3637
(out: T,
3738
// ^^^ definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#out.
3839
// documentation ```scala\nprivate[this] val out: T\n```
40+
// relationship is_reference semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#`<init>`().(out)
3941
// ___ synthetic_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#`<init>`().(out)
4042
// documentation ```scala\nout: T \n```
4143
// relationship is_reference is_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#out.
4244
// ^ reference semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#[T]
4345
indent: Int = -1,
4446
// ^^^^^^ definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#indent.
4547
// documentation ```scala\nprivate[this] val indent: Int\n```
48+
// relationship is_reference semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#`<init>`().(indent)
4649
// ______ synthetic_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#`<init>`().(indent)
4750
// documentation ```scala\ndefault indent: Int \n```
4851
// relationship is_reference is_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#indent.
4952
// ^^^ reference semanticdb maven maven/org.scala-lang/scala-library 2.13.10 scala/Int#
5053
escapeUnicode: Boolean = false) extends JsVisitor[T, T]{
5154
// ^^^^^^^^^^^^^ definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#escapeUnicode.
5255
// documentation ```scala\nprivate[this] val escapeUnicode: Boolean\n```
56+
// relationship is_reference semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#`<init>`().(escapeUnicode)
5357
// _____________ synthetic_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#`<init>`().(escapeUnicode)
5458
// documentation ```scala\ndefault escapeUnicode: Boolean \n```
5559
// relationship is_reference is_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseByteRenderer#escapeUnicode.

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

+4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import upickle.core.{ArrVisitor, ObjVisitor}
2424
class BaseCharRenderer[T <: upickle.core.CharOps.Output]
2525
// ^^^^^^^^^^^^^^^^ definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#
2626
// documentation ```scala\nclass BaseCharRenderer[T <: Output]\n```
27+
// relationship is_reference semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer.
2728
// ________________ synthetic_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer.
2829
// documentation ```scala\nobject BaseCharRenderer\n```
2930
// relationship is_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#
@@ -36,20 +37,23 @@ class BaseCharRenderer[T <: upickle.core.CharOps.Output]
3637
(out: T,
3738
// ^^^ definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#out.
3839
// documentation ```scala\nprivate[this] val out: T\n```
40+
// relationship is_reference semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#`<init>`().(out)
3941
// ___ synthetic_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#`<init>`().(out)
4042
// documentation ```scala\nout: T \n```
4143
// relationship is_reference is_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#out.
4244
// ^ reference semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#[T]
4345
indent: Int = -1,
4446
// ^^^^^^ definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#indent.
4547
// documentation ```scala\nprivate[this] val indent: Int\n```
48+
// relationship is_reference semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#`<init>`().(indent)
4649
// ______ synthetic_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#`<init>`().(indent)
4750
// documentation ```scala\ndefault indent: Int \n```
4851
// relationship is_reference is_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#indent.
4952
// ^^^ reference semanticdb maven maven/org.scala-lang/scala-library 2.13.10 scala/Int#
5053
escapeUnicode: Boolean = false) extends JsVisitor[T, T]{
5154
// ^^^^^^^^^^^^^ definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#escapeUnicode.
5255
// documentation ```scala\nprivate[this] val escapeUnicode: Boolean\n```
56+
// relationship is_reference semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#`<init>`().(escapeUnicode)
5357
// _____________ synthetic_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#`<init>`().(escapeUnicode)
5458
// documentation ```scala\ndefault escapeUnicode: Boolean \n```
5559
// relationship is_reference is_definition semanticdb maven maven/com.lihaoyi/ujson_2.13 1.4.0 ujson/BaseCharRenderer#escapeUnicode.

tests/snapshots/src/main/generated/tests/minimized-scala/src/main/scala/minimized/Issue396.scala

+15
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,52 @@ package minimized
44
case class Issue396(a: Int)
55
// ^^^^^^^^ definition semanticdb maven . . minimized/Issue396#
66
// documentation ```scala\ncase class Issue396(a: Int)\n```
7+
// relationship is_reference semanticdb maven . . minimized/Issue396.
8+
// relationship is_reference semanticdb maven . . minimized/Issue396.apply().
79
// ________ synthetic_definition semanticdb maven . . minimized/Issue396#copy().
810
// documentation ```scala\ndef copy(a: Int): Issue396\n```
911
// relationship is_definition semanticdb maven . . minimized/Issue396#
12+
// relationship is_reference semanticdb maven . . minimized/Issue396.apply().
1013
// ________ synthetic_definition semanticdb maven . . minimized/Issue396#productElement().
1114
// documentation ```scala\ndef productElement(x$1: Int): Any\n```
1215
// relationship is_definition semanticdb maven . . minimized/Issue396#
16+
// relationship is_reference semanticdb maven . . minimized/Issue396.apply().
1317
// relationship is_reference is_implementation semanticdb maven . . scala/Product#productElement().
1418
// ________ synthetic_definition semanticdb maven . . minimized/Issue396.
1519
// documentation ```scala\nobject Issue396\n```
1620
// relationship is_definition semanticdb maven . . minimized/Issue396#
21+
// relationship is_reference semanticdb maven . . minimized/Issue396.apply().
1722
// ________ synthetic_definition semanticdb maven . . minimized/Issue396.apply().
1823
// documentation ```scala\ndef apply(a: Int): Issue396\n```
1924
// relationship is_definition semanticdb maven . . minimized/Issue396#
2025
// relationship is_reference is_implementation semanticdb maven . . scala/Function1#apply().
2126
// ________ synthetic_definition semanticdb maven . . minimized/Issue396#productElementName().
2227
// documentation ```scala\ndef productElementName(x$1: Int): String\n```
2328
// relationship is_definition semanticdb maven . . minimized/Issue396#
29+
// relationship is_reference semanticdb maven . . minimized/Issue396.apply().
2430
// relationship is_reference is_implementation semanticdb maven . . scala/Product#productElementName().
2531
// ^ definition semanticdb maven . . minimized/Issue396#`<init>`().
2632
// documentation ```scala\ndef this(a: Int)\n```
2733
// ^ definition semanticdb maven . . minimized/Issue396#a.
2834
// documentation ```scala\nval a: Int\n```
35+
// relationship is_reference semanticdb maven . . minimized/Issue396#`<init>`().(a)
36+
// relationship is_reference semanticdb maven . . minimized/Issue396#copy().(a)
37+
// relationship is_reference semanticdb maven . . minimized/Issue396.apply().(a)
2938
// _ synthetic_definition semanticdb maven . . minimized/Issue396.apply().(a)
3039
// documentation ```scala\na: Int \n```
40+
// relationship is_reference semanticdb maven . . minimized/Issue396#`<init>`().(a)
3141
// relationship is_reference is_definition semanticdb maven . . minimized/Issue396#a.
42+
// relationship is_reference semanticdb maven . . minimized/Issue396#copy().(a)
3243
// _ synthetic_definition semanticdb maven . . minimized/Issue396#`<init>`().(a)
3344
// documentation ```scala\na: Int \n```
3445
// relationship is_reference is_definition semanticdb maven . . minimized/Issue396#a.
46+
// relationship is_reference semanticdb maven . . minimized/Issue396#copy().(a)
47+
// relationship is_reference semanticdb maven . . minimized/Issue396.apply().(a)
3548
// _ synthetic_definition semanticdb maven . . minimized/Issue396#copy().(a)
3649
// documentation ```scala\ndefault a: Int \n```
50+
// relationship is_reference semanticdb maven . . minimized/Issue396#`<init>`().(a)
3751
// relationship is_reference is_definition semanticdb maven . . minimized/Issue396#a.
52+
// relationship is_reference semanticdb maven . . minimized/Issue396.apply().(a)
3853
// ^^^ reference semanticdb maven . . scala/Int#
3954
object Issue396App {
4055
// ^^^^^^^^^^^ definition semanticdb maven . . minimized/Issue396App.

0 commit comments

Comments
 (0)