Skip to content

Commit 8681738

Browse files
authored
Merge pull request #342 from olafurpg/synthetics
2 parents 6aeae65 + 98671e8 commit 8681738

File tree

19 files changed

+437
-23
lines changed

19 files changed

+437
-23
lines changed

build.sbt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ lazy val minimizedScala = project
313313
.in(file("tests/minimized-scala"))
314314
.settings(
315315
(publish / skip) := true,
316-
semanticdbOptions ++= List("-P:semanticdb:text:on")
316+
semanticdbOptions ++=
317+
List("-P:semanticdb:text:on", "-P:semanticdb:synthetics:on")
317318
)
318319
.dependsOn(minimized)
319320

lsif-java/src/main/scala/com/sourcegraph/lsif_java/SemanticdbPrinters.scala

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.sourcegraph.lsif_java
33
import scala.jdk.CollectionConverters._
44

55
import com.sourcegraph.lsif_java.commands.CommentSyntax
6+
import com.sourcegraph.lsif_semanticdb.LsifTextDocument
67
import com.sourcegraph.lsif_semanticdb.SignatureFormatter
78
import com.sourcegraph.lsif_semanticdb.Symtab
89
import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolOccurrence
@@ -14,8 +15,8 @@ object SemanticdbPrinters {
1415
doc: TextDocument,
1516
comments: CommentSyntax = CommentSyntax.default
1617
): String = {
17-
val occurrencesByLine = doc
18-
.getOccurrencesList
18+
val occurrencesByLine = LsifTextDocument
19+
.sortedSymbolOccurrences(doc)
1920
.asScala
2021
.groupBy(_.getRange.getStartLine)
2122
val out = new StringBuilder()
@@ -80,13 +81,7 @@ object SemanticdbPrinters {
8081
.append(occ.getSymbol)
8182
.append(
8283
if (isMultiline)
83-
" "
84-
else
85-
""
86-
)
87-
.append(
88-
if (isMultiline)
89-
s"${r.getEndLine - r.getStartLine}:${r.getEndCharacter}"
84+
s" ${r.getEndLine - r.getStartLine}:${r.getEndCharacter}"
9085
else
9186
""
9287
)
@@ -102,7 +97,10 @@ object SemanticdbPrinters {
10297
""
10398
}
10499
)
105-
.append("\n")
100+
while (out.last == ' ') { // Trim trailing whitespace
101+
out.setLength(out.length() - 1)
102+
}
103+
out.append("\n")
106104
}
107105

108106
}

lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/LsifSemanticdb.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolOccurrence;
88
import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolOccurrence.Role;
99
import com.sourcegraph.semanticdb_javac.SemanticdbSymbols;
10+
1011
import java.io.IOException;
1112
import java.nio.file.Files;
1213
import java.nio.file.Path;
@@ -189,9 +190,7 @@ private Integer processDocumentUnsafe(
189190

190191
private Stream<LsifTextDocument> parseTextDocument(Path semanticdbPath) {
191192
try {
192-
CodedInputStream in = CodedInputStream.newInstance(Files.readAllBytes(semanticdbPath));
193-
in.setRecursionLimit(1000);
194-
return Semanticdb.TextDocuments.parseFrom(in).getDocumentsList().stream()
193+
return textDocumentsParseFrom(semanticdbPath).getDocumentsList().stream()
195194
.filter(sdb -> !sdb.getOccurrencesList().isEmpty())
196195
.map(sdb -> new LsifTextDocument(semanticdbPath, sdb, options.sourceroot));
197196
} catch (IOException e) {
@@ -200,4 +199,19 @@ private Stream<LsifTextDocument> parseTextDocument(Path semanticdbPath) {
200199
return Stream.empty();
201200
}
202201
}
202+
203+
private Semanticdb.TextDocuments textDocumentsParseFrom(Path semanticdbPath) throws IOException {
204+
byte[] bytes = Files.readAllBytes(semanticdbPath);
205+
try {
206+
CodedInputStream in = CodedInputStream.newInstance(bytes);
207+
in.setRecursionLimit(1000);
208+
return Semanticdb.TextDocuments.parseFrom(in);
209+
} catch (NoSuchMethodError ignored) {
210+
// NOTE(olafur): For some reason, NoSuchMethodError gets thrown when running `snapshots/run`
211+
// in the sbt build. I'm unable to reproduce the error in `snapshots/test` or when running the
212+
// published version
213+
// of `lsif-java index`.
214+
return Semanticdb.TextDocuments.parseFrom(bytes);
215+
}
216+
}
203217
}

lsif-semanticdb/src/main/java/com/sourcegraph/lsif_semanticdb/LsifTextDocument.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,42 @@ public String toString() {
3737
}
3838

3939
public List<Semanticdb.SymbolOccurrence> sortedSymbolOccurrences() {
40+
return LsifTextDocument.sortedSymbolOccurrences(semanticdb);
41+
}
42+
43+
public static List<Semanticdb.SymbolOccurrence> sortedSymbolOccurrences(
44+
Semanticdb.TextDocument semanticdb) {
4045
ArrayList<Semanticdb.SymbolOccurrence> result =
4146
new ArrayList<>(semanticdb.getOccurrencesList().size());
4247
result.addAll(semanticdb.getOccurrencesList());
48+
for (Semanticdb.Synthetic synthetic : semanticdb.getSyntheticsList()) {
49+
addAllSyntheticOccurrences(synthetic, result);
50+
}
4351
result.sort((o1, o2) -> new RangeComparator().compare(o1.getRange(), o2.getRange()));
4452
return result;
4553
}
4654

55+
private static void addAllSyntheticOccurrences(
56+
Semanticdb.Synthetic synthetic, ArrayList<Semanticdb.SymbolOccurrence> buffer) {
57+
Semanticdb.Range offsetRange =
58+
Semanticdb.Range.newBuilder(synthetic.getRange())
59+
.setStartLine(synthetic.getRange().getEndLine())
60+
.setStartCharacter(synthetic.getRange().getEndCharacter())
61+
.build();
62+
new SemanticdbTreeVisitor() {
63+
@Override
64+
void visitIdTree(Semanticdb.IdTree tree) {
65+
Semanticdb.SymbolOccurrence syntheticOccurrence =
66+
Semanticdb.SymbolOccurrence.newBuilder()
67+
.setRange(offsetRange)
68+
.setSymbol(tree.getSymbol())
69+
.setRole(Semanticdb.SymbolOccurrence.Role.REFERENCE)
70+
.build();
71+
buffer.add(syntheticOccurrence);
72+
}
73+
}.visitTree(synthetic.getTree());
74+
}
75+
4776
private void setSemanticdb(Semanticdb.TextDocument semanticdb) {
4877
this.semanticdb = semanticdb;
4978
for (Semanticdb.SymbolInformation info : semanticdb.getSymbolsList()) {
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.sourcegraph.lsif_semanticdb;
2+
3+
import com.sourcegraph.semanticdb_javac.Semanticdb.*;
4+
5+
public abstract class SemanticdbTreeVisitor {
6+
public void visitTree(Tree tree) {
7+
if (tree.hasApplyTree()) {
8+
this.visitApplyTree(tree.getApplyTree());
9+
} else if (tree.hasFunctionTree()) {
10+
this.visitFunctionTree(tree.getFunctionTree());
11+
} else if (tree.hasIdTree()) {
12+
this.visitIdTree(tree.getIdTree());
13+
} else if (tree.hasLiteralTree()) {
14+
this.visitLiteralTree(tree.getLiteralTree());
15+
} else if (tree.hasMacroExpansionTree()) {
16+
this.visitMacroExpansionTree(tree.getMacroExpansionTree());
17+
} else if (tree.hasOriginalTree()) {
18+
this.visitOriginalTree(tree.getOriginalTree());
19+
} else if (tree.hasSelectTree()) {
20+
this.visitSelectTree(tree.getSelectTree());
21+
} else if (tree.hasTypeApplyTree()) {
22+
this.visitTypeApplyTree(tree.getTypeApplyTree());
23+
} else if (tree.hasAnnotationTree()) {
24+
this.visitAnnotationTree(tree.getAnnotationTree());
25+
} else if (tree.hasAssignTree()) {
26+
this.visitAssignTree(tree.getAssignTree());
27+
} else if (tree.hasBinopTree()) {
28+
this.visitBinaryOperatorTree(tree.getBinopTree());
29+
}
30+
}
31+
32+
void visitApplyTree(ApplyTree tree) {
33+
visitTree(tree.getFunction());
34+
for (Tree argument : tree.getArgumentsList()) {
35+
visitTree(argument);
36+
}
37+
}
38+
39+
void visitFunctionTree(FunctionTree tree) {
40+
for (IdTree parameter : tree.getParametersList()) {
41+
visitIdTree(parameter);
42+
}
43+
visitTree(tree.getBody());
44+
}
45+
46+
void visitIdTree(IdTree tree) {}
47+
48+
void visitLiteralTree(LiteralTree tree) {}
49+
50+
void visitMacroExpansionTree(MacroExpansionTree tree) {
51+
visitTree(tree.getBeforeExpansion());
52+
}
53+
54+
void visitOriginalTree(OriginalTree tree) {}
55+
56+
void visitSelectTree(SelectTree tree) {
57+
visitTree(tree.getQualifier());
58+
visitIdTree(tree.getId());
59+
}
60+
61+
void visitTypeApplyTree(TypeApplyTree tree) {
62+
visitTree(tree.getFunction());
63+
}
64+
65+
void visitAnnotationTree(AnnotationTree tree) {
66+
for (Tree parameter : tree.getParametersList()) {
67+
visitTree(parameter);
68+
}
69+
}
70+
71+
void visitAssignTree(AssignTree tree) {
72+
visitTree(tree.getLhs());
73+
visitTree(tree.getRhs());
74+
}
75+
76+
void visitBinaryOperatorTree(BinaryOperatorTree tree) {
77+
visitTree(tree.getLhs());
78+
visitTree(tree.getRhs());
79+
}
80+
}

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

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ message TextDocument {
2626
Language language = 10;
2727
repeated SymbolInformation symbols = 5;
2828
repeated SymbolOccurrence occurrences = 6;
29+
repeated Synthetic synthetics = 12;
2930
}
3031

3132
enum Language {
@@ -267,13 +268,21 @@ message RepeatedType {
267268
Type tpe = 1;
268269
}
269270

271+
message Synthetic {
272+
Range range = 1;
273+
Tree tree = 2;
274+
}
275+
270276
message Tree {
271277
oneof sealed_value {
272278
ApplyTree apply_tree = 1;
279+
FunctionTree function_tree = 2;
273280
IdTree id_tree = 3;
274281
LiteralTree literal_tree = 4;
282+
MacroExpansionTree macro_expansion_tree = 5;
275283
OriginalTree original_tree = 6;
276284
SelectTree select_tree = 7;
285+
TypeApplyTree type_apply_tree = 8;
277286
// -- OUT OF SPEC -- //
278287
AnnotationTree annotation_tree = 9;
279288
AssignTree assign_tree = 10;
@@ -287,23 +296,40 @@ message ApplyTree {
287296
repeated Tree arguments = 2;
288297
}
289298

299+
300+
message FunctionTree {
301+
repeated IdTree parameters = 1;
302+
Tree body = 2;
303+
}
304+
290305
message IdTree {
291306
string symbol = 1;
292307
}
293308

294-
message OriginalTree {
295-
Range range = 1;
296-
}
297309

298310
message LiteralTree {
299311
Constant constant = 1;
300312
}
301313

314+
message MacroExpansionTree {
315+
Tree before_expansion = 1;
316+
Type tpe = 2;
317+
}
318+
319+
message OriginalTree {
320+
Range range = 1;
321+
}
322+
302323
message SelectTree {
303324
Tree qualifier = 1;
304325
IdTree id = 2;
305326
}
306327

328+
message TypeApplyTree {
329+
Tree function = 1;
330+
repeated Type type_arguments = 2;
331+
}
332+
307333
// -- OUT OF SPEC -- //
308334
message AnnotationTree {
309335
Type tpe = 1;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package minimized
2+
3+
import scala.concurrent.ExecutionContext.Implicits.global
4+
import scala.concurrent.Future
5+
6+
class MinimizedScalaSynthetic {
7+
def everything(): Unit = Future(1)
8+
def applyTree(): Unit = Future.apply[Int](1)
9+
def applyTree2(): Unit = List.apply[Int](1).sorted
10+
def selectTree(): Unit = Future[Int](1)
11+
def typeApplyTree(): Unit = Future.apply(1)
12+
def forComprehensions(): Unit =
13+
for {
14+
x <- Future(1)
15+
y <- Future.successful(1)
16+
if y < 2
17+
z <- Future.apply[Int](1)
18+
} yield x + y + z
19+
}

0 commit comments

Comments
 (0)