mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
MagicConstantInspection: handle special case of Calendar.get()
Fixes IDEA-144891 Good code is red: "Magic Constant" with Calendar.get() Tests modernized
This commit is contained in:
+52
-15
@@ -34,7 +34,11 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import com.siyeh.ig.callMatcher.CallMapper;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import gnu.trove.THashSet;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -42,11 +46,18 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
public class MagicConstantInspection extends AbstractBaseJavaLocalInspectionTool {
|
||||
private static final Key<Boolean> NO_ANNOTATIONS_FOUND = Key.create("REPORTED_NO_ANNOTATIONS_FOUND");
|
||||
|
||||
private static final CallMapper<AllowedValues> SPECIAL_CASES = new CallMapper<AllowedValues>()
|
||||
.register(CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_CALENDAR, "get").parameterTypes("int"),
|
||||
MagicConstantInspection::getCalendarGetValues);
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -136,9 +147,11 @@ public class MagicConstantInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
}
|
||||
}
|
||||
else if (l instanceof PsiMethodCallExpression) {
|
||||
PsiMethod method = ((PsiMethodCallExpression)l).resolveMethod();
|
||||
PsiMethodCallExpression call = (PsiMethodCallExpression)l;
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (method != null) {
|
||||
checkExpression(r, method, method.getReturnType(), holder);
|
||||
checkExpression(r, holder, SPECIAL_CASES.mapFirst(call));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -204,6 +217,12 @@ public class MagicConstantInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
@Nullable PsiType type,
|
||||
@NotNull ProblemsHolder holder) {
|
||||
AllowedValues allowed = getAllowedValues(owner, type, null);
|
||||
checkExpression(expression, holder, allowed);
|
||||
}
|
||||
|
||||
private static void checkExpression(@NotNull PsiExpression expression,
|
||||
@NotNull ProblemsHolder holder,
|
||||
AllowedValues allowed) {
|
||||
if (allowed == null) return;
|
||||
PsiElement scope = PsiUtil.getTopLevelEnclosingCodeBlock(expression, null);
|
||||
if (scope == null) scope = expression;
|
||||
@@ -213,10 +232,12 @@ public class MagicConstantInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
}
|
||||
|
||||
private static void checkCall(@NotNull PsiCallExpression methodCall, @NotNull ProblemsHolder holder) {
|
||||
PsiExpressionList argumentList = methodCall.getArgumentList();
|
||||
if (argumentList == null) return;
|
||||
PsiMethod method = methodCall.resolveMethod();
|
||||
if (method == null) return;
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
PsiExpression[] arguments = methodCall.getArgumentList().getExpressions();
|
||||
PsiExpression[] arguments = argumentList.getExpressions();
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
PsiParameter parameter = parameters[i];
|
||||
AllowedValues values = getAllowedValues(parameter, parameter.getType(), null);
|
||||
@@ -285,17 +306,8 @@ public class MagicConstantInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
}
|
||||
|
||||
boolean isSubsetOf(@NotNull AllowedValues other, @NotNull PsiManager manager) {
|
||||
for (PsiAnnotationMemberValue value : values) {
|
||||
boolean found = false;
|
||||
for (PsiAnnotationMemberValue otherValue : other.values) {
|
||||
if (same(value, otherValue, manager)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) return false;
|
||||
}
|
||||
return true;
|
||||
return Arrays.stream(values).allMatch(
|
||||
value -> Arrays.stream(other.values).anyMatch(otherValue -> same(value, otherValue, manager)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,6 +418,30 @@ public class MagicConstantInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
return parseBeanInfo(element, manager);
|
||||
}
|
||||
|
||||
private static AllowedValues getCalendarGetValues(PsiMethodCallExpression call) {
|
||||
Integer argument = tryCast(ExpressionUtils.computeConstantExpression(call.getArgumentList().getExpressions()[0]), Integer.class);
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (method == null || argument == null) return null;
|
||||
return CachedValuesManager.getCachedValue(method, () -> {
|
||||
final String[] days = {"SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"};
|
||||
final String[] months = {"JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY",
|
||||
"AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"};
|
||||
final String[] amPm = {"AM", "PM"};
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(method.getProject());
|
||||
Function<String[], AllowedValues> converter = strings -> {
|
||||
String expression = StreamEx.of(strings)
|
||||
.map((CommonClassNames.JAVA_UTIL_CALENDAR + ".")::concat).joining(",", "{", "}");
|
||||
PsiArrayInitializerExpression initializer = (PsiArrayInitializerExpression)factory.createExpressionFromText(expression, method);
|
||||
return new AllowedValues(initializer.getInitializers(), false);
|
||||
};
|
||||
Map<Integer, AllowedValues> map = new HashMap<>();
|
||||
map.put(Calendar.DAY_OF_WEEK, converter.apply(days));
|
||||
map.put(Calendar.MONTH, converter.apply(months));
|
||||
map.put(Calendar.AM_PM, converter.apply(amPm));
|
||||
return CachedValueProvider.Result.create(map, method);
|
||||
}).get(argument);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner element) {
|
||||
return CachedValuesManager.getCachedValue(element, () ->
|
||||
@@ -708,7 +744,7 @@ public class MagicConstantInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
static boolean processValuesFlownTo(@NotNull final PsiExpression argument,
|
||||
@NotNull PsiElement scope,
|
||||
@NotNull PsiManager manager,
|
||||
@NotNull final Processor<PsiExpression> processor) {
|
||||
@NotNull final Processor<? super PsiExpression> processor) {
|
||||
SliceAnalysisParams params = new SliceAnalysisParams();
|
||||
params.dataFlowToThis = true;
|
||||
params.scope = new AnalysisScope(new LocalSearchScope(scope), manager.getProject());
|
||||
@@ -744,7 +780,8 @@ public class MagicConstantInspection extends AbstractBaseJavaLocalInspectionTool
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
List<String> names = myMemberValuePointers.stream().map(SmartPsiElementPointer::getElement).map(PsiElement::getText).collect(Collectors.toList());
|
||||
List<String> names = myMemberValuePointers.stream().map(SmartPsiElementPointer::getElement).filter(Objects::nonNull)
|
||||
.map(PsiElement::getText).collect(Collectors.toList());
|
||||
String expression = StringUtil.join(names, " | ");
|
||||
return "Replace with '" + expression + "'";
|
||||
}
|
||||
|
||||
+13
-13
@@ -24,13 +24,13 @@ class Const2 {
|
||||
public static final int I = 4;
|
||||
}
|
||||
|
||||
public class X {
|
||||
class X {
|
||||
|
||||
void f(@MagicConstant(intValues = {Const1.X, Const2.I}) int x) {
|
||||
/////////// BAD
|
||||
f(0);
|
||||
f(1);
|
||||
f(Const1.X | Const2.I);
|
||||
f(<warning descr="Should be one of: Const1.X, Const2.I">0</warning>);
|
||||
f(<warning descr="Should be one of: Const1.X, Const2.I">1</warning>);
|
||||
f(<warning descr="Should be one of: Const1.X, Const2.I">Const1.X | Const2.I</warning>);
|
||||
|
||||
////////////// GOOD
|
||||
f(Const1.X);
|
||||
@@ -41,9 +41,9 @@ public class X {
|
||||
|
||||
void f2(@MagicConstant(valuesFromClass = Const1.class, intValues = {Const2.I}) int x) {
|
||||
/////////// BAD
|
||||
f2(0);
|
||||
f2(1);
|
||||
f2(Const1.X | Const2.I);
|
||||
f2(<warning descr="Should be one of: Const2.I, Const1.X">0</warning>);
|
||||
f2(<warning descr="Should be one of: Const2.I, Const1.X">1</warning>);
|
||||
f2(<warning descr="Should be one of: Const2.I, Const1.X">Const1.X | Const2.I</warning>);
|
||||
|
||||
////////////// GOOD
|
||||
f2(Const1.X);
|
||||
@@ -54,11 +54,11 @@ public class X {
|
||||
|
||||
void f3(@MagicConstant(flags = {Const1.X, Const2.I}) int x) {
|
||||
/////////// BAD
|
||||
f3(2);
|
||||
f3(1);
|
||||
f(Const1.X | Const2.I);
|
||||
f3(<warning descr="Should be one of: Const1.X, Const2.I or their combination">2</warning>);
|
||||
f3(<warning descr="Should be one of: Const1.X, Const2.I or their combination">1</warning>);
|
||||
f(<warning descr="Should be one of: Const1.X, Const2.I">Const1.X | Const2.I</warning>);
|
||||
int i = Const1.X | 4;
|
||||
f3(i);
|
||||
f3(<warning descr="Should be one of: Const1.X, Const2.I or their combination">i</warning>);
|
||||
|
||||
////////////// GOOD
|
||||
f3(Const1.X);
|
||||
@@ -69,8 +69,8 @@ public class X {
|
||||
|
||||
void f4(@MagicConstant(flagsFromClass = Const1.class, flags = {Const2.I}) int x) {
|
||||
/////////// BAD
|
||||
f4(-3);
|
||||
f4(1);
|
||||
f4(<warning descr="Should be one of: Const2.I, Const1.X or their combination">-3</warning>);
|
||||
f4(<warning descr="Should be one of: Const2.I, Const1.X or their combination">1</warning>);
|
||||
|
||||
////////////// GOOD
|
||||
f4(Const1.X);
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
class Const {
|
||||
public static final int X = 1;
|
||||
public static final int Y = 2;
|
||||
public static final int Z = 4;
|
||||
}
|
||||
public class X {
|
||||
|
||||
void f(@MagicConstant(intValues={Const.X, Const.Y, Const.Z}) int x) {
|
||||
/////////// BAD
|
||||
f(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">0</warning>);
|
||||
f(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">1</warning>);
|
||||
f(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">Const.X | Const.Y</warning>);
|
||||
int i = Const.X | Const.Y;
|
||||
f(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">i</warning>);
|
||||
if (x == <warning descr="Should be one of: Const.X, Const.Y, Const.Z">3</warning>) {
|
||||
x = <warning descr="Should be one of: Const.X, Const.Y, Const.Z">2</warning>;
|
||||
assert x != <warning descr="Should be one of: Const.X, Const.Y, Const.Z">1</warning>;
|
||||
}
|
||||
|
||||
////////////// GOOD
|
||||
f(Const.X);
|
||||
f(Const.Y);
|
||||
f(Const.Z);
|
||||
int i2 = this == null ? Const.X : Const.Y;
|
||||
f(i2);
|
||||
if (x == Const.X) {
|
||||
x = Const.Y;
|
||||
assert x != Const.Z;
|
||||
}
|
||||
|
||||
f2(x);
|
||||
}
|
||||
|
||||
void f2(@MagicConstant(valuesFromClass =Const.class) int x) {
|
||||
/////////// BAD
|
||||
f2(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">0</warning>);
|
||||
f2(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">1</warning>);
|
||||
f2(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">Const.X | Const.Y</warning>);
|
||||
int i = Const.X | Const.Y;
|
||||
f2(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">i</warning>);
|
||||
if (x == <warning descr="Should be one of: Const.X, Const.Y, Const.Z">3</warning>) {
|
||||
x = <warning descr="Should be one of: Const.X, Const.Y, Const.Z">2</warning>;
|
||||
assert x != <warning descr="Should be one of: Const.X, Const.Y, Const.Z">1</warning>;
|
||||
}
|
||||
|
||||
////////////// GOOD
|
||||
f2(Const.X);
|
||||
f2(Const.Y);
|
||||
f2(Const.Z);
|
||||
int i2 = this == null ? Const.X : Const.Y;
|
||||
f2(i2);
|
||||
if (x == Const.X) {
|
||||
x = Const.Y;
|
||||
assert x != Const.Z;
|
||||
}
|
||||
|
||||
f(x);
|
||||
}
|
||||
|
||||
void f3(@MagicConstant(flags ={Const.X, Const.Y, Const.Z}) int x) {
|
||||
/////////// BAD
|
||||
f3(<warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">2</warning>);
|
||||
f3(<warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">1</warning>);
|
||||
f(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">Const.X | Const.Y</warning>);
|
||||
int i = Const.X | 4;
|
||||
f3(<warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">i</warning>);
|
||||
if (x == <warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">3</warning>) {
|
||||
x = <warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">2</warning>;
|
||||
assert x != <warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">1</warning>;
|
||||
}
|
||||
|
||||
////////////// GOOD
|
||||
f3(Const.X);
|
||||
f3(Const.Y);
|
||||
f3(Const.Z);
|
||||
|
||||
int i2 = this == null ? Const.X : Const.Y;
|
||||
f3(i2);
|
||||
int ix = Const.X | Const.Y;
|
||||
f3(ix);
|
||||
f3(0);
|
||||
f3(-1);
|
||||
int f = 0;
|
||||
if (x == Const.X) {
|
||||
x = Const.Y;
|
||||
assert x != Const.Z;
|
||||
f |= Const.Y; f &= Const.X & ~(Const.Z | Const.X);
|
||||
}
|
||||
else {
|
||||
f |= Const.X; f = f & ~(Const.X | Const.X);
|
||||
}
|
||||
f3(f);
|
||||
|
||||
f4(x);
|
||||
}
|
||||
|
||||
void f4(@MagicConstant(flagsFromClass =Const.class) int x) {
|
||||
/////////// BAD
|
||||
f4(<warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">-3</warning>);
|
||||
f4(<warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">1</warning>);
|
||||
f4(Const.X | Const.Y);
|
||||
int i = Const.X | 4;
|
||||
f4(<warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">i</warning>);
|
||||
if (x == <warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">3</warning>) {
|
||||
x = <warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">2</warning>;
|
||||
assert x != <warning descr="Should be one of: Const.X, Const.Y, Const.Z or their combination">1</warning>;
|
||||
}
|
||||
|
||||
////////////// GOOD
|
||||
f4(Const.X);
|
||||
f4(Const.Y);
|
||||
f4(Const.Z);
|
||||
|
||||
int i2 = this == null ? Const.X : Const.Y;
|
||||
f4(i2);
|
||||
int ix = Const.X | Const.Y;
|
||||
f4(ix);
|
||||
f4(0);
|
||||
f4(-1);
|
||||
int f = 0;
|
||||
if (x == Const.X) {
|
||||
x = Const.Y;
|
||||
assert x != Const.Z;
|
||||
f |= Const.Y;
|
||||
}
|
||||
else {
|
||||
f |= Const.X;
|
||||
}
|
||||
f4(f);
|
||||
|
||||
f3(x);
|
||||
}
|
||||
|
||||
@MagicConstant(intValues={Const.X, Const.Y, Const.Z})
|
||||
@interface IntEnum{}
|
||||
|
||||
class Alias {
|
||||
|
||||
void f(@IntEnum int x) {
|
||||
////////////// GOOD
|
||||
f(Const.X);
|
||||
f(Const.Y);
|
||||
f(Const.Z);
|
||||
int i2 = this == null ? Const.X : Const.Y;
|
||||
f(i2);
|
||||
if (x == Const.X) {
|
||||
x = Const.Y;
|
||||
assert x != Const.Z;
|
||||
}
|
||||
|
||||
f2(x);
|
||||
|
||||
/////////// BAD
|
||||
f(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">0</warning>);
|
||||
f(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">1</warning>);
|
||||
f(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">Const.X | Const.Y</warning>);
|
||||
int i = Const.X | Const.Y;
|
||||
f(<warning descr="Should be one of: Const.X, Const.Y, Const.Z">i</warning>);
|
||||
if (x == <warning descr="Should be one of: Const.X, Const.Y, Const.Z">3</warning> || getClass().isInterface()) {
|
||||
x = <warning descr="Should be one of: Const.X, Const.Y, Const.Z">2</warning>;
|
||||
assert x != <warning descr="Should be one of: Const.X, Const.Y, Const.Z">1</warning>;
|
||||
}
|
||||
|
||||
f2(x);
|
||||
}
|
||||
}
|
||||
|
||||
@interface III {
|
||||
@MagicConstant(intValues = {Const.X, Const.Y}) int val();
|
||||
}
|
||||
class MagicAnnoInsideAnnotationUsage {
|
||||
|
||||
// bad
|
||||
@III(val = <warning descr="Should be one of: Const.X, Const.Y">2</warning>)
|
||||
int h;
|
||||
@III(val = <warning descr="Should be one of: Const.X, Const.Y">Const.X | Const.Y</warning>)
|
||||
void f(){}
|
||||
|
||||
// good
|
||||
@III(val = Const.X)
|
||||
int h2;
|
||||
}
|
||||
|
||||
abstract class BeanInfoParsing {
|
||||
/**
|
||||
* @see java.lang.Runtime#exit(int)
|
||||
*
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* bound: true
|
||||
* enum: DO_NOTHING_ON_CLOSE Const.X
|
||||
* HIDE_ON_CLOSE Const.Y
|
||||
* description: The frame's default close operation.
|
||||
*/
|
||||
public void setX(int operation) {
|
||||
|
||||
}
|
||||
|
||||
public abstract int getX();
|
||||
|
||||
{
|
||||
// good
|
||||
setX(Const.X);
|
||||
setX(Const.Y);
|
||||
if (getX() == Const.X || getX() == Const.Y) {}
|
||||
|
||||
// bad
|
||||
setX(<warning descr="Should be one of: Const.X, Const.Y">0</warning>);
|
||||
setX(<warning descr="Should be one of: Const.X, Const.Y">-1</warning>);
|
||||
setX(<warning descr="Should be one of: Const.X, Const.Y">Const.Z</warning>);
|
||||
if (getX() == <warning descr="Should be one of: Const.X, Const.Y">1</warning>) {}
|
||||
if (getX() == <warning descr="Should be one of: Const.X, Const.Y">Const.Z</warning>) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ExternalAnnotations {
|
||||
void f() {
|
||||
java.util.Calendar.getInstance().set(2000,<warning descr="Should be one of: Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL, Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST, Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER, Calendar.DECEMBER">9</warning>,0)<EOLError descr="';' expected"></EOLError>
|
||||
new javax.swing.JLabel("text", <warning descr="Should be one of: SwingConstants.LEFT, SwingConstants.CENTER, SwingConstants.RIGHT, SwingConstants.LEADING, SwingConstants.TRAILING">3</warning>);
|
||||
}
|
||||
}
|
||||
static class OverrideX extends X {
|
||||
void f(int x) {
|
||||
super.f(x);
|
||||
}
|
||||
}
|
||||
|
||||
void plusSupportedInFlags(@MagicConstant(flags ={Const.X, Const.Y, Const.Z}) int x) {
|
||||
////////////// GOOD
|
||||
plusSupportedInFlags(Const.X + Const.Y);
|
||||
plusSupportedInFlags(Const.Z + Const.X + Const.Y);
|
||||
plusSupportedInFlags(Const.Z + (Const.X + Const.Y));
|
||||
|
||||
int ix = Const.X + Const.Y;
|
||||
plusSupportedInFlags(ix);
|
||||
plusSupportedInFlags(0);
|
||||
plusSupportedInFlags(-1);
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
static class FontType {
|
||||
public static final int PLAIN = 0;
|
||||
public static final int BOLD = 1;
|
||||
public static final int ITALIC = 2;
|
||||
}
|
||||
void font(@MagicConstant(flags = {FontType.PLAIN, FontType.BOLD, FontType.ITALIC}) int x) {
|
||||
// 0 is not allowed despite the fact that it's flags parameter
|
||||
font(<warning descr="Should be one of: FontType.PLAIN, FontType.BOLD, FontType.ITALIC or their combination">0</warning>);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.util.Calendar;
|
||||
|
||||
class SpecialCases {
|
||||
void test() {
|
||||
Calendar instance = Calendar.getInstance();
|
||||
if(instance.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {}
|
||||
if(instance.get(Calendar.DAY_OF_WEEK) == <warning descr="Should be one of: Calendar.SUNDAY, Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY, Calendar.FRIDAY, Calendar.SATURDAY">Calendar.FEBRUARY</warning>) {}
|
||||
if(instance.get(Calendar.MONTH) == <warning descr="Should be one of: Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL, Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST, Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER, Calendar.DECEMBER">Calendar.MONDAY</warning>) {}
|
||||
if(instance.get(Calendar.MONTH) == Calendar.FEBRUARY) {}
|
||||
if(instance.get(Calendar.MONTH) == <warning descr="Should be one of: Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL, Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST, Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER, Calendar.DECEMBER">Calendar.AM</warning>) {}
|
||||
if(instance.get(Calendar.AM_PM) == Calendar.AM) {}
|
||||
if(instance.get(Calendar.AM_PM) == <warning descr="Should be one of: Calendar.AM, Calendar.PM">Calendar.MONDAY</warning>) {}
|
||||
if(instance.get(Calendar.DATE) == 1) {}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -18,9 +18,9 @@ import org.intellij.lang.annotations.MagicConstant;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
public class X {
|
||||
class X {
|
||||
void f(JFrame frame) {
|
||||
frame.setDefaultCloseOperation(2); // there is beanInfo in in JFrame.java, have to parse (but added to exceptions, so ok)
|
||||
frame.setDefaultCloseOperation(<warning descr="Should be one of: javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE, javax.swing.WindowConstants.HIDE_ON_CLOSE, javax.swing.WindowConstants.DISPOSE_ON_CLOSE, javax.swing.WindowConstants.EXIT_ON_CLOSE, JFrame.EXIT_ON_CLOSE">2</warning>); // there is beanInfo in in JFrame.java, have to parse (but added to exceptions, so ok)
|
||||
|
||||
// despite JFrame.EXIT_ON_CLOSE (incorrectly) not mentioned in beaninfo, we override it in our annotations.xml, see IDEA-186767
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
@@ -1,79 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>31</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>32</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>33</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>44</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const2.I, Const1.X</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>45</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const2.I, Const1.X</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>46</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const2.I, Const1.X</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>57</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I or their combination</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>58</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I or their combination</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>59</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>61</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const1.X, Const2.I or their combination</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>72</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const2.I, Const1.X or their combination</description>
|
||||
</problem>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>73</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const2.I, Const1.X or their combination</description>
|
||||
</problem>
|
||||
|
||||
</problems>
|
||||
@@ -1,455 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<!--<problem>-->
|
||||
<!--<file>X.java</file>-->
|
||||
<!--<line>5</line>-->
|
||||
<!--<problem_class>Duplicate throws</problem_class>-->
|
||||
<!--<description>Duplicate throws</description>-->
|
||||
<!--</problem>-->
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>29</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>30</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>31</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>33</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>34</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>35</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>36</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>55</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>56</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>57</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>59</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>60</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>61</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>62</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>81</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>82</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>83</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>85</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>86</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>87</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>88</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>118</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>119</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>122</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>123</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>124</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>125</line>
|
||||
|
||||
|
||||
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z or their combination</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>173</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>174</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>175</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>177</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>178</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>179</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>180</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y, Const.Z</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>193</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>195</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>227</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>228</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>229</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y</description>
|
||||
</problem>
|
||||
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>230</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>231</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">magic constant</problem_class>
|
||||
<description>Should be one of: Const.X, Const.Y</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>238</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Magic Constant</problem_class>
|
||||
<description>Should be one of: Calendar.JANUARY, Calendar.FEBRUARY, Calendar.MARCH, Calendar.APRIL, Calendar.MAY, Calendar.JUNE, Calendar.JULY, Calendar.AUGUST, Calendar.SEPTEMBER, Calendar.OCTOBER, Calendar.NOVEMBER, Calendar.DECEMBER</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>239</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Magic Constant</problem_class>
|
||||
<description>Should be one of: SwingConstants.LEFT, SwingConstants.CENTER, SwingConstants.RIGHT, SwingConstants.LEADING, SwingConstants.TRAILING</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>268</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Magic Constant</problem_class>
|
||||
<description>Should be one of: FontType.PLAIN, FontType.BOLD, FontType.ITALIC or their combination</description>
|
||||
</problem>
|
||||
</problems>
|
||||
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import org.intellij.lang.annotations.MagicConstant;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
class Const {
|
||||
public static final int X = 1;
|
||||
public static final int Y = 2;
|
||||
public static final int Z = 4;
|
||||
}
|
||||
public class X {
|
||||
|
||||
void f(@MagicConstant(intValues={Const.X, Const.Y, Const.Z}) int x) {
|
||||
/////////// BAD
|
||||
f(0);
|
||||
f(1);
|
||||
f(Const.X | Const.Y);
|
||||
int i = Const.X | Const.Y;
|
||||
f(i);
|
||||
if (x == 3) {
|
||||
x = 2;
|
||||
assert x != 1;
|
||||
}
|
||||
|
||||
////////////// GOOD
|
||||
f(Const.X);
|
||||
f(Const.Y);
|
||||
f(Const.Z);
|
||||
int i2 = this == null ? Const.X : Const.Y;
|
||||
f(i2);
|
||||
if (x == Const.X) {
|
||||
x = Const.Y;
|
||||
assert x != Const.Z;
|
||||
}
|
||||
|
||||
f2(x);
|
||||
}
|
||||
|
||||
void f2(@MagicConstant(valuesFromClass =Const.class) int x) {
|
||||
/////////// BAD
|
||||
f2(0);
|
||||
f2(1);
|
||||
f2(Const.X | Const.Y);
|
||||
int i = Const.X | Const.Y;
|
||||
f2(i);
|
||||
if (x == 3) {
|
||||
x = 2;
|
||||
assert x != 1;
|
||||
}
|
||||
|
||||
////////////// GOOD
|
||||
f2(Const.X);
|
||||
f2(Const.Y);
|
||||
f2(Const.Z);
|
||||
int i2 = this == null ? Const.X : Const.Y;
|
||||
f2(i2);
|
||||
if (x == Const.X) {
|
||||
x = Const.Y;
|
||||
assert x != Const.Z;
|
||||
}
|
||||
|
||||
f(x);
|
||||
}
|
||||
|
||||
void f3(@MagicConstant(flags ={Const.X, Const.Y, Const.Z}) int x) {
|
||||
/////////// BAD
|
||||
f3(2);
|
||||
f3(1);
|
||||
f(Const.X | Const.Y);
|
||||
int i = Const.X | 4;
|
||||
f3(i);
|
||||
if (x == 3) {
|
||||
x = 2;
|
||||
assert x != 1;
|
||||
}
|
||||
|
||||
////////////// GOOD
|
||||
f3(Const.X);
|
||||
f3(Const.Y);
|
||||
f3(Const.Z);
|
||||
|
||||
int i2 = this == null ? Const.X : Const.Y;
|
||||
f3(i2);
|
||||
int ix = Const.X | Const.Y;
|
||||
f3(ix);
|
||||
f3(0);
|
||||
f3(-1);
|
||||
int f = 0;
|
||||
if (x == Const.X) {
|
||||
x = Const.Y;
|
||||
assert x != Const.Z;
|
||||
f |= Const.Y; f &= Const.X & ~(Const.Z | Const.X);
|
||||
}
|
||||
else {
|
||||
f |= Const.X; f = f & ~(Const.X | Const.X);
|
||||
}
|
||||
f3(f);
|
||||
|
||||
f4(x);
|
||||
}
|
||||
|
||||
void f4(@MagicConstant(flagsFromClass =Const.class) int x) {
|
||||
/////////// BAD
|
||||
f4(-3);
|
||||
f4(1);
|
||||
f4(Const.X | Const.Y);
|
||||
int i = Const.X | 4;
|
||||
f4(i);
|
||||
if (x == 3) {
|
||||
x = 2;
|
||||
assert x != 1;
|
||||
}
|
||||
|
||||
////////////// GOOD
|
||||
f4(Const.X);
|
||||
f4(Const.Y);
|
||||
f4(Const.Z);
|
||||
|
||||
int i2 = this == null ? Const.X : Const.Y;
|
||||
f4(i2);
|
||||
int ix = Const.X | Const.Y;
|
||||
f4(ix);
|
||||
f4(0);
|
||||
f4(-1);
|
||||
int f = 0;
|
||||
if (x == Const.X) {
|
||||
x = Const.Y;
|
||||
assert x != Const.Z;
|
||||
f |= Const.Y;
|
||||
}
|
||||
else {
|
||||
f |= Const.X;
|
||||
}
|
||||
f4(f);
|
||||
|
||||
f3(x);
|
||||
}
|
||||
|
||||
|
||||
class Alias {
|
||||
@MagicConstant(intValues={Const.X, Const.Y, Const.Z})
|
||||
@interface IntEnum{}
|
||||
|
||||
void f(@IntEnum int x) {
|
||||
////////////// GOOD
|
||||
f(Const.X);
|
||||
f(Const.Y);
|
||||
f(Const.Z);
|
||||
int i2 = this == null ? Const.X : Const.Y;
|
||||
f(i2);
|
||||
if (x == Const.X) {
|
||||
x = Const.Y;
|
||||
assert x != Const.Z;
|
||||
}
|
||||
|
||||
f2(x);
|
||||
|
||||
/////////// BAD
|
||||
f(0);
|
||||
f(1);
|
||||
f(Const.X | Const.Y);
|
||||
int i = Const.X | Const.Y;
|
||||
f(i);
|
||||
if (x == 3 || getClass().isInterface()) {
|
||||
x = 2;
|
||||
assert x != 1;
|
||||
}
|
||||
|
||||
f2(x);
|
||||
}
|
||||
}
|
||||
|
||||
class MagicAnnoInsideAnnotationUsage {
|
||||
@interface III {
|
||||
@MagicConstant(intValues = {Const.X, Const.Y}) int val();
|
||||
}
|
||||
|
||||
// bad
|
||||
@III(val = 2)
|
||||
int h;
|
||||
@III(val = Const.X | Const.Y)
|
||||
void f(){}
|
||||
|
||||
// good
|
||||
@III(val = Const.X)
|
||||
int h2;
|
||||
}
|
||||
|
||||
abstract class BeanInfoParsing {
|
||||
/**
|
||||
* @see java.lang.Runtime#exit(int)
|
||||
*
|
||||
* @beaninfo
|
||||
* preferred: true
|
||||
* bound: true
|
||||
* enum: DO_NOTHING_ON_CLOSE Const.X
|
||||
* HIDE_ON_CLOSE Const.Y
|
||||
* description: The frame's default close operation.
|
||||
*/
|
||||
public void setX(int operation) {
|
||||
|
||||
}
|
||||
|
||||
public abstract int getX();
|
||||
|
||||
{
|
||||
// good
|
||||
setX(Const.X);
|
||||
setX(Const.Y);
|
||||
if (getX() == Const.X || getX() == Const.Y) {}
|
||||
|
||||
// bad
|
||||
setX(0);
|
||||
setX(-1);
|
||||
setX(Const.Z);
|
||||
if (getX() == 1) {}
|
||||
if (getX() == Const.Z) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ExternalAnnotations {
|
||||
void f() {
|
||||
java.util.Calendar.getInstance().set(2000,9,0)
|
||||
new javax.swing.JLabel("text", 3);
|
||||
}
|
||||
}
|
||||
static class OverrideX extends X {
|
||||
void f(int x) {
|
||||
super.f(x);
|
||||
}
|
||||
}
|
||||
|
||||
void plusSupportedInFlags(@MagicConstant(flags ={Const.X, Const.Y, Const.Z}) int x) {
|
||||
////////////// GOOD
|
||||
plusSupportedInFlags(Const.X + Const.Y);
|
||||
plusSupportedInFlags(Const.Z + Const.X + Const.Y);
|
||||
plusSupportedInFlags(Const.Z + (Const.X + Const.Y));
|
||||
|
||||
int ix = Const.X + Const.Y;
|
||||
plusSupportedInFlags(ix);
|
||||
plusSupportedInFlags(0);
|
||||
plusSupportedInFlags(-1);
|
||||
}
|
||||
|
||||
///////////////////////////////////////
|
||||
static class FontType {
|
||||
public static final int PLAIN = 0;
|
||||
public static final int BOLD = 1;
|
||||
public static final int ITALIC = 2;
|
||||
}
|
||||
void font(@MagicConstant(flags = {FontType.PLAIN, FontType.BOLD, FontType.ITALIC}) int x) {
|
||||
// 0 is not allowed despite the fact that it's flags parameter
|
||||
font(0);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>X.java</file>
|
||||
<line>23</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Magic Constant</problem_class>
|
||||
<description>Should be one of: WindowConstants.DO_NOTHING_ON_CLOSE, WindowConstants.HIDE_ON_CLOSE, WindowConstants.DISPOSE_ON_CLOSE, WindowConstants.EXIT_ON_CLOSE</description>
|
||||
</problem>
|
||||
</problems>
|
||||
+33
-54
@@ -17,73 +17,38 @@
|
||||
package com.intellij.java.codeInspection;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
|
||||
import com.intellij.codeInspection.magicConstant.MagicConstantInspection;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.impl.PsiManagerEx;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.impl.source.PsiClassImpl;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.testFramework.FileTreeAccessFilter;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.InspectionTestCase;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class MagicConstantInspectionTest extends InspectionTestCase {
|
||||
private FileTreeAccessFilter myFilter;
|
||||
public class MagicConstantInspectionTest extends LightCodeInsightFixtureTestCase {
|
||||
private static final LightProjectDescriptor DESCRIPTOR = new LightProjectDescriptor() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Sdk getSdk() {
|
||||
// has to have JFrame and sources
|
||||
return PsiTestUtil.addJdkAnnotations(IdeaTestUtil.getMockJdk17());
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath() + "/inspection";
|
||||
protected String getBasePath() {
|
||||
return JavaTestUtil.getRelativeJavaTestDataPath() + "/inspection/magic/";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myFilter = new FileTreeAccessFilter();
|
||||
PsiManagerEx.getInstanceEx(getProject()).setAssertOnFileLoadingFilter(myFilter, getTestRootDisposable());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getTestProjectSdk() {
|
||||
// has to have JFrame and sources
|
||||
return PsiTestUtil.addJdkAnnotations(IdeaTestUtil.getMockJdk17());
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest("magic/" + getTestName(true), new LocalInspectionToolWrapper(new MagicConstantInspection()), "jdk 1.7");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupRootModel(@NotNull String testDir, @NotNull VirtualFile[] sourceDir, String sdkName) {
|
||||
super.setupRootModel(testDir, sourceDir, sdkName);
|
||||
|
||||
PsiClass jframe = getJavaFacade().findClass("javax.swing.JFrame", GlobalSearchScope.allScope(getProject()));
|
||||
assertNotNull("configure decent JDK for testsake", jframe);
|
||||
|
||||
VirtualFile projectDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(testDir));
|
||||
// allow to load AST for all files to highlight
|
||||
VfsUtilCore.visitChildrenRecursively(projectDir, new VirtualFileVisitor() {
|
||||
@Override
|
||||
public boolean visitFile(@NotNull VirtualFile v) {
|
||||
myFilter.allowTreeAccessForFile(v);
|
||||
return super.visitFile(v);
|
||||
}
|
||||
});
|
||||
// and JFrame
|
||||
PsiClass cls = JavaPsiFacade.getInstance(getProject()).findClass("javax.swing.JFrame", GlobalSearchScope.allScope(getProject()));
|
||||
PsiClass aClass = (PsiClass)cls.getNavigationElement();
|
||||
assertTrue(aClass instanceof PsiClassImpl); // must to have sources
|
||||
|
||||
myFilter.allowTreeAccessForFile(aClass.getContainingFile().getVirtualFile());
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return DESCRIPTOR;
|
||||
}
|
||||
|
||||
public void testSimple() { doTest(); }
|
||||
@@ -91,4 +56,18 @@ public class MagicConstantInspectionTest extends InspectionTestCase {
|
||||
public void testManyConstantSources() { doTest(); }
|
||||
// test that the optimisation for not loading AST works
|
||||
public void testWithLibrary() { doTest(); }
|
||||
public void testSpecialCases() { doTest(); }
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
|
||||
PsiClass calendarClass = myFixture.getJavaFacade().findClass(CommonClassNames.JAVA_UTIL_CALENDAR);
|
||||
assertNotNull("No Calendar class in mockJDK", calendarClass);
|
||||
PsiElement calendarSource = calendarClass.getNavigationElement();
|
||||
assertTrue(calendarSource instanceof PsiClassImpl);
|
||||
myFixture.allowTreeAccessForFile(calendarSource.getContainingFile().getVirtualFile());
|
||||
|
||||
myFixture.enableInspections(new MagicConstantInspection());
|
||||
myFixture.testHighlighting(true, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,11 +835,6 @@
|
||||
<val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
|
||||
</annotation>
|
||||
</item>
|
||||
<item name="java.util.Calendar int get(int)">
|
||||
<annotation name="org.intellij.lang.annotations.MagicConstant">
|
||||
<val name="intValues" val="{java.util.Calendar.SUNDAY, java.util.Calendar.MONDAY, java.util.Calendar.TUESDAY, java.util.Calendar.WEDNESDAY, java.util.Calendar.THURSDAY, java.util.Calendar.FRIDAY, java.util.Calendar.SATURDAY}" />
|
||||
</annotation>
|
||||
</item>
|
||||
<item name="java.util.Calendar int get(int) 0">
|
||||
<annotation name="org.intellij.lang.annotations.MagicConstant">
|
||||
<val name="intValues" val="{java.util.Calendar.ERA, java.util.Calendar.YEAR, java.util.Calendar.MONTH, java.util.Calendar.WEEK_OF_YEAR, java.util.Calendar.WEEK_OF_MONTH, java.util.Calendar.DATE, java.util.Calendar.DAY_OF_MONTH, java.util.Calendar.DAY_OF_YEAR, java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.DAY_OF_WEEK_IN_MONTH, java.util.Calendar.AM_PM, java.util.Calendar.HOUR, java.util.Calendar.HOUR_OF_DAY, java.util.Calendar.MINUTE, java.util.Calendar.SECOND, java.util.Calendar.MILLISECOND, java.util.Calendar.ZONE_OFFSET, java.util.Calendar.DST_OFFSET}" />
|
||||
|
||||
Reference in New Issue
Block a user