mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Array can be replaced with enum values inspection added (IDEA-195323)
This commit is contained in:
committed by
Anna.Kozlova
parent
28098f0d76
commit
e498a28646
+4
@@ -2158,6 +2158,10 @@ junit5.converter.fix.name=Migrate to JUnit 5
|
||||
call.to.suspicious.string.method.display.name=Call to suspicious String method
|
||||
call.to.suspicious.string.method.problem.descriptor=<code>String.#ref()</code> called in internationalized context #loc
|
||||
|
||||
array.can.be.replaced.with.enum.values = Array can be replaced with enum values
|
||||
array.can.be.replaced.with.enum.values.quickfix = Replace array with {0}.values()
|
||||
array.can.be.replaced.with.enum.values.family.quickfix = Replace array with EnumType.values()
|
||||
|
||||
string.concatenation.replace.fix=Replace with StringBuilder
|
||||
string.concatenation.replace.fix.name=Convert variable ''{0}'' from String to {1}
|
||||
string.concatenation.introduce.fix=Introduce StringBuilder
|
||||
|
||||
@@ -2536,6 +2536,10 @@
|
||||
key="inspection.simplifiable.if.statement.display.name" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.code.style.issues" enabledByDefault="true" level="INFORMATION"
|
||||
implementationClass="com.siyeh.ig.style.SimplifiableIfStatementInspection"/>
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="ArrayCanBeReplacedWithEnumValues" bundle="com.siyeh.InspectionGadgetsBundle"
|
||||
key="array.can.be.replaced.with.enum.values" groupBundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.code.style.issues" enabledByDefault="true" level="INFORMATION"
|
||||
implementationClass="com.siyeh.ig.style.ArrayCanBeReplacedWithEnumValuesInspection"/>
|
||||
|
||||
<!--group.names.threading.issues-->
|
||||
<localInspection groupPath="Java" language="JAVA" suppressId="AccessToNonThreadSafeStaticField" shortName="AccessToNonThreadSafeStaticFieldFromInstance"
|
||||
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.siyeh.ig.style;
|
||||
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.PsiReplacementUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author okli
|
||||
*/
|
||||
public class ArrayCanBeReplacedWithEnumValuesInspection extends BaseInspection {
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return InspectionGadgetsBundle.message("array.can.be.replaced.with.enum.values");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String buildErrorString(Object... infos) {
|
||||
return getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseInspectionVisitor buildVisitor() {
|
||||
return new ArrayCreationExpressionVisitor();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionGadgetsFix buildFix(Object... infos) {
|
||||
if (infos.length == 1 && infos[0] instanceof String) {
|
||||
return new ArrayToEnumValueFix((String)infos[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class ArrayToEnumValueFix extends InspectionGadgetsFix {
|
||||
private final String myEnumName;
|
||||
|
||||
private ArrayToEnumValueFix(String enumName) {
|
||||
myEnumName = enumName;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return InspectionGadgetsBundle.message("array.can.be.replaced.with.enum.values.quickfix", StringUtil.getShortName(myEnumName));
|
||||
}
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return InspectionGadgetsBundle.message("array.can.be.replaced.with.enum.values.family.quickfix");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
if (myEnumName == null) {
|
||||
return;
|
||||
}
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
if (element instanceof PsiNewExpression || element instanceof PsiArrayInitializerExpression) {
|
||||
PsiReplacementUtil.replaceExpression((PsiExpression)element, myEnumName + ".values()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ArrayCreationExpressionVisitor extends BaseInspectionVisitor {
|
||||
@Override
|
||||
public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
|
||||
super.visitArrayInitializerExpression(expression);
|
||||
|
||||
final PsiType type = expression.getType();
|
||||
if (!(type instanceof PsiArrayType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PsiType initExprType = ((PsiArrayType)type).getComponentType();
|
||||
final PsiClass initClass = PsiUtil.resolveClassInClassTypeOnly(initExprType);
|
||||
|
||||
if (initClass == null || !initClass.isEnum()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<String> enumValues = Stream.of(initClass.getFields())
|
||||
.filter(ev -> ev instanceof PsiEnumConstant)
|
||||
.map(ev -> ev.getName())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final PsiExpression[] initializers = expression.getInitializers();
|
||||
if (enumValues.size() != initializers.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < initializers.length; i++) {
|
||||
if (!(initializers[i] instanceof PsiReferenceExpression &&
|
||||
enumValues.get(i).equals(((PsiReferenceExpression)initializers[i]).getReferenceName()) &&
|
||||
initExprType.equals(initializers[i].getType()))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final PsiElement parent = expression.getParent();
|
||||
final String enumName = initClass.getQualifiedName();
|
||||
|
||||
if (parent instanceof PsiNewExpression) {
|
||||
registerError(parent, enumName);
|
||||
}
|
||||
else {
|
||||
registerError(expression, enumName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<!-- Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||
<html>
|
||||
<body>
|
||||
Reports arrays of enum constants which may be replaced with <code>EnumType.values()</code>.
|
||||
</body>
|
||||
</html>
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class ClassWithEnum {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(TestEnum.values());
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum[] values) { }
|
||||
|
||||
public enum TestEnum {
|
||||
ONE, TWO, THREE
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class ClassWithEnum {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(new TestEnum[]<caret>{TestEnum.ONE, TestEnum.TWO, TestEnum.THREE});
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum[] values) { }
|
||||
|
||||
public enum TestEnum {
|
||||
ONE, TWO, THREE
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class EnumRevOrder {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(new TestEnum[]<caret>{TestEnum.THREE, TestEnum.TWO, TestEnum.ONE});
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum[] values) { }
|
||||
|
||||
public enum TestEnum {
|
||||
ONE, TWO, THREE;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
class EnumWithField {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(TestEnum.values());
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum[] values) { }
|
||||
|
||||
public enum TestEnum {
|
||||
ONE(1), TWO(2), THREE(3);
|
||||
|
||||
private final int levelCode;
|
||||
|
||||
TestEnum(int levelCode) {
|
||||
this.levelCode = levelCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
class EnumWithField {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(new TestEnum[]{TestE<caret>num.ONE, TestEnum.TWO, TestEnum.THREE});
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum[] values) { }
|
||||
|
||||
public enum TestEnum {
|
||||
ONE(1), TWO(2), THREE(3);
|
||||
|
||||
private final int levelCode;
|
||||
|
||||
TestEnum(int levelCode) {
|
||||
this.levelCode = levelCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class ErrorInMultiDArray {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(new TestEnum[]{{TestE<caret>num.ONE, TestEnum.TWO, TestEnum.THREE}});
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum[] values) { }
|
||||
|
||||
public enum TestEnum {
|
||||
ONE, TWO, THREE;
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class Foo {
|
||||
enum En {A;}
|
||||
static En foo() {
|
||||
return En.A;
|
||||
}
|
||||
|
||||
{
|
||||
En[] array = En.values();
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
class Foo {
|
||||
enum En {A;}
|
||||
static En foo() {
|
||||
return En.A;
|
||||
}
|
||||
|
||||
{
|
||||
En[] array = new En[] {fo<caret>o()};
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class InnerEnum {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(TestEnum.Inner.values());
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum.Inner[] values) {
|
||||
}
|
||||
|
||||
public enum TestEnum {
|
||||
ONE, TWO, THREE;
|
||||
|
||||
enum Inner {FIVE, SIX, SEVEN}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
class InnerEnum {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(new TestEnum.Inner[]{TestEnum.Inn<caret>er.FIVE, TestEnum.Inner.SIX, TestEnum.Inner.SEVEN});
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum.Inner[] values) {
|
||||
}
|
||||
|
||||
public enum TestEnum {
|
||||
ONE, TWO, THREE;
|
||||
|
||||
enum Inner {FIVE, SIX, SEVEN}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
class MultiDArrayNoError {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(new TestEnum[][]{{Test<caret>Enum.ONE, TestEnum.THREE, TestEnum.TWO}});
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum[][] values) {
|
||||
}
|
||||
|
||||
public enum TestEnum {
|
||||
ONE, TWO, THREE;
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class NotEnumInit {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(new TestEnum[]<caret>{"", TestEnum.ONE});
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum[] values) { }
|
||||
|
||||
public enum TestEnum {
|
||||
ONE, TWO, THREE
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class NotEnumMulti {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(new TestEnum[][]<caret>{{TestEnum.ONE}});
|
||||
}
|
||||
|
||||
private static void testMethod(TestEnum[] values) { }
|
||||
|
||||
public enum TestEnum {
|
||||
ONE, TWO, THREE
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class OuterEnumUse {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(OuterEnum.TestEnum.values());
|
||||
}
|
||||
private static void testMethod(OuterEnum.TestEnum[] values) {
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class OuterEnumUse {
|
||||
|
||||
public static void foo() {
|
||||
testMethod(new OuterEnum.TestEnum[]{OuterEnum.TestEnum.<caret>A, OuterEnum.TestEnum.B, OuterEnum.TestEnum.C});
|
||||
}
|
||||
private static void testMethod(OuterEnum.TestEnum[] values) {
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.siyeh.ig.fixes.style;
|
||||
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.IGQuickFixesTestCase;
|
||||
import com.siyeh.ig.style.ArrayCanBeReplacedWithEnumValuesInspection;
|
||||
|
||||
|
||||
public class ArrayCanBeReplacedWithEnumValuesFixTest extends IGQuickFixesTestCase {
|
||||
|
||||
public void testClassWithEnum() { doTest("TestEnum"); }
|
||||
|
||||
public void testEnumWithField() {doTest("TestEnum");}
|
||||
|
||||
public void testNotEnumInit() { assertQuickfixNotAvailable(); }
|
||||
|
||||
public void testNotEnumMulti() { assertQuickfixNotAvailable(); }
|
||||
|
||||
public void testEnumRevOrder() { assertQuickfixNotAvailable();}
|
||||
|
||||
public void testErrorInMultiDArray() { assertQuickfixNotAvailable();}
|
||||
|
||||
public void testMultiDArrayNoError() {assertQuickfixNotAvailable();}
|
||||
|
||||
public void testInnerEnum() {doTest("Inner");}
|
||||
|
||||
public void testFooInit() {assertQuickfixNotAvailable();}
|
||||
|
||||
public void testOuterEnumUse() {doTest("TestEnum");}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void doTest(String hint) {
|
||||
super.doTest(InspectionGadgetsBundle.message("array.can.be.replaced.with.enum.values.quickfix", hint));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertQuickfixNotAvailable() {
|
||||
String message = InspectionGadgetsBundle.message("array.can.be.replaced.with.enum.values.quickfix", "@");
|
||||
super.assertQuickfixNotAvailable(message.substring(0, message.indexOf('@')));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myFixture.enableInspections(new ArrayCanBeReplacedWithEnumValuesInspection());
|
||||
myRelativePath = "style/array_replaced_enum_values";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String[] getEnvironmentClasses() {
|
||||
return new String[] {
|
||||
"public class OuterEnum {\n" +
|
||||
" public enum TestEnum {\n" +
|
||||
" A, B, C\n" +
|
||||
" }\n" +
|
||||
"}"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user