From 877f0f4966e7d5178e96803f5fc98d1e98fc6c64 Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Fri, 14 Nov 2025 01:07:46 +0000 Subject: [PATCH 1/2] Migrate from SubProgressMonitor to SubMonitor Migrated all usages of the deprecated SubProgressMonitor class to use SubMonitor following Eclipse 4.6+ best practices: - resources/Policy.java: Updated subMonitorFor() to use SubMonitor.convert() - team/InfiniteSubProgressMonitor: Refactored from inheritance to composition, now implements IProgressMonitor and delegates to SubMonitor - team/SubscriberSyncInfoEventHandler: Replaced anonymous SubProgressMonitor with IProgressMonitor wrapper that delegates to SubMonitor All changes follow the official Eclipse SubMonitor migration guide. --- .../eclipse/core/internal/utils/Policy.java | 2 +- .../core/InfiniteSubProgressMonitor.java | 48 +++++++++++++++--- .../SubscriberSyncInfoEventHandler.java | 49 ++++++++++++++++--- 3 files changed, 84 insertions(+), 15 deletions(-) diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java index 97a3c093cff..1777907d252 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java @@ -189,6 +189,6 @@ public static IProgressMonitor subMonitorFor(IProgressMonitor monitor, int ticks if (monitor instanceof NullProgressMonitor) { return monitor; } - return new SubProgressMonitor(monitor, ticks); + return SubMonitor.convert(monitor, ticks); } } diff --git a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/InfiniteSubProgressMonitor.java b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/InfiniteSubProgressMonitor.java index 3b3cd555264..87da881a325 100644 --- a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/InfiniteSubProgressMonitor.java +++ b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/InfiniteSubProgressMonitor.java @@ -15,7 +15,7 @@ import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; /** * Provides an infinite progress monitor by subdividing by half repeatedly. @@ -27,8 +27,9 @@ * 2^n = totalWork. What this means is that if you provide a totalWork of 32 (2^5) than * the maximum number of ticks is 5*32/2 = 80. */ -public class InfiniteSubProgressMonitor extends SubProgressMonitor { +public class InfiniteSubProgressMonitor implements IProgressMonitor { + private final SubMonitor delegate; int totalWork; int halfWay; int currentIncrement; @@ -39,19 +40,26 @@ public class InfiniteSubProgressMonitor extends SubProgressMonitor { * Constructor for InfiniteSubProgressMonitor. */ public InfiniteSubProgressMonitor(IProgressMonitor monitor, int ticks) { - this(monitor, ticks, 0); + this(monitor, ticks, SubMonitor.SUPPRESS_NONE); } /** * Constructor for InfiniteSubProgressMonitor. */ public InfiniteSubProgressMonitor(IProgressMonitor monitor, int ticks, int style) { - super(monitor, ticks, style); + if (monitor instanceof SubMonitor subMonitor) { + this.delegate = subMonitor.split(ticks, style); + } else { + // For non-SubMonitor, convert it first then split + SubMonitor converted = SubMonitor.convert(monitor); + this.delegate = converted.split(ticks, style); + } } @Override public void beginTask(String name, int totalWork) { - super.beginTask(name, totalWork); + delegate.setTaskName(name); + delegate.setWorkRemaining(totalWork); this.totalWork = totalWork; this.halfWay = totalWork / 2; this.currentIncrement = 1; @@ -65,7 +73,7 @@ public void worked(int work) { return; } if (--nextProgress <= 0) { - super.worked(1); + delegate.worked(1); worked++; if (worked >= halfWay) { // we have passed the current halfway point, so double the @@ -87,7 +95,33 @@ public void worked(int work) { @Override public void subTask(String name) { if(name != null && ! name.isEmpty()) { - super.subTask(name); + delegate.subTask(name); } } + + @Override + public void done() { + // SubMonitor doesn't require explicit done() calls, but delegate for compatibility + delegate.done(); + } + + @Override + public void internalWorked(double work) { + delegate.internalWorked(work); + } + + @Override + public boolean isCanceled() { + return delegate.isCanceled(); + } + + @Override + public void setCanceled(boolean value) { + delegate.setCanceled(value); + } + + @Override + public void setTaskName(String name) { + delegate.setTaskName(name); + } } diff --git a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberSyncInfoEventHandler.java b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberSyncInfoEventHandler.java index 3cf305c6b30..6b4589f9fbc 100644 --- a/team/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberSyncInfoEventHandler.java +++ b/team/bundles/org.eclipse.team.core/src/org/eclipse/team/internal/core/subscribers/SubscriberSyncInfoEventHandler.java @@ -20,7 +20,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; import org.eclipse.team.core.ITeamStatus; import org.eclipse.team.core.TeamException; import org.eclipse.team.core.TeamStatus; @@ -110,17 +110,20 @@ protected void collectAll( int depth, IProgressMonitor monitor) { - monitor.beginTask(null, IProgressMonitor.UNKNOWN); + SubMonitor subMonitor = SubMonitor.convert(monitor); try { // Create a monitor that will handle preemption and dispatch if required - IProgressMonitor collectionMonitor = new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN) { - boolean dispatching = false; + IProgressMonitor collectionMonitor = new IProgressMonitor() { + private final SubMonitor delegate = subMonitor.split(IProgressMonitor.UNKNOWN); + private boolean dispatching = false; + @Override public void subTask(String name) { dispatch(); - super.subTask(name); + delegate.subTask(name); } + private void dispatch() { if (dispatching) { return; @@ -133,10 +136,42 @@ private void dispatch() { dispatching = false; } } + @Override public void worked(int work) { dispatch(); - super.worked(work); + delegate.worked(work); + } + + @Override + public void beginTask(String name, int totalWork) { + delegate.setTaskName(name); + delegate.setWorkRemaining(totalWork); + } + + @Override + public void done() { + delegate.done(); + } + + @Override + public void internalWorked(double work) { + delegate.internalWorked(work); + } + + @Override + public boolean isCanceled() { + return delegate.isCanceled(); + } + + @Override + public void setCanceled(boolean value) { + delegate.setCanceled(value); + } + + @Override + public void setTaskName(String name) { + delegate.setTaskName(name); } }; @@ -173,7 +208,7 @@ public void remove(IResource resource) { syncSetInput.getSubscriber().collectOutOfSync(new IResource[] { resource }, depth, collectionSet, collectionMonitor); } finally { - monitor.done(); + subMonitor.done(); } } From 50398d1f40495f797b08d92b99330f7aa65884c9 Mon Sep 17 00:00:00 2001 From: Lars Vogel Date: Fri, 14 Nov 2025 09:32:23 +0100 Subject: [PATCH 2/2] Fix SubMonitor usage in Policy.subMonitorFor() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous implementation used SubMonitor.convert(monitor, ticks) which sets work remaining on the converted monitor. This causes an error when beginTask() is called again on the returned monitor, as SubMonitor only allows beginTask() to be called once. The correct approach is to use SubMonitor.convert(monitor).split(ticks), which creates a properly configured child monitor that can have beginTask() called on it. This fixes test failures in org.eclipse.core.tests.resources where tests were failing with: "beginTask may only be called once" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../src/org/eclipse/core/internal/utils/Policy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java index 1777907d252..c7d961aadce 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/utils/Policy.java @@ -189,6 +189,6 @@ public static IProgressMonitor subMonitorFor(IProgressMonitor monitor, int ticks if (monitor instanceof NullProgressMonitor) { return monitor; } - return SubMonitor.convert(monitor, ticks); + return SubMonitor.convert(monitor).split(ticks); } }