Skip to content

Commit 66f9691

Browse files
committed
add support for existential (wildcard quantified) types in signatures
1 parent ee732de commit 66f9691

File tree

12 files changed

+256
-218
lines changed

12 files changed

+256
-218
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ public static void pprint(Object any) {
77
if (any instanceof String) {
88
any = String.format("\"%s\"", any);
99
}
10-
System.err.printf("%s:%s %s%n", trace.getFileName(), trace.getLineNumber(), any);
10+
System.out.printf("%s:%s %s%n", trace.getFileName(), trace.getLineNumber(), any);
1111
}
1212
}

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

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@
33
import com.sun.tools.javac.code.Symbol;
44
import com.sun.tools.javac.code.Type;
55
import com.sourcegraph.semanticdb_javac.Semanticdb.*;
6-
import com.sun.tools.javac.util.List;
76

87
import javax.lang.model.element.Element;
9-
import javax.lang.model.element.ElementKind;
108
import javax.lang.model.type.*;
119
import javax.lang.model.type.IntersectionType;
1210
import javax.lang.model.util.SimpleTypeVisitor8;
1311
import java.util.ArrayList;
12+
import java.util.List;
1413

1514
import static com.sourcegraph.semanticdb_javac.Debugging.pprint;
1615

@@ -42,17 +41,28 @@ private Signature generateClassSignature(Symbol.ClassSymbol sym) {
4241
builder.setTypeParameters(generateScope(sym.getTypeParameters()));
4342

4443
if (sym.getSuperclass() != Type.noType) {
45-
builder.addParents(generateType(sym.getSuperclass()));
44+
Semanticdb.Type superType = generateType(sym.getSuperclass());
45+
if (superType == null) {
46+
pprint("CLASS GAVE NULL " + sym.getSuperclass() + " " + sym);
47+
} else {
48+
builder.addParents(superType);
49+
}
4650
}
4751
for (Type iType : sym.getInterfaces()) {
48-
builder.addParents(generateType(iType));
52+
Semanticdb.Type type = generateType(iType);
53+
// this can happen if an interface type isnt properly resolved. Shows as _root_ in snapshots
54+
if (type == null) {
55+
pprint("INTERFACE GAVE NULL " + iType + " " + sym);
56+
continue;
57+
}
58+
builder.addParents(type);
4959
}
5060

5161
Scope.Builder declarations = Scope.newBuilder();
5262
for (Symbol enclosed : sym.getEnclosedElements()) {
5363
declarations.addSymlinks(cache.semanticdbSymbol(enclosed, locals));
5464
}
55-
builder.setDeclarations(declarations);
65+
builder.setDeclarations(generateScope(sym.getEnclosedElements()));
5666

5767
return Signature.newBuilder().setClassSignature(builder).build();
5868
}
@@ -73,23 +83,24 @@ private Signature generateMethodSignature(Symbol.MethodSymbol sym) {
7383
}
7484

