From e187f68cbca9e47b6c881e2891e72ca2d4499904 Mon Sep 17 00:00:00 2001
From: Alain Magloire
+ * The life time of a shared working copy is as follows:
+ *
+ * Note that the buffer factory will be used for the life time of this working copy, i.e. if the
+ * working copy is closed then reopened, this factory will be used.
+ * The buffer will be automatically initialized with the original's compilation unit content
+ * upon creation.
+ *
+ * When the shared working copy instance is created, an ADDED ICElementDelta is reported on this
+ * working copy.
+ *
+ * @param monitor a progress monitor used to report progress while opening this compilation unit
+ * or false, problem will
+ * not be discovered any more until the next iteration.
+ *
+ * This predicate will be invoked once prior to each problem detection iteration.
+ *
+ * @return boolean - indicates whether the requestor is currently interested by problems.
+ */
+ boolean isActive();
+}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java
index 9ff9a892664..0642e0e65a2 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java
@@ -185,6 +185,51 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
IBufferFactory factory)
throws CModelException;
+ /**
+ * Returns a shared working copy on this element using the given factory to create
+ * the buffer, or this element if this element is already a working copy.
+ * This API can only answer an already existing working copy if it is based on the same
+ * original translation unit AND was using the same buffer factory (i.e. as
+ * defined by
Object#equals
).
+ *
+ *
+ * So users of this method must destroy exactly once the working copy.
+ * getSharedWorkingCopy(...)
creates a new working copy for this
+ * elementdestroy()
decrements the internal counter.null
if no progress should be reported
+ * @param factory the factory that creates a buffer that is used to get the content of the working copy
+ * or null
if the internal factory should be used
+ * @param problemRequestor a requestor which will get notified of problems detected during
+ * reconciling as they are discovered. The requestor can be set to null
indicating
+ * that the client is not interested in problems.
+ * @exception CModelException if the contents of this element can not be
+ * determined. Reasons include:
+ *
+ *
+ * @return a shared working copy on this element using the given factory to create
+ * the buffer, or this element if this element is already a working copy
+ * @see IBufferFactory
+ * @see IProblemRequestor
+ * @since 2.0
+ */
+ IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor requestor) throws CModelException;
+
/**
* Returns the first namespace declaration in this translation unit with the given package name
* This is a handle-only method. The namespace declaration may or may not exist.
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateWorkingCopyOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateWorkingCopyOperation.java
new file mode 100644
index 00000000000..90599b34122
--- /dev/null
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CreateWorkingCopyOperation.java
@@ -0,0 +1,77 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003,2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ ***********************************************************************/
+
+package org.eclipse.cdt.internal.core.model;
+
+import java.util.Map;
+
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.IProblemRequestor;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.core.resources.IFile;
+
+/**
+ * CreateWorkingCopyOperation
+ */
+public class CreateWorkingCopyOperation extends CModelOperation {
+
+ Map perFactoryWorkingCopies;
+ IBufferFactory factory;
+ IProblemRequestor problemRequestor;
+
+ /*
+ * Creates a working copy from the given original tu and the given buffer factory.
+ * perFactoryWorkingCopies map is not null if the working copy is a shared working copy.
+ */
+ public CreateWorkingCopyOperation(ITranslationUnit originalElement, Map perFactoryWorkingCopies, IBufferFactory factory, IProblemRequestor problemRequestor) {
+ super(new ICElement[] {originalElement});
+ this.perFactoryWorkingCopies = perFactoryWorkingCopies;
+ this.factory = factory;
+ this.problemRequestor = problemRequestor;
+ }
+ protected void executeOperation() throws CModelException {
+ ITranslationUnit tu = getTranslationUnit();
+
+ WorkingCopy workingCopy = new WorkingCopy(tu.getParent(), (IFile)tu.getResource(), this.factory, this.problemRequestor);
+ // open the working copy now to ensure contents are that of the current state of this element
+ workingCopy.open(this.fMonitor);
+
+ if (this.perFactoryWorkingCopies != null) {
+ this.perFactoryWorkingCopies.put(tu, workingCopy);
+ //if (TranslationUnit.SHARED_WC_VERBOSE) {
+ // System.out.println("Creating shared working copy " + workingCopy.toStringWithAncestors()); //$NON-NLS-1$
+ //}
+ }
+
+ // report added java delta
+ CElementDelta delta = new CElementDelta(this.getCModel());
+ delta.added(workingCopy);
+ addDelta(delta);
+
+ fResultElements = new ICElement[] {workingCopy};
+ }
+
+ /**
+ * Returns the translation unit this operation is working on.
+ */
+ protected ITranslationUnit getTranslationUnit() {
+ return (ITranslationUnit)getElementToProcess();
+ }
+
+ /**
+ * @see JavaModelOperation#isReadOnly
+ */
+ public boolean isReadOnly() {
+ return true;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java
index cf850a295fa..83c2adf700f 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ReconcileWorkingCopyOperation.java
@@ -14,6 +14,7 @@ import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICModelStatus;
import org.eclipse.cdt.core.model.ICModelStatusConstants;
+import org.eclipse.cdt.core.model.IProblemRequestor;
/**
* Reconcile a working copy and signal the changes through a delta.
@@ -57,12 +58,12 @@ public class ReconcileWorkingCopyOperation extends CModelOperation {
if (forceProblemDetection && wasConsistent){
if (fMonitor != null && fMonitor.isCanceled()) return;
- //IProblemRequestor problemRequestor = workingCopy.problemRequestor;
- //if (problemRequestor != null && problemRequestor.isActive()){
- // problemRequestor.beginReporting();
- // CompilationUnitProblemFinder.process(workingCopy, problemRequestor, fMonitor);
- // problemRequestor.endReporting();
- //}
+ IProblemRequestor problemRequestor = workingCopy.problemRequestor;
+ if (problemRequestor != null && problemRequestor.isActive()){
+ problemRequestor.beginReporting();
+ TranslationUnitProblemFinder.process(workingCopy, problemRequestor, fMonitor);
+ problemRequestor.endReporting();
+ }
}
// register the deltas
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
index 3eeecc679ac..4f9e37518f9 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
@@ -19,6 +19,7 @@ import org.eclipse.cdt.core.model.IBuffer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IInclude;
import org.eclipse.cdt.core.model.IParent;
+import org.eclipse.cdt.core.model.IProblemRequestor;
import org.eclipse.cdt.core.model.ISourceManipulation;
import org.eclipse.cdt.core.model.ISourceRange;
import org.eclipse.cdt.core.model.ISourceReference;
@@ -366,6 +367,14 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
*/
public IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor,IBufferFactory factory)
throws CModelException {
+ return getSharedWorkingCopy(monitor, factory, null);
+ }
+
+ /**
+ * @see org.eclipse.cdt.core.model.ITranslationUnit#getSharedWorkingCopy(IProgressMonitor, IBufferFactory)
+ */
+ public IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor,IBufferFactory factory, IProblemRequestor requestor)
+ throws CModelException {
// if factory is null, default factory must be used
if (factory == null) factory = BufferManager.getDefaultBufferManager();
@@ -388,15 +397,9 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return workingCopy;
} else {
- workingCopy = (WorkingCopy)this.getWorkingCopy(monitor, factory);
- perFactoryWorkingCopies.put(this, workingCopy);
-
- // report added java delta
-// CElementDelta delta = new CElementDelta(this.getCModel());
-// delta.added(workingCopy);
-// manager.fire(delta, CModelManager.DEFAULT_CHANGE_EVENT);
-
- return workingCopy;
+ CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, requestor);
+ runOperation(op, monitor);
+ return (IWorkingCopy)op.getResultElements()[0];
}
}
/**
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnitProblemFinder.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnitProblemFinder.java
new file mode 100644
index 00000000000..2d440a31e49
--- /dev/null
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnitProblemFinder.java
@@ -0,0 +1,96 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003,2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ ***********************************************************************/
+
+package org.eclipse.cdt.internal.core.model;
+
+import java.io.StringReader;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.IProblemRequestor;
+import org.eclipse.cdt.core.parser.IParser;
+import org.eclipse.cdt.core.parser.IProblem;
+import org.eclipse.cdt.core.parser.IScanner;
+import org.eclipse.cdt.core.parser.IScannerInfo;
+import org.eclipse.cdt.core.parser.IScannerInfoProvider;
+import org.eclipse.cdt.core.parser.NullSourceElementRequestor;
+import org.eclipse.cdt.core.parser.ParserFactory;
+import org.eclipse.cdt.core.parser.ParserFactoryError;
+import org.eclipse.cdt.core.parser.ParserLanguage;
+import org.eclipse.cdt.core.parser.ParserMode;
+import org.eclipse.cdt.core.parser.ScannerInfo;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * TranslationUnitProblemFinder
+ */
+public class TranslationUnitProblemFinder extends NullSourceElementRequestor {
+
+ IProblemRequestor requestor;
+ /**
+ *
+ */
+ public TranslationUnitProblemFinder(IProblemRequestor requestor) {
+ super();
+ this.requestor = requestor;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptProblem(org.eclipse.cdt.core.parser.IProblem)
+ */
+ public boolean acceptProblem(IProblem problem) {
+ requestor.acceptProblem(problem);
+ return true;
+ }
+
+ /**
+ * @param copy
+ * @param requestor
+ * @param monitor
+ */
+ public static void process(WorkingCopy copy, IProblemRequestor requestor, IProgressMonitor monitor) {
+
+ TranslationUnitProblemFinder problemFinder = new TranslationUnitProblemFinder(requestor);
+ IProject project = copy.getCProject().getProject();
+ String code = new String();
+ try{
+ code = copy.getBuffer().getContents();
+ } catch (CModelException e) {
+ //
+ }
+
+ // pick the language
+ ParserLanguage language = copy.isCXXLanguage()? ParserLanguage.CPP : ParserLanguage.C;
+
+ IParser parser = null;
+ try {
+ IScannerInfo scanInfo = new ScannerInfo();
+ IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project);
+ if (provider != null){
+ IScannerInfo buildScanInfo = provider.getScannerInformation(project);
+ if (buildScanInfo != null){
+ scanInfo = new ScannerInfo(buildScanInfo.getDefinedSymbols(), buildScanInfo.getIncludePaths());
+ }
+ }
+
+ boolean quickParseMode = ! (CCorePlugin.getDefault().useStructuralParseMode());
+ ParserMode mode = quickParseMode ? ParserMode.QUICK_PARSE : ParserMode.STRUCTURAL_PARSE;
+ IScanner scanner = ParserFactory.createScanner(new StringReader(code), copy.getPath().toOSString(),
+ scanInfo, mode, language, problemFinder, null, null);
+ parser = ParserFactory.createParser(scanner, problemFinder, mode, language, null);
+ parser.parse();
+ } catch(ParserFactoryError pfe) {
+ //
+ }
+
+ }
+}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java
index 8cfded82178..6067bed8df8 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java
@@ -17,6 +17,7 @@ import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.IBuffer;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICModelStatusConstants;
+import org.eclipse.cdt.core.model.IProblemRequestor;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.IWorkingCopy;
import org.eclipse.core.resources.IFile;
@@ -45,16 +46,26 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy {
* never true if this translation unit is not a working copy.
*/
protected int useCount = 1;
-
+
+ /**
+ * If set, this is the problem requestor which will be used to notify problems
+ * detected during reconciling.
+ */
+ protected IProblemRequestor problemRequestor;
+
/**
* Creates a working copy of this element
*/
public WorkingCopy(ICElement parent, IFile file, IBufferFactory bufferFactory) {
+ this(parent, file, bufferFactory, null);
+ }
+ public WorkingCopy(ICElement parent, IFile file, IBufferFactory bufferFactory, IProblemRequestor requestor) {
super(parent, file);
this.bufferFactory =
bufferFactory == null ?
getBufferManager() :
bufferFactory;
+ this.problemRequestor = requestor;
}
public WorkingCopy(ICElement parent, IPath path, IBufferFactory bufferFactory) {
@@ -206,11 +217,17 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy {
* something other than navigation or if this is a working copy being
* opened after it has been destroyed.
*/
- public void open(IProgressMonitor pm) throws CModelException {
+ public void open(IProgressMonitor monitor) throws CModelException {
if (this.useCount == 0) { // was destroyed
throw newNotPresentException();
} else {
- super.open(pm);
+ super.open(monitor);
+ if (monitor != null && monitor.isCanceled()) return;
+ if (this.problemRequestor != null && this.problemRequestor.isActive()){
+ this.problemRequestor.beginReporting();
+ TranslationUnitProblemFinder.process(this, this.problemRequestor, monitor);
+ this.problemRequestor.endReporting();
+ }
}
}
/**
diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog
index 576164e7541..7cc1670f074 100644
--- a/core/org.eclipse.cdt.ui/ChangeLog
+++ b/core/org.eclipse.cdt.ui/ChangeLog
@@ -1,3 +1,7 @@
+2004-05-11 Alain Magloire
+
+ Preliminary work to get Parser IProblem in the CEditor.
+
2004-05-10 Andrew Niefer
- fixing bug 60493:
- created CSearchUtil.getSearchForFromElement and CSearchUtil.getSearchForFromNode
diff --git a/core/org.eclipse.cdt.ui/icons/full/obj16/quickfix_error_obj.gif b/core/org.eclipse.cdt.ui/icons/full/obj16/quickfix_error_obj.gif
new file mode 100644
index 0000000000000000000000000000000000000000..d6427e85933dfafcce23127a20117f55e9290484
GIT binary patch
literal 232
zcmZ?wbhEHb6krfwIKseiW5)pti-;dT7#bQFe*CbQF~j1=kBS*HDsJ4^@#DvbA2%$1
z+=%$G!(v7SkTK&21H%priwX;i9T5>fDk}c}|KHHi5D^iIProblem
.
+ */
+ static protected class ProblemAnnotation extends Annotation implements ICAnnotation, IAnnotationPresentation {
+
+ private static final String SPELLING_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.spelling"; //$NON-NLS-1$
+
+ //XXX: To be fully correct these constants should be non-static
+ /**
+ * The layer in which task problem annotations are located.
+ */
+ private static final int TASK_LAYER;
+ /**
+ * The layer in which info problem annotations are located.
+ */
+ private static final int INFO_LAYER;
+ /**
+ * The layer in which warning problem annotations representing are located.
+ */
+ private static final int WARNING_LAYER;
+ /**
+ * The layer in which error problem annotations representing are located.
+ */
+ private static final int ERROR_LAYER;
+
+ static {
+ AnnotationPreferenceLookup lookup= EditorsUI.getAnnotationPreferenceLookup();
+ TASK_LAYER= computeLayer("org.eclipse.ui.workbench.texteditor.task", lookup); //$NON-NLS-1$
+ INFO_LAYER= computeLayer("org.eclipse.cdt.ui.info", lookup); //$NON-NLS-1$
+ WARNING_LAYER= computeLayer("org.eclipse.cdt.ui.warning", lookup); //$NON-NLS-1$
+ ERROR_LAYER= computeLayer("org.eclipse.cdt.ui.error", lookup); //$NON-NLS-1$
+ }
+
+ private static int computeLayer(String annotationType, AnnotationPreferenceLookup lookup) {
+ Annotation annotation= new Annotation(annotationType, false, null);
+ AnnotationPreference preference= lookup.getAnnotationPreference(annotation);
+ if (preference != null)
+ return preference.getPresentationLayer() + 1;
+ else
+ return IAnnotationAccessExtension.DEFAULT_LAYER + 1;
+ }
+
+ private static Image fgQuickFixImage;
+ private static Image fgQuickFixErrorImage;
+ private static boolean fgQuickFixImagesInitialized= false;
+
+ private ITranslationUnit fTranslationUnit;
+ private List fOverlaids;
+ private IProblem fProblem;
+ private Image fImage;
+ private boolean fQuickFixImagesInitialized= false;
+ private int fLayer= IAnnotationAccessExtension.DEFAULT_LAYER;
+
+
+ public ProblemAnnotation(IProblem problem, ITranslationUnit cu) {
+
+ fProblem= problem;
+ fTranslationUnit= cu;
+
+ //if (SpellProblem.Spelling == fProblem.getID()) {
+ // setType(SPELLING_ANNOTATION_TYPE);
+ // fLayer= WARNING_LAYER;
+ //if (IProblem.Task == fProblem.getID()) {
+ // setType(CMarkerAnnotation.TASK_ANNOTATION_TYPE);
+ // fLayer= TASK_LAYER;
+ if (fProblem.isWarning()) {
+ setType(CMarkerAnnotation.WARNING_ANNOTATION_TYPE);
+ fLayer= WARNING_LAYER;
+ } else if (fProblem.isError()) {
+ setType(CMarkerAnnotation.ERROR_ANNOTATION_TYPE);
+ fLayer= ERROR_LAYER;
+ } else {
+ setType(CMarkerAnnotation.INFO_ANNOTATION_TYPE);
+ fLayer= INFO_LAYER;
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer()
+ */
+ public int getLayer() {
+ return fLayer;
+ }
+
+ private void initializeImages() {
+ // http://bugs.eclipse.org/bugs/show_bug.cgi?id=18936
+ if (!fQuickFixImagesInitialized) {
+ if (isProblem() && indicateQuixFixableProblems() /*&& JavaCorrectionProcessor.hasCorrections(this)*/) { // no light bulb for tasks
+ if (!fgQuickFixImagesInitialized) {
+ fgQuickFixImage= CPluginImages.get(CPluginImages.IMG_OBJS_FIXABLE_PROBLEM);
+ fgQuickFixErrorImage= CPluginImages.get(CPluginImages.IMG_OBJS_FIXABLE_ERROR);
+ fgQuickFixImagesInitialized= true;
+ }
+ if (CMarkerAnnotation.ERROR_ANNOTATION_TYPE.equals(getType()))
+ fImage= fgQuickFixErrorImage;
+ else
+ fImage= fgQuickFixImage;
+ }
+ fQuickFixImagesInitialized= true;
+ }
+ }
+
+ private boolean indicateQuixFixableProblems() {
+ return PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.EDITOR_CORRECTION_INDICATION);
+ }
+
+ /*
+ * @see Annotation#paint
+ */
+ public void paint(GC gc, Canvas canvas, Rectangle r) {
+ initializeImages();
+ if (fImage != null) {
+ drawImage(fImage, gc, canvas, r, SWT.CENTER, SWT.TOP);
+ }
+ }
+
+ /*
+ * @see ICAnnotation#getImage(Display)
+ */
+ public Image getImage(Display display) {
+ initializeImages();
+ return fImage;
+ }
+
+ /*
+ * @see ICAnnotation#getMessage()
+ */
+ public String getText() {
+ return fProblem.getMessage();
+ }
+
+ /*
+ * @see ICAnnotation#getArguments()
+ */
+ public String[] getArguments() {
+ return isProblem() ? new String[]{fProblem.getArguments()} : null;
+ }
+
+ /*
+ * @see ICAnnotation#getId()
+ */
+ public int getId() {
+ return fProblem.getID();
+ }
+
+ /*
+ * @see ICAnnotation#isProblem()
+ */
+ public boolean isProblem() {
+ String type= getType();
+ return CMarkerAnnotation.WARNING_ANNOTATION_TYPE.equals(type) ||
+ CMarkerAnnotation.ERROR_ANNOTATION_TYPE.equals(type) ||
+ SPELLING_ANNOTATION_TYPE.equals(type);
+ }
+
+ /*
+ * @see ICAnnotation#hasOverlay()
+ */
+ public boolean hasOverlay() {
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.javaeditor.IJavaAnnotation#getOverlay()
+ */
+ public ICAnnotation getOverlay() {
+ return null;
+ }
+
+ /*
+ * @see ICAnnotation#addOverlaid(ICAnnotation)
+ */
+ public void addOverlaid(ICAnnotation annotation) {
+ if (fOverlaids == null)
+ fOverlaids= new ArrayList(1);
+ fOverlaids.add(annotation);
+ }
+
+ /*
+ * @see ICAnnotation#removeOverlaid(ICAnnotation)
+ */
+ public void removeOverlaid(ICAnnotation annotation) {
+ if (fOverlaids != null) {
+ fOverlaids.remove(annotation);
+ if (fOverlaids.size() == 0)
+ fOverlaids= null;
+ }
+ }
+
+ /*
+ * @see ICAnnotation#getOverlaidIterator()
+ */
+ public Iterator getOverlaidIterator() {
+ if (fOverlaids != null)
+ return fOverlaids.iterator();
+ return null;
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.ICAnnotation#getTranslationUnit()
+ */
+ public ITranslationUnit getTranslationUnit() {
+ return fTranslationUnit;
+ }
+ }
+
+ /**
+ * Internal structure for mapping positions to some value.
+ * The reason for this specific structure is that positions can
+ * change over time. Thus a lookup is based on value and not
+ * on hash value.
+ */
+ protected static class ReverseMap {
+
+ static class Entry {
+ Position fPosition;
+ Object fValue;
+ }
+
+ private List fList= new ArrayList(2);
+ private int fAnchor= 0;
+
+ public ReverseMap() {
+ }
+
+ public Object get(Position position) {
+
+ Entry entry;
+
+ // behind anchor
+ int length= fList.size();
+ for (int i= fAnchor; i < length; i++) {
+ entry= (Entry) fList.get(i);
+ if (entry.fPosition.equals(position)) {
+ fAnchor= i;
+ return entry.fValue;
+ }
+ }
+
+ // before anchor
+ for (int i= 0; i < fAnchor; i++) {
+ entry= (Entry) fList.get(i);
+ if (entry.fPosition.equals(position)) {
+ fAnchor= i;
+ return entry.fValue;
+ }
+ }
+
+ return null;
+ }
+
+ private int getIndex(Position position) {
+ Entry entry;
+ int length= fList.size();
+ for (int i= 0; i < length; i++) {
+ entry= (Entry) fList.get(i);
+ if (entry.fPosition.equals(position))
+ return i;
+ }
+ return -1;
+ }
+
+ public void put(Position position, Object value) {
+ int index= getIndex(position);
+ if (index == -1) {
+ Entry entry= new Entry();
+ entry.fPosition= position;
+ entry.fValue= value;
+ fList.add(entry);
+ } else {
+ Entry entry= (Entry) fList.get(index);
+ entry.fValue= value;
+ }
+ }
+
+ public void remove(Position position) {
+ int index= getIndex(position);
+ if (index > -1)
+ fList.remove(index);
+ }
+
+ public void clear() {
+ fList.clear();
+ }
+ }
+
+ /**
+ * Annotation model dealing with c marker annotations and temporary problems.
+ * Also acts as problem requestor for its translation unit. Initialiy inactive. Must explicitly be
+ * activated.
+ */
+ protected static class TranslationUnitAnnotationModel extends ResourceMarkerAnnotationModel implements IProblemRequestor, IProblemRequestorExtension {
+
+ private static class ProblemRequestorState {
+ boolean fInsideReportingSequence= false;
+ List fReportedProblems;
+ }
+
+ private ThreadLocal fProblemRequestorState= new ThreadLocal();
+ private int fStateCount= 0;
+
+ private ITranslationUnit fTranslationUnit;
+ private List fGeneratedAnnotations;
+ private IProgressMonitor fProgressMonitor;
+ private boolean fIsActive= false;
+
+ private ReverseMap fReverseMap= new ReverseMap();
+ private List fPreviouslyOverlaid= null;
+ private List fCurrentlyOverlaid= new ArrayList();
+
+
+ public TranslationUnitAnnotationModel(IResource resource) {
+ super(resource);
+ }
+
+ public void setCompilationUnit(ITranslationUnit unit) {
+ fTranslationUnit= unit;
+ }
+
+ protected MarkerAnnotation createMarkerAnnotation(IMarker marker) {
+ String markerType= MarkerUtilities.getMarkerType(marker);
+ if (markerType != null && markerType.startsWith(CMarkerAnnotation.C_MARKER_TYPE_PREFIX)) {
+ // TODO: Fix this we need the document
+ return new CMarkerAnnotation(marker, null);
+ }
+ return super.createMarkerAnnotation(marker);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.AnnotationModel#createAnnotationModelEvent()
+ */
+ protected AnnotationModelEvent createAnnotationModelEvent() {
+ return new TranslationUnitAnnotationModelEvent(this, getResource());
+ }
+
+ protected Position createPositionFromProblem(IProblem problem) {
+ int start= problem.getSourceStart();
+ if (start < 0)
+ return null;
+
+ int length= problem.getSourceEnd() - problem.getSourceStart() + 1;
+ if (length < 0)
+ return null;
+ return new Position(start, length);
+ }
+
+ /*
+ * @see IProblemRequestor#beginReporting()
+ */
+ public void beginReporting() {
+ ProblemRequestorState state= (ProblemRequestorState) fProblemRequestorState.get();
+ if (state == null)
+ internalBeginReporting(false);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.java.IProblemRequestorExtension#beginReportingSequence()
+ */
+ public void beginReportingSequence() {
+ ProblemRequestorState state= (ProblemRequestorState) fProblemRequestorState.get();
+ if (state == null)
+ internalBeginReporting(true);
+ }
+
+ /**
+ * Sets up the infrastructure necessary for problem reporting.
+ *
+ * @param insideReportingSequence true
if this method
+ * call is issued from inside a reporting sequence
+ */
+ private void internalBeginReporting(boolean insideReportingSequence) {
+ if (fTranslationUnit != null && fTranslationUnit.getCProject().isOnSourceRoot(fTranslationUnit.getResource())) {
+ ProblemRequestorState state= new ProblemRequestorState();
+ state.fInsideReportingSequence= insideReportingSequence;
+ state.fReportedProblems= new ArrayList();
+ synchronized (getLockObject()) {
+ fProblemRequestorState.set(state);
+ ++fStateCount;
+ }
+ }
+ }
+
+ /*
+ * @see IProblemRequestor#acceptProblem(IProblem)
+ */
+ public void acceptProblem(IProblem problem) {
+ if (isActive()) {
+ ProblemRequestorState state= (ProblemRequestorState) fProblemRequestorState.get();
+ if (state != null)
+ state.fReportedProblems.add(problem);
+ }
+ }
+
+ /*
+ * @see IProblemRequestor#endReporting()
+ */
+ public void endReporting() {
+ ProblemRequestorState state= (ProblemRequestorState) fProblemRequestorState.get();
+ if (state != null && !state.fInsideReportingSequence)
+ internalEndReporting(state);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.text.java.IProblemRequestorExtension#endReportingSequence()
+ */
+ public void endReportingSequence() {
+ ProblemRequestorState state= (ProblemRequestorState) fProblemRequestorState.get();
+ if (state != null && state.fInsideReportingSequence)
+ internalEndReporting(state);
+ }
+
+ private void internalEndReporting(ProblemRequestorState state) {
+ int stateCount= 0;
+ synchronized(getLockObject()) {
+ -- fStateCount;
+ stateCount= fStateCount;
+ fProblemRequestorState.set(null);
+ }
+
+ if (stateCount == 0 && isActive())
+ reportProblems(state.fReportedProblems);
+ }
+
+ /**
+ * Signals the end of problem reporting.
+ */
+ private void reportProblems(List reportedProblems) {
+ if (fProgressMonitor != null && fProgressMonitor.isCanceled())
+ return;
+
+ boolean temporaryProblemsChanged= false;
+
+ synchronized (getLockObject()) {
+
+ boolean isCanceled= false;
+
+ fPreviouslyOverlaid= fCurrentlyOverlaid;
+ fCurrentlyOverlaid= new ArrayList();
+
+ if (fGeneratedAnnotations.size() > 0) {
+ temporaryProblemsChanged= true;
+ removeAnnotations(fGeneratedAnnotations, false, true);
+ fGeneratedAnnotations.clear();
+ }
+
+ if (reportedProblems != null && reportedProblems.size() > 0) {
+
+ Iterator e= reportedProblems.iterator();
+ while (e.hasNext()) {
+
+ if (fProgressMonitor != null && fProgressMonitor.isCanceled()) {
+ isCanceled= true;
+ break;
+ }
+
+ IProblem problem= (IProblem) e.next();
+ Position position= createPositionFromProblem(problem);
+ if (position != null) {
+
+ try {
+ ProblemAnnotation annotation= new ProblemAnnotation(problem, fTranslationUnit);
+ overlayMarkers(position, annotation);
+ addAnnotation(annotation, position, false);
+ fGeneratedAnnotations.add(annotation);
+
+ temporaryProblemsChanged= true;
+ } catch (BadLocationException x) {
+ // ignore invalid position
+ }
+ }
+ }
+ }
+
+ removeMarkerOverlays(isCanceled);
+ fPreviouslyOverlaid= null;
+ }
+
+ if (temporaryProblemsChanged)
+ fireModelChanged();
+ }
+
+ private void removeMarkerOverlays(boolean isCanceled) {
+ if (isCanceled) {
+ fCurrentlyOverlaid.addAll(fPreviouslyOverlaid);
+ } else if (fPreviouslyOverlaid != null) {
+ Iterator e= fPreviouslyOverlaid.iterator();
+ while (e.hasNext()) {
+ CMarkerAnnotation annotation= (CMarkerAnnotation) e.next();
+ annotation.setOverlay(null);
+ }
+ }
+ }
+
+ /**
+ * Overlays value with problem annotation.
+ * @param problemAnnotation
+ */
+ private void setOverlay(Object value, ProblemAnnotation problemAnnotation) {
+ if (value instanceof CMarkerAnnotation) {
+ CMarkerAnnotation annotation= (CMarkerAnnotation) value;
+ if (annotation.isProblem()) {
+ annotation.setOverlay(problemAnnotation);
+ fPreviouslyOverlaid.remove(annotation);
+ fCurrentlyOverlaid.add(annotation);
+ }
+ } else {
+ }
+ }
+
+ private void overlayMarkers(Position position, ProblemAnnotation problemAnnotation) {
+ Object value= getAnnotations(position);
+ if (value instanceof List) {
+ List list= (List) value;
+ for (Iterator e = list.iterator(); e.hasNext();)
+ setOverlay(e.next(), problemAnnotation);
+ } else {
+ setOverlay(value, problemAnnotation);
+ }
+ }
+
+ /**
+ * Tells this annotation model to collect temporary problems from now on.
+ */
+ private void startCollectingProblems() {
+ fGeneratedAnnotations= new ArrayList();
+ }
+
+ /**
+ * Tells this annotation model to no longer collect temporary problems.
+ */
+ private void stopCollectingProblems() {
+ if (fGeneratedAnnotations != null)
+ removeAnnotations(fGeneratedAnnotations, true, true);
+ fGeneratedAnnotations= null;
+ }
+
+ /*
+ * @see IProblemRequestor#isActive()
+ */
+ public boolean isActive() {
+ return fIsActive;
+ }
+
+ /*
+ * @see IProblemRequestorExtension#setProgressMonitor(IProgressMonitor)
+ */
+ public void setProgressMonitor(IProgressMonitor monitor) {
+ fProgressMonitor= monitor;
+ }
+
+ /*
+ * @see IProblemRequestorExtension#setIsActive(boolean)
+ */
+ public void setIsActive(boolean isActive) {
+ if (fIsActive != isActive) {
+ fIsActive= isActive;
+ if (fIsActive)
+ startCollectingProblems();
+ else
+ stopCollectingProblems();
+ }
+ }
+
+ private Object getAnnotations(Position position) {
+ return fReverseMap.get(position);
+ }
+
+ /*
+ * @see AnnotationModel#addAnnotation(Annotation, Position, boolean)
+ */
+ protected void addAnnotation(Annotation annotation, Position position, boolean fireModelChanged) throws BadLocationException {
+ super.addAnnotation(annotation, position, fireModelChanged);
+
+ Object cached= fReverseMap.get(position);
+ if (cached == null)
+ fReverseMap.put(position, annotation);
+ else if (cached instanceof List) {
+ List list= (List) cached;
+ list.add(annotation);
+ } else if (cached instanceof Annotation) {
+ List list= new ArrayList(2);
+ list.add(cached);
+ list.add(annotation);
+ fReverseMap.put(position, list);
+ }
+ }
+
+ /*
+ * @see AnnotationModel#removeAllAnnotations(boolean)
+ */
+ protected void removeAllAnnotations(boolean fireModelChanged) {
+ super.removeAllAnnotations(fireModelChanged);
+ fReverseMap.clear();
+ }
+
+ /*
+ * @see AnnotationModel#removeAnnotation(Annotation, boolean)
+ */
+ protected void removeAnnotation(Annotation annotation, boolean fireModelChanged) {
+ Position position= getPosition(annotation);
+ Object cached= fReverseMap.get(position);
+ if (cached instanceof List) {
+ List list= (List) cached;
+ list.remove(annotation);
+ if (list.size() == 1) {
+ fReverseMap.put(position, list.get(0));
+ list.clear();
+ }
+ } else if (cached instanceof Annotation) {
+ fReverseMap.remove(position);
+ }
+ super.removeAnnotation(annotation, fireModelChanged);
+ }
+ }
+
+ protected static class GlobalAnnotationModelListener implements IAnnotationModelListener, IAnnotationModelListenerExtension {
+
+ private ArrayList fListenerList;
+
+ public GlobalAnnotationModelListener() {
+ fListenerList= new ArrayList();
+ }
+
+ /**
+ * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
+ */
+ public void modelChanged(IAnnotationModel model) {
+ Object[] listeners= fListenerList.toArray();
+ for (int i= 0; i < listeners.length; i++) {
+ ((IAnnotationModelListener) listeners[i]).modelChanged(model);
+ }
+ }
+
+ /**
+ * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent)
+ */
+ public void modelChanged(AnnotationModelEvent event) {
+ Object[] listeners= fListenerList.toArray();
+ for (int i= 0; i < listeners.length; i++) {
+ Object curr= listeners[i];
+ if (curr instanceof IAnnotationModelListenerExtension) {
+ ((IAnnotationModelListenerExtension) curr).modelChanged(event);
+ }
+ }
+ }
+
+ public void addListener(IAnnotationModelListener listener) {
+ fListenerList.add(listener);
+ }
+
+ public void removeListener(IAnnotationModelListener listener) {
+ fListenerList.remove(listener);
+ }
+ }
+
+ /** Preference key for temporary problems */
+ private final static String HANDLE_TEMPORARY_PROBLEMS= PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS;
+
/** Indicates whether the save has been initialized by this provider */
private boolean fIsAboutToSave = false;
+ /** Internal property changed listener */
+ private IPropertyChangeListener fPropertyListener;
+ /** Annotation model listener added to all created CU annotation models */
+ private GlobalAnnotationModelListener fGlobalAnnotationModelListener;
+
/** The save policy used by this provider */
//private ISavePolicy fSavePolicy;
@@ -54,7 +749,15 @@ public class CDocumentProvider extends TextFileDocumentProvider {
*/
public CDocumentProvider() {
super();
- setParentDocumentProvider(new TextFileDocumentProvider(new CStorageDocumentProvider()));
+ setParentDocumentProvider(new TextFileDocumentProvider(new CStorageDocumentProvider()));
+ fGlobalAnnotationModelListener= new GlobalAnnotationModelListener();
+ fPropertyListener= new IPropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent event) {
+ if (HANDLE_TEMPORARY_PROBLEMS.equals(event.getProperty()))
+ enableHandlingTemporaryProblems();
+ }
+ };
+ CUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(fPropertyListener);
}
/**
@@ -82,7 +785,8 @@ public class CDocumentProvider extends TextFileDocumentProvider {
* @see org.eclipse.ui.editors.text.TextFileDocumentProvider#createAnnotationModel(org.eclipse.core.resources.IFile)
*/
protected IAnnotationModel createAnnotationModel(IFile file) {
- return new CMarkerAnnotationModel(file);
+ //return new CMarkerAnnotationModel(file);
+ return new TranslationUnitAnnotationModel(file);
}
/*
@@ -90,23 +794,15 @@ public class CDocumentProvider extends TextFileDocumentProvider {
*/
protected FileInfo createFileInfo(Object element) throws CoreException {
ITranslationUnit original = null;
- IWorkingCopy copy = null;
if (element instanceof IFileEditorInput) {
IFileEditorInput input = (IFileEditorInput)element;
original = createTranslationUnit(input.getFile());
- if (original != null) {
- IBufferFactory factory = CUIPlugin.getDefault().getBufferFactory();
- copy = original.getSharedWorkingCopy(getProgressMonitor(), factory);
- }
} else if (element instanceof ITranslationUnitEditorInput) {
ITranslationUnitEditorInput input = (ITranslationUnitEditorInput)element;
- ITranslationUnit u = input.getTranslationUnit();
- if (u != null) {
- copy = new CFileElementWorkingCopy(u);
- }
+ original = input.getTranslationUnit();
}
-
- if (copy == null) {
+
+ if (original == null) {
return null;
}
@@ -115,22 +811,27 @@ public class CDocumentProvider extends TextFileDocumentProvider {
return null;
TranslationUnitInfo tuInfo = (TranslationUnitInfo) info;
setUpSynchronization(tuInfo);
-
- //IProblemRequestor requestor= tuInfo.fModel instanceof IProblemRequestor ? (IProblemRequestor) tuInfo.fModel : null;
- //original.becomeWorkingCopy(requestor, getProgressMonitor());
+ IProblemRequestor requestor= tuInfo.fModel instanceof IProblemRequestor ? (IProblemRequestor) tuInfo.fModel : null;
+ IWorkingCopy copy = null;
+ if (element instanceof IFileEditorInput) {
+ IBufferFactory factory = CUIPlugin.getDefault().getBufferFactory();
+ copy = original.getSharedWorkingCopy(getProgressMonitor(), factory, requestor);
+ } else if (element instanceof ITranslationUnitEditorInput) {
+ copy = new CFileElementWorkingCopy(original);
+ }
tuInfo.fCopy = copy;
- //if (tuInfo.fModel instanceof CMarkerAnnotationModel) {
- // CMarkerAnnotationModel model= (CMarkerAnnotationModel) tuInfo.fModel;
- // model.setCompilationUnit(tuInfo.fCopy);
- //}
- //if (tuInfo.fModel != null)
- // tuInfo.fModel.addAnnotationModelListener(fGlobalAnnotationModelListener);
- //if (requestor instanceof IProblemRequestorExtension) {
- // IProblemRequestorExtension extension= (IProblemRequestorExtension)requestor;
- // extension.setIsActive(isHandlingTemporaryProblems());
- //}
+ if (tuInfo.fModel instanceof TranslationUnitAnnotationModel) {
+ TranslationUnitAnnotationModel model= (TranslationUnitAnnotationModel) tuInfo.fModel;
+ model.setCompilationUnit(tuInfo.fCopy);
+ }
+ if (tuInfo.fModel != null)
+ tuInfo.fModel.addAnnotationModelListener(fGlobalAnnotationModelListener);
+ if (requestor instanceof IProblemRequestorExtension) {
+ IProblemRequestorExtension extension= (IProblemRequestorExtension)requestor;
+ extension.setIsActive(isHandlingTemporaryProblems());
+ }
return tuInfo;
}
@@ -151,8 +852,8 @@ public class CDocumentProvider extends TextFileDocumentProvider {
if (info instanceof TranslationUnitInfo) {
TranslationUnitInfo tuInfo = (TranslationUnitInfo) info;
tuInfo.fCopy.destroy();
- //if (cuInfo.fModel != null)
- // cuInfo.fModel.removeAnnotationModelListener(fGlobalAnnotationModelListener);
+ if (tuInfo.fModel != null)
+ tuInfo.fModel.removeAnnotationModelListener(fGlobalAnnotationModelListener);
}
super.disposeFileInfo(element, info);
}
@@ -192,6 +893,15 @@ public class CDocumentProvider extends TextFileDocumentProvider {
} finally {
fIsAboutToSave = false;
}
+
+ // If here, the dirty state of the editor will change to "not dirty".
+ // Thus, the state changing flag will be reset.
+ // NOTE: this is done in commitFileBuffer() if we use info.fCopy.comit(...) reenable code
+ //if (info.fModel instanceof AbstractMarkerAnnotationModel) {
+ // AbstractMarkerAnnotationModel model= (AbstractMarkerAnnotationModel) info.fModel;
+ // model.updateMarkers(document);
+ //}
+
}
/*
@@ -226,6 +936,43 @@ public class CDocumentProvider extends TextFileDocumentProvider {
return null;
}
+ /**
+ * Returns the preference whether handling temporary problems is enabled.
+ */
+ protected boolean isHandlingTemporaryProblems() {
+ IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
+ return store.getBoolean(HANDLE_TEMPORARY_PROBLEMS);
+ }
+
+ /**
+ * Switches the state of problem acceptance according to the value in the preference store.
+ */
+ protected void enableHandlingTemporaryProblems() {
+ boolean enable= isHandlingTemporaryProblems();
+ for (Iterator iter= getFileInfosIterator(); iter.hasNext();) {
+ FileInfo info= (FileInfo) iter.next();
+ if (info.fModel instanceof IProblemRequestorExtension) {
+ IProblemRequestorExtension extension= (IProblemRequestorExtension) info.fModel;
+ extension.setIsActive(enable);
+ }
+ }
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.javaeditor.ITranlationUnitDocumentProvider#addGlobalAnnotationModelListener(org.eclipse.jface.text.source.IAnnotationModelListener)
+ */
+ public void addGlobalAnnotationModelListener(IAnnotationModelListener listener) {
+ fGlobalAnnotationModelListener.addListener(listener);
+ }
+
+ /*
+ * @see org.eclipse.jdt.internal.ui.javaeditor.ITranslationUnitDocumentProvider#removeGlobalAnnotationModelListener(org.eclipse.jface.text.source.IAnnotationModelListener)
+ */
+ public void removeGlobalAnnotationModelListener(IAnnotationModelListener listener) {
+ fGlobalAnnotationModelListener.removeListener(listener);
+ }
+
+
/*
* @see org.eclipse.jdt.internal.ui.javaeditor.ICompilationUnitDocumentProvider#getWorkingCopy(java.lang.Object)
*/
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CMarkerAnnotation.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CMarkerAnnotation.java
index c80e810b359..25bfde409e3 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CMarkerAnnotation.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CMarkerAnnotation.java
@@ -5,26 +5,40 @@ package org.eclipse.cdt.internal.ui.editor;
* All Rights Reserved.
*/
+import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICModelMarker;
+import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.search.ui.SearchUI;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.texteditor.MarkerAnnotation;
import org.eclipse.ui.texteditor.MarkerUtilities;
-public class CMarkerAnnotation extends MarkerAnnotation implements IProblemAnnotation {
-
+public class CMarkerAnnotation extends MarkerAnnotation implements IProblemAnnotation, ICAnnotation {
+
+ public static final String C_MARKER_TYPE_PREFIX= "org.eclipse.cdt"; //$NON-NLS-1$
+ public static final String ERROR_ANNOTATION_TYPE= "org.eclipse.cdt.ui.error"; //$NON-NLS-1$
+ public static final String WARNING_ANNOTATION_TYPE= "org.eclipse.cdt.ui.warning"; //$NON-NLS-1$
+ public static final String INFO_ANNOTATION_TYPE= "org.eclipse.cdt.ui.info"; //$NON-NLS-1$
+ public static final String TASK_ANNOTATION_TYPE= "org.eclipse.ui.workbench.texteditor.task"; //$NON-NLS-1$
+
private boolean fIsProblemMarker;
private IDocument fDocument;
private int error_start = -1;
private int error_length = 0;
+ private ICAnnotation fOverlay;
+
public CMarkerAnnotation(IMarker marker, IDocument document) {
super(marker);
fDocument = document;
@@ -173,7 +187,7 @@ public class CMarkerAnnotation extends MarkerAnnotation implements IProblemAnnot
super.initialize();
}
-
+
/**
* @see IProblemAnnotation#getMessage()
*/
@@ -245,4 +259,76 @@ public class CMarkerAnnotation extends MarkerAnnotation implements IProblemAnnot
public int getErrorLength() {
return error_length;
}
+
+ /**
+ * Overlays this annotation with the given cAnnotation.
+ *
+ * @param cAnnotation annotation that is overlaid by this annotation
+ */
+ public void setOverlay(ICAnnotation cAnnotation) {
+ if (fOverlay != null)
+ fOverlay.removeOverlaid(this);
+
+ fOverlay= cAnnotation;
+ if (!isMarkedDeleted())
+ markDeleted(fOverlay != null);
+
+ if (fOverlay != null)
+ fOverlay.addOverlaid(this);
+ }
+
+ /*
+ * @see ICAnnotation#hasOverlay()
+ */
+ public boolean hasOverlay() {
+ return fOverlay != null;
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.ICAnnotation#getOverlay()
+ */
+ public ICAnnotation getOverlay() {
+ return fOverlay;
+ }
+
+ /*
+ * @see ICAnnotation#addOverlaid(ICAnnotation)
+ */
+ public void addOverlaid(ICAnnotation annotation) {
+ // not supported
+ }
+
+ /*
+ * @see ICAnnotation#removeOverlaid(ICAnnotation)
+ */
+ public void removeOverlaid(ICAnnotation annotation) {
+ // not supported
+ }
+
+ /*
+ * @see ICAnnotation#getOverlaidIterator()
+ */
+ public Iterator getOverlaidIterator() {
+ // not supported
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jdt.internal.ui.javaeditor.IJavaAnnotation#getCompilationUnit()
+ */
+ public ITranslationUnit getTranslationUnit() {
+ ICElement element= CoreModel.getDefault().create(getMarker().getResource());
+ if (element instanceof ITranslationUnit) {
+ return (ITranslationUnit)element;
+ }
+ return null;
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.editor.ICAnnotation#getImage(org.eclipse.swt.widgets.Display)
+ */
+ public Image getImage(Display display) {
+ return super.getImage(display);
+ }
+
}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICAnnotation.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICAnnotation.java
new file mode 100644
index 00000000000..3a66d573196
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICAnnotation.java
@@ -0,0 +1,108 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003,2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ ***********************************************************************/
+
+package org.eclipse.cdt.internal.ui.editor;
+
+import java.util.Iterator;
+
+import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * ICAnnotation
+ *
+ * Interface of annotations representing markers
+ * and problems.
+ *
+ * @see org.eclipse.core.resources.IMarker
+ * @see org.eclipse.jdt.core.compiler.IProblem
+ */
+public interface ICAnnotation {
+
+ /**
+ * @see org.eclipse.jface.text.source.Annotation#getType()
+ */
+ String getType();
+
+ /**
+ * @see org.eclipse.jface.text.source.Annotation#isPersistent()
+ */
+ boolean isPersistent();
+
+ /**
+ * @see org.eclipse.jface.text.source.Annotation#isMarkedDeleted()
+ */
+ boolean isMarkedDeleted();
+
+ /**
+ * @see org.eclipse.jface.text.source.Annotation#getText()
+ */
+ String getText();
+
+ /**
+ * Returns whether this annotation is overlaid.
+ *
+ * @return true
if overlaid
+ */
+ boolean hasOverlay();
+
+ /**
+ * Returns the overlay of this annotation.
+ *
+ * @return the annotation's overlay
+ */
+ ICAnnotation getOverlay();
+
+ /**
+ * Returns an iterator for iterating over the
+ * annotation which are overlaid by this annotation.
+ *
+ * @return an iterator over the overlaid annotaions
+ */
+ Iterator getOverlaidIterator();
+
+ /**
+ * Adds the given annotation to the list of
+ * annotations which are overlaid by this annotations.
+ *
+ * @param annotation the problem annoation
+ */
+ void addOverlaid(ICAnnotation annotation);
+
+ /**
+ * Removes the given annotation from the list of
+ * annotations which are overlaid by this annotation.
+ *
+ * @param annotation the problem annoation
+ */
+ void removeOverlaid(ICAnnotation annotation);
+
+ /**
+ * Tells whether this annotation is a problem
+ * annotation.
+ *
+ * @return true
if it is a problem annotation
+ */
+ boolean isProblem();
+
+ /**
+ * Returns the compilation unit corresponding to the document on which the annotation is set
+ * or null
if no corresponding co0mpilationunit exists.
+ */
+ ITranslationUnit getTranslationUnit();
+
+ String[] getArguments();
+
+ int getId();
+
+ Image getImage(Display display);
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/TranslationUnitAnnotationModelEvent.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/TranslationUnitAnnotationModelEvent.java
new file mode 100644
index 00000000000..6c99899bb9f
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/TranslationUnitAnnotationModelEvent.java
@@ -0,0 +1,107 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003,2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ ***********************************************************************/
+
+package org.eclipse.cdt.internal.ui.editor;
+
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationModelEvent;
+import org.eclipse.jface.text.source.IAnnotationModel;
+
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+
+
+/**
+ *
+ * TranslationUnitAnnotationModelEvent
+ *
+ * Event sent out by changes of the compilation unit annotation model.
+ */
+public class TranslationUnitAnnotationModelEvent extends AnnotationModelEvent {
+
+ private boolean fIncludesProblemMarkerAnnotations;
+ private IResource fUnderlyingResource;
+
+ /**
+ * Constructor for CompilationUnitAnnotationModelEvent.
+ * @param model
+ * @param underlyingResource The annotation model's underlying resource
+ */
+ public TranslationUnitAnnotationModelEvent(IAnnotationModel model, IResource underlyingResource) {
+ super(model);
+ fUnderlyingResource= underlyingResource;
+ fIncludesProblemMarkerAnnotations= false;
+ }
+
+ private void testIfProblemMarker(Annotation annotation) {
+ if (fIncludesProblemMarkerAnnotations) {
+ return;
+ }
+ if (annotation instanceof CMarkerAnnotation) {
+ fIncludesProblemMarkerAnnotations= ((CMarkerAnnotation) annotation).isProblem();
+ } else if (annotation instanceof MarkerAnnotation) {
+ try {
+ IMarker marker= ((MarkerAnnotation) annotation).getMarker();
+ if (!marker.exists() || marker.isSubtypeOf(IMarker.PROBLEM)) {
+ fIncludesProblemMarkerAnnotations= true;
+ }
+ } catch (CoreException e) {
+ CUIPlugin.getDefault().log(e);
+ }
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.AnnotationModelEvent#annotationAdded(org.eclipse.jface.text.source.Annotation)
+ */
+ public void annotationAdded(Annotation annotation) {
+ super.annotationAdded(annotation);
+ testIfProblemMarker(annotation);
+ }
+
+
+ /*
+ * @see org.eclipse.jface.text.source.AnnotationModelEvent#annotationRemoved(org.eclipse.jface.text.source.Annotation)
+ */
+ public void annotationRemoved(Annotation annotation) {
+ super.annotationRemoved(annotation);
+ testIfProblemMarker(annotation);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.source.AnnotationModelEvent#annotationChanged(org.eclipse.jface.text.source.Annotation)
+ */
+ public void annotationChanged(Annotation annotation) {
+ testIfProblemMarker(annotation);
+ super.annotationChanged(annotation);
+ }
+
+ /**
+ * Returns whether the change included problem marker annotations.
+ *
+ * @return true
if the change included marker annotations
+ */
+ public boolean includesProblemMarkerAnnotationChanges() {
+ return fIncludesProblemMarkerAnnotations;
+ }
+
+ /**
+ * Returns the annotation model's underlying resource
+ */
+ public IResource getUnderlyingResource() {
+ return fUnderlyingResource;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java
index d91a95ea731..ab126cbdd7a 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java
@@ -13,6 +13,7 @@ import org.eclipse.cdt.core.browser.AllTypesCache;
import org.eclipse.cdt.internal.core.search.indexing.SourceIndexer;
import org.eclipse.cdt.internal.ui.search.CSearchPage;
import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.utils.ui.controls.ControlFactory;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.dialogs.IDialogConstants;
@@ -47,6 +48,7 @@ public class WorkInProgressPreferencePage extends PreferencePage
private Button fExternEnabled;
private Button fIProblemMarkers;
private Button fBackgroundTypeCacheEnabled;
+ private Button fEditorCorrection;
protected OverlayPreferenceStore fOverlayStore;
private Text fTextControl;
@@ -62,6 +64,7 @@ public class WorkInProgressPreferencePage extends PreferencePage
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.INT, CSearchPage.EXTERNALMATCH_VISIBLE));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, SourceIndexer.CDT_INDEXER_TIMEOUT));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE));
+ overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS));
OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
overlayKeys.toArray(keys);
@@ -140,6 +143,21 @@ public class WorkInProgressPreferencePage extends PreferencePage
}
});
+ Group editorCorrectionGroup= new Group(result, SWT.NONE);
+ editorCorrectionGroup.setLayout(new GridLayout());
+ editorCorrectionGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ editorCorrectionGroup.setText("Editor"); //$NON-NLS-1$
+
+ fEditorCorrection = createCheckButton(editorCorrectionGroup, "Enable editor problem marker"); //$NON-NLS-1$
+ fEditorCorrection.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ public void widgetSelected(SelectionEvent e) {
+ Button button = (Button) e.widget;
+ fOverlayStore.setValue(PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS, button.getSelection());
+ }
+ });
+
initialize();
return result;
@@ -156,6 +174,8 @@ public class WorkInProgressPreferencePage extends PreferencePage
fTextControl.setText(fOverlayStore.getString(SourceIndexer.CDT_INDEXER_TIMEOUT));
fBackgroundTypeCacheEnabled.setSelection(fOverlayStore.getBoolean(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE));
+
+ fEditorCorrection.setSelection(fOverlayStore.getBoolean(PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS));
}
/* (non-Javadoc)
@@ -220,6 +240,8 @@ public class WorkInProgressPreferencePage extends PreferencePage
prefs.setValue(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE, fOverlayStore.getString(AllTypesCache.ENABLE_BACKGROUND_TYPE_CACHE));
+ prefs.setValue(PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS, fOverlayStore.getString(PreferenceConstants.EDITOR_EVALUATE_TEMPORARY_PROBLEMS));
+
CCorePlugin.getDefault().savePluginPreferences();
return true;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAnnotationHover.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAnnotationHover.java
index dd7b550d534..6e2b9d93822 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAnnotationHover.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CAnnotationHover.java
@@ -88,7 +88,7 @@ public class CAnnotationHover implements IAnnotationHover {
*/
public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
List markers= getMarkersForLine(sourceViewer, lineNumber);
- if (markers != null) {
+ if (markers != null && markers.size() > 0) {
if (markers.size() == 1) {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/IProblemRequestorExtension.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/IProblemRequestorExtension.java
new file mode 100644
index 00000000000..d2e4553776c
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/IProblemRequestorExtension.java
@@ -0,0 +1,51 @@
+/**********************************************************************
+ * Copyright (c) 2002,2003,2004 QNX Software Systems and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * QNX Software Systems - Initial API and implementation
+ ***********************************************************************/
+
+package org.eclipse.cdt.internal.ui.text;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * Extension to IProblemRequestor
.
+ * IProblemRequestorExtension
+ */
+public interface IProblemRequestorExtension {
+
+ /**
+ * Sets the progress monitor to this problem requestor.
+ *
+ * @param monitor the progress monitor to be used
+ */
+ void setProgressMonitor(IProgressMonitor monitor);
+
+ /**
+ * Sets the active state of this problem requestor.
+ *
+ * @param isActive the state of this problem requestor
+ */
+ void setIsActive(boolean isActive);
+
+ /**
+ * Informs the problem requestor that a sequence of reportings is about to start. While
+ * a sequence is active, multiple peering calls of beginReporting
and
+ * endReporting
can appear.
+ *
+ * @since 3.0
+ */
+ void beginReportingSequence();
+
+ /**
+ * Informs the problem requestor that the sequence of reportings has been finished.
+ *
+ * @since 3.0
+ */
+ void endReportingSequence();
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemMarkerManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemMarkerManager.java
index 2f94b8a662c..0eda74bb4c9 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemMarkerManager.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/ProblemMarkerManager.java
@@ -7,8 +7,10 @@ package org.eclipse.cdt.internal.ui.util;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.cdt.core.CProjectNature;
+import org.eclipse.cdt.internal.ui.editor.TranslationUnitAnnotationModelEvent;
import org.eclipse.cdt.ui.CUIPlugin;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -23,7 +25,12 @@ import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.text.source.AnnotationModelEvent;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelListener;
+import org.eclipse.jface.text.source.IAnnotationModelListenerExtension;
import org.eclipse.jface.util.ListenerList;
+import org.eclipse.swt.widgets.Display;
/**
@@ -31,7 +38,7 @@ import org.eclipse.jface.util.ListenerList;
* Viewers showing error ticks should register as listener to
* this type.
*/
-public class ProblemMarkerManager implements IResourceChangeListener {
+public class ProblemMarkerManager implements IResourceChangeListener, IAnnotationModelListener, IAnnotationModelListenerExtension {
/**
* Visitors used to filter the element delta changes
@@ -113,17 +120,42 @@ public class ProblemMarkerManager implements IResourceChangeListener {
CUIPlugin.getDefault().log(e.getStatus());
}
- if (changedElements.size() > 0) {
+ if (!changedElements.isEmpty()) {
fireChanges(changedElements);
}
+
}
-
+
+ /* (non-Javadoc)
+ * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
+ */
+ public void modelChanged(IAnnotationModel model) {
+ // no action
+ }
+
+ /* (non-Javadoc)
+ * @see IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent)
+ */
+ public void modelChanged(AnnotationModelEvent event) {
+ if (event instanceof TranslationUnitAnnotationModelEvent) {
+ TranslationUnitAnnotationModelEvent cuEvent= (TranslationUnitAnnotationModelEvent) event;
+ if (cuEvent.includesProblemMarkerAnnotationChanges()) {
+ //IResource[] changes= new IResource[] {cuEvent.getUnderlyingResource()};
+ IResource res = cuEvent.getUnderlyingResource();
+ if (res != null) {
+ fireChanges(Collections.singleton(res.getFullPath()));
+ }
+ }
+ }
+ }
+
/**
* Adds a listener for problem marker changes.
*/
public void addListener(IProblemChangedListener listener) {
if (fListeners.isEmpty()) {
CUIPlugin.getWorkspace().addResourceChangeListener(this);
+ CUIPlugin.getDefault().getDocumentProvider().addGlobalAnnotationModelListener(this);
}
fListeners.add(listener);
}
@@ -135,15 +167,23 @@ public class ProblemMarkerManager implements IResourceChangeListener {
fListeners.remove(listener);
if (fListeners.isEmpty()) {
CUIPlugin.getWorkspace().removeResourceChangeListener(this);
+ CUIPlugin.getDefault().getDocumentProvider().removeGlobalAnnotationModelListener(this);
}
}
- private void fireChanges(Set changes) {
- Object[] listeners= fListeners.getListeners();
- for (int i= 0; i < listeners.length; i++) {
- IProblemChangedListener curr= (IProblemChangedListener) listeners[i];
- curr.problemsChanged(changes);
- }
+ private void fireChanges(final Set changes) {
+ Display display= SWTUtil.getStandardDisplay();
+ if (display != null && !display.isDisposed()) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ Object[] listeners= fListeners.getListeners();
+ for (int i= 0; i < listeners.length; i++) {
+ IProblemChangedListener curr= (IProblemChangedListener) listeners[i];
+ curr.problemsChanged(changes);
+ }
+ }
+ });
+ }
}
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java
index 56ef7215a92..d41492b4112 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java
@@ -62,7 +62,7 @@ public class PreferenceConstants {
*
@@ -121,7 +121,24 @@ public class PreferenceConstants { * @since 2.1 */ public final static String EDITOR_TASK_INDICATION_IN_OVERVIEW_RULER= "taskIndicationInOverviewRuler"; //$NON-NLS-1$ - + + /** + * A named preference that controls if correction indicators are shown in the UI. + *
+ * Value is of type Boolean
.
+ *
+ * Value is of type Boolean
.
+ *