1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Fix mark occurrences on outdated offset while editing (second attempt)

This commit is contained in:
Anton Leherbauer 2008-03-07 11:23:15 +00:00
parent fcd3e477bd
commit 9bbcd90dd9
3 changed files with 75 additions and 48 deletions

View file

@ -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) {

View file

@ -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);

View file

@ -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 <code>true</code> 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<ITextEditor, PartListenerGroup> fListenerGroups;
private SelectionListenerWithASTManager() {