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:
parent
fcd3e477bd
commit
9bbcd90dd9
3 changed files with 75 additions and 48 deletions
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Add table
Reference in a new issue