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:
Tagir Valeev
2018-06-19 17:57:40 +07:00
parent e4e02bca43
commit 233c16b3e4
11 changed files with 400 additions and 902 deletions
@@ -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 + "'";
}
@@ -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) {}
}
}
@@ -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>
@@ -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}" />