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 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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,6 +55,14 @@ 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;
|
||||||
|
@ -61,11 +70,9 @@ public class SelectionListenerWithASTManager {
|
||||||
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,9 +119,11 @@ 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fireSelectionChanged(final ITextSelection selection) {
|
public void fireSelectionChanged(final ITextSelection selection) {
|
||||||
|
@ -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() {
|
||||||
|
|
Loading…
Add table
Reference in a new issue