mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java: Convert switch labeled rule expression to a block (IDEA-202622)
This commit is contained in:
@@ -940,6 +940,11 @@
|
||||
groupKey="group.names.language.level.specific.issues.and.migration.aids12" groupBundle="messages.InspectionsBundle"
|
||||
enabledByDefault="true" level="INFORMATION"
|
||||
implementationClass="com.intellij.codeInspection.EnhancedSwitchMigrationInspection" />
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="SwitchLabeledRuleCanBeCodeBlock"
|
||||
key="inspection.switch.labeled.rule.can.be.code.block.display.name" bundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.code.style.issues" groupBundle="messages.InspectionsBundle"
|
||||
enabledByDefault="true" level="INFORMATION"
|
||||
implementationClass="com.intellij.codeInspection.enhancedSwitch.SwitchLabeledRuleCanBeCodeBlockInspection" />
|
||||
|
||||
<globalInspection groupPath="Java" language="JAVA" shortName="EmptyMethod" displayName="Empty method" groupKey="group.names.declaration.redundancy" enabledByDefault="true" groupBundle="messages.InspectionsBundle"
|
||||
level="WARNING" implementationClass="com.intellij.codeInspection.emptyMethod.EmptyMethodInspection"/>
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
// 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.intellij.codeInspection.enhancedSwitch;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.codeInspection.InspectionsBundle.message;
|
||||
|
||||
/**
|
||||
* @author Pavel.Dolgov
|
||||
*/
|
||||
public class SwitchLabeledRuleCanBeCodeBlockInspection extends LocalInspectionTool {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
if (!PsiUtil.getLanguageLevel(holder.getFile()).isAtLeast(LanguageLevel.JDK_12_PREVIEW)) {
|
||||
return PsiElementVisitor.EMPTY_VISITOR;
|
||||
}
|
||||
|
||||
return new JavaElementVisitor() {
|
||||
@Override
|
||||
public void visitSwitchLabeledRuleStatement(PsiSwitchLabeledRuleStatement statement) {
|
||||
super.visitSwitchLabeledRuleStatement(statement);
|
||||
|
||||
PsiSwitchBlock switchBlock = statement.getEnclosingSwitchBlock();
|
||||
PsiStatement body = statement.getBody();
|
||||
if (switchBlock != null && (body instanceof PsiExpressionStatement || body instanceof PsiThrowStatement)) {
|
||||
if (switchBlock instanceof PsiSwitchExpression && body instanceof PsiExpressionStatement) {
|
||||
registerProblem(statement, true);
|
||||
}
|
||||
else {
|
||||
registerProblem(statement, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerProblem(PsiSwitchLabeledRuleStatement statement, boolean isExpressionResult) {
|
||||
holder.registerProblem(ObjectUtils.notNull(ObjectUtils.tryCast(statement.getFirstChild(), PsiKeyword.class), statement),
|
||||
message(isExpressionResult ? "inspection.switch.labeled.rule.can.be.code.block.expression.message"
|
||||
: "inspection.switch.labeled.rule.can.be.code.block.statement.message"),
|
||||
new WrapWithCodeBlockFix(isExpressionResult));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class WrapWithCodeBlockFix implements LocalQuickFix {
|
||||
private final String myMessage;
|
||||
|
||||
WrapWithCodeBlockFix(boolean isExpressionResult) {
|
||||
myMessage = message(isExpressionResult ? "inspection.switch.labeled.rule.can.be.code.block.fix.expression.name"
|
||||
: "inspection.switch.labeled.rule.can.be.code.block.fix.statement.name");
|
||||
}
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return myMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PsiElement element = descriptor.getStartElement();
|
||||
if (element instanceof PsiKeyword) {
|
||||
element = element.getParent();
|
||||
if (element instanceof PsiSwitchLabeledRuleStatement) {
|
||||
PsiSwitchLabeledRuleStatement rule = (PsiSwitchLabeledRuleStatement)element;
|
||||
PsiSwitchBlock switchBlock = rule.getEnclosingSwitchBlock();
|
||||
PsiStatement body = rule.getBody();
|
||||
|
||||
if (switchBlock instanceof PsiSwitchExpression && body instanceof PsiExpressionStatement) {
|
||||
wrapExpression((PsiExpressionStatement)body);
|
||||
}
|
||||
else if (body != null) {
|
||||
wrapStatement(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void wrapExpression(PsiExpressionStatement expressionStatement) {
|
||||
PsiExpression expression = expressionStatement.getExpression();
|
||||
CommentTracker tracker = new CommentTracker();
|
||||
tracker.markUnchanged(expression);
|
||||
tracker.replaceAndRestoreComments(expressionStatement, "{ break " + expression.getText() + "; }");
|
||||
}
|
||||
|
||||
private static void wrapStatement(@NotNull PsiStatement statement) {
|
||||
CommentTracker tracker = new CommentTracker();
|
||||
tracker.markUnchanged(statement);
|
||||
tracker.replaceAndRestoreComments(statement, "{ " + statement.getText() + " }");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports rules of <code>switch</code> expression or enhanced <code>switch</code> statement which can be converted to a code block.
|
||||
<!-- tooltip end -->
|
||||
<p><small>New in 2019.1</small></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,12 @@
|
||||
class C {
|
||||
String foo(int n) {
|
||||
return switch (n) {
|
||||
<warning descr="Labeled rule's result can be wrapped with code block">case</warning> 1 -> Integer.toString(n);
|
||||
case 2 -> { break Integer.toString(n); }
|
||||
<warning descr="Labeled rule's statement can be wrapped with code block">case</warning> 3 -> throw new RuntimeException();
|
||||
case 4 -> { throw new RuntimeException(); }
|
||||
case 5 -> { break "a";}
|
||||
<warning descr="Labeled rule's result can be wrapped with code block">default</warning> -> "b";
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
class C {
|
||||
String foo(int n) {
|
||||
String s;
|
||||
switch (n) {
|
||||
<warning descr="Labeled rule's statement can be wrapped with code block">case</warning> 1 -> s = Integer.toString(n);
|
||||
case 2 -> { s = Integer.toString(n); }
|
||||
<warning descr="Labeled rule's statement can be wrapped with code block">case</warning> 3 -> throw new RuntimeException();
|
||||
case 4 -> { throw new RuntimeException(); }
|
||||
case 5 -> { s = "a"; }
|
||||
<warning descr="Labeled rule's statement can be wrapped with code block">default</warning> -> s = "b";
|
||||
};
|
||||
return s;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Wrap labeled rule's result with code block" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
String foo(int n) {
|
||||
return switch (n) {
|
||||
case 1 -> /*1*/{
|
||||
break Integer.toString(/*2*/n);
|
||||
}/*3*/
|
||||
default -> "b";
|
||||
};
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
String foo(int n) {
|
||||
String s;
|
||||
switch (n) {
|
||||
case 1 -> /*1*/{
|
||||
s = Integer.toString(/*2*/n);
|
||||
}/*3*/
|
||||
default -> s = "b";
|
||||
};
|
||||
return s;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Wrap labeled rule's result with code block" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
String foo(int n) {
|
||||
return switch (n) {
|
||||
case 1 -> /*1*/ {
|
||||
break "a";
|
||||
} /*2*/
|
||||
default -> "b";
|
||||
};
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
String foo(int n) {
|
||||
return switch (n) {
|
||||
case 1 -> /*1*/ {
|
||||
throw new RuntimeException(); /*2*/
|
||||
}
|
||||
default -> "b";
|
||||
};
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
String foo(int n) {
|
||||
String s;
|
||||
switch (n) {
|
||||
case 1 -> /*1*/ {
|
||||
throw /*2*/new RuntimeException(); /*3*/
|
||||
}
|
||||
default -> s = "b";
|
||||
};
|
||||
return s;
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Wrap labeled rule's result with code block" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
String foo(int n) {
|
||||
return switch (n) {
|
||||
<caret>case 1 -> /*1*/Integer.toString(/*2*/n);/*3*/
|
||||
default -> "b";
|
||||
};
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
String foo(int n) {
|
||||
String s;
|
||||
switch (n) {
|
||||
<caret>case 1 -> /*1*/s = Integer.toString(/*2*/n);/*3*/
|
||||
default -> s = "b";
|
||||
};
|
||||
return s;
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Wrap labeled rule's result with code block" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
String foo(int n) {
|
||||
return switch (n) {
|
||||
<caret>case 1 -> /*1*/ "a"; /*2*/
|
||||
default -> "b";
|
||||
};
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
String foo(int n) {
|
||||
return switch (n) {
|
||||
<caret>case 1 -> /*1*/ throw new RuntimeException(); /*2*/
|
||||
default -> "b";
|
||||
};
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Wrap labeled rule's statement with code block" "GENERIC_ERROR_OR_WARNING"
|
||||
class C {
|
||||
String foo(int n) {
|
||||
String s;
|
||||
switch (n) {
|
||||
<caret>case 1 -> /*1*/ throw /*2*/new RuntimeException(); /*3*/
|
||||
default -> s = "b";
|
||||
};
|
||||
return s;
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// 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.intellij.java.codeInspection.enhancedSwitch
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase
|
||||
import com.intellij.codeInspection.LocalInspectionTool
|
||||
import com.intellij.codeInspection.enhancedSwitch.SwitchLabeledRuleCanBeCodeBlockInspection
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
|
||||
/**
|
||||
* @author Pavel.Dolgov
|
||||
*/
|
||||
class SwitchLabeledRuleCanBeCodeBlockFixTest : LightQuickFixParameterizedTestCase() {
|
||||
|
||||
override fun configureLocalInspectionTools(): Array<LocalInspectionTool> = arrayOf(SwitchLabeledRuleCanBeCodeBlockInspection())
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = LightCodeInsightFixtureTestCase.JAVA_12
|
||||
|
||||
override fun getBasePath() = "/inspection/switchLabeledRuleCanBeCodeBlockFix"
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// 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.intellij.java.codeInspection.enhancedSwitch
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
import com.intellij.codeHighlighting.HighlightDisplayLevel
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey
|
||||
import com.intellij.codeInspection.enhancedSwitch.SwitchLabeledRuleCanBeCodeBlockInspection
|
||||
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
|
||||
/**
|
||||
* @author Pavel.Dolgov
|
||||
*/
|
||||
class SwitchLabeledRuleCanBeCodeBlockTest : LightCodeInsightFixtureTestCase() {
|
||||
val inspection = SwitchLabeledRuleCanBeCodeBlockInspection()
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
myFixture.enableInspections(inspection)
|
||||
|
||||
val currentProfile = ProjectInspectionProfileManager.getInstance(project).currentProfile
|
||||
currentProfile.setErrorLevel(HighlightDisplayKey.find(inspection.shortName), HighlightDisplayLevel.WARNING, project)
|
||||
}
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = LightCodeInsightFixtureTestCase.JAVA_12
|
||||
|
||||
override fun getBasePath() = JavaTestUtil.getRelativeJavaTestDataPath() + "/inspection/switchLabeledRuleCanBeCodeBlock"
|
||||
|
||||
fun testInExpression() = doTest()
|
||||
fun testInStatement() = doTest()
|
||||
|
||||
private fun doTest() {
|
||||
myFixture.testHighlighting("${getTestName(false)}.java")
|
||||
}
|
||||
}
|
||||
@@ -1035,4 +1035,10 @@ inspection.replace.with.enhanced.switch.statement.fix.name=Replace with enhanced
|
||||
inspection.duplicate.branches.in.switch.display.name=Duplicate branches in 'switch' statement
|
||||
inspection.duplicate.branches.in.switch.message=Duplicate branch in 'switch' statement
|
||||
inspection.duplicate.branches.in.switch.fix.family.name=Merge duplicate branches of 'switch' statement
|
||||
inspection.duplicate.branches.in.switch.fix.name=Merge with ''{0}:''
|
||||
inspection.duplicate.branches.in.switch.fix.name=Merge with ''{0}:''
|
||||
|
||||
inspection.switch.labeled.rule.can.be.code.block.display.name=Labeled switch rule can have code block
|
||||
inspection.switch.labeled.rule.can.be.code.block.expression.message=Labeled rule's result can be wrapped with code block
|
||||
inspection.switch.labeled.rule.can.be.code.block.statement.message=Labeled rule's statement can be wrapped with code block
|
||||
inspection.switch.labeled.rule.can.be.code.block.fix.expression.name=Wrap labeled rule's result with code block
|
||||
inspection.switch.labeled.rule.can.be.code.block.fix.statement.name=Wrap labeled rule's statement with code block
|
||||
Reference in New Issue
Block a user