7585
private Signature generateFieldSignature(Symbol.VarSymbol sym) {
76-
if (generateType(sym.type) == null) {
77-
// pprint(generateType(sym.type) + " " + sym.type + " " + cache.semanticdbSymbol(sym,
78-
// locals));
86+
Semanticdb.Type generateType = generateType(sym.type);
87+
if (generateType == null) {
88+
pprint("FIELD TYPE GAVE NULL " + sym.type + " " + cache.semanticdbSymbol(sym, locals));
89+
return null;
7990
}
8091
return Signature.newBuilder()
81-
.setValueSignature(ValueSignature.newBuilder().setTpe(generateType(sym.type)))
92+
.setValueSignature(ValueSignature.newBuilder().setTpe(generateType))
8293
.build();
8394
}
8495

8596
private Signature generateTypeSignature(Symbol.TypeVariableSymbol sym) {
8697
TypeSignature.Builder builder = TypeSignature.newBuilder();
8798

88-
pprint(sym.type.getKind() + " " + sym);
89-
9099
builder.setTypeParameters(generateScope(sym.getTypeParameters()));
91100

92-
builder.setUpperBound(generateType(sym.type.getUpperBound()));
101+
Semanticdb.Type upperBound = generateType(sym.type.getUpperBound());
102+
if (upperBound != null) builder.setUpperBound(upperBound);
103+
if (upperBound == null) pprint("UPPER BOUND GAVE NULL " + sym + " " + sym.type.getUpperBound());
93104

94105
return Signature.newBuilder().setTypeSignature(builder).build();
95106
}
@@ -123,13 +134,35 @@ public Semanticdb.Type visitDeclared(DeclaredType t, Void unused) {
123134
t.getTypeArguments().stream().anyMatch((type) -> type instanceof WildcardType);
124135

125136
ArrayList<Semanticdb.Type> typeParams = new ArrayList<>();
137+
Scope.Builder declarations = Scope.newBuilder();
126138
for (TypeMirror type : t.getTypeArguments()) {
127-
Semanticdb.Type visit = super.visit(type);
128-
if (visit == null) {
129-
pprint(type + " " + visit + " " + type.getClass());
139+
Semanticdb.Type visited = super.visit(type);
140+
if (visited == null) {
141+
pprint("NULL TYPE PARAM " + type + " " + type.getClass());
130142
continue;
131143
}
132-
typeParams.add(visit);
144+
typeParams.add(visited);
145+
146+
if (type instanceof WildcardType) {
147+
TypeSignature.Builder typeSig = TypeSignature.newBuilder();
148+
WildcardType wildcardType = (WildcardType) type;
149+
150+
// semanticdb spec asks for List() not None for type_parameters field
151+
typeSig.setTypeParameters(Scope.newBuilder());
152+
153+
if (wildcardType.getExtendsBound() != null) {
154+
typeSig.setUpperBound(super.visit(wildcardType.getExtendsBound()));
155+
} else if (wildcardType.getSuperBound() != null) {
156+
typeSig.setLowerBound(super.visit(wildcardType.getSuperBound()));
157+
}
158+
159+
declarations.addHardlinks(
160+
SymbolInformation.newBuilder()
161+
.setSymbol("local_wildcard")
162+
.setSignature(Signature.newBuilder().setTypeSignature(typeSig)));
163+
} else {
164+
declarations.addSymlinks(cache.semanticdbSymbol(((Type) type).asElement(), locals));
165+
}
133166
}
134167

135168
if (!isExistential) {
@@ -148,18 +181,22 @@ public Semanticdb.Type visitDeclared(DeclaredType t, Void unused) {
148181
.setTypeRef(
149182
TypeRef.newBuilder()
150183
.setSymbol(cache.semanticdbSymbol(t.asElement(), locals))
151-
.addAllTypeArguments(typeParams))))
184+
.addAllTypeArguments(typeParams)))
185+
.setDeclarations(declarations))
152186
.build();
153187
}
154188
}
155189

156190
@Override
157191
public Semanticdb.Type visitArray(ArrayType t, Void unused) {
192+
Semanticdb.Type arrayComponentType = super.visit(t.getComponentType());
193+
if (arrayComponentType == null) {
194+
pprint("ARRAY GAVE NULL " + t.getComponentType() + " " + t);
195+
return null;
196+
}
158197
return Semanticdb.Type.newBuilder()
159198
.setTypeRef(
160-
TypeRef.newBuilder()
161-
.setSymbol("scala/Array#")
162-
.addTypeArguments(super.visit(t.getComponentType())))
199+
TypeRef.newBuilder().setSymbol("scala/Array#").addTypeArguments(arrayComponentType))
163200
.build();
164201
}
165202

