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 IRegion fMarkOccurrenceTargetRegion;
private OccurrencesFinderJob fOccurrencesFinderJob; private OccurrencesAnnotationUpdaterJob fOccurrencesAnnotationUpdaterJob;
private OccurrencesFinderJobCanceler fOccurrencesFinderJobCanceler; private OccurrencesFinderJobCanceler fOccurrencesFinderJobCanceler;
private ISelectionListenerWithAST fPostSelectionListenerWithAST; private ISelectionListenerWithAST fPostSelectionListenerWithAST;
@ -2815,12 +2815,6 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
((ICReconcilingListener)listeners[i]).reconciled(ast, force, progressMonitor); ((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 * @since 5.0
*/ */
class OccurrencesFinderJob extends Job { class OccurrencesAnnotationUpdaterJob extends Job {
private final IDocument fDocument; private final IDocument fDocument;
private final ISelection fSelection; private final ISelection fSelection;
@ -2923,16 +2917,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
private boolean fCanceled= false; private boolean fCanceled= false;
private final OccurrenceLocation[] fLocations; 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$ super(CEditorMessages.getString("CEditor_markOccurrences_job_name")); //$NON-NLS-1$
fDocument= document; fDocument= document;
fSelection= selection; fSelection= selection;
fLocations= locations; fLocations= locations;
fPostSelectionValidator= validator;
if (getSelectionProvider() instanceof ISelectionValidator)
fPostSelectionValidator= (ISelectionValidator)getSelectionProvider();
else
fPostSelectionValidator= null;
} }
// cannot use cancel() because it is declared final // 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) * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
*/ */
public void documentAboutToBeChanged(DocumentEvent event) { public void documentAboutToBeChanged(DocumentEvent event) {
if (fOccurrencesFinderJob != null) if (fOccurrencesAnnotationUpdaterJob != null)
fOccurrencesFinderJob.doCancel(); fOccurrencesAnnotationUpdaterJob.doCancel();
} }
/* /*
@ -3088,9 +3078,8 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
* @since 5.0 * @since 5.0
*/ */
protected void updateOccurrenceAnnotations(ITextSelection selection, IASTTranslationUnit astRoot) { protected void updateOccurrenceAnnotations(ITextSelection selection, IASTTranslationUnit astRoot) {
if (fOccurrencesAnnotationUpdaterJob != null)
if (fOccurrencesFinderJob != null) fOccurrencesAnnotationUpdaterJob.cancel();
fOccurrencesFinderJob.cancel();
if (!fMarkOccurrenceAnnotations) if (!fMarkOccurrenceAnnotations)
return; return;
@ -3102,8 +3091,9 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
if (document == null) if (document == null)
return; return;
if (getSelectionProvider() instanceof ISelectionValidator) { ISelectionValidator validator= null;
ISelectionValidator validator= (ISelectionValidator)getSelectionProvider(); if (fForcedMarkOccurrencesSelection != selection && getSelectionProvider() instanceof ISelectionValidator) {
validator= (ISelectionValidator)getSelectionProvider();
if (!validator.isValid(selection)) { if (!validator.isValid(selection)) {
return; return;
} }
@ -3125,10 +3115,22 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
OccurrenceLocation[] locations= null; OccurrenceLocation[] locations= null;
IASTNodeSelector selector= astRoot.getNodeSelector(astRoot.getFilePath()); IASTNodeSelector selector= astRoot.getNodeSelector(null);
IASTName name= selector.findEnclosingName(selection.getOffset(), selection.getLength()); IASTName name= selector.findEnclosingName(selection.getOffset(), selection.getLength());
if (validator != null && !validator.isValid(selection)) {
return;
}
if (name != null) { 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(); IBinding binding= name.resolveBinding();
if (binding != null) { if (binding != null) {
OccurrencesFinder occurrencesFinder= new OccurrencesFinder(); 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) if (!fStickyOccurrenceAnnotations)
removeOccurrenceAnnotations(); removeOccurrenceAnnotations();
else if (hasChanged) // check consistency of current annotations else if (hasChanged) // check consistency of current annotations
@ -3146,11 +3148,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
return; 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.setPriority(Job.DECORATE);
//fOccurrencesFinderJob.setSystem(true); //fOccurrencesFinderJob.setSystem(true);
//fOccurrencesFinderJob.schedule(); //fOccurrencesFinderJob.schedule();
fOccurrencesFinderJob.run(new NullProgressMonitor()); fOccurrencesAnnotationUpdaterJob.run(new NullProgressMonitor());
} }
protected void installOccurrencesFinder(boolean forceUpdate) { protected void installOccurrencesFinder(boolean forceUpdate) {
@ -3180,9 +3183,9 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
protected void uninstallOccurrencesFinder() { protected void uninstallOccurrencesFinder() {
fMarkOccurrenceAnnotations= false; fMarkOccurrenceAnnotations= false;
if (fOccurrencesFinderJob != null) { if (fOccurrencesAnnotationUpdaterJob != null) {
fOccurrencesFinderJob.cancel(); fOccurrencesAnnotationUpdaterJob.cancel();
fOccurrencesFinderJob= null; fOccurrencesAnnotationUpdaterJob= null;
} }
if (fOccurrencesFinderJobCanceler != null) { if (fOccurrencesFinderJobCanceler != null) {

View file

@ -138,13 +138,16 @@ public class CReconcilingStrategy implements IReconcilingStrategy, IReconcilingS
index= ast.getIndex(); index= ast.getIndex();
} }
try { try {
if (ast == null) { if (ast == null || fProgressMonitor.isCanceled()) {
((ICReconcilingListener)fEditor).reconciled(ast, forced, fProgressMonitor); ((ICReconcilingListener)fEditor).reconciled(null, forced, fProgressMonitor);
} else { } else {
synchronized (ast) { synchronized (ast) {
((ICReconcilingListener)fEditor).reconciled(ast, forced, fProgressMonitor); ((ICReconcilingListener)fEditor).reconciled(ast, forced, fProgressMonitor);
} }
} }
if (fProgressMonitor.isCanceled()) {
aboutToBeReconciled();
}
} catch(Exception e) { } catch(Exception e) {
IStatus status= new Status(IStatus.ERROR, CUIPlugin.PLUGIN_ID, IStatus.OK, "Error in CDT UI during reconcile", e); //$NON-NLS-1$ 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); 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.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.ISelectionValidator;
import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionChangedListener;
@ -54,18 +55,24 @@ public class SelectionListenerWithASTManager {
return fgDefault; 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 final static class PartListenerGroup {
private ITextEditor fPart; private ITextEditor fPart;
private ISelectionListener fPostSelectionListener; private ISelectionListener fPostSelectionListener;
private ISelectionChangedListener fSelectionListener; private ISelectionChangedListener fSelectionListener;
private Job fCurrentJob; private Job fCurrentJob;
private ListenerList fAstListeners; private ListenerList fAstListeners;
/** /** Rule to make sure only one job is running at a time */
* Lock to avoid having more than one calculateAndInform job in parallel. private final ISchedulingRule fJobRule= new SingletonRule();
* Only jobs may synchronize on this as otherwise deadlocks are possible. private ISelectionValidator fValidator;
*/
private final Object fJobLock= new Object();
public PartListenerGroup(ITextEditor editorPart) { public PartListenerGroup(ITextEditor editorPart) {
fPart= editorPart; fPart= editorPart;
@ -97,8 +104,12 @@ public class SelectionListenerWithASTManager {
if (isEmpty()) { if (isEmpty()) {
fPart.getEditorSite().getPage().addPostSelectionListener(fPostSelectionListener); fPart.getEditorSite().getPage().addPostSelectionListener(fPostSelectionListener);
ISelectionProvider selectionProvider= fPart.getSelectionProvider(); ISelectionProvider selectionProvider= fPart.getSelectionProvider();
if (selectionProvider != null) if (selectionProvider != null) {
selectionProvider.addSelectionChangedListener(fSelectionListener); selectionProvider.addSelectionChangedListener(fSelectionListener);
if (selectionProvider instanceof ISelectionValidator) {
fValidator= (ISelectionValidator) selectionProvider;
}
}
} }
fAstListeners.add(listener); fAstListeners.add(listener);
} }
@ -108,8 +119,10 @@ public class SelectionListenerWithASTManager {
if (isEmpty()) { if (isEmpty()) {
fPart.getEditorSite().getPage().removePostSelectionListener(fPostSelectionListener); fPart.getEditorSite().getPage().removePostSelectionListener(fPostSelectionListener);
ISelectionProvider selectionProvider= fPart.getSelectionProvider(); ISelectionProvider selectionProvider= fPart.getSelectionProvider();
if (selectionProvider != null) if (selectionProvider != null) {
selectionProvider.removeSelectionChangedListener(fSelectionListener); selectionProvider.removeSelectionChangedListener(fSelectionListener);
}
fValidator= null;
} }
} }
@ -130,23 +143,32 @@ public class SelectionListenerWithASTManager {
fCurrentJob= new Job(Messages.SelectionListenerWithASTManager_jobName) { fCurrentJob= new Job(Messages.SelectionListenerWithASTManager_jobName) {
public IStatus run(IProgressMonitor monitor) { public IStatus run(IProgressMonitor monitor) {
if (monitor == null) { if (!monitor.isCanceled() && isSelectionValid(selection)) {
monitor= new NullProgressMonitor();
}
synchronized (fJobLock) {
return calculateASTandInform(workingCopy, selection, monitor); return calculateASTandInform(workingCopy, selection, monitor);
} }
return Status.OK_STATUS;
} }
}; };
fCurrentJob.setPriority(Job.DECORATE); fCurrentJob.setPriority(Job.DECORATE);
fCurrentJob.setSystem(true); fCurrentJob.setSystem(true);
fCurrentJob.setRule(fJobRule);
fCurrentJob.schedule(); 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) { 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) { public IStatus runOnAST(ILanguage lang, IASTTranslationUnit astRoot) {
if (astRoot != null && !monitor.isCanceled()) { if (astRoot != null && !monitor.isCanceled() && isSelectionValid(selection)) {
Object[] listeners; Object[] listeners;
synchronized (PartListenerGroup.this) { synchronized (PartListenerGroup.this) {
listeners= fAstListeners.getListeners(); listeners= fAstListeners.getListeners();
@ -162,7 +184,6 @@ public class SelectionListenerWithASTManager {
} }
} }
private Map<ITextEditor, PartListenerGroup> fListenerGroups; private Map<ITextEditor, PartListenerGroup> fListenerGroups;
private SelectionListenerWithASTManager() { private SelectionListenerWithASTManager() {