forked from eclipse-jdt/eclipse.jdt.core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
IrritantSet.java
323 lines (298 loc) · 13.2 KB
/
IrritantSet.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/*******************************************************************************
* Copyright (c) 2000, 2024 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contributions for
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
* bug 370639 - [compiler][resource] restore the default for resource leak warnings
* bug 265744 - Enum switch should warn about missing default
* bug 374605 - Unreasonable warning for enum-based switch statements
* bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
* Bug 441208 - [1.8][null]SuppressWarnings("null") does not suppress / marked Unnecessary
* Bug 410218 - Optional warning for arguments of "unexpected" types to Map#get(Object), Collection#remove(Object) et al.
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.impl;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
/**
* Represent a set of irritant flags. Irritants are organized in up to 8 group
* of 29, allowing for a maximum of 232 distinct irritants.
*/
public class IrritantSet {
// Reserve two high bits for selecting the right bit pattern
public final static int GROUP_MASK = ASTNode.Bit32 | ASTNode.Bit31 | ASTNode.Bit30;
public final static int GROUP_SHIFT = 29;
public final static int GROUP_MAX = 4; // can be increased up to 8
// Group prefix for irritants
public final static int GROUP0 = 0 << GROUP_SHIFT;
public final static int GROUP1 = 1 << GROUP_SHIFT;
public final static int GROUP2 = 2 << GROUP_SHIFT;
public final static int GROUP3 = 3 << GROUP_SHIFT;
// reveal subsequent groups as needed
// public final static int GROUP4 = 4 << GROUP_SHIFT;
// public final static int GROUP5 = 5 << GROUP_SHIFT;
// public final static int GROUP6 = 6 << GROUP_SHIFT;
// public final static int GROUP7 = 7 << GROUP_SHIFT;
// Predefine sets of irritants matching warning tokens
public static final IrritantSet ALL = new IrritantSet(0xFFFFFFFF & ~GROUP_MASK);
public static final IrritantSet BOXING = new IrritantSet(CompilerOptions.AutoBoxing);
public static final IrritantSet CAST = new IrritantSet(CompilerOptions.UnnecessaryTypeCheck);
public static final IrritantSet DEPRECATION = new IrritantSet(CompilerOptions.UsingDeprecatedAPI);
public static final IrritantSet TERMINAL_DEPRECATION = new IrritantSet(CompilerOptions.UsingTerminallyDeprecatedAPI);
public static final IrritantSet DEP_ANN = new IrritantSet(CompilerOptions.MissingDeprecatedAnnotation);
public static final IrritantSet FALLTHROUGH = new IrritantSet(CompilerOptions.FallthroughCase);
public static final IrritantSet FINALLY = new IrritantSet(CompilerOptions.FinallyBlockNotCompleting);
public static final IrritantSet HIDING = new IrritantSet(CompilerOptions.MaskedCatchBlock);
public static final IrritantSet INCOMPLETE_SWITCH = new IrritantSet(CompilerOptions.MissingEnumConstantCase);
public static final IrritantSet NLS = new IrritantSet(CompilerOptions.NonExternalizedString);
public static final IrritantSet NULL = new IrritantSet(CompilerOptions.NullReference);
public static final IrritantSet RAW = new IrritantSet(CompilerOptions.RawTypeReference);
public static final IrritantSet RESTRICTION = new IrritantSet(CompilerOptions.ForbiddenReference);
public static final IrritantSet SERIAL = new IrritantSet(CompilerOptions.MissingSerialVersion);
public static final IrritantSet STATIC_ACCESS = new IrritantSet(CompilerOptions.IndirectStaticAccess);
public static final IrritantSet STATIC_METHOD = new IrritantSet(CompilerOptions.MethodCanBeStatic);
public static final IrritantSet SYNTHETIC_ACCESS = new IrritantSet(CompilerOptions.AccessEmulation);
public static final IrritantSet SYNCHRONIZED = new IrritantSet(CompilerOptions.MissingSynchronizedModifierInInheritedMethod);
public static final IrritantSet SUPER = new IrritantSet(CompilerOptions.OverridingMethodWithoutSuperInvocation);
public static final IrritantSet UNUSED = new IrritantSet(CompilerOptions.UnusedLocalVariable);
public static final IrritantSet UNCHECKED = new IrritantSet(CompilerOptions.UncheckedTypeOperation);
public static final IrritantSet UNQUALIFIED_FIELD_ACCESS = new IrritantSet(CompilerOptions.UnqualifiedFieldAccess);
public static final IrritantSet RESOURCE = new IrritantSet(CompilerOptions.UnclosedCloseable);
public static final IrritantSet UNLIKELY_ARGUMENT_TYPE = new IrritantSet(CompilerOptions.UnlikelyCollectionMethodArgumentType);
public static final IrritantSet API_LEAK = new IrritantSet(CompilerOptions.APILeak);
public static final IrritantSet MODULE = new IrritantSet(CompilerOptions.UnstableAutoModuleName);
public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc);
public static final IrritantSet PREVIEW = new IrritantSet(CompilerOptions.PreviewFeatureUsed);
public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default
public static final IrritantSet COMPILER_DEFAULT_WARNINGS = new IrritantSet(0); // see static initializer below
public static final IrritantSet COMPILER_DEFAULT_INFOS = new IrritantSet(0); // see static initializer below
static {
COMPILER_DEFAULT_INFOS
// group-2 infos enabled by default
.set(
CompilerOptions.UnlikelyEqualsArgumentType
| CompilerOptions.SuppressWarningsNotAnalysed
| CompilerOptions.AnnotatedTypeArgumentToUnannotated);
COMPILER_DEFAULT_WARNINGS
// group-0 warnings enabled by default
.set(
CompilerOptions.MethodWithConstructorName
| CompilerOptions.OverriddenPackageDefaultMethod
| CompilerOptions.UsingDeprecatedAPI
| CompilerOptions.MaskedCatchBlock
| CompilerOptions.UnusedLocalVariable
| CompilerOptions.NoImplicitStringConversion
| CompilerOptions.AssertUsedAsAnIdentifier
| CompilerOptions.UnusedImport
| CompilerOptions.NonStaticAccessToStatic
| CompilerOptions.NoEffectAssignment
| CompilerOptions.IncompatibleNonInheritedInterfaceMethod
| CompilerOptions.UnusedPrivateMember
| CompilerOptions.FinallyBlockNotCompleting)
// group-1 warnings enabled by default
.set(
CompilerOptions.UncheckedTypeOperation
| CompilerOptions.FinalParameterBound
| CompilerOptions.MissingSerialVersion
| CompilerOptions.EnumUsedAsAnIdentifier
| CompilerOptions.ForbiddenReference
| CompilerOptions.VarargsArgumentNeedCast
| CompilerOptions.NullReference
| CompilerOptions.AnnotationSuperInterface
| CompilerOptions.TypeHiding
| CompilerOptions.DiscouragedReference
| CompilerOptions.UnhandledWarningToken
| CompilerOptions.RawTypeReference
| CompilerOptions.UnusedLabel
| CompilerOptions.UnusedTypeArguments
| CompilerOptions.UnusedWarningToken
| CompilerOptions.ComparingIdentical
| CompilerOptions.MissingEnumConstantCase)
// group-2 warnings enabled by default
.set(
CompilerOptions.DeadCode
|CompilerOptions.Tasks
|CompilerOptions.UnclosedCloseable
|CompilerOptions.NullUncheckedConversion
|CompilerOptions.RedundantNullAnnotation
|CompilerOptions.NonnullParameterAnnotationDropped
|CompilerOptions.PessimisticNullAnalysisForFreeTypeVariables
|CompilerOptions.NonNullTypeVariableFromLegacyInvocation
|CompilerOptions.UnlikelyCollectionMethodArgumentType
|CompilerOptions.UsingTerminallyDeprecatedAPI
|CompilerOptions.APILeak
|CompilerOptions.UnstableAutoModuleName
|CompilerOptions.PreviewFeatureUsed)
.set(CompilerOptions.InsufficientResourceManagement
|CompilerOptions.IncompatibleOwningContract);
// default errors IF AnnotationBasedNullAnalysis is enabled:
COMPILER_DEFAULT_ERRORS.set(
CompilerOptions.NullSpecViolation
|CompilerOptions.NullAnnotationInferenceConflict);
ALL.setAll();
HIDING
.set(CompilerOptions.FieldHiding)
.set(CompilerOptions.LocalVariableHiding)
.set(CompilerOptions.TypeHiding);
NULL
.set(CompilerOptions.PotentialNullReference)
.set(CompilerOptions.RedundantNullCheck)
.set(CompilerOptions.NullSpecViolation)
.set(CompilerOptions.NullAnnotationInferenceConflict)
.set(CompilerOptions.NullUncheckedConversion)
.set(CompilerOptions.RedundantNullAnnotation)
.set(CompilerOptions.NonnullParameterAnnotationDropped)
.set(CompilerOptions.MissingNonNullByDefaultAnnotation)
.set(CompilerOptions.PessimisticNullAnalysisForFreeTypeVariables)
.set(CompilerOptions.NonNullTypeVariableFromLegacyInvocation)
.set(CompilerOptions.AnnotatedTypeArgumentToUnannotated);
RESTRICTION.set(CompilerOptions.DiscouragedReference);
STATIC_ACCESS.set(CompilerOptions.NonStaticAccessToStatic);
UNUSED
.set(CompilerOptions.UnusedArgument)
.set(CompilerOptions.UnusedExceptionParameter)
.set(CompilerOptions.UnusedPrivateMember)
.set(CompilerOptions.UnusedDeclaredThrownException)
.set(CompilerOptions.UnusedLabel)
.set(CompilerOptions.UnusedImport)
.set(CompilerOptions.UnusedTypeArguments)
.set(CompilerOptions.RedundantSuperinterface)
.set(CompilerOptions.DeadCode)
.set(CompilerOptions.UnusedObjectAllocation)
.set(CompilerOptions.UnusedTypeParameter)
.set(CompilerOptions.RedundantSpecificationOfTypeArguments);
STATIC_METHOD
.set(CompilerOptions.MethodCanBePotentiallyStatic);
RESOURCE
.set(CompilerOptions.PotentiallyUnclosedCloseable
|CompilerOptions.ExplicitlyClosedAutoCloseable)
.set(CompilerOptions.InsufficientResourceManagement
|CompilerOptions.IncompatibleOwningContract);
INCOMPLETE_SWITCH.set(CompilerOptions.MissingDefaultCase);
String suppressRawWhenUnchecked = System.getProperty("suppressRawWhenUnchecked"); //$NON-NLS-1$
if (suppressRawWhenUnchecked != null && "true".equalsIgnoreCase(suppressRawWhenUnchecked)) { //$NON-NLS-1$
UNCHECKED.set(CompilerOptions.RawTypeReference);
}
JAVADOC
.set(CompilerOptions.MissingJavadocComments)
.set(CompilerOptions.MissingJavadocTags);
UNLIKELY_ARGUMENT_TYPE
.set(CompilerOptions.UnlikelyEqualsArgumentType);
}
// Internal state
private int[] bits = new int[GROUP_MAX];
/**
* Constructor with initial irritant set
*/
public IrritantSet(int singleGroupIrritants) {
initialize(singleGroupIrritants);
}
/**
* Constructor with initial irritant set
*/
public IrritantSet(IrritantSet other) {
initialize(other);
}
public boolean areAllSet() {
for (int i = 0; i < GROUP_MAX; i++) {
if (this.bits[i] != (0xFFFFFFFF & ~GROUP_MASK))
return false;
}
return true;
}
public IrritantSet clear(int singleGroupIrritants) {
int group = (singleGroupIrritants & GROUP_MASK) >>> GROUP_SHIFT;
this.bits[group] &= ~singleGroupIrritants;
return this;
}
public IrritantSet clearAll() {
for (int i = 0; i < GROUP_MAX; i++) {
this.bits[i] = 0;
}
return this;
}
/**
* Initialize a set of irritants in one group
*/
public void initialize(int singleGroupIrritants) {
if (singleGroupIrritants == 0)
return;
int group = (singleGroupIrritants & GROUP_MASK) >>> GROUP_SHIFT;
this.bits[group] = singleGroupIrritants & ~GROUP_MASK; // erase group information
}
public void initialize(IrritantSet other) {
if (other == null)
return;
System.arraycopy(other.bits, 0, this.bits = new int[GROUP_MAX], 0, GROUP_MAX);
}
/**
* Returns true if any of the irritants in given other set is positionned in receiver
*/
public boolean isAnySet(IrritantSet other) {
if (other == null)
return false;
for (int i = 0; i < GROUP_MAX; i++) {
if ((this.bits[i] & other.bits[i]) != 0)
return true;
}
return false;
}
/**
* Returns true if all of the irritants in the given irritant set are set in receiver
* @param irritantSet the given irritant set
*/
public boolean hasSameIrritants(IrritantSet irritantSet) {
if (irritantSet == null)
return false;
for (int i = 0; i < GROUP_MAX; i++) {
if (this.bits[i] != irritantSet.bits[i])
return false;
}
return true;
}
public boolean isSet(int singleGroupIrritants) {
int group = (singleGroupIrritants & GROUP_MASK) >>> GROUP_SHIFT;
return (this.bits[group] & singleGroupIrritants) != 0;
}
public int[] getBits() {
return this.bits;
}
public IrritantSet set(int singleGroupIrritants) {
int group = (singleGroupIrritants & GROUP_MASK) >>> GROUP_SHIFT;
this.bits[group] |= (singleGroupIrritants & ~GROUP_MASK); // erase the group bits
return this;
}
/**
* Return updated irritantSet or null if it was a no-op
*/
public IrritantSet set(IrritantSet other) {
if (other == null)
return this;
boolean wasNoOp = true;
for (int i = 0; i < GROUP_MAX; i++) {
int otherIrritant = other.bits[i] & ~GROUP_MASK; // erase the
// group
// bits
if ((this.bits[i] & otherIrritant) != otherIrritant) {
wasNoOp = false;
this.bits[i] |= otherIrritant;
}
}
return wasNoOp ? null : this;
}
public IrritantSet setAll() {
for (int i = 0; i < GROUP_MAX; i++) {
this.bits[i] |= 0xFFFFFFFF & ~GROUP_MASK; // erase the group
// bits;
}
return this;
}
}