11package com .sourcegraph .semanticdb_javac ;
22
3- import com .sun .tools .javac .code .Symbol ;
4-
53import javax .lang .model .element .Element ;
64import javax .lang .model .element .ElementKind ;
75import 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 ;
914
1015import static com .sourcegraph .semanticdb_javac .Debugging .pprint ;
1116
1217/** Cache of SemanticDB symbols that can be referenced between files. */
1318public final class GlobalSymbolsCache {
1419
15- private final IdentityHashMap <Symbol , String > globals = new IdentityHashMap <>();
20+ private final IdentityHashMap <Element , String > globals = new IdentityHashMap <>();
1621 private final SemanticdbJavacOptions options ;
1722
1823 public GlobalSymbolsCache (SemanticdbJavacOptions options ) {
1924 this .options = options ;
2025 }
2126
22- public String semanticdbSymbol (Symbol sym , LocalSymbolsCache locals ) {
27+ public String semanticdbSymbol (Element sym , LocalSymbolsCache locals ) {
2328 String result = globals .get (sym );
2429 if (result != null ) return result ;
2530 String localResult = locals .get (sym );
@@ -31,33 +36,54 @@ public String semanticdbSymbol(Symbol sym, LocalSymbolsCache locals) {
3136 return result ;
3237 }
3338
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 ) {
3940 return sym == null ;
4041 }
4142
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+
5074 SemanticdbSymbols .Descriptor desc = semanticdbDescriptor (sym );
5175 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 ());
5379 pprint (
5480 String .format (
5581 "sym: %s (%s - superclass %s)" , sym , sym .getClass (), sym .getClass ().getSuperclass ()));
5682 }
5783 return SemanticdbSymbols .global (owner , desc );
5884 }
5985
60- private boolean isLocalVariable (Symbol sym ) {
86+ private boolean isLocalVariable (Element sym ) {
6187 switch (sym .getKind ()) {
6288 case PARAMETER :
6389 case EXCEPTION_PARAMETER :
@@ -68,28 +94,25 @@ private boolean isLocalVariable(Symbol sym) {
6894 }
6995 }
7096
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 ;
7399 }
74100
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 ) {
77103 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 ) {
80106 return new SemanticdbSymbols .Descriptor (
81107 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 ) {
88111 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 ) {
91114 return new SemanticdbSymbols .Descriptor (
92- SemanticdbSymbols .Descriptor .Kind .Term , sym .name .toString ());
115+ SemanticdbSymbols .Descriptor .Kind .Term , sym .getSimpleName () .toString ());
93116 } else {
94117 return SemanticdbSymbols .Descriptor .NONE ;
95118 }
@@ -113,11 +136,11 @@ private SemanticdbSymbols.Descriptor semanticdbDescriptor(Symbol sym) {
113136 * <p><a href="https://scalameta.org/docs/semanticdb/specification.html#symbol-2">Link to
114137 * SemanticDB spec</a>.
115138 */
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 ();
118141 ArrayList <ExecutableElement > methods = new ArrayList <>();
119142 for (Element e : elements ) {
120- if (e instanceof ExecutableElement && e .getSimpleName () == sym .name ) {
143+ if (e instanceof ExecutableElement && e .getSimpleName () == sym .getSimpleName () ) {
121144 methods .add ((ExecutableElement ) e );
122145 }
123146 }
0 commit comments