[java] ImplicitSwitchFallThrough should consider switch expressions

Fixes #3362
This commit is contained in:
Andreas Dangel 2024-10-04 16:45:29 +02:00
parent a0818d5ab2
commit 312d8e46ae
No known key found for this signature in database
GPG Key ID: 93450DF2DF9A3FA3
3 changed files with 40 additions and 9 deletions

View File

@ -33,6 +33,7 @@ The old rule names still work but are deprecated.
* java
* [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules
* java-errorprone
* [#3362](https://github.com/pmd/pmd/issues/3362): \[java] ImplicitSwitchFallThrough should consider switch expressions
* [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault()
### 🚨 API Changes

View File

@ -9,28 +9,40 @@ import java.util.regex.Pattern;
import net.sourceforge.pmd.lang.ast.GenericToken;
import net.sourceforge.pmd.lang.ast.impl.javacc.JavaccToken;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchBranch;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchFallthroughBranch;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchLike;
import net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement;
import net.sourceforge.pmd.lang.java.ast.JavaNode;
import net.sourceforge.pmd.lang.java.ast.internal.JavaAstUtils;
import net.sourceforge.pmd.lang.java.rule.AbstractJavaRulechainRule;
import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass;
import net.sourceforge.pmd.lang.java.rule.internal.DataflowPass.DataflowResult;
import net.sourceforge.pmd.reporting.RuleContext;
import net.sourceforge.pmd.util.OptionalBool;
public class ImplicitSwitchFallThroughRule extends AbstractJavaRulechainRule {
//todo should consider switch exprs
private static final Pattern IGNORED_COMMENT = Pattern.compile("/[/*].*\\bfalls?[ -]?thr(ough|u)\\b.*",
Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
public ImplicitSwitchFallThroughRule() {
super(ASTSwitchStatement.class);
super(ASTSwitchStatement.class, ASTSwitchExpression.class);
}
@Override
public Object visit(ASTSwitchStatement node, Object data) {
checkSwitchLike(node, asCtx(data));
return null;
}
@Override
public Object visit(ASTSwitchExpression node, Object data) {
checkSwitchLike(node, asCtx(data));
return null;
}
private void checkSwitchLike(ASTSwitchLike node, RuleContext ruleContext) {
DataflowResult dataflow = DataflowPass.getDataflowResult(node.getRoot());
for (ASTSwitchBranch branch : node.getBranches()) {
@ -38,15 +50,14 @@ public class ImplicitSwitchFallThroughRule extends AbstractJavaRulechainRule {
ASTSwitchFallthroughBranch fallthrough = (ASTSwitchFallthroughBranch) branch;
OptionalBool bool = dataflow.switchBranchFallsThrough(branch);
if (bool != OptionalBool.NO
&& fallthrough.getStatements().nonEmpty()
&& !nextBranchHasComment(branch)) {
asCtx(data).addViolation(branch.getNextBranch().getLabel());
&& fallthrough.getStatements().nonEmpty()
&& !nextBranchHasComment(branch)) {
ruleContext.addViolation(branch.getNextBranch().getLabel());
}
} else {
return null;
return;
}
}
return null;
}
boolean nextBranchHasComment(ASTSwitchBranch branch) {
@ -62,5 +73,4 @@ public class ImplicitSwitchFallThroughRule extends AbstractJavaRulechainRule {
}
return false;
}
}

View File

@ -581,4 +581,24 @@ public class Test {
}
]]></code>
</test-code>
<test-code>
<description>switch expression with one case, which is not empty</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>6</expected-linenumbers>
<code><![CDATA[
public class Foo {
public static void main(String[] args) {
int i = 1;
String result = switch(i) {
case 1: doSomething();
default: yield "default case fall through";
};
System.out.println(result);
}
private static void doSomething() {}
}
]]></code>
</test-code>
</test-data>