Skip to content

Commit d252f98

Browse files
committed
add pretty-printing of annotations on symbols
1 parent d033d95 commit d252f98

File tree

85 files changed

+1154
-752
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+1154
-752
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ _site/
2929
metals.sbt
3030
metals/project/
3131

32+
.bsp
33+
3234
.vscode/
3335

3436
local.*

.jvmopts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
-Xss2m
22
-Xms1G
33
-Xmx4G
4-
-Dfile.encoding=UTF-8
5-
-Dsbt.server.autostart=false
4+
-Dfile.encoding=UTF-8

build.sbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ lazy val unit = project
248248
.in(file("tests/unit"))
249249
.settings(
250250
testSettings,
251+
//javaOptions ++= Seq( "-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"),
251252
buildInfoKeys :=
252253
Seq[BuildInfoKey](
253254
version,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ object SemanticdbPrinters {
8888
if (sig.isEmpty)
8989
" " + info.getDisplayName
9090
else
91-
" " + sig
91+
" " + sig.replace('\n', ' ')
9292
case _ =>
9393
""
9494
}

lsif-java/src/main/scala/com/sourcegraph/lsif_java/commands/SnapshotLsifCommand.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ object SnapshotLsifCommand {
138138
// we cheese it a bit here, as this is less work than trying to reconstruct
139139
// a Signature from the pretty-printed Signature, with accompanying logic
140140
// to fallback to display_name in SemanticdbPrinters.scala
141-
.setDisplayName(hover).setSymbol(symbol).build()
141+
.setDisplayName(hover.replace('\n', ' ')).setSymbol(symbol).build()
142142
doc.addSymbols(symInfo)
143143
}
144144
}

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

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.sourcegraph.semanticdb_javac.Semanticdb.*;
55

66
import java.util.ArrayList;
7+
import java.util.Arrays;
78
import java.util.List;
89
import java.util.Objects;
910
import java.util.concurrent.atomic.AtomicInteger;
@@ -51,6 +52,8 @@ private void formatClassSignature(ClassSignature classSignature) {
5152

5253
boolean isEnum = has(Property.ENUM);
5354

55+
printKeywordln(formatAnnotations());
56+
5457
printKeyword(formatAccess());
5558
if (!isEnum && !isAnnotation) printKeyword(formatModifiers());
5659

@@ -143,6 +146,7 @@ private void formatClassSignature(ClassSignature classSignature) {
143146
}
144147

145148
private void formatMethodSignature(MethodSignature methodSignature) {
149+
printKeywordln(formatAnnotations());
146150
printKeyword(formatAccess());
147151
printKeyword(formatModifiers());
148152

@@ -177,6 +181,7 @@ private void formatMethodSignature(MethodSignature methodSignature) {
177181
}
178182

179183
private void formatValueSignature(ValueSignature valueSignature) {
184+
printKeywordln(formatAnnotations());
180185
if (isEnumConstant()) {
181186
String ownerSym = SymbolDescriptor.parseFromSymbol(symbolInformation.getSymbol()).owner;
182187
SymbolInformation ownerInfo = symtab.symbols.get(ownerSym);
@@ -234,6 +239,98 @@ private String formatTypeArguments(List<Type> typeArguments) {
234239
return typeArguments.stream().map(this::formatType).collect(Collectors.joining(", ", "<", ">"));
235240
}
236241

242+
private String formatAnnotations() {
243+
return formatAnnotations(symbolInformation);
244+
}
245+
246+
private String formatAnnotations(SymbolInformation symInfo) {
247+
return symInfo.getAnnotationsList().stream()
248+
.map(this::formatAnnotation)
249+
.collect(Collectors.joining("\n"));
250+
}
251+
252+
private String formatAnnotation(Annotation annotation) {
253+
StringBuilder b = new StringBuilder();
254+
b.append('@');
255+
b.append(formatType(annotation.getTpe()));
256+
if (annotation.getParametersCount() > 0) {
257+
b.append('(');
258+
Annotation.ParameterPair firstParam = annotation.getParameters(0);
259+
// if only 1 parameter, and its LHS is named 'value', we can omit the 'value = '
260+
// docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.7.3
261+
if (annotation.getParametersCount() == 1
262+
&& SymbolDescriptor.parseFromSymbol(firstParam.getKey())
263+
.descriptor
264+
.name
265+
.equals("value")) {
266+
b.append(formatTree(firstParam.getValue()));
267+
} else {
268+
String parameter =
269+
annotation.getParametersList().stream()
270+
.map(
271+
p ->
272+
SymbolDescriptor.parseFromSymbol(p.getKey()).descriptor.name
273+
+ " = "
274+
+ formatTree(p.getValue()))
275+
.collect(Collectors.joining(", "));
276+
b.append(parameter);
277+
}
278+
b.append(')');
279+
}
280+
return b.toString();
281+
}
282+
283+
private String formatTree(Tree tree) {
284+
if (tree.hasIdTree()) {
285+
return SymbolDescriptor.parseFromSymbol(tree.getIdTree().getSymbol()).descriptor.name;
286+
} else if (tree.hasLiteralTree()) {
287+
return formatConstant(tree.getLiteralTree().getConstant());
288+
} else if (tree.hasSelectTree()) {
289+
return formatTree(tree.getSelectTree().getQualifier())
290+
+ "."
291+
+ SymbolDescriptor.parseFromSymbol(tree.getSelectTree().getId().getSymbol())
292+
.descriptor
293+
.name;
294+
} else if (tree.hasAnnotationTree()) {
295+
return formatAnnotation(tree.getAnnotationTree().getAnnotation());
296+
} else if (tree.hasApplyTree()) {
297+
if (tree.getApplyTree().getFunction().hasIdTree()
298+
&& tree.getApplyTree().getFunction().getIdTree().getSymbol().equals(ARRAY_SYMBOL)) {
299+
return tree.getApplyTree().getArgumentsList().stream()
300+
.map(this::formatTree)
301+
.collect(Collectors.joining(", ", "{", "}"));
302+
} else {
303+
throw new IllegalArgumentException(
304+
"unexpected apply tree function " + tree.getApplyTree().getFunction());
305+
}
306+
}
307+
308+
throw new IllegalArgumentException("tree was of unexpected type " + tree);
309+
}
310+
311+
private String formatConstant(Constant constant) {
312+
if (constant.hasBooleanConstant()) {
313+
return Boolean.toString(constant.getBooleanConstant().getValue());
314+
} else if (constant.hasByteConstant()) {
315+
return Integer.toString(constant.getByteConstant().getValue());
316+
} else if (constant.hasShortConstant()) {
317+
return Integer.toString(constant.getShortConstant().getValue());
318+
} else if (constant.hasCharConstant()) {
319+
return String.valueOf((char) constant.getCharConstant().getValue());
320+
} else if (constant.hasIntConstant()) {
321+
return Integer.toString(constant.getIntConstant().getValue());
322+
} else if (constant.hasLongConstant()) {
323+
return Long.toString(constant.getLongConstant().getValue());
324+
} else if (constant.hasFloatConstant()) {
325+
return Float.toString(constant.getFloatConstant().getValue()) + 'f';
326+
} else if (constant.hasDoubleConstant()) {
327+
return Double.toString(constant.getDoubleConstant().getValue());
328+
} else if (constant.hasStringConstant()) {
329+
return '"' + constant.getStringConstant().getValue() + '"';
330+
}
331+
throw new IllegalArgumentException("constant was not of known type " + constant);
332+
}
333+
237334
private String formatType(Type type) {
238335
StringBuilder b = new StringBuilder();
239336
if (type.hasTypeRef()) {
@@ -307,6 +404,11 @@ private void printKeyword(String keyword) {
307404
s.append(keyword).append(' ');
308405
}
309406

407+
private void printKeywordln(String keyword) {
408+
if (keyword.isEmpty()) return;
409+
s.append(keyword).append('\n');
410+
}
411+
310412
private boolean isEnumConstant(SymbolInformation symInfo) {
311413
if (!(has(Property.ENUM, symInfo)
312414
&& has(Property.FINAL, symInfo)

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

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,24 @@ message SymbolInformation {
103103
Kind kind = 3;
104104
int32 properties = 4;
105105
string display_name = 5;
106+
repeated Annotation annotations = 13;
106107
Signature signature = 17;
107108
Access access = 18;
108109
repeated string overridden_symbols = 19;
109110
Documentation documentation = 20;
110111
}
111112

113+
message Annotation {
114+
Type tpe = 1;
115+
// -- OUT OF SPEC -- //
116+
message ParameterPair {
117+
string key = 1;
118+
Tree value = 2;
119+
}
120+
repeated ParameterPair parameters = 2;
121+
// -- OUT OF SPEC -- //
122+
}
123+
112124
message Access {
113125
oneof sealed_value {
114126
PrivateAccess private_access = 1;
@@ -178,4 +190,93 @@ message ExistentialType {
178190
reserved 2;
179191
Type tpe = 1;
180192
Scope declarations = 3;
193+
}
194+
195+
message Tree {
196+
oneof sealed_value {
197+
ApplyTree apply_tree = 1;
198+
IdTree id_tree = 3;
199+
LiteralTree literal_tree = 4;
200+
OriginalTree original_tree = 6;
201+
SelectTree select_tree = 7;
202+
// -- OUT OF SPEC -- //
203+
AnnotationTree annotation_tree = 8;
204+
// -- OUT OF SPEC -- //
205+
}
206+
}
207+
208+
message ApplyTree {
209+
Tree function = 1;
210+
repeated Tree arguments = 2;
211+
}
212+
213+
message IdTree {
214+
string symbol = 1;
215+
}
216+
217+
message OriginalTree {
218+
Range range = 1;
219+
}
220+
221+
message LiteralTree {
222+
Constant constant = 1;
223+
}
224+
225+
message SelectTree {
226+
Tree qualifier = 1;
227+
IdTree id = 2;
228+
}
229+
230+
message AnnotationTree {
231+
Annotation annotation = 1;
232+
}
233+
234+
message Constant {
235+
oneof sealed_value {
236+
BooleanConstant boolean_constant = 2;
237+
ByteConstant byte_constant = 3;
238+
ShortConstant short_constant = 4;
239+
CharConstant char_constant = 5;
240+
IntConstant int_constant = 6;
241+
LongConstant long_constant = 7;
242+
FloatConstant float_constant = 8;
243+
DoubleConstant double_constant = 9;
244+
StringConstant string_constant = 10;
245+
}
246+
}
247+
248+
message BooleanConstant {
249+
bool value = 1;
250+
}
251+
252+
message ByteConstant {
253+
int32 value = 1;
254+
}
255+
256+
message ShortConstant {
257+
int32 value = 1;
258+
}
259+
260+
message CharConstant {
261+
int32 value = 1;
262+
}
263+
264+
message IntConstant {
265+
int32 value = 1;
266+
}
267+
268+
message LongConstant {
269+
int64 value = 1;
270+
}
271+
272+
message FloatConstant {
273+
float value = 1;
274+
}
275+
276+
message DoubleConstant {
277+
double value = 1;
278+
}
279+
280+
message StringConstant {
281+
string value = 1;
181282
}

0 commit comments

Comments
 (0)