@@ -192,9 +229,11 @@ public Semanticdb.Type visitIntersection(IntersectionType t, Void unused) {
192229

193230
@Override
194231
public Semanticdb.Type visitWildcard(WildcardType t, Void unused) {
195-
new Exception().printStackTrace();
196232
return Semanticdb.Type.newBuilder()
197-
.setExistentialType(ExistentialType.newBuilder().build())
233+
.setTypeRef(
234+
// https://github.com/scalameta/scalameta/issues/1703
235+
// https://sourcegraph.com/github.com/scalameta/scalameta/-/blob/semanticdb/metacp/src/main/scala/scala/meta/internal/javacp/Javacp.scala#L452:19
236+
TypeRef.newBuilder().setSymbol("local_wildcard").build())
198237
.build();
199238
}
200239

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public SemanticdbVisitor(
5656
}
5757

5858
public Semanticdb.TextDocument buildTextDocument(CompilationUnitTree tree) {
59-
// pprint(semanticdbUri());
59+
pprint(semanticdbUri());
6060
this.scan(tree, null); // Trigger recursive AST traversal to collect SemanticDB information.
6161

6262
return Semanticdb.TextDocument.newBuilder()
@@ -83,9 +83,10 @@ private void emitSymbolOccurrence(
8383
private void emitSymbolInformation(Symbol sym) {
8484
Semanticdb.SymbolInformation.Builder builder =
8585
Semanticdb.SymbolInformation.newBuilder().setSymbol(semanticdbSymbol(sym));
86-
// .setSignature(semanticdbSignature(sym));
8786
Semanticdb.Documentation documentation = semanticdbDocumentation(sym);
8887
if (documentation != null) builder.setDocumentation(documentation);
88+
Semanticdb.Signature signature = semanticdbSignature(sym);
89+
if (signature != null) builder.setSignature(signature);
8990

9091
Semanticdb.SymbolInformation info = builder.build();
9192

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ message MethodSignature {
6464

6565
message TypeSignature {
6666
Scope type_parameters = 1;
67+
Type lower_bound = 2;
6768
Type upper_bound = 3;
6869
}
6970

@@ -146,6 +147,7 @@ message SymbolOccurrence {
146147

147148
message Scope {
148149
repeated string symlinks = 1;
150+
repeated SymbolInformation hardlinks = 2;
149151
}
150152

151153
message Type {
@@ -158,7 +160,6 @@ message Type {
158160
}
159161

160162
message TypeRef {
161-
Type prefix = 1;
162163
string symbol = 2;
163164
repeated Type type_arguments = 3;
164165
}
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package minimized;
22

3-
import java.util.List;
3+
import java.util.Map;
44

55
public class ParameterizedTypes<A, B> {
6-
//Class<?> clazz;
7-
86
public String app(A a, B b) {
97
return a.toString() + b;
108
}
119

12-
public List<?> doStuff() { return null; }
10+
public Map<? extends String, ?> doStuff() { return null; }
1311
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ class ControllerModelList extends ModelList {
2121
// ^^^^^^^^ reference java/lang/Override#
2222
public void onItemRangeInserted(int positionStart, int itemCount) {
2323
// ^^^^^^^^^^^^^^^^^^^ definition local2
24-
// ^^^^^^^^^^^^^ definition local3
25-
// ^^^^^^^^^ definition local4
24+
// ^^^^^^^^^^^^^ definition local4
25+
// ^^^^^^^^^ definition local5
2626
throw new IllegalStateException(
2727
// ^^^^^^^^^^^^^^^^^^^^^^^^^^ reference java/lang/IllegalStateException#`<init>`(+1). 1:75
2828
// ^^^^^^^^^^^^^^^^^^^^^ reference java/lang/IllegalStateException#
@@ -32,7 +32,7 @@ public void onItemRangeInserted(int positionStart, int itemCount) {
3232
@Override
3333
// ^^^^^^^^ reference java/lang/Override#
3434
public void onItemRangeRemoved(int positionStart, int itemCount) {
35-
// ^^^^^^^^^^^^^^^^^^ definition local5
35+
// ^^^^^^^^^^^^^^^^^^ definition local3
3636
// ^^^^^^^^^^^^^ definition local6
3737
// ^^^^^^^^^ definition local7
3838
throw new IllegalStateException(

0 commit comments

Comments
 (0)