1
1
/*
2
- * Copyright (c) 2012, 2020 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2012, 2021 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
26
26
package jdk .javadoc .internal .doclint ;
27
27
28
28
29
+ import java .util .ArrayList ;
29
30
import java .util .Arrays ;
31
+ import java .util .Collections ;
32
+ import java .util .EnumSet ;
33
+ import java .util .HashMap ;
30
34
import java .util .HashSet ;
31
35
import java .util .LinkedHashSet ;
32
36
import java .util .List ;
37
+ import java .util .Map ;
33
38
import java .util .Set ;
39
+ import java .util .function .Function ;
34
40
import java .util .regex .Pattern ;
41
+ import java .util .stream .Collectors ;
35
42
43
+ import javax .lang .model .element .AnnotationMirror ;
44
+ import javax .lang .model .element .AnnotationValue ;
36
45
import javax .lang .model .element .Element ;
37
46
import javax .lang .model .element .ElementKind ;
38
47
import javax .lang .model .element .ExecutableElement ;
39
48
import javax .lang .model .element .Modifier ;
49
+ import javax .lang .model .type .DeclaredType ;
50
+ import javax .lang .model .type .TypeKind ;
40
51
import javax .lang .model .type .TypeMirror ;
41
52
import javax .lang .model .util .Elements ;
42
53
import javax .lang .model .util .Types ;
43
- import javax .tools .Diagnostic .Kind ;
44
54
45
55
import com .sun .source .doctree .DocCommentTree ;
46
56
import com .sun .source .tree .CompilationUnitTree ;
@@ -106,6 +116,7 @@ else if (mods.contains(Modifier.PRIVATE))
106
116
// Types used when analysing doc comments.
107
117
TypeMirror java_lang_Error ;
108
118
TypeMirror java_lang_RuntimeException ;
119
+ TypeMirror java_lang_SuppressWarnings ;
109
120
TypeMirror java_lang_Throwable ;
110
121
TypeMirror java_lang_Void ;
111
122
@@ -125,6 +136,9 @@ else if (mods.contains(Modifier.PRIVATE))
125
136
/** The set of methods, if any, that the current declaration overrides. */
126
137
Set <? extends ExecutableElement > currOverriddenMethods ;
127
138
139
+ /** A map containing the info derived from {@code @SuppressWarnings} for an element. */
140
+ Map <Element , Set <Messages .Group >> suppressWarnings = new HashMap <>();
141
+
128
142
Env () {
129
143
messages = new Messages (this );
130
144
}
@@ -145,6 +159,7 @@ void initTypes() {
145
159
146
160
java_lang_Error = elements .getTypeElement ("java.lang.Error" ).asType ();
147
161
java_lang_RuntimeException = elements .getTypeElement ("java.lang.RuntimeException" ).asType ();
162
+ java_lang_SuppressWarnings = elements .getTypeElement ("java.lang.SuppressWarnings" ).asType ();
148
163
java_lang_Throwable = elements .getTypeElement ("java.lang.Throwable" ).asType ();
149
164
java_lang_Void = elements .getTypeElement ("java.lang.Void" ).asType ();
150
165
}
@@ -247,6 +262,96 @@ boolean shouldCheck(CompilationUnitTree unit) {
247
262
return true ;
248
263
}
249
264
265
+ /**
266
+ * {@return whether or not warnings in a group are suppressed for the current element}
267
+ * @param g the group
268
+ */
269
+ boolean suppressWarnings (Messages .Group g ) {
270
+ return suppressWarnings (currElement , g );
271
+ }
272
+
273
+ /**
274
+ * {@return whether or not warnings in a group are suppressed for a given element}
275
+ * @param e the element
276
+ * @param g the group
277
+ */
278
+ boolean suppressWarnings (Element e , Messages .Group g ) {
279
+ // check if warnings are suppressed in any enclosing classes
280
+ Element encl = e .getEnclosingElement ();
281
+ if (encl != null && encl .asType ().getKind () == TypeKind .DECLARED ) {
282
+ if (suppressWarnings (encl , g )) {
283
+ return true ;
284
+ }
285
+ }
286
+
287
+ // check the local @SuppressWarnings annotation, caching the results
288
+ return suppressWarnings .computeIfAbsent (e , this ::getSuppressedGroups ).contains (g );
289
+ }
290
+
291
+ /**
292
+ * Returns the set of groups for an element for which messages should be suppressed.
293
+ * The set is determined by examining the arguments for any {@code @SuppressWarnings}
294
+ * annotation that may be present on the element.
295
+ * The supported strings are: "doclint" and "doclint:GROUP,..." for each GROUP
296
+ *
297
+ * @param e the element
298
+ * @return the set
299
+ */
300
+ private Set <Messages .Group > getSuppressedGroups (Element e ) {
301
+ var gMap = Arrays .stream (Messages .Group .values ())
302
+ .collect (Collectors .toMap (Messages .Group ::optName , Function .identity ()));
303
+ var set = EnumSet .noneOf (Messages .Group .class );
304
+ for (String arg : getSuppressWarningsValue (e )) {
305
+ if (arg .equals ("doclint" )) {
306
+ set = EnumSet .allOf (Messages .Group .class );
307
+ break ;
308
+ } else if (arg .startsWith ("doclint:" )) {
309
+ final int len = "doclint:" .length ();
310
+ for (String a : arg .substring (len ).split ("," )) {
311
+ Messages .Group argGroup = gMap .get (a );
312
+ if (argGroup != null ) {
313
+ set .add (argGroup );
314
+ }
315
+ }
316
+ }
317
+ }
318
+ return set ;
319
+ }
320
+
321
+ /**
322
+ * Returns the list of values given to an instance of {@code @SuppressWarnings} for an element,
323
+ * or an empty list if there is no annotation.
324
+ *
325
+ * @param e the element
326
+ * @return the list
327
+ */
328
+ private List <String > getSuppressWarningsValue (Element e ) {
329
+ for (AnnotationMirror am : e .getAnnotationMirrors ()) {
330
+ DeclaredType dt = am .getAnnotationType ();
331
+ if (types .isSameType (dt , java_lang_SuppressWarnings )) {
332
+ var values = am .getElementValues ();
333
+ for (var entry : values .entrySet ()) {
334
+ if (entry .getKey ().getSimpleName ().contentEquals ("value" )) {
335
+ AnnotationValue av = entry .getValue ();
336
+ if (av .getValue () instanceof List <?> list ) {
337
+ List <String > result = new ArrayList <>();
338
+ for (var item : list ) {
339
+ if (item instanceof AnnotationValue avItem
340
+ && avItem .getValue () instanceof String s ) {
341
+ result .add (s );
342
+ }
343
+ }
344
+ return result ;
345
+ }
346
+ }
347
+ }
348
+
349
+ }
350
+ }
351
+ return Collections .emptyList ();
352
+ }
353
+
354
+
250
355
private <T extends Comparable <T >> T min (T item1 , T item2 ) {
251
356
return (item1 == null ) ? item2
252
357
: (item2 == null ) ? item1
0 commit comments