src/share/classes/com/sun/tools/javac/code/Lint.java

changeset 1
9a66ca7c79fa
child 11
b66d15dfd001
equal deleted inserted replaced
-1:000000000000 1:9a66ca7c79fa
1 /*
2 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package com.sun.tools.javac.code;
27
28 import java.util.EnumSet;
29 import java.util.HashMap;
30 import java.util.Map;
31 import com.sun.tools.javac.code.Symbol.*;
32 import com.sun.tools.javac.util.Context;
33 import com.sun.tools.javac.util.List;
34 import com.sun.tools.javac.util.Options;
35 import com.sun.tools.javac.util.Pair;
36 import static com.sun.tools.javac.code.Flags.*;
37
38
39 /**
40 * A class for handling -Xlint suboptions and @SuppresssWarnings.
41 *
42 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
43 * you write code that depends on this, you do so at your own risk.
44 * This code and its internal interfaces are subject to change or
45 * deletion without notice.</b>
46 */
47 public class Lint
48 {
49 /** The context key for the root Lint object. */
50 protected static final Context.Key<Lint> lintKey = new Context.Key<Lint>();
51
52 /** Get the root Lint instance. */
53 public static Lint instance(Context context) {
54 Lint instance = context.get(lintKey);
55 if (instance == null)
56 instance = new Lint(context);
57 return instance;
58 }
59
60 /**
61 * Returns the result of combining the values in this object with
62 * the given annotation.
63 */
64 public Lint augment(Attribute.Compound attr) {
65 return augmentor.augment(this, attr);
66 }
67
68
69 /**
70 * Returns the result of combining the values in this object with
71 * the given annotations.
72 */
73 public Lint augment(List<Attribute.Compound> attrs) {
74 return augmentor.augment(this, attrs);
75 }
76
77 /**
78 * Returns the result of combining the values in this object with
79 * the given annotations and flags.
80 */
81 public Lint augment(List<Attribute.Compound> attrs, long flags) {
82 Lint l = augmentor.augment(this, attrs);
83 if ((flags & DEPRECATED) != 0) {
84 if (l == this)
85 l = new Lint(this);
86 l.values.remove(LintCategory.DEPRECATION);
87 l.suppressedValues.add(LintCategory.DEPRECATION);
88 }
89 return l;
90 }
91
92
93 private final AugmentVisitor augmentor;
94
95 private final EnumSet<LintCategory> values;
96 private final EnumSet<LintCategory> suppressedValues;
97
98 private static Map<String, LintCategory> map = new HashMap<String,LintCategory>();
99
100
101 protected Lint(Context context) {
102 // initialize values according to the lint options
103 Options options = Options.instance(context);
104 values = EnumSet.noneOf(LintCategory.class);
105 for (Map.Entry<String, LintCategory> e: map.entrySet()) {
106 if (options.lint(e.getKey()))
107 values.add(e.getValue());
108 }
109
110 suppressedValues = EnumSet.noneOf(LintCategory.class);
111
112 context.put(lintKey, this);
113 augmentor = new AugmentVisitor(context);
114 }
115
116 protected Lint(Lint other) {
117 this.augmentor = other.augmentor;
118 this.values = other.values.clone();
119 this.suppressedValues = other.suppressedValues.clone();
120 }
121
122 public String toString() {
123 return "Lint:[values" + values + " suppressedValues" + suppressedValues + "]";
124 }
125
126 /**
127 * Categories of warnings that can be generated by the compiler.
128 */
129 public enum LintCategory {
130 /**
131 * Warn about use of unnecessary casts.
132 */
133 CAST("cast"),
134
135 /**
136 * Warn about use of deprecated items.
137 */
138 DEPRECATION("deprecation"),
139
140 /**
141 * Warn about items which are documented with an {@code @deprecated} JavaDoc
142 * comment, but which do not have {@code @Deprecated} annotation.
143 */
144 DEP_ANN("dep-ann"),
145
146 /**
147 * Warn about division by constant integer 0.
148 */
149 DIVZERO("divzero"),
150
151 /**
152 * Warn about empty statement after if.
153 */
154 EMPTY("empty"),
155
156 /**
157 * Warn about falling through from one case of a switch statement to the next.
158 */
159 FALLTHROUGH("fallthrough"),
160
161 /**
162 * Warn about finally clauses that do not terminate normally.
163 */
164 FINALLY("finally"),
165
166 /**
167 * Warn about issues regarding method overrides.
168 */
169 OVERRIDES("overrides"),
170
171 /**
172 * Warn about invalid path elements on the command line.
173 * Such warnings cannot be suppressed with the SuppressWarnings
174 * annotation.
175 */
176 PATH("path"),
177
178 /**
179 * Warn about Serializable classes that do not provide a serial version ID.
180 */
181 SERIAL("serial"),
182
183 /**
184 * Warn about unchecked operations on raw types.
185 */
186 UNCHECKED("unchecked");
187
188 LintCategory(String option) {
189 this.option = option;
190 map.put(option, this);
191 }
192
193 static LintCategory get(String option) {
194 return map.get(option);
195 }
196
197 private final String option;
198 };
199
200 /**
201 * Checks if a warning category is enabled. A warning category may be enabled
202 * on the command line, or by default, and can be temporarily disabled with
203 * the SuppressWarnings annotation.
204 */
205 public boolean isEnabled(LintCategory lc) {
206 return values.contains(lc);
207 }
208
209 /**
210 * Checks is a warning category has been specifically suppressed, by means
211 * of the SuppressWarnings annotation, or, in the case of the deprecated
212 * category, whether it has been implicitly suppressed by virtue of the
213 * current entity being itself deprecated.
214 */
215 public boolean isSuppressed(LintCategory lc) {
216 return suppressedValues.contains(lc);
217 }
218
219 protected static class AugmentVisitor implements Attribute.Visitor {
220 private final Context context;
221 private Symtab syms;
222 private Lint parent;
223 private Lint lint;
224
225 AugmentVisitor(Context context) {
226 // to break an ugly sequence of initialization dependencies,
227 // we defer the initialization of syms until it is needed
228 this.context = context;
229 }
230
231 Lint augment(Lint parent, Attribute.Compound attr) {
232 initSyms();
233 this.parent = parent;
234 lint = null;
235 attr.accept(this);
236 return (lint == null ? parent : lint);
237 }
238
239 Lint augment(Lint parent, List<Attribute.Compound> attrs) {
240 initSyms();
241 this.parent = parent;
242 lint = null;
243 for (Attribute.Compound a: attrs) {
244 a.accept(this);
245 }
246 return (lint == null ? parent : lint);
247 }
248
249 private void initSyms() {
250 if (syms == null)
251 syms = Symtab.instance(context);
252 }
253
254 private void suppress(LintCategory lc) {
255 if (lint == null)
256 lint = new Lint(parent);
257 lint.suppressedValues.add(lc);
258 lint.values.remove(lc);
259 }
260
261 public void visitConstant(Attribute.Constant value) {
262 if (value.type.tsym == syms.stringType.tsym) {
263 LintCategory lc = LintCategory.get((String) (value.value));
264 if (lc != null)
265 suppress(lc);
266 }
267 }
268
269 public void visitClass(Attribute.Class clazz) {
270 }
271
272 // If we find a @SuppressWarnings annotation, then we continue
273 // walking the tree, in order to suppress the individual warnings
274 // specified in the @SuppressWarnings annotation.
275 public void visitCompound(Attribute.Compound compound) {
276 if (compound.type.tsym == syms.suppressWarningsType.tsym) {
277 for (List<Pair<MethodSymbol,Attribute>> v = compound.values;
278 v.nonEmpty(); v = v.tail) {
279 Pair<MethodSymbol,Attribute> value = v.head;
280 if (value.fst.name.toString().equals("value"))
281 value.snd.accept(this);
282 }
283
284 }
285 }
286
287 public void visitArray(Attribute.Array array) {
288 for (Attribute value : array.values)
289 value.accept(this);
290 }
291
292 public void visitEnum(Attribute.Enum e) {
293 }
294
295 public void visitError(Attribute.Error e) {
296 }
297 };
298 }

mercurial