package com.redhat.ceylon.eclipse.code.editor; import static com.redhat.ceylon.eclipse.code.editor.RefinementAnnotationCreator.TODO_ANNOTATION_TYPE; import static com.redhat.ceylon.eclipse.code.editor.CeylonAnnotation.isParseAnnotation; import static com.redhat.ceylon.eclipse.code.parse.TreeLifecycleListener.Stage.TYPE_ANALYSIS; import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.PROBLEM_MARKER_ID; import static com.redhat.ceylon.eclipse.core.builder.CeylonBuilder.TASK_MARKER_ID; import java.util.Iterator; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.text.Position; import org.eclipse.jface.text.source.Annotation; import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.ui.texteditor.MarkerAnnotation; import com.redhat.ceylon.eclipse.code.parse.CeylonParseController; import com.redhat.ceylon.eclipse.code.parse.TreeLifecycleListener; class MarkerAnnotationUpdater implements TreeLifecycleListener { private CeylonEditor editor; public MarkerAnnotationUpdater(CeylonEditor editor) { this.editor = editor; } public Stage getStage() { return TYPE_ANALYSIS; } /** * Remove any Marker annotations that don't correspond * to existing problems according to the most recent * tree / typecheck */ public void update(CeylonParseController parseController, IProgressMonitor monitor) { if (editor.isBackgroundParsingPaused() || monitor.isCanceled()) { return; } if (parseController.getStage().ordinal() >= getStage().ordinal()) { IAnnotationModel model = editor.getDocumentProvider() .getAnnotationModel( editor.getEditorInput()); for (@SuppressWarnings("unchecked") Iterator<Annotation> iter = model.getAnnotationIterator(); iter.hasNext();) { Annotation ann = iter.next(); if (ann instanceof MarkerAnnotation) { MarkerAnnotation ma = (MarkerAnnotation) ann; IMarker marker = ma.getMarker(); try { String type = marker.getType(); boolean isProblemMarker = type.equals(PROBLEM_MARKER_ID); // boolean isModuleDependencyMarker = // type.equals(MODULE_DEPENDENCY_PROBLEM_MARKER_ID); boolean isTaskMarker = type.equals(TASK_MARKER_ID); Integer markerStart = (Integer) marker.getAttribute( IMarker.CHAR_START); Integer markerEnd = (Integer) marker.getAttribute( IMarker.CHAR_END); if (markerStart==null || markerEnd==null) { continue; } if (isProblemMarker //&& !isModuleDependencyMarker || isTaskMarker) { boolean found = false; for (@SuppressWarnings("unchecked") Iterator<Annotation> iter2 = model.getAnnotationIterator(); iter2.hasNext();) { Annotation ann2 = iter2.next(); boolean problem = isProblemMarker && isParseAnnotation(ann2); boolean task = isTaskMarker && isTodoAnnotation(ann2); if (problem || task) { Position position = model.getPosition(ann2); if (markerStart.intValue() == position.offset && markerEnd.intValue() == position.offset + position.length) { found=true; break; } } } if (!found) { model.removeAnnotation(ann); } } } catch (CoreException e) { model.removeAnnotation(ann); } } } } } private static boolean isTodoAnnotation(Annotation ann) { return ann.getType().equals(TODO_ANNOTATION_TYPE); } }