diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java
index 1a7d4ad5600..a68a265f537 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java
@@ -2579,7 +2579,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
*/
private IRegion fMarkOccurrenceTargetRegion;
- private OccurrencesFinderJob fOccurrencesFinderJob;
+ private OccurrencesAnnotationUpdaterJob fOccurrencesAnnotationUpdaterJob;
private OccurrencesFinderJobCanceler fOccurrencesFinderJobCanceler;
private ISelectionListenerWithAST fPostSelectionListenerWithAST;
@@ -2815,12 +2815,6 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
((ICReconcilingListener)listeners[i]).reconciled(ast, force, progressMonitor);
}
- // delayed installation of mark occurrences
-// if (!fMarkOccurrenceAnnotations && isMarkingOccurrences())
-// getSite().getShell().getDisplay().asyncExec(new Runnable() {
-// public void run() {
-// installOccurrencesFinder(true);
-// }});
}
/**
@@ -2911,11 +2905,11 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
}
/**
- * Finds and marks occurrence annotations.
+ * Updates occurrence annotations.
*
* @since 5.0
*/
- class OccurrencesFinderJob extends Job {
+ class OccurrencesAnnotationUpdaterJob extends Job {
private final IDocument fDocument;
private final ISelection fSelection;
@@ -2923,16 +2917,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
private boolean fCanceled= false;
private final OccurrenceLocation[] fLocations;
- public OccurrencesFinderJob(IDocument document, OccurrenceLocation[] locations, ISelection selection) {
+ public OccurrencesAnnotationUpdaterJob(IDocument document, OccurrenceLocation[] locations, ISelection selection, ISelectionValidator validator) {
super(CEditorMessages.getString("CEditor_markOccurrences_job_name")); //$NON-NLS-1$
fDocument= document;
fSelection= selection;
fLocations= locations;
-
- if (getSelectionProvider() instanceof ISelectionValidator)
- fPostSelectionValidator= (ISelectionValidator)getSelectionProvider();
- else
- fPostSelectionValidator= null;
+ fPostSelectionValidator= validator;
}
// cannot use cancel() because it is declared final
@@ -3049,8 +3039,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
* @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
*/
public void documentAboutToBeChanged(DocumentEvent event) {
- if (fOccurrencesFinderJob != null)
- fOccurrencesFinderJob.doCancel();
+ if (fOccurrencesAnnotationUpdaterJob != null)
+ fOccurrencesAnnotationUpdaterJob.doCancel();
}
/*
@@ -3088,9 +3078,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
* @since 5.0
*/
protected void updateOccurrenceAnnotations(ITextSelection selection, IASTTranslationUnit astRoot) {
-
- if (fOccurrencesFinderJob != null)
- fOccurrencesFinderJob.cancel();
+ if (fOccurrencesAnnotationUpdaterJob != null)
+ fOccurrencesAnnotationUpdaterJob.cancel();
if (!fMarkOccurrenceAnnotations)
return;
@@ -3102,8 +3091,9 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
if (document == null)
return;
- if (getSelectionProvider() instanceof ISelectionValidator) {
- ISelectionValidator validator= (ISelectionValidator)getSelectionProvider();
+ ISelectionValidator validator= null;
+ if (fForcedMarkOccurrencesSelection != selection && getSelectionProvider() instanceof ISelectionValidator) {
+ validator= (ISelectionValidator)getSelectionProvider();
if (!validator.isValid(selection)) {
return;
}
@@ -3125,10 +3115,22 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
OccurrenceLocation[] locations= null;
- IASTNodeSelector selector= astRoot.getNodeSelector(astRoot.getFilePath());
+ IASTNodeSelector selector= astRoot.getNodeSelector(null);
IASTName name= selector.findEnclosingName(selection.getOffset(), selection.getLength());
+ if (validator != null && !validator.isValid(selection)) {
+ return;
+ }
+
if (name != null) {
+// try {
+// IASTFileLocation location= name.getFileLocation();
+// if (!document.get(location.getNodeOffset(), location.getNodeLength()).equals(name.toString())) {
+// System.err.println("CEditor.updateOccurrenceAnnotations() invalid ast");
+// return;
+// }
+// } catch (BadLocationException exc) {
+// }
IBinding binding= name.resolveBinding();
if (binding != null) {
OccurrencesFinder occurrencesFinder= new OccurrencesFinder();
@@ -3138,7 +3140,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
}
}
- if (locations == null) {
+ if (locations == null || locations.length == 0) {
if (!fStickyOccurrenceAnnotations)
removeOccurrenceAnnotations();
else if (hasChanged) // check consistency of current annotations
@@ -3146,11 +3148,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
return;
}
- fOccurrencesFinderJob= new OccurrencesFinderJob(document, locations, selection);
+ fOccurrencesAnnotationUpdaterJob= new OccurrencesAnnotationUpdaterJob(document, locations, selection, validator);
+ // we are already in a background job
//fOccurrencesFinderJob.setPriority(Job.DECORATE);
//fOccurrencesFinderJob.setSystem(true);
//fOccurrencesFinderJob.schedule();
- fOccurrencesFinderJob.run(new NullProgressMonitor());
+ fOccurrencesAnnotationUpdaterJob.run(new NullProgressMonitor());
}
protected void installOccurrencesFinder(boolean forceUpdate) {
@@ -3180,9 +3183,9 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
protected void uninstallOccurrencesFinder() {
fMarkOccurrenceAnnotations= false;
- if (fOccurrencesFinderJob != null) {
- fOccurrencesFinderJob.cancel();
- fOccurrencesFinderJob= null;
+ if (fOccurrencesAnnotationUpdaterJob != null) {
+ fOccurrencesAnnotationUpdaterJob.cancel();
+ fOccurrencesAnnotationUpdaterJob= null;
}
if (fOccurrencesFinderJobCanceler != null) {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java
index 521dc79657f..2398134bbc1 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CReconcilingStrategy.java
@@ -138,13 +138,16 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
index= ast.getIndex();
}
try {
- if (ast == null) {
- ((ICReconcilingListener)fEditor).reconciled(ast, forced, fProgressMonitor);
+ if (ast == null || fProgressMonitor.isCanceled()) {
+ ((ICReconcilingListener)fEditor).reconciled(null, forced, fProgressMonitor);
} else {
synchronized (ast) {
((ICReconcilingListener)fEditor).reconciled(ast, forced, fProgressMonitor);
}
}
+ if (fProgressMonitor.isCanceled()) {
+ aboutToBeReconciled();
+ }
} catch(Exception e) {
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT UI during reconcile", e); //$NON-NLS-1$
CUIPlugin.getDefault().log(status);
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java
index cbf577e6ba3..47b54048483 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/SelectionListenerWithASTManager.java
@@ -17,9 +17,10 @@ import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
-import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.text.ISelectionValidator;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -54,18 +55,24 @@ public class SelectionListenerWithASTManager {
return fgDefault;
}
-
+ private static class SingletonRule implements ISchedulingRule {
+ public boolean contains(ISchedulingRule rule) {
+ return rule == this;
+ }
+ public boolean isConflicting(ISchedulingRule rule) {
+ return rule == this;
+ }
+ }
+
private final static class PartListenerGroup {
private ITextEditor fPart;
private ISelectionListener fPostSelectionListener;
private ISelectionChangedListener fSelectionListener;
private Job fCurrentJob;
private ListenerList fAstListeners;
- /**
- * Lock to avoid having more than one calculateAndInform job in parallel.
- * Only jobs may synchronize on this as otherwise deadlocks are possible.
- */
- private final Object fJobLock= new Object();
+ /** Rule to make sure only one job is running at a time */
+ private final ISchedulingRule fJobRule= new SingletonRule();
+ private ISelectionValidator fValidator;
public PartListenerGroup(ITextEditor editorPart) {
fPart= editorPart;
@@ -97,8 +104,12 @@ public class SelectionListenerWithASTManager {
if (isEmpty()) {
fPart.getEditorSite().getPage().addPostSelectionListener(fPostSelectionListener);
ISelectionProvider selectionProvider= fPart.getSelectionProvider();
- if (selectionProvider != null)
- selectionProvider.addSelectionChangedListener(fSelectionListener);
+ if (selectionProvider != null) {
+ selectionProvider.addSelectionChangedListener(fSelectionListener);
+ if (selectionProvider instanceof ISelectionValidator) {
+ fValidator= (ISelectionValidator) selectionProvider;
+ }
+ }
}
fAstListeners.add(listener);
}
@@ -108,8 +119,10 @@ public class SelectionListenerWithASTManager {
if (isEmpty()) {
fPart.getEditorSite().getPage().removePostSelectionListener(fPostSelectionListener);
ISelectionProvider selectionProvider= fPart.getSelectionProvider();
- if (selectionProvider != null)
+ if (selectionProvider != null) {
selectionProvider.removeSelectionChangedListener(fSelectionListener);
+ }
+ fValidator= null;
}
}
@@ -130,23 +143,32 @@ public class SelectionListenerWithASTManager {
fCurrentJob= new Job(Messages.SelectionListenerWithASTManager_jobName) {
public IStatus run(IProgressMonitor monitor) {
- if (monitor == null) {
- monitor= new NullProgressMonitor();
- }
- synchronized (fJobLock) {
+ if (!monitor.isCanceled() && isSelectionValid(selection)) {
return calculateASTandInform(workingCopy, selection, monitor);
}
+ return Status.OK_STATUS;
}
};
fCurrentJob.setPriority(Job.DECORATE);
fCurrentJob.setSystem(true);
+ fCurrentJob.setRule(fJobRule);
fCurrentJob.schedule();
}
+ /**
+ * Verify that selection is still valid.
+ *
+ * @param selection
+ * @return true
if selection is valid
+ */
+ protected boolean isSelectionValid(ITextSelection selection) {
+ return fValidator == null || fValidator.isValid(selection);
+ }
+
protected IStatus calculateASTandInform(final IWorkingCopy workingCopy, final ITextSelection selection, final IProgressMonitor monitor) {
- return ASTProvider.getASTProvider().runOnAST(workingCopy, ASTProvider.WAIT_YES, monitor, new ASTRunnable() {
+ return ASTProvider.getASTProvider().runOnAST(workingCopy, ASTProvider.WAIT_ACTIVE_ONLY, monitor, new ASTRunnable() {
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit astRoot) {
- if (astRoot != null && !monitor.isCanceled()) {
+ if (astRoot != null && !monitor.isCanceled() && isSelectionValid(selection)) {
Object[] listeners;
synchronized (PartListenerGroup.this) {
listeners= fAstListeners.getListeners();
@@ -162,7 +184,6 @@ public class SelectionListenerWithASTManager {
}
}
-
private Map fListenerGroups;
private SelectionListenerWithASTManager() {