diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheck.java index f536f74e0a..c6d10270df 100644 --- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheck.java +++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheck.java @@ -88,7 +88,7 @@ private static boolean needOptimization(DetailAST logicNode) { final boolean secondTypeCast = branchContains(operands, 2, TokenTypes.TYPECAST); final boolean result; - if (firstInstanceOf && secondTypeCast) { + if (isPatternVariableIntroduced(logicNode) || firstInstanceOf && secondTypeCast) { result = false; } else { @@ -190,4 +190,18 @@ private static boolean branchContains(DetailAST start, DetailAST end, int type) return result; } + /** + * If pattern variable is introduced, 'instanceof` must appear before condition + * that checks pattern variable. + * + * @param logicNode logic node whose children we check + * @return true if a pattern variable is introduced + */ + private static boolean isPatternVariableIntroduced(DetailAST logicNode) { + final DetailAST firstOperand = logicNode.getFirstChild(); + return firstOperand.getType() == TokenTypes.LITERAL_INSTANCEOF + && firstOperand.getLastChild() != null + && firstOperand.getLastChild().getType() == TokenTypes.PATTERN_VARIABLE_DEF; + } + } diff --git a/sevntu-checks/src/test/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheckTest.java b/sevntu-checks/src/test/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheckTest.java index 9de2c4e72e..ab991561d5 100644 --- a/sevntu-checks/src/test/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheckTest.java +++ b/sevntu-checks/src/test/java/com/github/sevntu/checkstyle/checks/coding/LogicConditionNeedOptimizationCheckTest.java @@ -25,6 +25,7 @@ import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport; import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import com.puppycrawl.tools.checkstyle.utils.CommonUtil; public class LogicConditionNeedOptimizationCheckTest extends AbstractModuleTestSupport { @@ -66,4 +67,14 @@ public void test() throws Exception { verify(checkConfig, getPath("InputLogicConditionNeedOptimizationCheck.java"), expected); } + @Test + public void testJava17Patterns() throws Exception { + final DefaultConfiguration checkConfig = + createModuleConfig(LogicConditionNeedOptimizationCheck.class); + final String[] expected = CommonUtil.EMPTY_STRING_ARRAY; + verify(checkConfig, + getNonCompilablePath("InputLogicConditionNeedsOptimizationPatterns.java"), + expected); + } + } diff --git a/sevntu-checks/src/test/resources-noncompilable/com/github/sevntu/checkstyle/checks/coding/InputLogicConditionNeedsOptimizationPatterns.java b/sevntu-checks/src/test/resources-noncompilable/com/github/sevntu/checkstyle/checks/coding/InputLogicConditionNeedsOptimizationPatterns.java new file mode 100644 index 0000000000..6e1b88fee3 --- /dev/null +++ b/sevntu-checks/src/test/resources-noncompilable/com/github/sevntu/checkstyle/checks/coding/InputLogicConditionNeedsOptimizationPatterns.java @@ -0,0 +1,16 @@ +package com.github.sevntu.checkstyle.checks.coding; + +public class InputLogicConditionNeedsOptimizationPatterns { + void m1(Object o) { + for (int i = 0; o instanceof Integer myInt && myInt > 5;) { // ok + // type pattern, no `PATTERN_DEF` + } + for (int i = 0; o instanceof (Integer myInt && myInt > 5);) { // ok + // parenthesized pattern, `PATTERN_DEF` + } + for (int i = 0; o instanceof Integer myInt; ) { // ok + // type pattern, no `PATTERN_DEF` + } + } + +}