diff --git a/org.eclipse.jdt.core.manipulation/.settings/.api_filters b/org.eclipse.jdt.core.manipulation/.settings/.api_filters
index a42165f7e4b..3198459f671 100644
--- a/org.eclipse.jdt.core.manipulation/.settings/.api_filters
+++ b/org.eclipse.jdt.core.manipulation/.settings/.api_filters
@@ -59,6 +59,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/OneIfRatherThanDuplicateBlocksThatFallThroughFixCore.java b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/OneIfRatherThanDuplicateBlocksThatFallThroughFixCore.java
index 4394cf6a632..6e4fb0de3a4 100644
--- a/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/OneIfRatherThanDuplicateBlocksThatFallThroughFixCore.java
+++ b/org.eclipse.jdt.core.manipulation/core extension/org/eclipse/jdt/internal/corext/fix/OneIfRatherThanDuplicateBlocksThatFallThroughFixCore.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2021 Fabrice TIERCELIN and others.
+ * Copyright (c) 2021, 2024 Fabrice TIERCELIN and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -14,7 +14,9 @@
package org.eclipse.jdt.internal.corext.fix;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.core.runtime.CoreException;
@@ -29,6 +31,10 @@
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.InfixExpression;
+import org.eclipse.jdt.core.dom.Pattern;
+import org.eclipse.jdt.core.dom.PatternInstanceofExpression;
+import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.TypePattern;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.TargetSourceRangeComputer;
@@ -72,10 +78,14 @@ public boolean visit(final Block node) {
public boolean visit(final IfStatement visited) {
if (result && ASTNodes.fallsThrough(visited.getThenStatement())) {
List duplicateIfBlocks= new ArrayList<>(ASTNodes.EXCESSIVE_OPERAND_NUMBER - 1);
+ Set patternNames= new HashSet<>();
+ PatternNameVisitor visitor= new PatternNameVisitor();
+ visited.accept(visitor);
+ patternNames= visitor.getPatternNames();
AtomicInteger operandCount= new AtomicInteger(ASTNodes.getNbOperands(visited.getExpression()));
duplicateIfBlocks.add(visited);
- while (addOneMoreIf(duplicateIfBlocks, operandCount)) {
+ while (addOneMoreIf(duplicateIfBlocks, patternNames, operandCount)) {
// OK continue
}
@@ -89,7 +99,27 @@ public boolean visit(final IfStatement visited) {
return true;
}
- private boolean addOneMoreIf(final List duplicateIfBlocks, final AtomicInteger operandCount) {
+ private class PatternNameVisitor extends ASTVisitor {
+ private Set patternNames= new HashSet<>();
+
+ @Override
+ public boolean visit(PatternInstanceofExpression node) {
+ Pattern p= node.getPattern();
+ if (p instanceof TypePattern typePattern) {
+ List patternVariables= typePattern.patternVariables();
+ for (SingleVariableDeclaration patternVariable : patternVariables) {
+ patternNames.add(patternVariable.getName().getFullyQualifiedName());
+ }
+ }
+ return true;
+ }
+
+ public Set getPatternNames() {
+ return patternNames;
+ }
+ }
+
+ private boolean addOneMoreIf(final List duplicateIfBlocks, final Set patternNames, final AtomicInteger operandCount) {
IfStatement lastBlock= duplicateIfBlocks.get(duplicateIfBlocks.size() - 1);
if (lastBlock.getElseStatement() == null) {
@@ -99,6 +129,14 @@ private boolean addOneMoreIf(final List duplicateIfBlocks, final At
&& nextSibling.getElseStatement() == null
&& operandCount.get() + ASTNodes.getNbOperands(nextSibling.getExpression()) < ASTNodes.EXCESSIVE_OPERAND_NUMBER
&& ASTNodes.match(lastBlock.getThenStatement(), nextSibling.getThenStatement())) {
+ PatternNameVisitor visitor= new PatternNameVisitor();
+ nextSibling.getExpression().accept(visitor);
+ Set siblingPatternNames= visitor.getPatternNames();
+ for (String siblingPatternName : siblingPatternNames) {
+ if (!patternNames.add(siblingPatternName)) {
+ return false;
+ }
+ }
operandCount.addAndGet(ASTNodes.getNbOperands(nextSibling.getExpression()));
duplicateIfBlocks.add(nextSibling);
return true;
diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java
index e4368f378af..c0156c06555 100644
--- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java
+++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest16.java
@@ -332,6 +332,68 @@ public void testPatternMatchingForInstanceof2() throws Exception { // https://gi
new HashSet<>(Arrays.asList(MultiFixMessages.PatternMatchingForInstanceofCleanup_description)));
}
+ @Test
+ public void testOneIfWithPatternInstanceof() throws Exception { // https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/1200
+ IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null);
+ String sample= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E {\n" //
+ + "\n" //
+ + " protected String getString(Number number) {\n" //
+ + "\n" //
+ + " if (number instanceof Long n) {\n" //
+ + " return n.toString();\n" //
+ + " }\n" //
+ + " if (number instanceof Float n) {\n" //
+ + " return n.toString();\n" //
+ + " }\n" //
+ + " if (number instanceof Double n) {\n" //
+ + " return n.toString();\n" //
+ + " }\n" //
+ + " if (number instanceof Float n && n.isInfinite()) {\n" //
+ + " return \"Inf\"; //$NON-NLS-1$\n" //
+ + " }\n" //
+ + " if (number instanceof Double m && m.isInfinite()) {\n" //
+ + " return \"Inf\"; //$NON-NLS-1$\n" //
+ + " }\n" //
+ + "\n" //
+ + " return null;\n" //
+ + " }\n" //
+ + "\n" //
+ + "}\n"; //
+ ICompilationUnit cu= pack.createCompilationUnit("E.java", sample, false, null);
+
+ enable(CleanUpConstants.ONE_IF_RATHER_THAN_DUPLICATE_BLOCKS_THAT_FALL_THROUGH);
+
+ String expected= "" //
+ + "package test1;\n" //
+ + "\n" //
+ + "public class E {\n" //
+ + "\n" //
+ + " protected String getString(Number number) {\n" //
+ + "\n" //
+ + " if (number instanceof Long n) {\n" //
+ + " return n.toString();\n" //
+ + " }\n" //
+ + " if (number instanceof Float n) {\n" //
+ + " return n.toString();\n" //
+ + " }\n" //
+ + " if (number instanceof Double n) {\n" //
+ + " return n.toString();\n" //
+ + " }\n" //
+ + " if ((number instanceof Float n && n.isInfinite()) || (number instanceof Double m && m.isInfinite())) {\n" //
+ + " return \"Inf\"; //$NON-NLS-1$\n" //
+ + " }\n" //
+ + "\n" //
+ + " return null;\n" //
+ + " }\n" //
+ + "\n" //
+ + "}\n"; //
+ assertRefactoringResultAsExpected(new ICompilationUnit[] { cu }, new String[] { expected },
+ new HashSet<>(Arrays.asList(MultiFixMessages.OneIfRatherThanDuplicateBlocksThatFallThroughCleanUp_description)));
+ }
+
@Test
public void testDoNotMatchPatternForInstanceof() throws Exception {
IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null);