23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package javax.annotation.processing; |
26 package javax.annotation.processing; |
27 |
27 |
|
28 import java.util.List; |
28 import java.util.Set; |
29 import java.util.Set; |
29 import java.util.HashSet; |
30 import java.util.HashSet; |
30 import java.util.Collections; |
31 import java.util.Collections; |
31 import java.util.Objects; |
32 import java.util.Objects; |
32 import javax.lang.model.element.*; |
33 import javax.lang.model.element.*; |
78 * @return the options recognized by this processor, or an empty |
79 * @return the options recognized by this processor, or an empty |
79 * set if none |
80 * set if none |
80 */ |
81 */ |
81 public Set<String> getSupportedOptions() { |
82 public Set<String> getSupportedOptions() { |
82 SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class); |
83 SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class); |
83 if (so == null) |
84 return (so == null) ? |
84 return Collections.emptySet(); |
85 Set.of() : |
85 else |
86 arrayToSet(so.value(), false, "option value", "@SupportedOptions"); |
86 return arrayToSet(so.value(), false); |
|
87 } |
87 } |
88 |
88 |
89 /** |
89 /** |
90 * If the processor class is annotated with {@link |
90 * If the processor class is annotated with {@link |
91 * SupportedAnnotationTypes}, return an unmodifiable set with the |
91 * SupportedAnnotationTypes}, return an unmodifiable set with the |
108 if (initialized) |
108 if (initialized) |
109 processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, |
109 processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, |
110 "No SupportedAnnotationTypes annotation " + |
110 "No SupportedAnnotationTypes annotation " + |
111 "found on " + this.getClass().getName() + |
111 "found on " + this.getClass().getName() + |
112 ", returning an empty set."); |
112 ", returning an empty set."); |
113 return Collections.emptySet(); |
113 return Set.of(); |
114 } else { |
114 } else { |
115 boolean stripModulePrefixes = |
115 boolean stripModulePrefixes = |
116 initialized && |
116 initialized && |
117 processingEnv.getSourceVersion().compareTo(SourceVersion.RELEASE_8) <= 0; |
117 processingEnv.getSourceVersion().compareTo(SourceVersion.RELEASE_8) <= 0; |
118 return arrayToSet(sat.value(), stripModulePrefixes); |
118 return arrayToSet(sat.value(), stripModulePrefixes, |
|
119 "annotation type", "@SupportedAnnotationTypes"); |
119 } |
120 } |
120 } |
121 } |
121 |
122 |
122 /** |
123 /** |
123 * If the processor class is annotated with {@link |
124 * If the processor class is annotated with {@link |
179 */ |
180 */ |
180 public Iterable<? extends Completion> getCompletions(Element element, |
181 public Iterable<? extends Completion> getCompletions(Element element, |
181 AnnotationMirror annotation, |
182 AnnotationMirror annotation, |
182 ExecutableElement member, |
183 ExecutableElement member, |
183 String userText) { |
184 String userText) { |
184 return Collections.emptyList(); |
185 return List.of(); |
185 } |
186 } |
186 |
187 |
187 /** |
188 /** |
188 * Returns {@code true} if this object has been {@linkplain #init |
189 * Returns {@code true} if this object has been {@linkplain #init |
189 * initialized}, {@code false} otherwise. |
190 * initialized}, {@code false} otherwise. |
193 */ |
194 */ |
194 protected synchronized boolean isInitialized() { |
195 protected synchronized boolean isInitialized() { |
195 return initialized; |
196 return initialized; |
196 } |
197 } |
197 |
198 |
198 private static Set<String> arrayToSet(String[] array, |
199 private Set<String> arrayToSet(String[] array, |
199 boolean stripModulePrefixes) { |
200 boolean stripModulePrefixes, |
|
201 String contentType, |
|
202 String annotationName) { |
200 assert array != null; |
203 assert array != null; |
201 Set<String> set = new HashSet<>(array.length); |
204 Set<String> set = new HashSet<>(); |
202 for (String s : array) { |
205 for (String s : array) { |
|
206 boolean stripped = false; |
203 if (stripModulePrefixes) { |
207 if (stripModulePrefixes) { |
204 int index = s.indexOf('/'); |
208 int index = s.indexOf('/'); |
205 if (index != -1) |
209 if (index != -1) { |
206 s = s.substring(index + 1); |
210 s = s.substring(index + 1); |
|
211 stripped = true; |
|
212 } |
207 } |
213 } |
208 set.add(s); |
214 boolean added = set.add(s); |
|
215 // Don't issue a duplicate warning when the module name is |
|
216 // stripped off to avoid spurious warnings in a case like |
|
217 // "foo/a.B", "bar/a.B". |
|
218 if (!added && !stripped && isInitialized() ) { |
|
219 processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, |
|
220 "Duplicate " + contentType + |
|
221 " ``" + s + "'' for processor " + |
|
222 this.getClass().getName() + |
|
223 " in its " + annotationName + |
|
224 "annotation."); |
|
225 } |
209 } |
226 } |
210 return Collections.unmodifiableSet(set); |
227 return Collections.unmodifiableSet(set); |
211 } |
228 } |
212 } |
229 } |