Skip to content

Commit 30114ed

Browse files
committed
add support for binary operator trees in annotations
1 parent 04287b3 commit 30114ed

File tree

5 files changed

+174
-6
lines changed

5 files changed

+174
-6
lines changed

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,12 @@ private String formatTree(Tree tree) {
315315
throw new IllegalArgumentException(
316316
"unexpected apply tree function " + tree.getApplyTree().getFunction());
317317
}
318+
} else if (tree.hasBinopTree()) {
319+
return formatTree(tree.getBinopTree().getLhs())
320+
+ " "
321+
+ formatBinaryOperator(tree.getBinopTree().getOp())
322+
+ " "
323+
+ formatTree(tree.getBinopTree().getRhs());
318324
}
319325

320326
throw new IllegalArgumentException("tree was of unexpected type " + tree);
@@ -343,6 +349,52 @@ private String formatConstant(Constant constant) {
343349
throw new IllegalArgumentException("constant was not of known type " + constant);
344350
}
345351

352+
private String formatBinaryOperator(BinaryOperator op) {
353+
switch (op) {
354+
case PLUS:
355+
return "+";
356+
case MINUS:
357+
return "-";
358+
case MULTIPLY:
359+
return "*";
360+
case DIVIDE:
361+
return "/";
362+
case REMAINDER:
363+
return "%";
364+
case GREATER_THAN:
365+
return ">";
366+
case LESS_THAN:
367+
return "<";
368+
case AND:
369+
return "&";
370+
case XOR:
371+
return "^";
372+
case OR:
373+
return "|";
374+
case CONDITIONAL_AND:
375+
return "&&";
376+
case CONDITIONAL_OR:
377+
return "||";
378+
case SHIFT_LEFT:
379+
return "<<";
380+
case SHIFT_RIGHT:
381+
return ">>";
382+
case SHIFT_RIGHT_UNSIGNED:
383+
return ">>>";
384+
case EQUAL_TO:
385+
return "==";
386+
case NOT_EQUAL_TO:
387+
return "!=";
388+
case GREATER_THAN_EQUAL:
389+
return ">=";
390+
case LESS_THAN_EQUAL:
391+
return "<=";
392+
case UNRECOGNIZED:
393+
throw new IllegalArgumentException("unexpected binary operator " + op);
394+
}
395+
return null;
396+
}
397+
346398
private String formatType(Type type) {
347399
StringBuilder b = new StringBuilder();
348400
if (type.hasTypeRef()) {

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ message Tree {
194194
// -- OUT OF SPEC -- //
195195
AnnotationTree annotation_tree = 9;
196196
AssignTree assign_tree = 10;
197+
BinaryOperatorTree binop_tree = 11;
197198
// -- OUT OF SPEC -- //
198199
}
199200
}
@@ -230,6 +231,34 @@ message AssignTree {
230231
Tree lhs = 1;
231232
Tree rhs = 2;
232233
}
234+
235+
message BinaryOperatorTree {
236+
Tree lhs = 1;
237+
BinaryOperator op = 2;
238+
Tree rhs = 3;
239+
}
240+
241+
enum BinaryOperator {
242+
PLUS = 0;
243+
MINUS = 1;
244+
MULTIPLY = 2;
245+
DIVIDE = 3;
246+
REMAINDER = 4;
247+
GREATER_THAN = 5;
248+
LESS_THAN = 6;
249+
AND = 7;
250+
XOR = 8;
251+
OR = 9;
252+
CONDITIONAL_AND = 10;
253+
CONDITIONAL_OR = 11;
254+
SHIFT_LEFT = 12;
255+
SHIFT_RIGHT = 13;
256+
SHIFT_RIGHT_UNSIGNED = 14;
257+
EQUAL_TO = 15;
258+
NOT_EQUAL_TO = 16;
259+
GREATER_THAN_EQUAL = 17;
260+
LESS_THAN_EQUAL = 18;
261+
}
233262
// -- OUT OF SPEC -- //
234263

235264
message Constant {

semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@
1919
import java.nio.file.Path;
2020
import java.nio.file.Paths;
2121
import java.security.NoSuchAlgorithmException;
22-
import java.util.ArrayList;
23-
import java.util.Iterator;
24-
import java.util.List;
25-
import java.util.Optional;
22+
import java.util.*;
2623
import java.util.stream.Collectors;
2724

2825
import static com.sourcegraph.semanticdb_javac.SemanticdbTypeVisitor.ARRAY_SYMBOL;
@@ -469,7 +466,9 @@ private Semanticdb.Tree.Builder semanticdbAnnotationParameter(JCTree.JCExpressio
469466
break;
470467
case CHAR:
471468
constantBuilder.setCharConstant(
472-
Semanticdb.CharConstant.newBuilder().setValue((Character) rhs.value).build());
469+
Semanticdb.CharConstant.newBuilder()
470+
.setValue(Character.forDigit((Integer) rhs.value, 10))
471+
.build());
473472
break;
474473
case FLOAT:
475474
constantBuilder.setFloatConstant(
@@ -516,6 +515,13 @@ private Semanticdb.Tree.Builder semanticdbAnnotationParameter(JCTree.JCExpressio
516515
Semanticdb.IdTree.newBuilder()
517516
.setSymbol(globals.semanticdbSymbol(((JCTree.JCIdent) expr).sym, locals))
518517
.build());
518+
} else if (expr instanceof JCTree.JCBinary) {
519+
Semanticdb.BinaryOperatorTree.Builder binOp = Semanticdb.BinaryOperatorTree.newBuilder();
520+
JCTree.JCBinary binExpr = (JCTree.JCBinary) expr;
521+
binOp.setLhs(semanticdbAnnotationParameter(binExpr.lhs));
522+
binOp.setOp(semanticdbBinaryOperator(expr.getKind()));
523+
binOp.setRhs(semanticdbAnnotationParameter(binExpr.rhs));
524+
return Semanticdb.Tree.newBuilder().setBinopTree(binOp.build());
519525
}
520526

521527
throw new IllegalArgumentException(
@@ -559,6 +565,52 @@ private Semanticdb.Access semanticdbAccess(Symbol sym) {
559565
}
560566
}
561567

568+
private Semanticdb.BinaryOperator semanticdbBinaryOperator(Tree.Kind kind) {
569+
switch (kind) {
570+
case PLUS:
571+
return Semanticdb.BinaryOperator.PLUS;
572+
case MINUS:
573+
return Semanticdb.BinaryOperator.MINUS;
574+
case MULTIPLY:
575+
return Semanticdb.BinaryOperator.MULTIPLY;
576+
case DIVIDE:
577+
return Semanticdb.BinaryOperator.DIVIDE;
578+
case REMAINDER:
579+
return Semanticdb.BinaryOperator.REMAINDER;
580+
case LESS_THAN:
581+
return Semanticdb.BinaryOperator.LESS_THAN;
582+
case GREATER_THAN:
583+
return Semanticdb.BinaryOperator.GREATER_THAN;
584+
case LEFT_SHIFT:
585+
return Semanticdb.BinaryOperator.SHIFT_LEFT;
586+
case RIGHT_SHIFT:
587+
return Semanticdb.BinaryOperator.SHIFT_RIGHT;
588+
case UNSIGNED_RIGHT_SHIFT:
589+
return Semanticdb.BinaryOperator.SHIFT_RIGHT_UNSIGNED;
590+
case EQUAL_TO:
591+
return Semanticdb.BinaryOperator.EQUAL_TO;
592+
case NOT_EQUAL_TO:
593+
return Semanticdb.BinaryOperator.NOT_EQUAL_TO;
594+
case LESS_THAN_EQUAL:
595+
return Semanticdb.BinaryOperator.LESS_THAN_EQUAL;
596+
case GREATER_THAN_EQUAL:
597+
return Semanticdb.BinaryOperator.GREATER_THAN_EQUAL;
598+
case CONDITIONAL_AND:
599+
return Semanticdb.BinaryOperator.CONDITIONAL_AND;
600+
case CONDITIONAL_OR:
601+
return Semanticdb.BinaryOperator.CONDITIONAL_OR;
602+
case AND:
603+
return Semanticdb.BinaryOperator.AND;
604+
case OR:
605+
return Semanticdb.BinaryOperator.OR;
606+
case XOR:
607+
return Semanticdb.BinaryOperator.XOR;
608+
default:
609+
throw new IllegalStateException(
610+
semanticdbUri() + ": unexpected binary expression operator kind " + kind);
611+
}
612+
}
613+
562614
private String semanticdbUri() {
563615
Path absolutePath = Paths.get(event.getSourceFile().toUri());
564616
Path relativePath = options.sourceroot.relativize(absolutePath);

tests/minimized/src/main/java/minimized/InnerClasses.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ public class InnerClasses {
44

55
private final int exampleField;
66

7+
private static final String STRING = "asdf";
8+
9+
private static final int top = 5;
10+
private static final int bottom = 10;
11+
712
public InnerClasses(int exampleField) {
813
this.exampleField = exampleField;
914
}
@@ -18,7 +23,14 @@ public interface InnerInterface<A, B> {
1823
B apply(A a);
1924
}
2025

26+
public @interface InnerAnnotation {
27+
int value();
28+
}
29+
30+
@SuppressWarnings(STRING + " ")
31+
@InnerAnnotation(top / bottom)
2132
public static class InnerStaticClass {
33+
2234
public static void innerStaticMethod() {}
2335
}
2436

tests/snapshots/src/main/generated/minimized/InnerClasses.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ public class InnerClasses {
66
private final int exampleField;
77
// ^^^^^^^^^^^^ definition minimized/InnerClasses#exampleField. private final int exampleField
88

9+
private static final String STRING = "asdf";
10+
// ^^^^^^ reference java/lang/String#
11+
// ^^^^^^ definition minimized/InnerClasses#STRING. private static final String STRING
12+
13+
private static final int top = 5;
14+
// ^^^ definition minimized/InnerClasses#top. private static final int top
15+
private static final int bottom = 10;
16+
// ^^^^^^ definition minimized/InnerClasses#bottom. private static final int bottom
17+
918
public InnerClasses(int exampleField) {
1019
// ^^^^^^^^^^^^ definition minimized/InnerClasses#`<init>`(). public InnerClasses(int exampleField)
1120
// ^^^^^^^^^^^^ definition local0 int exampleField
@@ -36,9 +45,23 @@ public interface InnerInterface<A, B> {
3645
// ^ definition local1 A a
3746
}
3847

48+
public @interface InnerAnnotation {
49+
// ^^^^^^^^^^^^^^^ definition minimized/InnerClasses#InnerAnnotation# public @interface InnerAnnotation
50+
int value();
51+
// ^^^^^ definition minimized/InnerClasses#InnerAnnotation#value(). public abstract int value()
52+
}
53+
54+
@SuppressWarnings(STRING + " ")
55+
// ^^^^^^^^^^^^^^^^ reference java/lang/SuppressWarnings#
56+
// ^^^^^^ reference minimized/InnerClasses#STRING.
57+
@InnerAnnotation(top / bottom)
58+
// ^^^^^^^^^^^^^^^ reference minimized/InnerClasses#InnerAnnotation#
59+
// ^^^ reference minimized/InnerClasses#top.
60+
// ^^^^^^ reference minimized/InnerClasses#bottom.
3961
public static class InnerStaticClass {
40-
// ^^^^^^^^^^^^^^^^ definition minimized/InnerClasses#InnerStaticClass# public static class InnerStaticClass
62+
// ^^^^^^^^^^^^^^^^ definition minimized/InnerClasses#InnerStaticClass# @SuppressWarnings(STRING + " ") @InnerAnnotation(top / bottom) public static class InnerStaticClass
4163
// ^^^^^^^^^^^^^^^^ definition minimized/InnerClasses#InnerStaticClass#`<init>`(). public InnerStaticClass()
64+
4265
public static void innerStaticMethod() {}
4366
// ^^^^^^^^^^^^^^^^^ definition minimized/InnerClasses#InnerStaticClass#innerStaticMethod(). public static void innerStaticMethod()
4467
}

0 commit comments

Comments
 (0)