1
1
package com .sourcegraph .semanticdb_javac ;
2
2
3
- import com .sun .source .tree .Tree ;
3
+ import com .sun .source .tree .* ;
4
4
import com .sun .source .util .Trees ;
5
5
import javax .lang .model .element .Element ;
6
6
import javax .lang .model .util .Types ;
7
+ import javax .lang .model .type .TypeMirror ;
7
8
import com .sun .source .util .TreePath ;
8
9
import com .sun .source .tree .Tree ;
9
10
import com .sun .source .tree .Tree .Kind ;
10
- import com .sun .source .tree .BinaryTree ;
11
- import com .sun .source .tree .UnaryTree ;
12
- import com .sun .source .tree .AssignmentTree ;
13
- import com .sun .source .tree .MemberSelectTree ;
14
- import com .sun .source .tree .ClassTree ;
15
- import com .sun .source .tree .VariableTree ;
16
- import com .sun .source .tree .MethodTree ;
17
- import com .sun .source .tree .ModifiersTree ;
18
- import com .sun .source .tree .IdentifierTree ;
19
- import com .sun .source .tree .ExpressionTree ;
20
- import com .sun .source .tree .LiteralTree ;
21
- import com .sun .source .tree .NewArrayTree ;
22
- import com .sun .source .tree .AnnotationTree ;
23
- import com .sun .source .tree .ParenthesizedTree ;
24
11
25
12
import java .util .HashMap ;
26
13
import java .util .ArrayList ;
@@ -44,6 +31,7 @@ public SemanticdbTrees(
44
31
this .types = types ;
45
32
this .trees = trees ;
46
33
this .nodes = nodes ;
34
+ this .typeVisitor = new SemanticdbTypeVisitor (globals , locals , types );
47
35
}
48
36
49
37
private final GlobalSymbolsCache globals ;
@@ -52,6 +40,7 @@ public SemanticdbTrees(
52
40
private final Types types ;
53
41
private final Trees trees ;
54
42
private final HashMap <Tree , TreePath > nodes ;
43
+ private final SemanticdbTypeVisitor typeVisitor ;
55
44
56
45
public List <Semanticdb .AnnotationTree > annotations (Tree node ) {
57
46
if (!(node instanceof ClassTree )
@@ -100,11 +89,15 @@ public Semanticdb.AnnotationTree annotationBuilder(AnnotationTree annotation) {
100
89
TreePath annotationTreePath = nodes .get (annotation );
101
90
Element annotationSym = trees .getElement (annotationTreePath );
102
91
103
- Semanticdb .Type type =
104
- new SemanticdbTypeVisitor (globals , locals , types ).semanticdbType (annotationSym .asType ());
92
+ Semanticdb .Type type = typeVisitor .semanticdbType (annotationSym .asType ());
105
93
return annotationTree (type , params );
106
94
}
107
95
96
+ private TypeMirror getTreeType (Tree tree ) {
97
+ TreePath path = nodes .get (tree );
98
+ return trees .getTypeMirror (path );
99
+ }
100
+
108
101
private Semanticdb .Tree annotationParameter (ExpressionTree expr ) {
109
102
if (expr instanceof MemberSelectTree ) {
110
103
TreePath expressionTreePath = nodes .get (expr );
@@ -125,7 +118,12 @@ private Semanticdb.Tree annotationParameter(ExpressionTree expr) {
125
118
// Literals can either be a primitive or String
126
119
Object value = ((LiteralTree ) expr ).getValue ();
127
120
final Semanticdb .Constant constant ;
128
- if (value instanceof String ) constant = stringConst ((String ) value );
121
+ // Technically, annotation parameter values cannot be null,
122
+ // according to JLS: https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.7.1
123
+ // But this codepath is still possible to hit when compiling invalid code - and
124
+ // we should handle the null const case in order to fail more gracefully
125
+ if (value == null ) constant = nullConst ();
126
+ else if (value instanceof String ) constant = stringConst ((String ) value );
129
127
else if (value instanceof Boolean ) constant = booleanConst ((Boolean ) value );
130
128
else if (value instanceof Byte ) constant = byteConst ((Byte ) value );
131
129
else if (value instanceof Short ) constant = shortConst ((Short ) value );
@@ -164,13 +162,20 @@ private Semanticdb.Tree annotationParameter(ExpressionTree expr) {
164
162
} else if (expr instanceof ParenthesizedTree ) {
165
163
ParenthesizedTree parenExpr = (ParenthesizedTree ) expr ;
166
164
return annotationParameter (parenExpr .getExpression ());
165
+ } else if (expr instanceof TypeCastTree ) {
166
+ TypeCastTree tree = (TypeCastTree ) expr ;
167
+ return tree (
168
+ castTree (
169
+ typeVisitor .semanticdbType (getTreeType (tree .getType ())),
170
+ annotationParameter (tree .getExpression ())));
171
+ } else {
172
+ throw new IllegalArgumentException (
173
+ semanticdbUri
174
+ + ": annotation parameter rhs was of unexpected tree node type "
175
+ + expr .getClass ()
176
+ + "\n "
177
+ + expr );
167
178
}
168
- throw new IllegalArgumentException (
169
- semanticdbUri
170
- + ": annotation parameter rhs was of unexpected tree node type "
171
- + expr .getClass ()
172
- + "\n "
173
- + expr );
174
179
}
175
180
176
181
private Semanticdb .BinaryOperator semanticdbBinaryOperator (Tree .Kind kind ) {
0 commit comments