diff --git a/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/ClassInstanceCreationVisitorTest.java b/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/ClassInstanceCreationVisitorTest.java
new file mode 100644
index 000000000..209150756
--- /dev/null
+++ b/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/ClassInstanceCreationVisitorTest.java
@@ -0,0 +1,530 @@
+/*******************************************************************************
+ * Copyright (c) 2026 Carsten Hammer.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Carsten Hammer
+ *******************************************************************************/
+package org.sandbox.jdt.ui.tests.quickfix;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.Block;
+import org.eclipse.jdt.core.dom.ClassInstanceCreation;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.internal.corext.dom.ASTNodes;
+import org.junit.jupiter.api.Test;
+import org.sandbox.jdt.internal.common.ASTProcessor;
+import org.sandbox.jdt.internal.common.AstProcessorBuilder;
+import org.sandbox.jdt.internal.common.HelperVisitor;
+import org.sandbox.jdt.internal.common.ReferenceHolder;
+import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+/**
+ * Tests for verifying that LambdaASTVisitor correctly finds ALL ClassInstanceCreation nodes.
+ *
+ *
This test class addresses issues identified in PR #593 where the ClassInstanceCreation
+ * visitor was only finding some instances instead of all instances in the code.
+ *
+ * Key Testing Areas
+ *
+ * - Multiple ClassInstanceCreation nodes in the same method
+ * - ClassInstanceCreation in nested blocks (if, while, for)
+ * - ClassInstanceCreation inside lambdas
+ * - ClassInstanceCreation in anonymous classes
+ * - Standalone ClassInstanceCreation without preceding method calls
+ * - Scope function parameter behavior
+ * - Chained visitor patterns similar to JFace plugin
+ *
+ *
+ * @author Carsten Hammer
+ */
+public class ClassInstanceCreationVisitorTest {
+
+ /**
+ * Helper method to create a CompilationUnit from source code.
+ *
+ * @param code the Java source code
+ * @param name the unit name
+ * @return the parsed CompilationUnit
+ */
+ private static CompilationUnit createUnit(String code, String name) {
+ ASTParser parser = ASTParser.newParser(AST.getJLSLatest());
+ parser.setKind(ASTParser.K_COMPILATION_UNIT);
+ Map options = JavaCore.getOptions();
+ JavaCore.setComplianceOptions(JavaCore.VERSION_17, options);
+ parser.setCompilerOptions(options);
+ parser.setEnvironment(new String[]{}, new String[]{}, null, true);
+ parser.setBindingsRecovery(true);
+ parser.setResolveBindings(true);
+ parser.setUnitName(name);
+ parser.setSource(code.toCharArray());
+ return (CompilationUnit) parser.createAST(null);
+ }
+
+ /**
+ * Test that the visitor finds all ClassInstanceCreation nodes in a simple method.
+ * This is the most basic test case - multiple instances in a linear flow.
+ */
+ @Test
+ public void testFindAllClassInstanceCreationInMethod() {
+ String code = """
+ package test;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+ public class Test {
+ public void doWork(MockProgressMonitor monitor) {
+ monitor.beginTask("Task", 100);
+ MockProgressMonitor sub1 = new MockSubProgressMonitor(monitor, 50);
+ MockProgressMonitor sub2 = new MockSubProgressMonitor(monitor, 30);
+ MockProgressMonitor sub3 = new MockSubProgressMonitor(monitor, 20);
+ }
+ }
+ """;
+
+ CompilationUnit cu = createUnit(code, "Test");
+
+ List found = new ArrayList<>();
+ Set nodesprocessed = null;
+ HelperVisitor, String, Object> hv =
+ new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>());
+
+ hv.addClassInstanceCreation((node, holder) -> {
+ found.add(node);
+ return true;
+ });
+
+ hv.build(cu);
+
+ assertEquals(3, found.size(), "Should find all 3 ClassInstanceCreation nodes");
+ }
+
+ /**
+ * Test that the visitor finds ClassInstanceCreation nodes with type filtering.
+ * This tests the typeof parameter functionality.
+ */
+ @Test
+ public void testFindClassInstanceCreationWithTypeFilter() {
+ String code = """
+ package test;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+ public class Test {
+ public void doWork(MockProgressMonitor monitor) {
+ monitor.beginTask("Task", 100);
+ MockProgressMonitor sub1 = new MockSubProgressMonitor(monitor, 50);
+ MockProgressMonitor sub2 = new MockSubProgressMonitor(monitor, 30);
+ String s = new String("test");
+ }
+ }
+ """;
+
+ CompilationUnit cu = createUnit(code, "Test");
+
+ List foundFiltered = new ArrayList<>();
+ List foundAll = new ArrayList<>();
+ Set nodesprocessed = null;
+
+ // First find all without filter
+ HelperVisitor, String, Object> hvAll =
+ new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>());
+ hvAll.addClassInstanceCreation((node, holder) -> {
+ foundAll.add(node);
+ return true;
+ });
+ hvAll.build(cu);
+
+ // Then find only MockSubProgressMonitor instances
+ HelperVisitor, String, Object> hvFiltered =
+ new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>());
+ hvFiltered.addClassInstanceCreation(MockSubProgressMonitor.class, (node, holder) -> {
+ foundFiltered.add(node);
+ return true;
+ });
+ hvFiltered.build(cu);
+
+ assertEquals(3, foundAll.size(), "Should find 3 total ClassInstanceCreation nodes (2 MockSubProgressMonitor + 1 String)");
+ assertEquals(2, foundFiltered.size(), "Should find only 2 MockSubProgressMonitor instances when filtered");
+ }
+
+ /**
+ * Test ClassInstanceCreation in nested blocks (if, while, for loops).
+ * This ensures the visitor properly traverses nested structures.
+ */
+ @Test
+ public void testFindClassInstanceCreationInNestedBlocks() {
+ String code = """
+ package test;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+ public class Test {
+ public void doWork(MockProgressMonitor monitor) {
+ monitor.beginTask("Task", 100);
+
+ if (true) {
+ MockProgressMonitor sub1 = new MockSubProgressMonitor(monitor, 10);
+ }
+
+ while (false) {
+ MockProgressMonitor sub2 = new MockSubProgressMonitor(monitor, 20);
+ }
+
+ for (int i = 0; i < 5; i++) {
+ MockProgressMonitor sub3 = new MockSubProgressMonitor(monitor, 30);
+ }
+
+ MockProgressMonitor sub4 = new MockSubProgressMonitor(monitor, 40);
+ }
+ }
+ """;
+
+ CompilationUnit cu = createUnit(code, "Test");
+
+ List found = new ArrayList<>();
+ Set nodesprocessed = null;
+ HelperVisitor, String, Object> hv =
+ new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>());
+
+ hv.addClassInstanceCreation((node, holder) -> {
+ found.add(node);
+ return true;
+ });
+
+ hv.build(cu);
+
+ assertEquals(4, found.size(), "Should find all 4 ClassInstanceCreation nodes including those in nested blocks");
+ }
+
+ /**
+ * Test ClassInstanceCreation inside lambdas.
+ * This ensures the visitor traverses into lambda expressions.
+ */
+ @Test
+ public void testFindClassInstanceCreationInLambdas() {
+ String code = """
+ package test;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+ public class Test {
+ public void doWork(MockProgressMonitor monitor) {
+ Runnable r = () -> {
+ MockProgressMonitor sub1 = new MockSubProgressMonitor(monitor, 50);
+ };
+
+ MockProgressMonitor sub2 = new MockSubProgressMonitor(monitor, 30);
+ }
+ }
+ """;
+
+ CompilationUnit cu = createUnit(code, "Test");
+
+ List found = new ArrayList<>();
+ Set nodesprocessed = null;
+ HelperVisitor, String, Object> hv =
+ new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>());
+
+ hv.addClassInstanceCreation((node, holder) -> {
+ found.add(node);
+ return true;
+ });
+
+ hv.build(cu);
+
+ assertEquals(2, found.size(), "Should find all 2 ClassInstanceCreation nodes including one inside lambda");
+ }
+
+ /**
+ * Test ClassInstanceCreation in anonymous classes.
+ * This ensures the visitor traverses into anonymous class bodies.
+ */
+ @Test
+ public void testFindClassInstanceCreationInAnonymousClasses() {
+ String code = """
+ package test;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+ public class Test {
+ public void doWork(MockProgressMonitor monitor) {
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ MockProgressMonitor sub1 = new MockSubProgressMonitor(monitor, 50);
+ }
+ };
+
+ MockProgressMonitor sub2 = new MockSubProgressMonitor(monitor, 30);
+ }
+ }
+ """;
+
+ CompilationUnit cu = createUnit(code, "Test");
+
+ List found = new ArrayList<>();
+ Set nodesprocessed = null;
+ HelperVisitor, String, Object> hv =
+ new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>());
+
+ hv.addClassInstanceCreation((node, holder) -> {
+ found.add(node);
+ return true;
+ });
+
+ hv.build(cu);
+
+ assertEquals(3, found.size(), "Should find all 3 ClassInstanceCreation nodes (1 Runnable anonymous + 2 MockSubProgressMonitor)");
+ }
+
+ /**
+ * Test standalone ClassInstanceCreation without any preceding method calls.
+ * This tests the case where there's no beginTask() before SubProgressMonitor creation.
+ */
+ @Test
+ public void testFindStandaloneClassInstanceCreation() {
+ String code = """
+ package test;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+ public class Test {
+ public void doWork(MockProgressMonitor monitor) {
+ // No beginTask() call here
+ MockProgressMonitor sub1 = new MockSubProgressMonitor(monitor, 50);
+ MockProgressMonitor sub2 = new MockSubProgressMonitor(monitor, 30);
+ MockProgressMonitor sub3 = new MockSubProgressMonitor(monitor, 20);
+ }
+ }
+ """;
+
+ CompilationUnit cu = createUnit(code, "Test");
+
+ List found = new ArrayList<>();
+ Set nodesprocessed = null;
+ HelperVisitor, String, Object> hv =
+ new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>());
+
+ hv.addClassInstanceCreation((node, holder) -> {
+ found.add(node);
+ return true;
+ });
+
+ hv.build(cu);
+
+ assertEquals(3, found.size(), "Should find all 3 ClassInstanceCreation nodes even without beginTask");
+ }
+
+ /**
+ * Test the scope function parameter and its effect on visitor traversal.
+ * This is CRITICAL - it tests how the navigate/scope function limits the search space.
+ */
+ @Test
+ public void testScopeFunctionBehavior() {
+ String code = """
+ package test;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+ public class Test {
+ public void doWork(MockProgressMonitor monitor) {
+ monitor.beginTask("Task", 100);
+ MockProgressMonitor sub1 = new MockSubProgressMonitor(monitor, 50);
+ MockProgressMonitor sub2 = new MockSubProgressMonitor(monitor, 30);
+
+ if (true) {
+ MockProgressMonitor sub3 = new MockSubProgressMonitor(monitor, 20);
+ }
+ }
+ }
+ """;
+
+ CompilationUnit cu = createUnit(code, "Test");
+
+ // Test 1: Find all instances without scope limitation
+ List foundAll = new ArrayList<>();
+ Set nodesprocessed = null;
+ HelperVisitor, String, Object> hvAll =
+ new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>());
+ hvAll.addClassInstanceCreation((node, holder) -> {
+ foundAll.add(node);
+ return true;
+ });
+ hvAll.build(cu);
+
+ assertEquals(3, foundAll.size(), "Without scope function, should find all 3 ClassInstanceCreation nodes");
+
+ // Test 2: Use ASTProcessor with scope function that navigates to Block
+ // This mimics the JFace plugin pattern
+ List foundWithScope = new ArrayList<>();
+ ReferenceHolder dataholder = new ReferenceHolder<>();
+
+ AstProcessorBuilder.with(dataholder, nodesprocessed)
+ .processor()
+ .callMethodInvocationVisitor(MockProgressMonitor.class, "beginTask", (node, holder) -> {
+ holder.put("beginTask", node);
+ return true;
+ }, s -> ASTNodes.getTypedAncestor(s, Block.class))
+ .callClassInstanceCreationVisitor((node, holder) -> {
+ foundWithScope.add(node);
+ return true;
+ })
+ .build(cu);
+
+ // After navigating to Block containing beginTask, we should find ALL ClassInstanceCreation
+ // nodes in that Block (including the one in the nested if block)
+ assertTrue(foundWithScope.size() > 0, "With scope function, should find ClassInstanceCreation nodes in the Block scope");
+ assertEquals(foundAll.size(), foundWithScope.size(),
+ "Scope function should find all nodes when the Block contains all instances");
+ }
+
+ /**
+ * Test the chained visitor pattern similar to JFace plugin.
+ * This reproduces the exact pattern used in JFacePlugin.java to find the issue.
+ */
+ @Test
+ public void testJFacePluginPattern() {
+ String code = """
+ package test;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+ public class Test {
+ public void doWork(MockProgressMonitor monitor) {
+ monitor.beginTask("Task", 100);
+ MockProgressMonitor sub1 = new MockSubProgressMonitor(monitor, 50);
+ MockProgressMonitor sub2 = new MockSubProgressMonitor(monitor, 30);
+ MockProgressMonitor sub3 = new MockSubProgressMonitor(monitor, 20);
+ }
+ }
+ """;
+
+ CompilationUnit cu = createUnit(code, "Test");
+
+ // Track how many beginTask and ClassInstanceCreation nodes we find
+ List beginTaskNodes = new ArrayList<>();
+ List cicNodes = new ArrayList<>();
+ Set nodesprocessed = null;
+ ReferenceHolder dataholder = new ReferenceHolder<>();
+
+ AstProcessorBuilder.with(dataholder, nodesprocessed)
+ .processor()
+ .callMethodInvocationVisitor(MockProgressMonitor.class, "beginTask", (node, holder) -> {
+ beginTaskNodes.add(node);
+ holder.put("beginTask", node);
+ return true;
+ }, s -> ASTNodes.getTypedAncestor(s, Block.class))
+ .callClassInstanceCreationVisitor(MockSubProgressMonitor.class, (node, holder) -> {
+ cicNodes.add(node);
+ return true;
+ })
+ .build(cu);
+
+ assertEquals(1, beginTaskNodes.size(), "Should find 1 beginTask invocation");
+ assertEquals(3, cicNodes.size(), "Should find all 3 MockSubProgressMonitor instances after beginTask");
+ }
+
+ /**
+ * Test with multiple blocks and verify scope behavior.
+ * This tests what happens when ClassInstanceCreation nodes are in different blocks.
+ */
+ @Test
+ public void testMultipleBlocksWithSeparateInstances() {
+ String code = """
+ package test;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+ public class Test {
+ public void method1(MockProgressMonitor monitor) {
+ monitor.beginTask("Task1", 50);
+ MockProgressMonitor sub1 = new MockSubProgressMonitor(monitor, 50);
+ }
+
+ public void method2(MockProgressMonitor monitor) {
+ monitor.beginTask("Task2", 50);
+ MockProgressMonitor sub2 = new MockSubProgressMonitor(monitor, 50);
+ }
+ }
+ """;
+
+ CompilationUnit cu = createUnit(code, "Test");
+
+ // Find all without scope
+ List foundAll = new ArrayList<>();
+ Set nodesprocessed = null;
+ HelperVisitor, String, Object> hv =
+ new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>());
+ hv.addClassInstanceCreation((node, holder) -> {
+ foundAll.add(node);
+ return true;
+ });
+ hv.build(cu);
+
+ assertEquals(2, foundAll.size(), "Should find both ClassInstanceCreation nodes in different methods");
+ }
+
+ /**
+ * Test edge case: deeply nested ClassInstanceCreation.
+ * This ensures the visitor traverses arbitrarily deep structures.
+ */
+ @Test
+ public void testDeeplyNestedClassInstanceCreation() {
+ String code = """
+ package test;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockProgressMonitor;
+ import org.sandbox.jdt.ui.tests.quickfix.mock.MockSubProgressMonitor;
+
+ public class Test {
+ public void doWork(MockProgressMonitor monitor) {
+ if (true) {
+ if (true) {
+ while (false) {
+ for (int i = 0; i < 1; i++) {
+ MockProgressMonitor sub1 = new MockSubProgressMonitor(monitor, 50);
+ }
+ }
+ }
+ }
+ MockProgressMonitor sub2 = new MockSubProgressMonitor(monitor, 50);
+ }
+ }
+ """;
+
+ CompilationUnit cu = createUnit(code, "Test");
+
+ List found = new ArrayList<>();
+ Set nodesprocessed = null;
+ HelperVisitor, String, Object> hv =
+ new HelperVisitor<>(nodesprocessed, new ReferenceHolder<>());
+
+ hv.addClassInstanceCreation((node, holder) -> {
+ found.add(node);
+ return true;
+ });
+
+ hv.build(cu);
+
+ assertEquals(2, found.size(), "Should find both ClassInstanceCreation nodes including deeply nested one");
+ }
+}
diff --git a/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/mock/MockProgressMonitor.java b/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/mock/MockProgressMonitor.java
new file mode 100644
index 000000000..a93506b04
--- /dev/null
+++ b/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/mock/MockProgressMonitor.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2026 Carsten Hammer.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Carsten Hammer
+ *******************************************************************************/
+package org.sandbox.jdt.ui.tests.quickfix.mock;
+
+/**
+ * Mock interface for testing ClassInstanceCreation visitor patterns.
+ * Mimics the IProgressMonitor pattern without JFace dependencies.
+ */
+public interface MockProgressMonitor {
+ /**
+ * Begins a task with the specified name and total work units.
+ *
+ * @param name the task name
+ * @param totalWork the total work units
+ */
+ void beginTask(String name, int totalWork);
+
+ /**
+ * Marks the task as complete.
+ */
+ void done();
+
+ /**
+ * Reports work progress.
+ *
+ * @param work the amount of work done
+ */
+ void worked(int work);
+}
diff --git a/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/mock/MockSubMonitor.java b/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/mock/MockSubMonitor.java
new file mode 100644
index 000000000..d531a2cb1
--- /dev/null
+++ b/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/mock/MockSubMonitor.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2026 Carsten Hammer.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Carsten Hammer
+ *******************************************************************************/
+package org.sandbox.jdt.ui.tests.quickfix.mock;
+
+/**
+ * Mock class for testing ClassInstanceCreation visitor patterns.
+ * Mimics the SubMonitor pattern (replacement for SubProgressMonitor) without JFace dependencies.
+ */
+public class MockSubMonitor implements MockProgressMonitor {
+
+ /**
+ * Converts a monitor to a SubMonitor.
+ *
+ * @param monitor the monitor to convert
+ * @param work the total work units
+ * @return a new MockSubMonitor instance
+ */
+ public static MockSubMonitor convert(MockProgressMonitor monitor, int work) {
+ return new MockSubMonitor();
+ }
+
+ /**
+ * Converts a monitor to a SubMonitor with a task name.
+ *
+ * @param monitor the monitor to convert
+ * @param taskName the task name
+ * @param work the total work units
+ * @return a new MockSubMonitor instance
+ */
+ public static MockSubMonitor convert(MockProgressMonitor monitor, String taskName, int work) {
+ return new MockSubMonitor();
+ }
+
+ /**
+ * Splits off a portion of work.
+ *
+ * @param work the amount of work to split
+ * @return a new MockSubMonitor for the split work
+ */
+ public MockSubMonitor split(int work) {
+ return new MockSubMonitor();
+ }
+
+ @Override
+ public void beginTask(String name, int totalWork) {
+ // Mock implementation
+ }
+
+ @Override
+ public void done() {
+ // Mock implementation
+ }
+
+ @Override
+ public void worked(int work) {
+ // Mock implementation
+ }
+}
diff --git a/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/mock/MockSubProgressMonitor.java b/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/mock/MockSubProgressMonitor.java
new file mode 100644
index 000000000..c17005c00
--- /dev/null
+++ b/sandbox_common_test/src/org/sandbox/jdt/ui/tests/quickfix/mock/MockSubProgressMonitor.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2026 Carsten Hammer.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Carsten Hammer
+ *******************************************************************************/
+package org.sandbox.jdt.ui.tests.quickfix.mock;
+
+/**
+ * Mock class for testing ClassInstanceCreation visitor patterns.
+ * Mimics the deprecated SubProgressMonitor pattern without JFace dependencies.
+ */
+public class MockSubProgressMonitor implements MockProgressMonitor {
+
+ private final MockProgressMonitor monitor;
+ private final int ticks;
+ private final int style;
+
+ /**
+ * Creates a new MockSubProgressMonitor with 2 arguments.
+ *
+ * @param monitor the parent monitor
+ * @param ticks the number of ticks
+ */
+ public MockSubProgressMonitor(MockProgressMonitor monitor, int ticks) {
+ this(monitor, ticks, 0);
+ }
+
+ /**
+ * Creates a new MockSubProgressMonitor with 3 arguments.
+ *
+ * @param monitor the parent monitor
+ * @param ticks the number of ticks
+ * @param style the style flags
+ */
+ public MockSubProgressMonitor(MockProgressMonitor monitor, int ticks, int style) {
+ this.monitor = monitor;
+ this.ticks = ticks;
+ this.style = style;
+ }
+
+ @Override
+ public void beginTask(String name, int totalWork) {
+ // Mock implementation
+ }
+
+ @Override
+ public void done() {
+ // Mock implementation
+ }
+
+ @Override
+ public void worked(int work) {
+ // Mock implementation
+ }
+}
diff --git a/sandbox_jface_cleanup/README.md b/sandbox_jface_cleanup/README.md
index 29b0c5f6e..7a21ec3b9 100644
--- a/sandbox_jface_cleanup/README.md
+++ b/sandbox_jface_cleanup/README.md
@@ -9,7 +9,8 @@ The **JFace Cleanup** plugin modernizes Eclipse JFace code by migrating deprecat
## Key Features
- 🔄 **SubProgressMonitor → SubMonitor** - Automatic migration to modern progress API
-- 🎯 **Style Flag Handling** - Properly converts `PREPEND_MAIN_LABEL_TO_SUBTASK` flag
+- 🎯 **Style Flag Mapping** - Maps `SUPPRESS_SUBTASK_LABEL` to `SUPPRESS_SUBTASK`
+- 🗑️ **Flag Dropping** - Removes `PREPEND_MAIN_LABEL_TO_SUBTASK` (no SubMonitor equivalent)
- 📦 **Variable Name Management** - Generates unique variable names to avoid conflicts
- ♻️ **Idempotent** - Running cleanup multiple times produces the same result
- 🔌 **Eclipse Integration** - Works seamlessly with Eclipse RCP/JFace code
@@ -27,52 +28,77 @@ The **JFace Cleanup** plugin modernizes Eclipse JFace code by migrating deprecat
**Basic Transformation:**
```java
// Before
-SubProgressMonitor subMonitor = new SubProgressMonitor(monitor, 100);
+monitor.beginTask("Task", 100);
+IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 50);
// After
-SubMonitor subMonitor = SubMonitor.convert(monitor, 100);
+SubMonitor subMonitor = SubMonitor.convert(monitor, "Task", 100);
+IProgressMonitor sub = subMonitor.split(50);
```
-**With Style Flags:**
+**With SUPPRESS_SUBTASK_LABEL Flag:**
```java
// Before
+monitor.beginTask("Task", 100);
SubProgressMonitor sub = new SubProgressMonitor(
- monitor, 50, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+ monitor, 50, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL);
// After
-SubMonitor sub = SubMonitor.convert(monitor, 50)
- .setWorkRemaining(50);
+SubMonitor subMonitor = SubMonitor.convert(monitor, "Task", 100);
+IProgressMonitor sub = subMonitor.split(50, SubMonitor.SUPPRESS_SUBTASK);
+```
+
+**With PREPEND_MAIN_LABEL_TO_SUBTASK Flag (Dropped):**
+```java
+// Before
+monitor.beginTask("Task", 100);
+SubProgressMonitor sub = new SubProgressMonitor(
+ monitor, 50, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+
+// After - flag is dropped as there's no equivalent in SubMonitor
+SubMonitor subMonitor = SubMonitor.convert(monitor, "Task", 100);
+IProgressMonitor sub = subMonitor.split(50);
```
**Unique Variable Names:**
```java
// Before
-SubProgressMonitor sub = new SubProgressMonitor(monitor, 100);
-// ... later in code ...
-SubProgressMonitor sub = new SubProgressMonitor(otherMonitor, 50);
+String subMonitor = "test";
+monitor.beginTask("Task", 100);
+IProgressMonitor sub = new SubProgressMonitor(monitor, 50);
// After
-SubMonitor sub = SubMonitor.convert(monitor, 100);
-// ... later in code ...
-SubMonitor sub2 = SubMonitor.convert(otherMonitor, 50); // Unique name generated
+String subMonitor = "test";
+SubMonitor subMonitor2 = SubMonitor.convert(monitor, "Task", 100);
+IProgressMonitor sub = subMonitor2.split(50); // Unique name generated
```
## Migration Pattern
-The cleanup transforms:
+The cleanup transforms `beginTask` + `SubProgressMonitor` to `SubMonitor.convert` + `split`:
```
+monitor.beginTask(msg, work);
new SubProgressMonitor(monitor, ticks)
↓
-SubMonitor.convert(monitor, ticks)
+SubMonitor subMonitor = SubMonitor.convert(monitor, msg, work);
+subMonitor.split(ticks)
+```
+
+With `SUPPRESS_SUBTASK_LABEL` flag:
+
+```
+new SubProgressMonitor(monitor, ticks, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL)
+ ↓ (in beginTask context)
+subMonitor.split(ticks, SubMonitor.SUPPRESS_SUBTASK)
```
-With style flag `PREPEND_MAIN_LABEL_TO_SUBTASK`:
+With `PREPEND_MAIN_LABEL_TO_SUBTASK` flag:
```
new SubProgressMonitor(monitor, ticks, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)
- ↓
-SubMonitor.convert(monitor, ticks).setWorkRemaining(ticks)
+ ↓ (flag is dropped - no equivalent in SubMonitor)
+subMonitor.split(ticks)
```
## Why Migrate?
@@ -137,8 +163,9 @@ xvfb-run --auto-servernum mvn test -pl sandbox_jface_cleanup_test
## Limitations
-- Does not handle complex style flag combinations (only `PREPEND_MAIN_LABEL_TO_SUBTASK`)
+- Combined flag expressions using bitwise OR (e.g., `FLAG1 | FLAG2`) or numeric flag literals are not automatically mapped and require manual review
- Custom SubProgressMonitor subclasses require manual review
+- Only handles SubProgressMonitor instances with a corresponding beginTask call in the same scope
- Some rare edge cases may need manual adjustment
See [TODO.md](TODO.md) for planned improvements.
diff --git a/sandbox_jface_cleanup/src/org/sandbox/jdt/internal/corext/fix/JfaceCleanUpFixCore.java b/sandbox_jface_cleanup/src/org/sandbox/jdt/internal/corext/fix/JfaceCleanUpFixCore.java
index 3eb374283..987bc8425 100644
--- a/sandbox_jface_cleanup/src/org/sandbox/jdt/internal/corext/fix/JfaceCleanUpFixCore.java
+++ b/sandbox_jface_cleanup/src/org/sandbox/jdt/internal/corext/fix/JfaceCleanUpFixCore.java
@@ -75,7 +75,19 @@ public void rewriteASTInternal(final CompilationUnitRewrite cuRewrite, final Lin
} else {
rangeComputer= new TightSourceRangeComputer();
}
- rangeComputer.addTightSourceNode( hit.get(0).minv);
+
+ // Get the first MonitorHolder from the hit map (key might not be 0 due to scope grouping)
+ MonitorHolder mh = hit.values().stream().findFirst().orElse(null);
+ if (mh != null) {
+ // For standalone SubProgressMonitor, use the ClassInstanceCreation node instead of minv
+ if (mh.minv != null) {
+ rangeComputer.addTightSourceNode(mh.minv);
+ } else if (!mh.setofcic.isEmpty()) {
+ // Use the first SubProgressMonitor creation for standalone case
+ rangeComputer.addTightSourceNode(mh.setofcic.iterator().next());
+ }
+ }
+
rewrite.setTargetSourceRangeComputer(rangeComputer);
jfacefound.rewrite(JfaceCleanUpFixCore.this, hit, cuRewrite, group);
}
diff --git a/sandbox_jface_cleanup/src/org/sandbox/jdt/internal/corext/fix/helper/JFacePlugin.java b/sandbox_jface_cleanup/src/org/sandbox/jdt/internal/corext/fix/helper/JFacePlugin.java
index 10d0873f1..5874b3c3c 100644
--- a/sandbox_jface_cleanup/src/org/sandbox/jdt/internal/corext/fix/helper/JFacePlugin.java
+++ b/sandbox_jface_cleanup/src/org/sandbox/jdt/internal/corext/fix/helper/JFacePlugin.java
@@ -33,10 +33,13 @@
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ExpressionStatement;
+import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.MethodInvocation;
+import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
+import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
+import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
@@ -188,11 +191,6 @@ public void find(JfaceCleanUpFixCore fixcore, CompilationUnit compilationUnit,
return true;
}, s -> ASTNodes.getTypedAncestor(s, Block.class))
.callClassInstanceCreationVisitor(SubProgressMonitor.class, (node, holder) -> {
- // Guard against empty holder
- if (holder.isEmpty()) {
- return true;
- }
- MonitorHolder mh = holder.get(holder.size() - 1);
List> arguments = node.arguments();
if (arguments.isEmpty()) {
return true;
@@ -208,15 +206,23 @@ public void find(JfaceCleanUpFixCore fixcore, CompilationUnit compilationUnit,
firstArgName = sn.getIdentifier();
}
- if (firstArgName == null || !mh.minvname.equals(firstArgName)) {
- return true;
+ // Check if this SubProgressMonitor is associated with a beginTask
+ if (!holder.isEmpty() && firstArgName != null) {
+ MonitorHolder mh = holder.get(holder.size() - 1);
+ if (mh.minvname.equals(firstArgName)) {
+ logDebug("Found SubProgressMonitor construction at position " + node.getStartPosition() + " for variable '" + firstArgName + "' with beginTask"); //$NON-NLS-1$ //$NON-NLS-2$
+ mh.setofcic.add(node);
+ }
}
- logDebug("Found SubProgressMonitor construction at position " + node.getStartPosition() + " for variable '" + firstArgName + "'"); //$NON-NLS-1$ //$NON-NLS-2$
- mh.setofcic.add(node);
- operations.add(fixcore.rewrite(holder));
+
return true;
- })
+ }, s -> ASTNodes.getTypedAncestor(s, Block.class))
.build(compilationUnit);
+
+ // Add operations for beginTask-associated monitors
+ if (!dataholder.isEmpty()) {
+ operations.add(fixcore.rewrite(dataholder));
+ }
}
/**
@@ -263,6 +269,8 @@ public void rewrite(JfaceCleanUpFixCore upp, final ReferenceHolder entry : hit.entrySet()) {
MonitorHolder mh = entry.getValue();
+
+ // Handle beginTask + SubProgressMonitor pattern
MethodInvocation minv = mh.minv;
// Generate unique identifier name for SubMonitor variable
@@ -289,12 +297,7 @@ public void rewrite(JfaceCleanUpFixCore upp, final ReferenceHolder arguments = submon.arguments();
if (arguments.size() < 2) {
continue;
@@ -327,7 +344,11 @@ public void rewrite(JfaceCleanUpFixCore upp, final ReferenceHolder subMonitor.split(work)
*
* 3-arg: new SubProgressMonitor(monitor, work, flags)
- * -> subMonitor.split(work, flags)
+ * -> subMonitor.split(work, mappedFlags)
+ *
+ * Flag mapping:
+ * - SUPPRESS_SUBTASK_LABEL -> SUPPRESS_SUBTASK
+ * - PREPEND_MAIN_LABEL_TO_SUBTASK -> dropped (no equivalent)
*/
MethodInvocation newMethodInvocation2 = ast.newMethodInvocation();
newMethodInvocation2.setName(ast.newSimpleName("split")); //$NON-NLS-1$
@@ -340,8 +361,13 @@ public void rewrite(JfaceCleanUpFixCore upp, final ReferenceHolder= 3) {
- ASTNode flagsArg = (ASTNode) arguments.get(2);
- splitCallArguments.add(ASTNodes.createMoveTarget(rewrite, ASTNodes.getUnparenthesedExpression(flagsArg)));
+ Expression flagsArg = (Expression) arguments.get(2);
+ Expression mappedFlag = mapSubProgressMonitorFlags(flagsArg, ast, cuRewrite);
+
+ // Only add the flag if it wasn't dropped (PREPEND_MAIN_LABEL_TO_SUBTASK is dropped)
+ if (mappedFlag != null) {
+ splitCallArguments.add(mappedFlag);
+ }
}
ASTNodes.replaceButKeepComment(rewrite, submon, newMethodInvocation2, group);
@@ -379,6 +405,63 @@ private String generateUniqueVariableName(ASTNode node, String baseName) {
return candidate;
}
+ /**
+ * Maps SubProgressMonitor flags to SubMonitor flags.
+ *
+ * Flag mappings:
+ *
+ * - {@code SubProgressMonitor.SUPPRESS_SUBTASK_LABEL} → {@code SubMonitor.SUPPRESS_SUBTASK}
+ * - {@code SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK} → removed (no equivalent)
+ *
+ *
+ * Limitations: This method only handles single flag constants. Combined flag expressions
+ * using bitwise OR (e.g., {@code FLAG1 | FLAG2}) or numeric literals are not mapped and will be
+ * passed through unchanged, which may result in incorrect behavior. Such cases require manual review.
+ *
+ * @param flagExpr the original flag expression from SubProgressMonitor constructor
+ * @param ast the AST to create new nodes
+ * @param cuRewrite the compilation unit rewrite context
+ * @return the mapped flag expression for SubMonitor, or null if flag should be dropped
+ */
+ private Expression mapSubProgressMonitorFlags(Expression flagExpr, AST ast, CompilationUnitRewrite cuRewrite) {
+ // Handle field access: SubProgressMonitor.SUPPRESS_SUBTASK_LABEL
+ if (flagExpr instanceof QualifiedName) {
+ QualifiedName qn = (QualifiedName) flagExpr;
+ String fieldName = qn.getName().getIdentifier();
+
+ if ("SUPPRESS_SUBTASK_LABEL".equals(fieldName)) { //$NON-NLS-1$
+ // Map to SubMonitor.SUPPRESS_SUBTASK
+ QualifiedName newFlag = ast.newQualifiedName(
+ ast.newSimpleName(SubMonitor.class.getSimpleName()),
+ ast.newSimpleName("SUPPRESS_SUBTASK")); //$NON-NLS-1$
+ return newFlag;
+ } else if ("PREPEND_MAIN_LABEL_TO_SUBTASK".equals(fieldName)) { //$NON-NLS-1$
+ // Drop this flag - no equivalent in SubMonitor
+ return null;
+ }
+ }
+
+ // Handle FieldAccess syntax (e.g., expression.FIELD_NAME)
+ if (flagExpr instanceof FieldAccess) {
+ FieldAccess fa = (FieldAccess) flagExpr;
+ String fieldName = fa.getName().getIdentifier();
+
+ if ("SUPPRESS_SUBTASK_LABEL".equals(fieldName)) { //$NON-NLS-1$
+ // Map to SubMonitor.SUPPRESS_SUBTASK
+ FieldAccess newFlag = ast.newFieldAccess();
+ newFlag.setExpression(ast.newSimpleName(SubMonitor.class.getSimpleName()));
+ newFlag.setName(ast.newSimpleName("SUPPRESS_SUBTASK")); //$NON-NLS-1$
+ return newFlag;
+ } else if ("PREPEND_MAIN_LABEL_TO_SUBTASK".equals(fieldName)) { //$NON-NLS-1$
+ // Drop this flag - no equivalent in SubMonitor
+ return null;
+ }
+ }
+
+ // For other expressions (constants, variables), pass through unchanged
+ return ASTNodes.createMoveTarget(cuRewrite.getASTRewrite(), ASTNodes.getUnparenthesedExpression(flagExpr));
+ }
+
@Override
public String getPreview(boolean afterRefactoring) {
if (!afterRefactoring) {
diff --git a/sandbox_jface_cleanup_test/pom.xml b/sandbox_jface_cleanup_test/pom.xml
index c038a8741..578b0cbf0 100644
--- a/sandbox_jface_cleanup_test/pom.xml
+++ b/sandbox_jface_cleanup_test/pom.xml
@@ -26,7 +26,6 @@
${tycho-version}
BREE
- false
true
diff --git a/sandbox_jface_cleanup_test/src/org/sandbox/jdt/ui/tests/quickfix/Java8CleanUpTest.java b/sandbox_jface_cleanup_test/src/org/sandbox/jdt/ui/tests/quickfix/Java8CleanUpTest.java
index 62e651772..edc34a82f 100644
--- a/sandbox_jface_cleanup_test/src/org/sandbox/jdt/ui/tests/quickfix/Java8CleanUpTest.java
+++ b/sandbox_jface_cleanup_test/src/org/sandbox/jdt/ui/tests/quickfix/Java8CleanUpTest.java
@@ -76,7 +76,7 @@ public void createPackageFragmentRoot(IProgressMonitor monitor) throws CoreExcep
import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
public class Test extends ArrayList {
public void createPackageFragmentRoot(IProgressMonitor monitor) throws CoreException, InterruptedException {
- SubMonitor subMonitor=SubMonitor.convert(monitor,NewWizardMessages.NewSourceFolderWizardPage_operation,3);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, NewWizardMessages.NewSourceFolderWizardPage_operation, 3);
IProgressMonitor subProgressMonitor= subMonitor.split(1);
IProgressMonitor subProgressMonitor2= subMonitor.split(2);
}
@@ -112,12 +112,12 @@ public void createPackageFragmentRoot2(IProgressMonitor monitor) throws CoreExce
import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
public class Test extends ArrayList {
public void createPackageFragmentRoot(IProgressMonitor monitor) throws CoreException, InterruptedException {
- SubMonitor subMonitor=SubMonitor.convert(monitor,NewWizardMessages.NewSourceFolderWizardPage_operation,3);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, NewWizardMessages.NewSourceFolderWizardPage_operation, 3);
IProgressMonitor subProgressMonitor= subMonitor.split(1);
IProgressMonitor subProgressMonitor2= subMonitor.split(2);
}
public void createPackageFragmentRoot2(IProgressMonitor monitor) throws CoreException, InterruptedException {
- SubMonitor subMonitor=SubMonitor.convert(monitor,NewWizardMessages.NewSourceFolderWizardPage_operation,3);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, NewWizardMessages.NewSourceFolderWizardPage_operation, 3);
IProgressMonitor subProgressMonitor3= subMonitor.split(1);
IProgressMonitor subProgressMonitor4= subMonitor.split(2);
}
@@ -141,7 +141,7 @@ public void doWork(IProgressMonitor monitor) {
import org.eclipse.core.runtime.SubMonitor;
public class Test {
public void doWork(IProgressMonitor monitor) {
- SubMonitor subMonitor=SubMonitor.convert(monitor,"Task",100);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Task", 100);
IProgressMonitor sub= subMonitor.split(50, 1);
}
}
@@ -166,7 +166,7 @@ public void doWork(IProgressMonitor monitor) {
public class Test {
public void doWork(IProgressMonitor monitor) {
String subMonitor = "test";
- SubMonitor subMonitor2=SubMonitor.convert(monitor,"Task",100);
+ SubMonitor subMonitor2 = SubMonitor.convert(monitor, "Task", 100);
IProgressMonitor sub= subMonitor2.split(50);
}
}
@@ -178,9 +178,9 @@ public void doWork(IProgressMonitor monitor) {
import org.eclipse.core.runtime.SubMonitor;
public class Test {
public void doWork(IProgressMonitor monitor) {
- SubMonitor subMonitor=SubMonitor.convert(monitor,"Task",100);
- IProgressMonitor sub= subMonitor.split(50);
- IProgressMonitor sub2= subMonitor.split(30);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Task", 100);
+ IProgressMonitor sub = subMonitor.split(50);
+ IProgressMonitor sub2 = subMonitor.split(30);
}
}
""", //$NON-NLS-1$
@@ -190,9 +190,9 @@ public void doWork(IProgressMonitor monitor) {
import org.eclipse.core.runtime.SubMonitor;
public class Test {
public void doWork(IProgressMonitor monitor) {
- SubMonitor subMonitor=SubMonitor.convert(monitor,"Task",100);
- IProgressMonitor sub= subMonitor.split(50);
- IProgressMonitor sub2= subMonitor.split(30);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Task", 100);
+ IProgressMonitor sub = subMonitor.split(50);
+ IProgressMonitor sub2 = subMonitor.split(30);
}
}
"""), //$NON-NLS-1$
@@ -205,8 +205,8 @@ public void doWork(IProgressMonitor monitor) {
public class Test {
// This method already uses SubMonitor - should not be modified
public void alreadyConverted(IProgressMonitor monitor) {
- SubMonitor subMonitor=SubMonitor.convert(monitor,"Already converted",50);
- IProgressMonitor sub= subMonitor.split(25);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Already converted", 50);
+ IProgressMonitor sub = subMonitor.split(25);
}
// This method still uses SubProgressMonitor - should be converted
public void needsConversion(IProgressMonitor monitor) {
@@ -222,12 +222,12 @@ public void needsConversion(IProgressMonitor monitor) {
public class Test {
// This method already uses SubMonitor - should not be modified
public void alreadyConverted(IProgressMonitor monitor) {
- SubMonitor subMonitor=SubMonitor.convert(monitor,"Already converted",50);
- IProgressMonitor sub= subMonitor.split(25);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Already converted", 50);
+ IProgressMonitor sub = subMonitor.split(25);
}
// This method still uses SubProgressMonitor - should be converted
public void needsConversion(IProgressMonitor monitor) {
- SubMonitor subMonitor=SubMonitor.convert(monitor,"Needs conversion",100);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Needs conversion", 100);
IProgressMonitor sub= subMonitor.split(60);
}
}
@@ -256,12 +256,12 @@ public void innerMethod(IProgressMonitor monitor) {
import org.eclipse.core.runtime.SubMonitor;
public class Test {
public void outerMethod(IProgressMonitor monitor) {
- SubMonitor subMonitor=SubMonitor.convert(monitor,"Outer task",50);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Outer task", 50);
IProgressMonitor sub= subMonitor.split(25);
}
class InnerClass {
public void innerMethod(IProgressMonitor monitor) {
- SubMonitor subMonitor=SubMonitor.convert(monitor,"Inner task",100);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Inner task", 100);
IProgressMonitor sub= subMonitor.split(50);
}
}
@@ -291,12 +291,60 @@ public void withLambda(IProgressMonitor monitor) {
public class Test {
public void withLambda(IProgressMonitor monitor) {
Consumer task = m -> {
- SubMonitor subMonitor=SubMonitor.convert(m,"Lambda task",100);
+ SubMonitor subMonitor = SubMonitor.convert(m, "Lambda task", 100);
IProgressMonitor sub = subMonitor.split(50);
};
task.accept(monitor);
}
}
+"""), //$NON-NLS-1$
+ // Test flag mapping: SUPPRESS_SUBTASK_LABEL -> SUPPRESS_SUBTASK
+ SuppressSubtaskLabelFlag(
+"""
+package test;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+public class Test {
+ public void doWork(IProgressMonitor monitor) {
+ monitor.beginTask("Task", 100);
+ IProgressMonitor sub = new SubProgressMonitor(monitor, 50, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL);
+ }
+}
+""", //$NON-NLS-1$
+"""
+package test;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+public class Test {
+ public void doWork(IProgressMonitor monitor) {
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Task", 100);
+ IProgressMonitor sub = subMonitor.split(50, SubMonitor.SUPPRESS_SUBTASK);
+ }
+}
+"""), //$NON-NLS-1$
+ // Test PREPEND_MAIN_LABEL_TO_SUBTASK flag is dropped
+ PrependMainLabelToSubtaskFlag(
+"""
+package test;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+public class Test {
+ public void doWork(IProgressMonitor monitor) {
+ monitor.beginTask("Task", 100);
+ IProgressMonitor sub = new SubProgressMonitor(monitor, 50, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+ }
+}
+""", //$NON-NLS-1$
+"""
+package test;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+public class Test {
+ public void doWork(IProgressMonitor monitor) {
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Task", 100);
+ IProgressMonitor sub = subMonitor.split(50);
+ }
+}
"""), //$NON-NLS-1$
BothImportsCoexist(
"""
@@ -320,7 +368,7 @@ public void doWork(IProgressMonitor monitor) {
// Simulating a scenario where both imports might coexist
public class Test {
public void doWork(IProgressMonitor monitor) {
- SubMonitor subMonitor=SubMonitor.convert(monitor,"Task with both imports",100);
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Task with both imports", 100);
// Only Eclipse's SubProgressMonitor should be converted
IProgressMonitor sub= subMonitor.split(50);
}
diff --git a/test_output.txt b/test_output.txt
new file mode 100644
index 000000000..af607abe0
--- /dev/null
+++ b/test_output.txt
@@ -0,0 +1,14 @@
+[INFO] Scanning for projects...
+[INFO] Tycho Version: 5.0.2 (9f65dc09a72ee08f29cc8a4d5381a45b33dc7144)
+[INFO] Tycho Mode: project
+[INFO] Tycho Builder: maven
+[INFO] Build Threads: 1
+Downloading from local: file:///home/runner/.m2/repository/org/sandbox/sandbox_target/1.2.5-SNAPSHOT/maven-metadata.xml
+Downloading from local: file:///home/runner/.m2/repository/org/sandbox/sandbox_target/1.2.5-SNAPSHOT/sandbox_target-1.2.5-SNAPSHOT.target
+[ERROR] resolve target artifact org.sandbox:sandbox_target:1.2.5-SNAPSHOT:no classifier failed! Could not resolve target platform specification artifact org.sandbox:sandbox_target:target:1.2.5-SNAPSHOT: The following artifacts could not be resolved: org.sandbox:sandbox_target:target:1.2.5-SNAPSHOT (absent): Could not find artifact org.sandbox:sandbox_target:target:1.2.5-SNAPSHOT in local (file:///home/runner/.m2/repository/) -> [Help 1]
+[ERROR]
+[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
+[ERROR] Re-run Maven using the -X switch to enable full debug logging.
+[ERROR]
+[ERROR] For more information about the errors and possible solutions, please read the following articles:
+[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MavenExecutionException