1
1
package com .sourcegraph .semanticdb_javac ;
2
2
3
- import com .sun .tools .javac .code .Symbol ;
4
-
5
3
import javax .lang .model .element .Element ;
6
4
import javax .lang .model .element .ElementKind ;
7
5
import javax .lang .model .element .ExecutableElement ;
8
- import java .util .*;
6
+ import javax .lang .model .element .TypeElement ;
7
+ import javax .lang .model .element .PackageElement ;
8
+ import javax .lang .model .element .TypeParameterElement ;
9
+ import javax .lang .model .element .VariableElement ;
10
+ import javax .lang .model .element .QualifiedNameable ;
11
+ import javax .lang .model .type .NoType ;
12
+ import java .util .IdentityHashMap ;
13
+ import java .util .ArrayList ;
9
14
10
15
import static com .sourcegraph .semanticdb_javac .Debugging .pprint ;
11
16
12
17
/** Cache of SemanticDB symbols that can be referenced between files. */
13
18
public final class GlobalSymbolsCache {
14
19
15
- private final IdentityHashMap <Symbol , String > globals = new IdentityHashMap <>();
20
+ private final IdentityHashMap <Element , String > globals = new IdentityHashMap <>();
16
21
private final SemanticdbJavacOptions options ;
17
22
18
23
public GlobalSymbolsCache (SemanticdbJavacOptions options ) {
19
24
this .options = options ;
20
25
}
21
26
22
- public String semanticdbSymbol (Symbol sym , LocalSymbolsCache locals ) {
27
+ public String semanticdbSymbol (Element sym , LocalSymbolsCache locals ) {
23
28
String result = globals .get (sym );
24
29
if (result != null ) return result ;
25
30
String localResult = locals .get (sym );
@@ -31,33 +36,54 @@ public String semanticdbSymbol(Symbol sym, LocalSymbolsCache locals) {
31
36
return result ;
32
37
}
33
38
34
- public String semanticdbSymbol (Element element , LocalSymbolsCache locals ) {
35
- return semanticdbSymbol ((Symbol ) element , locals );
36
- }
37
-
38
- public boolean isNone (Symbol sym ) {
39
+ public boolean isNone (Element sym ) {
39
40
return sym == null ;
40
41
}
41
42
42
- private String uncachedSemanticdbSymbol (Symbol sym , LocalSymbolsCache locals ) {
43
- if (isNone (sym )) return SemanticdbSymbols .NONE ;
44
- String owner = semanticdbSymbol (sym .owner , locals );
45
- if (owner .equals (SemanticdbSymbols .NONE )) {
46
- return SemanticdbSymbols .ROOT_PACKAGE ;
47
- } else if (SemanticdbSymbols .isLocal (owner ) || isAnonymousClass (sym ) || isLocalVariable (sym )) {
48
- return locals .put (sym );
49
- }
43
+ private String uncachedSemanticdbSymbol (Element sym , LocalSymbolsCache locals ) {
44
+ if (isNone (sym )) return SemanticdbSymbols .ROOT_PACKAGE ;
45
+
46
+ if (sym instanceof PackageElement ) {
47
+ if (((PackageElement ) sym ).isUnnamed ()) return SemanticdbSymbols .ROOT_PACKAGE ;
48
+
49
+ StringBuilder sb = new StringBuilder ();
50
+ String qualifiedName = ((PackageElement ) sym ).getQualifiedName ().toString ();
51
+ int i = 0 ;
52
+ int j = 0 ;
53
+ while (j < qualifiedName .length ()) {
54
+ if (i == qualifiedName .length () || qualifiedName .charAt (i ) == '.' ) {
55
+ final String name = qualifiedName .substring (j , i );
56
+ SemanticdbSymbols .Descriptor desc =
57
+ new SemanticdbSymbols .Descriptor (SemanticdbSymbols .Descriptor .Kind .Package , name );
58
+ sb .append (desc .encode ());
59
+ j = i + 1 ;
60
+ }
61
+ i ++;
62
+ }
63
+
64
+ return sb .toString ();
65
+ } else
66
+ // check for Module without referring to Module as it doesn't exist < JDK 9
67
+ if (sym .asType () instanceof NoType ) return SemanticdbSymbols .ROOT_PACKAGE ;
68
+
69
+ if (isAnonymousClass (sym ) || isLocalVariable (sym )) return locals .put (sym );
70
+
71
+ String owner = semanticdbSymbol (sym .getEnclosingElement (), locals );
72
+ if (SemanticdbSymbols .isLocal (owner )) return locals .put (sym );
73
+
50
74
SemanticdbSymbols .Descriptor desc = semanticdbDescriptor (sym );
51
75
if (options .verboseEnabled && desc .kind == SemanticdbSymbols .Descriptor .Kind .None ) {
52
- pprint (sym .getQualifiedName ().toString ());
76
+ if (sym instanceof QualifiedNameable )
77
+ pprint (((QualifiedNameable ) sym ).getQualifiedName ().toString ());
78
+ else pprint (sym .getSimpleName ().toString ());
53
79
pprint (
54
80
String .format (
55
81
"sym: %s (%s - superclass %s)" , sym , sym .getClass (), sym .getClass ().getSuperclass ()));
56
82
}
57
83
return SemanticdbSymbols .global (owner , desc );
58
84
}
59
85
60
- private boolean isLocalVariable (Symbol sym ) {
86
+ private boolean isLocalVariable (Element sym ) {
61
87
switch (sym .getKind ()) {
62
88
case PARAMETER :
63
89
case EXCEPTION_PARAMETER :
@@ -68,28 +94,25 @@ private boolean isLocalVariable(Symbol sym) {
68
94
}
69
95
}
70
96
71
- private boolean isAnonymousClass (Symbol sym ) {
72
- return sym instanceof Symbol . ClassSymbol && sym .name . isEmpty () ;
97
+ private boolean isAnonymousClass (Element sym ) {
98
+ return sym instanceof TypeElement && sym .getSimpleName (). length () == 0 ;
73
99
}
74
100
75
- private SemanticdbSymbols .Descriptor semanticdbDescriptor (Symbol sym ) {
76
- if (sym instanceof Symbol . ClassSymbol ) {
101
+ private SemanticdbSymbols .Descriptor semanticdbDescriptor (Element sym ) {
102
+ if (sym instanceof TypeElement ) {
77
103
return new SemanticdbSymbols .Descriptor (
78
- SemanticdbSymbols .Descriptor .Kind .Type , sym .name .toString ());
79
- } else if (sym instanceof Symbol . MethodSymbol ) {
104
+ SemanticdbSymbols .Descriptor .Kind .Type , sym .getSimpleName () .toString ());
105
+ } else if (sym instanceof ExecutableElement ) {
80
106
return new SemanticdbSymbols .Descriptor (
81
107
SemanticdbSymbols .Descriptor .Kind .Method ,
82
- sym .name .toString (),
83
- methodDisambiguator ((Symbol .MethodSymbol ) sym ));
84
- } else if (sym instanceof Symbol .PackageSymbol ) {
85
- return new SemanticdbSymbols .Descriptor (
86
- SemanticdbSymbols .Descriptor .Kind .Package , sym .name .toString ());
87
- } else if (sym instanceof Symbol .TypeVariableSymbol ) {
108
+ sym .getSimpleName ().toString (),
109
+ methodDisambiguator ((ExecutableElement ) sym ));
110
+ } else if (sym instanceof TypeParameterElement ) {
88
111
return new SemanticdbSymbols .Descriptor (
89
- SemanticdbSymbols .Descriptor .Kind .TypeParameter , sym .name .toString ());
90
- } else if (sym instanceof Symbol . VarSymbol ) {
112
+ SemanticdbSymbols .Descriptor .Kind .TypeParameter , sym .getSimpleName () .toString ());
113
+ } else if (sym instanceof VariableElement ) {
91
114
return new SemanticdbSymbols .Descriptor (
92
- SemanticdbSymbols .Descriptor .Kind .Term , sym .name .toString ());
115
+ SemanticdbSymbols .Descriptor .Kind .Term , sym .getSimpleName () .toString ());
93
116
} else {
94
117
return SemanticdbSymbols .Descriptor .NONE ;
95
118
}
@@ -113,11 +136,11 @@ private SemanticdbSymbols.Descriptor semanticdbDescriptor(Symbol sym) {
113
136
* <p><a href="https://scalameta.org/docs/semanticdb/specification.html#symbol-2">Link to
114
137
* SemanticDB spec</a>.
115
138
*/
116
- private String methodDisambiguator (Symbol . MethodSymbol sym ) {
117
- Iterable <? extends Element > elements = sym .owner .getEnclosedElements ();
139
+ private String methodDisambiguator (ExecutableElement sym ) {
140
+ Iterable <? extends Element > elements = sym .getEnclosingElement () .getEnclosedElements ();
118
141
ArrayList <ExecutableElement > methods = new ArrayList <>();
119
142
for (Element e : elements ) {
120
- if (e instanceof ExecutableElement && e .getSimpleName () == sym .name ) {
143
+ if (e instanceof ExecutableElement && e .getSimpleName () == sym .getSimpleName () ) {
121
144
methods .add ((ExecutableElement ) e );
122
145
}
123
146
}
0 commit comments