Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/gcov
diff options
context:
space:
mode:
Diffstat (limited to 'gcov')
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/META-INF/MANIFEST.MF5
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/plugin.xml61
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/pom.xml2
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/action/OpenGCAction.java7
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/CoverageAnnotationColumn.java61
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotation.java57
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModel.java298
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java232
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationProvider.java132
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovSourceEditorInput.java33
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/OpenSourceFileAction.java15
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.launch/src/org/eclipse/linuxtools/internal/gcov/launch/GcovLaunchConfigurationDelegate.java3
-rw-r--r--gcov/org.eclipse.linuxtools.gcov.test/src/org/eclipse/linuxtools/internal/gcov/test/GcovTest.java3
13 files changed, 665 insertions, 244 deletions
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/META-INF/MANIFEST.MF b/gcov/org.eclipse.linuxtools.gcov.core/META-INF/MANIFEST.MF
index 409f6a04f7..fba60d8f95 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/META-INF/MANIFEST.MF
+++ b/gcov/org.eclipse.linuxtools.gcov.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: org.eclipse.linuxtools.gcov.core;singleton:=true
-Bundle-Version: 5.0.0.qualifier
+Bundle-Version: 5.1.0.qualifier
Bundle-Activator: org.eclipse.linuxtools.internal.gcov.Activator
Bundle-Vendor: %bundleProvider
Require-Bundle: org.eclipse.ui,
@@ -24,4 +24,5 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-Localization: plugin
Export-Package:
org.eclipse.linuxtools.internal.gcov.parser;x-friends:="org.eclipse.linuxtools.gcov.launch",
- org.eclipse.linuxtools.internal.gcov.view;x-friends:="org.eclipse.linuxtools.gcov.launch"
+ org.eclipse.linuxtools.internal.gcov.view;x-friends:="org.eclipse.linuxtools.gcov.launch",
+ org.eclipse.linuxtools.internal.gcov.view.annotatedsource;x-friends:="org.eclipse.linuxtools.gcov.launch"
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/plugin.xml b/gcov/org.eclipse.linuxtools.gcov.core/plugin.xml
index 28dbc0ed5d..9364d2bc2f 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/plugin.xml
+++ b/gcov/org.eclipse.linuxtools.gcov.core/plugin.xml
@@ -45,6 +45,67 @@
class="org.eclipse.linuxtools.internal.gcov.preferences.ColorPreferencesInitializer">
</initializer>
</extension>
+
+ <extension
+ point="org.eclipse.ui.editors.markerAnnotationSpecification">
+ <specification
+ annotationType="org.eclipse.gcov.CoverageAnnotation"
+ colorPreferenceKey="coverage_color"
+ colorPreferenceValue="192,255,192"
+ contributesToHeader="false"
+ highlightPreferenceKey="coverage_highlight"
+ highlightPreferenceValue="true"
+ includeOnPreferencePage="true"
+ isGoToNextNavigationTarget="false"
+ isGoToNextNavigationTargetKey="coverage_isGoToNextNavigationTargetKey"
+ isGoToPreviousNavigationTarget="false"
+ isGoToPreviousNavigationTargetKey="coverage_isGoToPreviousNavigationTargetKey"
+ label="Coverage"
+ overviewRulerPreferenceKey="coverage_overviewRuler"
+ overviewRulerPreferenceValue="false"
+ presentationLayer="0"
+ showInNextPrevDropdownToolbarAction="false"
+ showInNextPrevDropdownToolbarActionKey="coverage_showInNextPrevDropdownToolbarAction"
+ textPreferenceKey="coverage_text"
+ textPreferenceValue="true"
+ textStylePreferenceKey="coverage_stylePreferences"
+ textStylePreferenceValue="BOX"
+ verticalRulerPreferenceKey="coverage_verticalRuler"
+ verticalRulerPreferenceValue="true"/>
+ <specification
+ annotationType="org.eclipse.gcov.NoCoverageAnnotation"
+ colorPreferenceKey="nocoverage_color"
+ colorPreferenceValue="255,160,160"
+ contributesToHeader="false"
+ highlightPreferenceKey="nocoverage_highlight"
+ highlightPreferenceValue="true"
+ includeOnPreferencePage="true"
+ isGoToNextNavigationTarget="false"
+ isGoToNextNavigationTargetKey="nocoverage_isGoToNextNavigationTargetKey"
+ isGoToPreviousNavigationTarget="false"
+ isGoToPreviousNavigationTargetKey="nocoverage_isGoToPreviousNavigationTargetKey"
+ label="No Coverage"
+ overviewRulerPreferenceKey="nocoverage_overviewRuler"
+ overviewRulerPreferenceValue="false"
+ presentationLayer="0"
+ showInNextPrevDropdownToolbarAction="false"
+ showInNextPrevDropdownToolbarActionKey="nocoverage_showInNextPrevDropdownToolbarAction"
+ textPreferenceKey="nocoverage_text"
+ textPreferenceValue="true"
+ textStylePreferenceKey="nocoverage_stylePreferences"
+ textStylePreferenceValue="BOX"
+ verticalRulerPreferenceKey="nocoverage_verticalRuler"
+ verticalRulerPreferenceValue="true"/>
+ </extension>
+ <extension
+ point="org.eclipse.ui.editors.annotationTypes">
+ <type
+ name="org.eclipse.gcov.CoverageAnnotation">
+ </type>
+ <type
+ name="org.eclipse.gcov.NoCoverageAnnotation">
+ </type>
+ </extension>
</plugin>
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/pom.xml b/gcov/org.eclipse.linuxtools.gcov.core/pom.xml
index 45a7aeed3f..678b4e4c19 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/pom.xml
+++ b/gcov/org.eclipse.linuxtools.gcov.core/pom.xml
@@ -18,7 +18,7 @@
</parent>
<artifactId>org.eclipse.linuxtools.gcov.core</artifactId>
- <version>5.0.0-SNAPSHOT</version>
+ <version>5.1.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<name>Linux Tools GCov Plug-in</name>
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/action/OpenGCAction.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/action/OpenGCAction.java
index dbb5db6795..d1d126598e 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/action/OpenGCAction.java
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/action/OpenGCAction.java
@@ -21,10 +21,12 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.linuxtools.internal.gcov.dialog.OpenGCDialog;
import org.eclipse.linuxtools.internal.gcov.view.CovView;
+import org.eclipse.linuxtools.internal.gcov.view.annotatedsource.GcovAnnotationModelTracker;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorLauncher;
@@ -72,6 +74,11 @@ public class OpenGCAction implements IEditorLauncher {
return;
}
String binaryPath = d.getBinaryFile();
+
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(file).getProject();
+ GcovAnnotationModelTracker.getInstance().addProject(project, new Path(binaryPath));
+ GcovAnnotationModelTracker.getInstance().annotateAllCEditors();
+
if (d.isCompleteCoverageResultWanted()) {
CovView.displayCovResults(binaryPath, gcda.getAbsolutePath());
} else {
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/CoverageAnnotationColumn.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/CoverageAnnotationColumn.java
deleted file mode 100644
index 8e159e69b1..0000000000
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/CoverageAnnotationColumn.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 STMicroelectronics.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xavier Raynaud <xavier.raynaud@st.com> - initial API and implementation
- *******************************************************************************/
-package org.eclipse.linuxtools.internal.gcov.view.annotatedsource;
-
-import java.util.ArrayList;
-
-import org.eclipse.linuxtools.dataviewers.annotatedsourceeditor.ISTAnnotationColumn;
-import org.eclipse.linuxtools.internal.gcov.parser.Line;
-import org.eclipse.linuxtools.internal.gcov.parser.SourceFile;
-import org.eclipse.osgi.util.NLS;
-
-public class CoverageAnnotationColumn implements ISTAnnotationColumn {
-
- private final ArrayList<Line> lines;
-
- public CoverageAnnotationColumn(SourceFile sourceFile) {
- lines = sourceFile.getLines();
- }
-
- @Override
- public String getAnnotation(int index) {
- try {
- Line l = lines.get(index + 1);
- if (l.exists()) {
- return Long.toString(l.getCount());
- }
- } catch (IndexOutOfBoundsException _) {
- // ignore as empty string will be returned anyway
- }
- return ""; //$NON-NLS-1$
- }
-
- @Override
- public String getTooltip(int index) {
- try {
- Line l = lines.get(index + 1);
- if (!l.exists()) {
- return Messages.CoverageAnnotationColumn_non_exec_line;
- } else {
- long count = l.getCount();
- if (count == 0) {
- return Messages.CoverageAnnotationColumn_line_never_exec;
- } else if (count == 1) {
- return Messages.CoverageAnnotationColumn_line_exec_once;
- }
- return NLS.bind(Messages.CoverageAnnotationColumn_line_mulitiple_exec, Long.toString(count));
- }
- } catch (IndexOutOfBoundsException _) {
- return Messages.CoverageAnnotationColumn_non_exec_line;
- }
- }
-
-}
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotation.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotation.java
new file mode 100644
index 0000000000..4b3274fcb3
--- /dev/null
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotation.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.gcov.view.annotatedsource;
+
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Representation of a GCov source file annotation.
+ */
+public class GcovAnnotation extends Annotation {
+
+ private static final String COVERAGE = "org.eclipse.gcov.CoverageAnnotation"; //$NON-NLS-1$
+ private static final String NO_COVERAGE = "org.eclipse.gcov.NoCoverageAnnotation"; //$NON-NLS-1$
+
+ private final Position position;
+ private final long count;
+
+ public GcovAnnotation(int offset, int length, long count) {
+ super(getAnnotationType(count), false, null);
+ this.position = new Position(offset, length);
+ this.count = count;
+ }
+
+ public Position getPosition() {
+ return position;
+ }
+
+ @Override
+ public String getText() {
+ if (count == 0) {
+ return Messages.CoverageAnnotationColumn_line_never_exec;
+ } else if (count == 1) {
+ return Messages.CoverageAnnotationColumn_line_exec_once;
+ } else if ( count > 0) {
+ return NLS.bind(Messages.CoverageAnnotationColumn_line_mulitiple_exec, Long.toString(count));
+ } else {
+ return Messages.CoverageAnnotationColumn_non_exec_line;
+ }
+ }
+
+ private static String getAnnotationType(long count) {
+ if (count == 0) {
+ return NO_COVERAGE;
+ }
+ return COVERAGE;
+ }
+}
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModel.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModel.java
new file mode 100644
index 0000000000..5bedee6209
--- /dev/null
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModel.java
@@ -0,0 +1,298 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.gcov.view.annotatedsource;
+
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.cdt.core.model.IBinary;
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.ui.CDTUITools;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.AnnotationModelEvent;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelExtension;
+import org.eclipse.jface.text.source.IAnnotationModelListener;
+import org.eclipse.jface.text.source.IAnnotationModelListenerExtension;
+import org.eclipse.linuxtools.binutils.link2source.STLink2SourceSupport;
+import org.eclipse.linuxtools.internal.gcov.parser.CovManager;
+import org.eclipse.linuxtools.internal.gcov.parser.Line;
+import org.eclipse.linuxtools.internal.gcov.parser.SourceFile;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Annotation model responsible for management of GcovAnnotation elements.
+ */
+public final class GcovAnnotationModel implements IAnnotationModel {
+
+ /** Key for identifying our model from other Editor models. */
+ private static final Object KEY = new Object();
+
+ /** List of GcovAnnotation elements */
+ private List<GcovAnnotation> annotations = new ArrayList<>();
+
+ /** List of IAnnotationModelListener */
+ private List<IAnnotationModelListener> annotationModelListeners = new ArrayList<>();
+
+ private final ITextEditor editor;
+ private final IDocument document;
+ private int openConnections = 0;
+ private boolean annotated = false;
+
+ private IDocumentListener documentListener = new IDocumentListener() {
+ @Override
+ public void documentChanged(DocumentEvent event) {
+ updateAnnotations(false);
+ }
+
+ @Override
+ public void documentAboutToBeChanged(DocumentEvent event) {}
+ };
+
+ private GcovAnnotationModel(ITextEditor editor, IDocument document) {
+ this.editor = editor;
+ this.document = document;
+ updateAnnotations(true);
+ }
+
+ /**
+ * Attaches a coverage annotation model for the given editor if the editor
+ * can be annotated. Does nothing if the model is already attached.
+ *
+ * @param editor Editor to which an annotation model should be attached
+ */
+ public static void attach(ITextEditor editor) {
+ IDocumentProvider provider = editor.getDocumentProvider();
+ if (provider == null) {
+ return;
+ }
+ IAnnotationModel model = provider.getAnnotationModel(editor.getEditorInput());
+ if (!(model instanceof IAnnotationModelExtension)) {
+ return;
+ }
+ IAnnotationModelExtension modelex = (IAnnotationModelExtension) model;
+ IDocument document = provider.getDocument(editor.getEditorInput());
+
+ GcovAnnotationModel coveragemodel = (GcovAnnotationModel) modelex.getAnnotationModel(KEY);
+ if (coveragemodel == null) {
+ coveragemodel = new GcovAnnotationModel(editor, document);
+ modelex.addAnnotationModel(KEY, coveragemodel);
+ } else {
+ coveragemodel.updateAnnotations(false);
+ }
+ }
+
+ public static void clear (ITextEditor editor) {
+ IDocumentProvider provider = editor.getDocumentProvider();
+ if (provider == null) {
+ return;
+ }
+ IAnnotationModel model = provider.getAnnotationModel(editor.getEditorInput());
+ if (!(model instanceof IAnnotationModelExtension)) {
+ return;
+ }
+ IAnnotationModelExtension modelex = (IAnnotationModelExtension) model;
+ IAnnotationModel coverageModel = modelex.getAnnotationModel(KEY);
+ if (coverageModel instanceof GcovAnnotationModel) {
+ ((GcovAnnotationModel) coverageModel).clear();
+ }
+ }
+
+ private void updateAnnotations(boolean force) {
+ // We do not annotate any editor displaying content of a project not tracked.
+ ICElement element = CDTUITools.getEditorInputCElement(editor.getEditorInput());
+ if (!GcovAnnotationModelTracker.getInstance().containsProject(element.getCProject().getProject())) {
+ return;
+ }
+
+ SourceFile coverage = findSourceCoverageForEditor();
+ if (coverage != null) {
+ if (!annotated || force) {
+ createAnnotations(coverage);
+ }
+ } else {
+ if (annotated) {
+ clear();
+ }
+ }
+ }
+
+ private SourceFile findSourceCoverageForEditor() {
+ if (editor.isDirty()) {
+ return null;
+ }
+ final IEditorInput input = editor.getEditorInput();
+ if (input == null) {
+ return null;
+ }
+ ICElement element = CDTUITools.getEditorInputCElement(input);
+ if (element == null) {
+ return null;
+ }
+ return findSourceCoverageForElement(element);
+ }
+
+ private SourceFile findSourceCoverageForElement(ICElement element) {
+ List<SourceFile> sources = new ArrayList<> ();
+ ICProject cProject = element.getCProject();
+ IPath target = GcovAnnotationModelTracker.getInstance().getBinaryPath(cProject.getProject());
+ try {
+ IBinary[] binaries = cProject.getBinaryContainer().getBinaries();
+ for (IBinary b : binaries) {
+ if (b.getResource().getLocation().equals(target)) {
+ CovManager covManager = new CovManager(b.getResource().getLocation().toOSString());
+ covManager.processCovFiles(covManager.getGCDALocations(), null);
+ sources.addAll(covManager.getAllSrcs());
+ }
+ }
+ } catch (Exception e) {
+ }
+
+ for (SourceFile sf : sources) {
+ IPath sfPath = new Path(sf.getName());
+ IFile file = STLink2SourceSupport.sharedInstance.getFileForPath(sfPath, cProject.getProject());
+ if (file != null) {
+ if (element.getLocationURI().getPath().equals(file.getLocation().toOSString())) {
+ return sf;
+ }
+ }
+ }
+
+ IPath binFolder = target.removeLastSegments(1);
+ for (SourceFile sf : sources) {
+ String sfPath = Paths.get(binFolder.toOSString(), sf.getName()).normalize().toString();
+ if (sfPath.equals(element.getLocationURI().getPath())) {
+ return sf;
+ }
+ }
+
+ return null;
+ }
+
+ private void createAnnotations(SourceFile sourceFile) {
+ AnnotationModelEvent event = new AnnotationModelEvent(this);
+ clear(event);
+ List<Line> lines = sourceFile.getLines();
+ for (int i = 0; i < lines.size(); i++) {
+ try {
+ Line line = lines.get((i+1) % lines.size());
+ if (line.exists()) {
+ GcovAnnotation ca = new GcovAnnotation(document.getLineOffset(i),
+ document.getLineLength(i), line.getCount());
+ annotations.add(ca);
+ event.annotationAdded(ca);
+ }
+ } catch (BadLocationException e) {
+ }
+ }
+ fireModelChanged(event);
+ annotated = true;
+ }
+
+ private void clear() {
+ AnnotationModelEvent event = new AnnotationModelEvent(this);
+ clear(event);
+ fireModelChanged(event);
+ annotated = false;
+ }
+
+ private void clear(AnnotationModelEvent event) {
+ for (final GcovAnnotation ca : annotations) {
+ event.annotationRemoved(ca, ca.getPosition());
+ }
+ annotations.clear();
+ }
+
+ @Override
+ public void addAnnotationModelListener(IAnnotationModelListener listener) {
+ if (!annotationModelListeners.contains(listener)) {
+ annotationModelListeners.add(listener);
+ fireModelChanged(new AnnotationModelEvent(this, true));
+ }
+ }
+
+ @Override
+ public void removeAnnotationModelListener(IAnnotationModelListener listener) {
+ annotationModelListeners.remove(listener);
+ }
+
+ private void fireModelChanged(AnnotationModelEvent event) {
+ event.markSealed();
+ if (!event.isEmpty()) {
+ for (final IAnnotationModelListener l : annotationModelListeners) {
+ if (l instanceof IAnnotationModelListenerExtension) {
+ ((IAnnotationModelListenerExtension) l).modelChanged(event);
+ } else {
+ l.modelChanged(this);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void connect(IDocument document) {
+ if (this.document != document) {
+ throw new IllegalArgumentException("Can't connect to different document."); //$NON-NLS-1$
+ }
+ for (final GcovAnnotation ca : annotations) {
+ try {
+ document.addPosition(ca.getPosition());
+ } catch (BadLocationException ex) {
+ }
+ }
+ if (openConnections++ == 0) {
+ document.addDocumentListener(documentListener);
+ }
+ }
+
+ @Override
+ public void disconnect(IDocument document) {
+ if (this.document != document) {
+ throw new IllegalArgumentException("Can't disconnect from different document."); //$NON-NLS-1$
+ }
+ for (final GcovAnnotation ca : annotations) {
+ document.removePosition(ca.getPosition());
+ }
+ if (--openConnections == 0) {
+ document.removeDocumentListener(documentListener);
+ }
+ }
+
+ @Override
+ public Position getPosition(Annotation annotation) {
+ return (annotation instanceof GcovAnnotation) ? ((GcovAnnotation) annotation).getPosition() : null;
+ }
+
+ @Override
+ public Iterator<?> getAnnotationIterator() {
+ return annotations.iterator();
+ }
+
+ @Override
+ public void addAnnotation(Annotation annotation, Position position) {}
+
+ @Override
+ public void removeAnnotation(Annotation annotation) {}
+
+}
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java
new file mode 100644
index 0000000000..0eed8fdad5
--- /dev/null
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationModelTracker.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.internal.gcov.view.annotatedsource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.cdt.core.model.ICElement;
+import org.eclipse.cdt.ui.CDTUITools;
+import org.eclipse.cdt.ui.ICEditor;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IPartListener2;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+/**
+ * Keep track of windows/parts and listen for opened editors to add
+ * the annotation model.
+ */
+public class GcovAnnotationModelTracker {
+
+ private static GcovAnnotationModelTracker single;
+ private final IWorkbench workbench;
+ private final Map<IProject, IPath> trackedProjects = new HashMap<>();
+
+ /**
+ * Add/Remove a part listener to every window open/closed.
+ */
+ private IWindowListener windowListener = new IWindowListener() {
+ @Override
+ public void windowOpened(IWorkbenchWindow window) {
+ window.getPartService().addPartListener(partListener);
+ }
+
+ @Override
+ public void windowClosed(IWorkbenchWindow window) {
+ window.getPartService().removePartListener(partListener);
+ }
+
+ @Override
+ public void windowActivated(IWorkbenchWindow window) {}
+
+ @Override
+ public void windowDeactivated(IWorkbenchWindow window) {}
+ };
+
+ /**
+ * Add the GcovAnnotationModel to any part that contains an
+ * instance of ICEditor.
+ */
+ private IPartListener2 partListener = new IPartListener2() {
+ @Override
+ public void partOpened(IWorkbenchPartReference partref) {
+ annotateCEditor(partref);
+ }
+
+ @Override
+ public void partActivated(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partBroughtToTop(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partClosed(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partDeactivated(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partHidden(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partVisible(IWorkbenchPartReference partRef) {}
+
+ @Override
+ public void partInputChanged(IWorkbenchPartReference partRef) {}
+ };
+
+ private GcovAnnotationModelTracker (IWorkbench workbench) {
+ this.workbench = workbench;
+
+ // Add part listener for current windows
+ for (IWorkbenchWindow w : workbench.getWorkbenchWindows()) {
+ w.getPartService().addPartListener(partListener);
+ }
+
+ // Add window listener to workbench for future windows
+ workbench.addWindowListener(windowListener);
+ }
+
+ public static GcovAnnotationModelTracker getInstance () {
+ if (single == null) {
+ single = new GcovAnnotationModelTracker(PlatformUI.getWorkbench());
+ }
+ return single;
+ }
+
+ public IPath getBinaryPath (IProject project) {
+ return trackedProjects.get(project);
+ }
+
+ public boolean containsProject (IProject project) {
+ return trackedProjects.containsKey(project);
+ }
+
+ public void addProject (IProject project, IPath binary) {
+ trackedProjects.put(project, binary);
+ }
+
+ public void dispose() {
+ workbench.removeWindowListener(windowListener);
+ for (IWorkbenchWindow w : workbench.getWorkbenchWindows()) {
+ w.getPartService().removePartListener(partListener);
+ }
+ }
+
+ public void annotateAllCEditors() {
+ for (IWorkbenchWindow w : workbench.getWorkbenchWindows()) {
+ for (IWorkbenchPage p : w.getPages()) {
+ for (IEditorReference e : p.getEditorReferences()) {
+ annotateCEditor(e);
+ }
+ }
+ }
+ }
+
+ private void annotateCEditor(IWorkbenchPartReference partref) {
+ IWorkbenchPart part = partref.getPart(false);
+ if (part instanceof ICEditor) {
+ ICEditor editor = (ICEditor) part;
+ ICElement element = CDTUITools.getEditorInputCElement(editor.getEditorInput());
+ IProject project = element.getCProject().getProject();
+
+ // Attach our annotation model to any compatible editor. (ICEditor)
+ GcovAnnotationModel.attach((ITextEditor) part);
+ // If a user triggers a build we will not render annotations.
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(
+ new ProjectBuildListener(project, editor),
+ IResourceChangeEvent.POST_BUILD);
+ }
+ }
+
+
+ private class ProjectBuildListener implements IResourceChangeListener {
+
+ // project to keep track of
+ private IProject project;
+ private ICEditor editor;
+
+ public ProjectBuildListener(IProject targetProject, ICEditor editor) {
+ this.editor = editor;
+ this.project = targetProject;
+ }
+
+ @Override
+ public void resourceChanged(IResourceChangeEvent event) {
+ if (project != null && isPostBuildEvent(event)) {
+
+ // find the project from event delta and delete its markers
+ IResourceDelta delta = event.getDelta();
+ IResourceDelta[] childrenDelta = delta.getAffectedChildren(IResourceDelta.CHANGED);
+ for (IResourceDelta childDelta : childrenDelta) {
+ if (isProjectDelta(childDelta, project)) {
+
+ // do not track this project and de-register this listener
+ GcovAnnotationModel.clear(editor);
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+ trackedProjects.remove(project);
+ }
+ }
+ }
+ }
+
+ /**
+ * Check if {@link IResourceDelta} represents a change in the specified {@link IProject}..
+ *
+ * @param delta IResourceDelta resource delta to check
+ * @param project IProject project to compare against
+ * @return boolean true if IResourceDelta is a project and equals the
+ */
+ public boolean isProjectDelta(IResourceDelta delta, IProject project){
+ if(delta != null){
+ IResource resource = delta.getResource();
+ return delta.getKind() == IResourceDelta.CHANGED
+ && resource != null
+ && resource.getType() == IResource.PROJECT
+ && resource.equals(project);
+ }
+ return false;
+ }
+
+ /**
+ * Check if {@link IResourceChangeEvent} is a post-build event.
+ *
+ * @param event IResourceChangeEvent event to check
+ * @return boolean true if IResourceChangeEvent is a post-build event, false
+ * otherwise
+ */
+ public boolean isPostBuildEvent(IResourceChangeEvent event) {
+ if(event != null){
+ int buildKind = event.getBuildKind();
+ return event.getType() == IResourceChangeEvent.POST_BUILD
+ && (buildKind == IncrementalProjectBuilder.FULL_BUILD
+ || buildKind == IncrementalProjectBuilder.INCREMENTAL_BUILD
+ || buildKind == IncrementalProjectBuilder.CLEAN_BUILD);
+ }
+ return false;
+ }
+ }
+}
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationProvider.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationProvider.java
deleted file mode 100644
index e497f99f97..0000000000
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovAnnotationProvider.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2013 Kalray.eu
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xavier Raynaud <xavier.raynaud@kalray.eu> - initial API and implementation
- *******************************************************************************/
-package org.eclipse.linuxtools.internal.gcov.view.annotatedsource;
-
-import java.util.ArrayList;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.resource.StringConverter;
-import org.eclipse.linuxtools.dataviewers.annotatedsourceeditor.IAnnotationProvider;
-import org.eclipse.linuxtools.dataviewers.annotatedsourceeditor.ISTAnnotationColumn;
-import org.eclipse.linuxtools.internal.gcov.Activator;
-import org.eclipse.linuxtools.internal.gcov.parser.Line;
-import org.eclipse.linuxtools.internal.gcov.parser.SourceFile;
-import org.eclipse.linuxtools.internal.gcov.preferences.ColorPreferencePage;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.graphics.Color;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.PlatformUI;
-
-/**
- *
- * @author Xavier Raynaud <xavier.raynaud@kalray.eu>
- */
-public class GcovAnnotationProvider implements IAnnotationProvider {
-
- private final ISTAnnotationColumn column;
-
- private final SourceFile sourceFile;
- private final int lineCount;
-
- private boolean initialized = false;
- private boolean COLORIZE_CODE;
- private boolean USE_GRADIENT;
- private Color GREEN_MAX;
- private Color GREEN_MIN;
- private Color RED;
- private final Color[] GREENCOLORS = new Color[129];
-
- public GcovAnnotationProvider(SourceFile sourceFile) {
- this.sourceFile = sourceFile;
- this.lineCount = sourceFile.getLines().size();
- this.column = new CoverageAnnotationColumn(sourceFile);
- }
-
- private void initColors() {
- for (int i = 0; i < GREENCOLORS.length; i++) {
- GREENCOLORS[i] = null;
- }
-
- Display d = PlatformUI.getWorkbench().getDisplay();
- /* Recover the preferences database. */
- IPreferenceStore prefs_store = Activator.getDefault().getPreferenceStore();
-
- COLORIZE_CODE = prefs_store.getBoolean(ColorPreferencePage.PREFKEY_COV_USE_COLORS);
- USE_GRADIENT = prefs_store.getBoolean(ColorPreferencePage.PREFKEY_COV_USE_GRADIENT);
-
- /* Recover and build the colors from the preferences database. */
- GREEN_MAX = new Color(d,
- StringConverter.asRGB(prefs_store.getString(ColorPreferencePage.PREFKEY_COV_MAX_COLOR)));
- GREEN_MIN = new Color(d,
- StringConverter.asRGB(prefs_store.getString(ColorPreferencePage.PREFKEY_COV_MIN_COLOR)));
- RED = new Color(d, StringConverter.asRGB(prefs_store.getString(ColorPreferencePage.PREFKEY_COV_0_COLOR)));
-
- /* Colors are now allocated. */
- initialized = true;
- }
-
- @Override
- public Color getColor(int ln) {
- if (!initialized) {
- initColors();
- }
- Display display = PlatformUI.getWorkbench().getDisplay();
- if (COLORIZE_CODE) {
- final int index = ln + 1;
- if (index < lineCount) {
- ArrayList<Line> lines = sourceFile.getLines();
- Line line = lines.get(index);
- if (line.exists()) {
- long count = line.getCount();
- if (count == 0) {
- return RED;
- }
- if (!USE_GRADIENT || count == sourceFile.getmaxLineCount()) {
- return GREEN_MAX;
- }
- int colorIndex = 128 - (int) ((128 * count) / sourceFile.getmaxLineCount());
- if (GREENCOLORS[colorIndex] == null) {
- int r = GREEN_MIN.getRed() + (GREEN_MAX.getRed() - GREEN_MIN.getRed()) / colorIndex;
- int v = GREEN_MIN.getGreen() + (GREEN_MAX.getGreen() - GREEN_MIN.getGreen()) / colorIndex;
- int b = GREEN_MIN.getBlue() + (GREEN_MAX.getBlue() - GREEN_MIN.getBlue()) / colorIndex;
- GREENCOLORS[colorIndex] = new Color(display, r, v, b);
- }
- return GREENCOLORS[colorIndex];
- }
- }
- }
- return display.getSystemColor(SWT.COLOR_WHITE);
- }
-
- @Override
- public ISTAnnotationColumn getColumn() {
- return column;
- }
-
- @Override
- public void dispose() {
- if (GREEN_MAX != null) {
- GREEN_MAX.dispose();
- }
- if (GREEN_MIN != null) {
- GREEN_MIN.dispose();
- }
- if (RED != null) {
- RED.dispose();
- }
- for (Color c : GREENCOLORS) {
- if (c != null) {
- c.dispose();
- }
- }
- }
-
-}
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovSourceEditorInput.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovSourceEditorInput.java
deleted file mode 100644
index c650877297..0000000000
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/GcovSourceEditorInput.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 STMicroelectronics.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Xavier Raynaud <xavier.raynaud@st.com> - initial API and implementation
- *******************************************************************************/
-package org.eclipse.linuxtools.internal.gcov.view.annotatedsource;
-
-import org.eclipse.core.filesystem.IFileStore;
-import org.eclipse.linuxtools.dataviewers.annotatedsourceeditor.IAnnotationProvider;
-import org.eclipse.linuxtools.dataviewers.annotatedsourceeditor.IEditorInputWithAnnotations;
-import org.eclipse.linuxtools.internal.gcov.parser.SourceFile;
-import org.eclipse.ui.ide.FileStoreEditorInput;
-
-public class GcovSourceEditorInput extends FileStoreEditorInput implements IEditorInputWithAnnotations {
-
- private final SourceFile sourceFile;
-
- public GcovSourceEditorInput(IFileStore fileStore, SourceFile sourceFile) {
- super(fileStore);
- this.sourceFile = sourceFile;
- }
-
- @Override
- public IAnnotationProvider createAnnotationProvider() {
- return new GcovAnnotationProvider(sourceFile);
- }
-
-}
diff --git a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/OpenSourceFileAction.java b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/OpenSourceFileAction.java
index 7ed9590e1f..8597604563 100644
--- a/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/OpenSourceFileAction.java
+++ b/gcov/org.eclipse.linuxtools.gcov.core/src/org/eclipse/linuxtools/internal/gcov/view/annotatedsource/OpenSourceFileAction.java
@@ -25,7 +25,6 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.linuxtools.binutils.link2source.STLink2SourceSupport;
-import org.eclipse.linuxtools.dataviewers.annotatedsourceeditor.STAnnotatedSourceEditorActivator;
import org.eclipse.linuxtools.internal.gcov.Activator;
import org.eclipse.linuxtools.internal.gcov.parser.SourceFile;
import org.eclipse.ui.IEditorInput;
@@ -33,6 +32,7 @@ import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IURIEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
@@ -62,16 +62,6 @@ public class OpenSourceFileAction {
return null;
}
- private GcovSourceEditorInput getInput(SourceFile sourceFile, IFileStore fs) {
- GcovSourceEditorInput input = new GcovSourceEditorInput(fs, sourceFile);
- IWorkbenchPage p = CUIPlugin.getActivePage();
- IEditorPart editorPart = p.findEditor(input);
- if (editorPart != null) {
- p.closeEditor(editorPart, false);
- }
- return input;
- }
-
public void openAnnotatedSourceFile(IProject project, IFile binary, SourceFile sourceFile, int lineNumber) {
if (sourceFile == null) {
return;
@@ -103,9 +93,8 @@ public class OpenSourceFileAction {
Activator.getDefault().getLog().log(s);
}
} else {
- IEditorInput input = getInput(sourceFile, fs);
try {
- IEditorPart editor = page.openEditor(input, STAnnotatedSourceEditorActivator.EDITOR_ID, true);
+ IEditorPart editor = IDE.openEditorOnFileStore(page, fs);
if (lineNumber > 0 && editor instanceof ITextEditor) {
IDocumentProvider provider = ((ITextEditor) editor).getDocumentProvider();
IDocument document = provider.getDocument(editor.getEditorInput());
diff --git a/gcov/org.eclipse.linuxtools.gcov.launch/src/org/eclipse/linuxtools/internal/gcov/launch/GcovLaunchConfigurationDelegate.java b/gcov/org.eclipse.linuxtools.gcov.launch/src/org/eclipse/linuxtools/internal/gcov/launch/GcovLaunchConfigurationDelegate.java
index 14c4e8771a..010236b5fc 100644
--- a/gcov/org.eclipse.linuxtools.gcov.launch/src/org/eclipse/linuxtools/internal/gcov/launch/GcovLaunchConfigurationDelegate.java
+++ b/gcov/org.eclipse.linuxtools.gcov.launch/src/org/eclipse/linuxtools/internal/gcov/launch/GcovLaunchConfigurationDelegate.java
@@ -32,6 +32,7 @@ import org.eclipse.debug.core.ILaunchesListener2;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.linuxtools.internal.gcov.parser.CovManager;
import org.eclipse.linuxtools.internal.gcov.view.CovView;
+import org.eclipse.linuxtools.internal.gcov.view.annotatedsource.GcovAnnotationModelTracker;
import org.eclipse.linuxtools.profiling.launch.IRemoteCommandLauncher;
import org.eclipse.linuxtools.profiling.launch.ProfileLaunchConfigurationDelegate;
import org.eclipse.linuxtools.profiling.launch.RemoteProxyManager;
@@ -107,6 +108,8 @@ public class GcovLaunchConfigurationDelegate extends ProfileLaunchConfigurationD
MessageDialog.openWarning(parent, title, message);
}
CovView.displayCovResults(s, null);
+ GcovAnnotationModelTracker.getInstance().addProject(getProject(), exePath);
+ GcovAnnotationModelTracker.getInstance().annotateAllCEditors();
} catch (InterruptedException e) {
// Do nothing
}
diff --git a/gcov/org.eclipse.linuxtools.gcov.test/src/org/eclipse/linuxtools/internal/gcov/test/GcovTest.java b/gcov/org.eclipse.linuxtools.gcov.test/src/org/eclipse/linuxtools/internal/gcov/test/GcovTest.java
index 8f20fbe1aa..41757266eb 100644
--- a/gcov/org.eclipse.linuxtools.gcov.test/src/org/eclipse/linuxtools/internal/gcov/test/GcovTest.java
+++ b/gcov/org.eclipse.linuxtools.gcov.test/src/org/eclipse/linuxtools/internal/gcov/test/GcovTest.java
@@ -19,7 +19,6 @@ import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.linuxtools.dataviewers.actions.STExportToCSVAction;
-import org.eclipse.linuxtools.dataviewers.annotatedsourceeditor.STAnnotatedSourceEditorActivator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
@@ -331,7 +330,7 @@ public abstract class GcovTest {
bot.button("OK").click();
bot.waitUntil(Conditions.shellCloses(shell));
- SWTBotEditor editor = bot.editorById(STAnnotatedSourceEditorActivator.EDITOR_ID);
+ SWTBotEditor editor = bot.activeEditor();
SWTBotEclipseEditor edt = editor.toTextEditor(); /* just to verify that the correct file was found */
edt.close();
}

Back to the top