Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Loskutov2022-02-16 09:11:54 +0000
committerAndrey Loskutov2022-03-08 16:00:02 +0000
commitbca984dc24bc623ddd4f152c5e5b2ba588dbb792 (patch)
treea7bf09f06cff589961cc085c74581cafdc56f3b2
parent8095aa46a092c2b9b75ffb8a18e6b688be362d20 (diff)
downloadeclipse.platform.debug-bca984dc24bc623ddd4f152c5e5b2ba588dbb792.tar.gz
eclipse.platform.debug-bca984dc24bc623ddd4f152c5e5b2ba588dbb792.tar.xz
eclipse.platform.debug-bca984dc24bc623ddd4f152c5e5b2ba588dbb792.zip
Serialized SourceLookup and SourceDisplay jobs. All source lookups tasks are now put in the queue and handled by a single job (not multiple jobs running in parallel). Once lookup is done, the result is passed to the second job dedicated to show lookup results in the UI. Both jobs ignore duplicated tasks. As a result, if previously there was possible to run multiple source lookups in parallel (that would compute same result) and all those lookup results were shown one after each other in the UI (re-triggering same UI actions again and again), now all source lookups are executed one by one and there are no attempts made to show identical lookup results again. Change-Id: I1737910e4269e6795d6da1fd71bad1874cc59f7d Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.debug/+/190843 Reviewed-by: Simeon Andreev <simeon.danailov.andreev@gmail.com> Reviewed-by: Andrey Loskutov <loskutov@gmx.de> Tested-by: Andrey Loskutov <loskutov@gmx.de>
-rw-r--r--org.eclipse.debug.tests/src/org/eclipse/debug/tests/sourcelookup/SourceLookupFacilityTests.java7
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupFacility.java493
-rw-r--r--org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupResult.java103
3 files changed, 372 insertions, 231 deletions
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/sourcelookup/SourceLookupFacilityTests.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/sourcelookup/SourceLookupFacilityTests.java
index fd963297b..8535bd4fa 100644
--- a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/sourcelookup/SourceLookupFacilityTests.java
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/sourcelookup/SourceLookupFacilityTests.java
@@ -21,8 +21,9 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Field;
-import java.util.HashMap;
+import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
+import java.util.Map;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.internal.ui.sourcelookup.SourceLookupFacility;
@@ -317,7 +318,7 @@ public class SourceLookupFacilityTests extends AbstractDebugTest {
// Get the original map
Field field = SourceLookupFacility.class.getDeclaredField("fLookupResults"); //$NON-NLS-1$
field.setAccessible(true);
- HashMap<?, ?> map = (HashMap<?, ?>) field.get(null);
+ Map<?, ?> map = (Map<?, ?>) field.get(SourceLookupFacility.getDefault());
LinkedHashMap<String, ISourceLookupResult> cached = new LinkedHashMap<>();
// fill the LRU with one element overflow
@@ -343,7 +344,7 @@ public class SourceLookupFacilityTests extends AbstractDebugTest {
String artifact = "" + 0; //$NON-NLS-1$
SourceLookupResult result = SourceLookupFacility.getDefault().lookup(artifact, fTestLocator, false);
assertNotNull("There should be a result", result); //$NON-NLS-1$
- assertFalse(cached.containsValue(result));
+ assertFalse(new IdentityHashMap<>(cached).containsValue(result));
// Check: the LRU map size should not grow
assertEquals(MAX_LRU_SIZE, map.size());
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupFacility.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupFacility.java
index c356da37e..74e359d73 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupFacility.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupFacility.java
@@ -15,9 +15,13 @@
*******************************************************************************/
package org.eclipse.debug.internal.ui.sourcelookup;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Objects;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -88,10 +92,9 @@ public class SourceLookupFacility implements IPageListener, IPartListener2, IPro
*
* @since 3.10
*/
- static class LRU extends HashMap<Object, SourceLookupResult> {
+ static class LRU extends LinkedHashMap<Object, SourceLookupResult> {
private static final long serialVersionUID = 1L;
- ArrayList<Object> fEntryStack = null;
int fSize;
/**
@@ -100,44 +103,14 @@ public class SourceLookupFacility implements IPageListener, IPartListener2, IPro
* @param size The desired size
*/
LRU(int size) {
+ // true == use this map like LRU cache
+ super(size, 0.75f, true);
fSize = size;
- fEntryStack = new ArrayList<>();
}
@Override
- public SourceLookupResult put(Object key, SourceLookupResult value) {
- shuffle(key);
- return super.put(key, value);
- }
-
- @Override
- public SourceLookupResult remove(Object key) {
- SourceLookupResult oldResult = super.remove(key);
- fEntryStack.remove(key);
- return oldResult;
- }
-
- /**
- * Shuffles the entry stack and removes mapped results as needed
- *
- * @param key
- */
- void shuffle(Object key) {
- int index = fEntryStack.indexOf(key);
- if (index < 0) {
- if (fEntryStack.size() >= fSize) {
- remove(fEntryStack.get(fEntryStack.size() - 1));
- }
- } else {
- fEntryStack.remove(index);
- }
- fEntryStack.add(0, key);
- }
-
- @Override
- public void clear() {
- fEntryStack.clear();
- super.clear();
+ protected boolean removeEldestEntry(Map.Entry<Object, SourceLookupResult> eldest) {
+ return size() > fSize;
}
}
@@ -158,7 +131,7 @@ public class SourceLookupFacility implements IPageListener, IPartListener2, IPro
*
* @since 3.10
*/
- private static LRU fLookupResults = new LRU(10);
+ private final Map<Object, SourceLookupResult> fLookupResults = Collections.synchronizedMap(new LRU(10));
/**
* Used to generate annotations for stack frames
@@ -170,6 +143,9 @@ public class SourceLookupFacility implements IPageListener, IPartListener2, IPro
*/
private boolean fReuseEditor = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugUIConstants.PREF_REUSE_EDITOR);
+ /** Singleton job to process source lookup requests */
+ private final SourceLookupJob sourceLookupJob;
+
/**
* Constructs singleton source display adapter for stack frames.
*/
@@ -199,6 +175,7 @@ public class SourceLookupFacility implements IPageListener, IPartListener2, IPro
*/
private SourceLookupFacility() {
fEditorsByPage = new HashMap<>();
+ sourceLookupJob = new SourceLookupJob();
DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
DebugPlugin.getDefault().addDebugEventListener(this);
}
@@ -237,7 +214,7 @@ public class SourceLookupFacility implements IPageListener, IPartListener2, IPro
}
}
- private class ArtifactWithLocator {
+ private static class ArtifactWithLocator {
public final Object artifact;
public final ISourceLocator locator;
public ArtifactWithLocator(Object artifact, ISourceLocator locator) {
@@ -247,12 +224,7 @@ public class SourceLookupFacility implements IPageListener, IPartListener2, IPro
@Override
public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + getOuterType().hashCode();
- result = prime * result + ((artifact == null) ? 0 : artifact.hashCode());
- result = prime * result + ((locator == null) ? 0 : locator.hashCode());
- return result;
+ return 31 + Objects.hash(artifact, locator);
}
@Override
@@ -260,36 +232,30 @@ public class SourceLookupFacility implements IPageListener, IPartListener2, IPro
if (this == obj) {
return true;
}
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
+ if (!(obj instanceof ArtifactWithLocator)) {
return false;
}
ArtifactWithLocator other = (ArtifactWithLocator) obj;
- if (!getOuterType().equals(other.getOuterType())) {
- return false;
- }
- if (artifact == null) {
- if (other.artifact != null) {
- return false;
- }
- } else if (!artifact.equals(other.artifact)) {
- return false;
+ return Objects.equals(artifact, other.artifact) && Objects.equals(locator, other.locator);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("ArtifactWithLocator ["); //$NON-NLS-1$
+ if (artifact != null) {
+ builder.append("artifact="); //$NON-NLS-1$
+ builder.append(artifact);
+ builder.append(", "); //$NON-NLS-1$
}
- if (locator == null) {
- if (other.locator != null) {
- return false;
- }
- } else if (!locator.equals(other.locator)) {
- return false;
+ if (locator != null) {
+ builder.append("locator="); //$NON-NLS-1$
+ builder.append(locator);
}
- return true;
+ builder.append("]"); //$NON-NLS-1$
+ return builder.toString();
}
- private SourceLookupFacility getOuterType() {
- return SourceLookupFacility.this;
- }
}
/**
@@ -305,74 +271,70 @@ public class SourceLookupFacility implements IPageListener, IPartListener2, IPro
*/
public SourceLookupResult lookup(Object artifact, ISourceLocator locator, boolean force) {
SourceLookupResult result = null;
- synchronized (fLookupResults) {
- ArtifactWithLocator key = new ArtifactWithLocator(artifact, locator);
- if (!force) {
- result = fLookupResults.get(key);
- if (result != null) {
- return result;
- }
+ ArtifactWithLocator key = new ArtifactWithLocator(artifact, locator);
+ if (!force) {
+ result = fLookupResults.get(key);
+ if (result != null) {
+ return result;
+ }
+ }
+ IDebugElement debugElement = null;
+ if (artifact instanceof IDebugElement) {
+ debugElement = (IDebugElement) artifact;
+ }
+ ISourceLocator localLocator = locator;
+ if (localLocator == null) {
+ ILaunch launch = null;
+ if (debugElement != null) {
+ launch = debugElement.getLaunch();
}
- result = new SourceLookupResult(artifact, null, null, null);
- IDebugElement debugElement = null;
- if (artifact instanceof IDebugElement) {
- debugElement = (IDebugElement) artifact;
+ if (launch != null) {
+ localLocator = launch.getSourceLocator();
}
- ISourceLocator localLocator = locator;
- if (localLocator == null) {
- ILaunch launch = null;
- if (debugElement != null) {
- launch = debugElement.getLaunch();
- }
- if (launch != null) {
- localLocator = launch.getSourceLocator();
- }
+ }
+ if (localLocator == null) {
+ return new SourceLookupResult(artifact, null, null, null);
+ }
+ String editorId = null;
+ IEditorInput editorInput = null;
+ Object sourceElement = null;
+ if (localLocator instanceof ISourceLookupDirector) {
+ ISourceLookupDirector director = (ISourceLookupDirector) localLocator;
+ sourceElement = director.getSourceElement(artifact);
+ } else {
+ if (artifact instanceof IStackFrame) {
+ sourceElement = localLocator.getSourceElement((IStackFrame) artifact);
}
- if (localLocator != null) {
- String editorId = null;
- IEditorInput editorInput = null;
- Object sourceElement = null;
- if (localLocator instanceof ISourceLookupDirector) {
- ISourceLookupDirector director = (ISourceLookupDirector) localLocator;
- sourceElement = director.getSourceElement(artifact);
- } else {
- if (artifact instanceof IStackFrame) {
- sourceElement = localLocator.getSourceElement((IStackFrame) artifact);
- }
+ }
+ if (sourceElement == null) {
+ if (localLocator instanceof AbstractSourceLookupDirector) {
+ editorInput = new CommonSourceNotFoundEditorInput(artifact);
+ editorId = IDebugUIConstants.ID_COMMON_SOURCE_NOT_FOUND_EDITOR;
+ } else {
+ if (artifact instanceof IStackFrame) {
+ IStackFrame frame = (IStackFrame) artifact;
+ editorInput = new SourceNotFoundEditorInput(frame);
+ editorId = IInternalDebugUIConstants.ID_SOURCE_NOT_FOUND_EDITOR;
}
- if (sourceElement == null) {
- if (localLocator instanceof AbstractSourceLookupDirector) {
- editorInput = new CommonSourceNotFoundEditorInput(artifact);
- editorId = IDebugUIConstants.ID_COMMON_SOURCE_NOT_FOUND_EDITOR;
- } else {
- if (artifact instanceof IStackFrame) {
- IStackFrame frame = (IStackFrame) artifact;
- editorInput = new SourceNotFoundEditorInput(frame);
- editorId = IInternalDebugUIConstants.ID_SOURCE_NOT_FOUND_EDITOR;
- }
- }
- } else {
- ISourcePresentation presentation = null;
- if (localLocator instanceof ISourcePresentation) {
- presentation = (ISourcePresentation) localLocator;
- } else {
- if (debugElement != null) {
- presentation = getPresentation(debugElement.getModelIdentifier());
- }
- }
- if (presentation != null) {
- editorInput = presentation.getEditorInput(sourceElement);
- }
- if (editorInput != null && presentation != null) {
- editorId = presentation.getEditorId(editorInput, sourceElement);
- }
+ }
+ } else {
+ ISourcePresentation presentation = null;
+ if (localLocator instanceof ISourcePresentation) {
+ presentation = (ISourcePresentation) localLocator;
+ } else {
+ if (debugElement != null) {
+ presentation = getPresentation(debugElement.getModelIdentifier());
}
- result.setEditorInput(editorInput);
- result.setEditorId(editorId);
- result.setSourceElement(sourceElement);
- fLookupResults.put(key, result);
+ }
+ if (presentation != null) {
+ editorInput = presentation.getEditorInput(sourceElement);
+ }
+ if (editorInput != null && presentation != null) {
+ editorId = presentation.getEditorId(editorInput, sourceElement);
}
}
+ result = new SourceLookupResult(artifact, sourceElement, editorId, editorInput);
+ fLookupResults.put(key, result);
return result;
}
@@ -692,110 +654,283 @@ public class SourceLookupFacility implements IPageListener, IPartListener2, IPro
fEditorsByPage.clear();
fPresentation.dispose();
fLookupResults.clear();
+ sourceLookupJob.cancel();
}
/**
- * A job to perform source lookup on the currently selected stack frame.
+ * A singleton job to perform source lookups via given {@link SourceLookupTask}
+ * objects. The tasks are put in the queue to process in the background,
+ * duplicated tasks are ignored. Job re-schedules itself if new task is added to
+ * the queue.
*/
- class SourceLookupJob extends Job {
+ final class SourceLookupJob extends Job {
- private IStackFrame fTarget;
- private ISourceLocator fLocator;
- private IWorkbenchPage fPage;
- private boolean fForce = false;
+ private final LinkedHashSet<SourceLookupTask> queue;
+ private final SourceDisplayJob sourceDisplayJob;
- /**
- * Constructs a new source lookup job.
- */
- public SourceLookupJob(IStackFrame frame, ISourceLocator locator, IWorkbenchPage page, boolean force) {
+ public SourceLookupJob() {
super("Debug Source Lookup"); //$NON-NLS-1$
- setPriority(Job.INTERACTIVE);
+ this.sourceDisplayJob = new SourceDisplayJob();
+ this.queue = new LinkedHashSet<>();
setSystem(true);
- fTarget = frame;
- fLocator = locator;
- fPage = page;
- fForce = force;
+ setPriority(Job.INTERACTIVE);
// Note: Be careful when trying to use scheduling rules with this
// job, in order to avoid blocking nested jobs (bug 339542).
}
@Override
+ public boolean belongsTo(Object family) {
+ return family instanceof SourceLookupFacility;
+ }
+
+ @Override
protected IStatus run(IProgressMonitor monitor) {
+ SourceLookupTask next;
+ while ((next = poll()) != null && !monitor.isCanceled()) {
+ SourceDisplayRequest uiTask = next.run(monitor);
+ if (uiTask != null) {
+ sourceDisplayJob.schedule(uiTask);
+ }
+ }
+
+ synchronized (queue) {
+ if (monitor.isCanceled()) {
+ queue.clear();
+ return Status.CANCEL_STATUS;
+ } else if (!queue.isEmpty()) {
+ schedule(100);
+ }
+ }
+ return Status.OK_STATUS;
+ }
+
+ private SourceLookupTask poll() {
+ SourceLookupTask next = null;
+ synchronized (queue) {
+ if (!queue.isEmpty()) {
+ Iterator<SourceLookupTask> iterator = queue.iterator();
+ next = iterator.next();
+ iterator.remove();
+ }
+ }
+ return next;
+ }
+
+ void schedule(SourceLookupTask task) {
+ synchronized (queue) {
+ boolean added = queue.add(task);
+ if (added) {
+ schedule(100);
+ }
+ }
+ }
+ }
+
+ /**
+ * A task to perform source lookup on the currently selected stack frame.
+ */
+ class SourceLookupTask {
+
+ final IStackFrame fTarget;
+ final ISourceLocator fLocator;
+ final IWorkbenchPage fPage;
+ final boolean fForce;
+
+ /**
+ * Constructs a new source lookup task.
+ */
+ public SourceLookupTask(IStackFrame frame, ISourceLocator locator, IWorkbenchPage page, boolean force) {
+ fTarget = frame;
+ fLocator = locator;
+ fPage = page;
+ fForce = force;
+ }
+
+ protected SourceDisplayRequest run(IProgressMonitor monitor) {
if (!monitor.isCanceled()) {
if (!fTarget.isTerminated()) {
- ISourceLookupResult result = lookup(fTarget, fLocator, fForce);
- if (!monitor.isCanceled() && !fTarget.isTerminated() && fPage != null) {
- new SourceDisplayJob(result, fPage).schedule();
+ SourceLookupResult result = lookup(fTarget, fLocator, fForce);
+ if (!monitor.isCanceled() && !fTarget.isTerminated() && fPage != null && result != null) {
+ return new SourceDisplayRequest(result, fPage);
}
}
}
- return Status.OK_STATUS;
+ return null;
}
@Override
- public boolean belongsTo(Object family) {
- // source lookup jobs are a family per workbench page
- if (family instanceof SourceLookupJob) {
- SourceLookupJob slj = (SourceLookupJob) family;
- return slj.fPage.equals(fPage);
+ public int hashCode() {
+ return 31 + Objects.hash(fForce, fLocator, fPage, fTarget);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
}
- return false;
+ if (!(obj instanceof SourceLookupTask)) {
+ return false;
+ }
+ SourceLookupTask other = (SourceLookupTask) obj;
+ return fForce == other.fForce && Objects.equals(fPage, other.fPage)
+ && Objects.equals(fLocator, other.fLocator) && Objects.equals(fTarget, other.fTarget);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SourceLookupTask ["); //$NON-NLS-1$
+ if (fTarget != null) {
+ builder.append("target="); //$NON-NLS-1$
+ builder.append(fTarget);
+ builder.append(", "); //$NON-NLS-1$
+ }
+ builder.append("force="); //$NON-NLS-1$
+ builder.append(fForce);
+ builder.append(", "); //$NON-NLS-1$
+ if (fLocator != null) {
+ builder.append("locator="); //$NON-NLS-1$
+ builder.append(fLocator);
+ builder.append(", "); //$NON-NLS-1$
+ }
+ if (fPage != null) {
+ builder.append("page="); //$NON-NLS-1$
+ builder.append(fPage);
+ }
+ builder.append("]"); //$NON-NLS-1$
+ return builder.toString();
+ }
+
+ }
+
+ /**
+ * A request to show the result of the source lookup in the UI
+ */
+ static class SourceDisplayRequest {
+
+ final SourceLookupResult fResult;
+ final IWorkbenchPage fPage;
+
+ public SourceDisplayRequest(SourceLookupResult result, IWorkbenchPage page) {
+ fResult = result;
+ fPage = page;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(fPage, fResult);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof SourceDisplayRequest)) {
+ return false;
+ }
+ SourceDisplayRequest other = (SourceDisplayRequest) obj;
+ return Objects.equals(fPage, other.fPage) && Objects.equals(fResult, other.fResult);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SourceDisplayRequest ["); //$NON-NLS-1$
+ if (fResult != null) {
+ builder.append("result="); //$NON-NLS-1$
+ builder.append(fResult);
+ builder.append(", "); //$NON-NLS-1$
+ }
+ if (fPage != null) {
+ builder.append("page="); //$NON-NLS-1$
+ builder.append(fPage);
+ }
+ builder.append("]"); //$NON-NLS-1$
+ return builder.toString();
}
}
+ /**
+ * A singleton job to show the result of the source lookup in the UI for given
+ * {@link SourceDisplayRequest} objects. The requests are put in the queue to
+ * process in the background, duplicated requests are ignored. Job re-schedules
+ * itself if new request is added to the queue.
+ */
class SourceDisplayJob extends UIJob {
- private ISourceLookupResult fResult;
- private IWorkbenchPage fPage;
+ private final LinkedHashSet<SourceDisplayRequest> queue;
- public SourceDisplayJob(ISourceLookupResult result, IWorkbenchPage page) {
+ public SourceDisplayJob() {
super("Debug Source Display"); //$NON-NLS-1$
setSystem(true);
setPriority(Job.INTERACTIVE);
- fResult = result;
- fPage = page;
+ this.queue = new LinkedHashSet<>();
}
+
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
- if (!monitor.isCanceled() && fResult != null) {
- display(fResult, fPage);
- // termination may have occurred while displaying source
- if (monitor.isCanceled()) {
- Object artifact = fResult.getArtifact();
+ SourceDisplayRequest next;
+ // Do not break on cancelled monitor, to allow remove debugger
+ // annotations from already opened editors
+ while ((next = poll()) != null) {
+ IWorkbenchPage page = next.fPage;
+ if (page.getWorkbenchWindow() == null) {
+ // don't try to update if page is closed
+ continue;
+ }
+ ISourceLookupResult result = next.fResult;
+ if (!monitor.isCanceled()) {
+ display(result, page);
+ } else {
+ // termination may have occurred while displaying source
+ Object artifact = result.getArtifact();
if (artifact instanceof IStackFrame) {
clearSourceSelection(((IStackFrame) artifact).getThread());
}
}
}
-
return Status.OK_STATUS;
}
+ private SourceDisplayRequest poll() {
+ SourceDisplayRequest next = null;
+ synchronized (queue) {
+ if (!queue.isEmpty()) {
+ Iterator<SourceDisplayRequest> iterator = queue.iterator();
+ next = iterator.next();
+ iterator.remove();
+ }
+ }
+ return next;
+ }
+
+ void schedule(SourceDisplayRequest task) {
+ synchronized (queue) {
+ boolean added = queue.add(task);
+ if (added) {
+ schedule(100);
+ }
+ }
+ }
+
@Override
public boolean belongsTo(Object family) {
- // source display jobs are a family per workbench page
- if (family instanceof SourceDisplayJob) {
- SourceDisplayJob sdj = (SourceDisplayJob) family;
- return sdj.fPage.equals(fPage);
- }
- return false;
+ return family instanceof SourceLookupFacility;
}
}
/*
- * @see
- * org.eclipse.debug.ui.contexts.ISourceDisplayAdapter#displaySource(java
- * .lang.Object, org.eclipse.ui.IWorkbenchPage, boolean)
+ * See org.eclipse.debug.ui.sourcelookup.ISourceDisplay
*/
- public synchronized void displaySource(Object context, IWorkbenchPage page, boolean force) {
+ public void displaySource(Object context, IWorkbenchPage page, boolean force) {
IStackFrame frame = (IStackFrame) context;
- SourceLookupJob slj = new SourceLookupJob(frame, frame.getLaunch().getSourceLocator(), page, force);
- // cancel any existing source lookup jobs for this page
- Job.getJobManager().cancel(slj);
- slj.schedule();
+ SourceLookupTask slj = new SourceLookupTask(frame, frame.getLaunch().getSourceLocator(), page, force);
+ // will drop any existing equal source lookup jobs
+ sourceLookupJob.schedule(slj);
}
/**
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupResult.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupResult.java
index c524b8cff..55ab38932 100644
--- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupResult.java
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/sourcelookup/SourceLookupResult.java
@@ -13,6 +13,8 @@
*******************************************************************************/
package org.eclipse.debug.internal.ui.sourcelookup;
+import java.util.Objects;
+
import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult;
import org.eclipse.ui.IEditorInput;
@@ -27,22 +29,22 @@ public class SourceLookupResult implements ISourceLookupResult {
/**
* Element that source was resolved for.
*/
- private Object fArtifact;
+ private final Object fArtifact;
/**
* Corresponding source element, or <code>null</code>
* if unknown.
*/
- private Object fSourceElement;
+ private final Object fSourceElement;
/**
* Associated editor id, used to display the source element,
* or <code>null</code> if unknown.
*/
- private String fEditorId;
+ private final String fEditorId;
/**
* Associated editor input, used to display the source element,
* or <code>null</code> if unknown.
*/
- private IEditorInput fEditorInput;
+ private final IEditorInput fEditorInput;
/**
* Creates a source lookup result on the given artifact, source element,
@@ -50,9 +52,9 @@ public class SourceLookupResult implements ISourceLookupResult {
*/
public SourceLookupResult(Object artifact, Object sourceElement, String editorId, IEditorInput editorInput) {
fArtifact = artifact;
- setSourceElement(sourceElement);
- setEditorId(editorId);
- setEditorInput(editorInput);
+ fSourceElement = sourceElement;
+ fEditorId = editorId;
+ fEditorInput = editorInput;
}
@Override
@@ -65,60 +67,63 @@ public class SourceLookupResult implements ISourceLookupResult {
return fSourceElement;
}
- /**
- * Sets the source element resolved for the artifact that source
- * lookup was performed for, or <code>null</code> if a source element
- * was not resolved.
- *
- * @param element resolved source element or <code>null</code> if unknown
- */
- protected void setSourceElement(Object element) {
- fSourceElement = element;
- }
-
@Override
public String getEditorId() {
return fEditorId;
}
- /**
- * Sets the identifier of the editor used to display this source
- * lookup result's source element, or <code>null</code> if unknown.
- *
- * @param id the identifier of the editor used to display this source
- * lookup result's source element, or <code>null</code> if unknown
- */
- protected void setEditorId(String id) {
- fEditorId = id;
- }
-
@Override
public IEditorInput getEditorInput() {
return fEditorInput;
}
- /**
- * Sets the editor input used to display this source lookup
- * result's source element, or <code>null</code> if unknown.
- *
- * @param input the editor input used to display this source lookup
- * result's source element, or <code>null</code> if unknown
- */
- protected void setEditorInput(IEditorInput input) {
- fEditorInput = input;
+ @Override
+ public int hashCode() {
+ return Objects.hash(fArtifact, fEditorId, fEditorInput, fSourceElement);
}
- /**
- * Updates the artifact to refer to the given artifact
- * if equal. For example, when a source lookup result is reused
- * for the same stack frame, we still need to update in case
- * the stack frame is not identical.
- *
- * @param artifact new artifact state
- */
- public void updateArtifact(Object artifact) {
- if (fArtifact.equals(artifact)) {
- fArtifact = artifact;
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (!(obj instanceof SourceLookupResult)) {
+ return false;
}
+
+ SourceLookupResult other = (SourceLookupResult) obj;
+ return Objects.equals(fEditorId, other.fEditorId)
+ && Objects.equals(fArtifact, other.fArtifact)
+ && Objects.equals(fEditorInput, other.fEditorInput)
+ && Objects.equals(fSourceElement, other.fSourceElement);
}
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("SourceLookupResult ["); //$NON-NLS-1$
+ if (fEditorId != null) {
+ builder.append("editorId="); //$NON-NLS-1$
+ builder.append(fEditorId);
+ builder.append(", "); //$NON-NLS-1$
+ }
+ if (fEditorInput != null) {
+ builder.append("editorInput="); //$NON-NLS-1$
+ builder.append(fEditorInput);
+ builder.append(", "); //$NON-NLS-1$
+ }
+ if (fArtifact != null) {
+ builder.append("artifact="); //$NON-NLS-1$
+ builder.append(fArtifact);
+ builder.append(", "); //$NON-NLS-1$
+ }
+ if (fSourceElement != null) {
+ builder.append("sourceElement="); //$NON-NLS-1$
+ builder.append(fSourceElement);
+ }
+ builder.append("]"); //$NON-NLS-1$
+ return builder.toString();
+ }
+
}

Back to the top