Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Pesch2014-01-16 08:39:12 +0000
committerDoug Schaefer2014-01-16 15:46:50 +0000
commiteb5c0c8a55d92f360c73bb17efb4a9718cbf08f5 (patch)
treec1c2365df722bef06b815895925fd98ea5309a88
parent93c60329b8abc3cfa003d3fd16c6a8715e5f3ba2 (diff)
downloadorg.eclipse.cdt-eb5c0c8a55d92f360c73bb17efb4a9718cbf08f5.tar.gz
org.eclipse.cdt-eb5c0c8a55d92f360c73bb17efb4a9718cbf08f5.tar.xz
org.eclipse.cdt-eb5c0c8a55d92f360c73bb17efb4a9718cbf08f5.zip
Bug 425538 - Syntax errors in QML reported as "C/C++ Problems" because errors from Qt Linguist
The problem is solved by allowing to ignore duplicated markers in case there is already loaded a plugin that could handle QML files The ProblemMarkerFilter extension point allows to filter out unneeded problem markers. For example during building of Qt base project with QML files tool Qt Linguist could report syntax errors in some qml file. These errors are presented as "C/C++ Problems" in qml files because they match format CDT expects for errors. If there is already installed plug-in that handles QML files it is a wise to ignore such errors because they are already reported as "QML Problems" with more meaningful descriptions. Change-Id: I3a0a1b58e9690bed9c2774e4328760c695d54a54 Signed-off-by: Daniel Pesch <dpesch@blackberry.com> Reviewed-on: https://git.eclipse.org/r/20581 Tested-by: Hudson CI Reviewed-by: Andrew Eidsness <eclipse@jfront.com> Reviewed-by: Doug Schaefer <dschaefer@qnx.com> IP-Clean: Doug Schaefer <dschaefer@qnx.com>
-rwxr-xr-xcore/org.eclipse.cdt.core/plugin.properties2
-rw-r--r--core/org.eclipse.cdt.core/plugin.xml1
-rw-r--r--core/org.eclipse.cdt.core/schema/ProblemMarkerFilter.exsd135
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java3
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IProblemMarkerFilter.java25
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterDesc.java160
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterManager.java124
7 files changed, 450 insertions, 0 deletions
diff --git a/core/org.eclipse.cdt.core/plugin.properties b/core/org.eclipse.cdt.core/plugin.properties
index f06189e829e..9f72cc6d3a7 100755
--- a/core/org.eclipse.cdt.core/plugin.properties
+++ b/core/org.eclipse.cdt.core/plugin.properties
@@ -138,3 +138,5 @@ uncPathConverter.name = UNC Path Converter
ScannerInfoExtensionLanguageSettingsProvider.name=Contributed ScannerInfo Entries
PathEntryScannerInfoLanguageSettingsProvider.name=Contributed PathEntry Containers
ReferencedProjectsLanguageSettingsProvider.name=Exported Entries from Referenced Projects
+
+problemMarkerFilter.name=Problem Marker Filter
diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml
index 3d6764c38ec..9bfaba5143d 100644
--- a/core/org.eclipse.cdt.core/plugin.xml
+++ b/core/org.eclipse.cdt.core/plugin.xml
@@ -675,6 +675,7 @@
<extension-point id="RefreshExclusionFactory" name="%refreshExclusionFactory.name" schema="schema/RefreshExclusionFactory.exsd"/>
<extension-point id="LanguageSettingsProvider" name="%LanguageSettingsProvider.name" schema="schema/LanguageSettingsProvider.exsd"/>
<extension-point id="UNCPathConverter" name="%uncPathConverter.name" schema="schema/UNCPathConverter.exsd"/>
+ <extension-point id="ProblemMarkerFilter" name="%problemMarkerFilter.name" schema="schema/ProblemMarkerFilter.exsd"/>
<extension
point="org.eclipse.cdt.core.templateProcessTypes">
diff --git a/core/org.eclipse.cdt.core/schema/ProblemMarkerFilter.exsd b/core/org.eclipse.cdt.core/schema/ProblemMarkerFilter.exsd
new file mode 100644
index 00000000000..3a575f9f9e7
--- /dev/null
+++ b/core/org.eclipse.cdt.core/schema/ProblemMarkerFilter.exsd
@@ -0,0 +1,135 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.cdt.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.cdt.core" id="ProblemMarkerFilter" name="Problem Marker Filter"/>
+ </appInfo>
+ <documentation>
+ This extension point allows to filter out unneeded problem markers.
+ For example during building of Qt base project with QML files tool Qt Linguist
+ could report syntax errors in some qml file. These errors are presented as
+ "C/C++ Problems" in qml files because they match format CDT expects for errors.
+ If there is already installed plug-in that handles QML files it is a wise to ignore such
+ errors because they are already reported as "QML Problems" with more meaningful descriptions.
+ </documentation>
+ </annotation>
+
+ <include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/>
+
+ <element name="extension">
+ <annotation>
+ <appInfo>
+ <meta.element />
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="problemMarkerFilter" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully qualified identifier of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional identifier of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name of the extension instance
+ </documentation>
+ <appInfo>
+ <meta.attribute translatable="true"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="problemMarkerFilter">
+ <complexType>
+ <sequence>
+ <element ref="enablement" minOccurs="0" maxOccurs="1"/>
+ </sequence>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ Implementation of Problem Marker Filter that allows to filter out unneded or duplicit problem markers.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.cdt.core.IProblemMarkerFilter"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 8.3
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ The following is an example of a qmakeEnvProvider contribution:
+&lt;p&gt;
+&lt;pre&gt;
+&lt;extension
+ point=&quot;org.eclipse.cdt.core.ProblemMarkerFilter&quot;
+ id=&quot;example&quot;
+ name=&quot;Example QMake Env Provider Extension&quot;&gt;
+ &lt;problemMarkerFilter
+ class=&quot;com.example.internal.ProblemMarkerFilter&quot;&gt;
+ &lt;enablement&gt;
+ &lt;with variable=&quot;projectNatures&quot;&gt;
+ &lt;iterate operator=&quot;or&quot;&gt;
+ &lt;equals value=&quot;com.example.my-nature&quot;/&gt;
+ &lt;/iterate&gt;
+ &lt;/with&gt;
+ &lt;/enablement&gt;
+ &lt;/problemMarkerFilter&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiinfo"/>
+ </appInfo>
+ <documentation>
+ The contributed class must implement &lt;code&gt;org.eclipse.cdt.core.IProblemMarkerFilter&lt;/code&gt;.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2014 BlackBerry Limited and others.
+ 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
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
index 735d8ce086a..12c4ab08e0d 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java
@@ -30,6 +30,7 @@ import org.eclipse.cdt.core.language.settings.providers.IWorkingDirectoryTracker
import org.eclipse.cdt.core.resources.ACBuilder;
import org.eclipse.cdt.internal.core.Cygwin;
import org.eclipse.cdt.internal.core.IErrorMarkeredOutputStream;
+import org.eclipse.cdt.internal.core.ProblemMarkerFilterManager;
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
import org.eclipse.cdt.internal.errorparsers.ErrorParserExtensionManager;
import org.eclipse.cdt.utils.EFSExtensionManager;
@@ -588,6 +589,8 @@ outer:
* @since 5.4
*/
public void addProblemMarker(ProblemMarkerInfo problemMarkerInfo){
+ if ( ! ProblemMarkerFilterManager.getInstance().acceptMarker(problemMarkerInfo) )
+ return;
fErrors.add(problemMarkerInfo);
fMarkerGenerator.addMarker(problemMarkerInfo);
if (problemMarkerInfo.severity == IMarkerGenerator.SEVERITY_ERROR_RESOURCE) {
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IProblemMarkerFilter.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IProblemMarkerFilter.java
new file mode 100644
index 00000000000..9bdb22b8907
--- /dev/null
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/IProblemMarkerFilter.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014 BlackBerry Limited and others.
+ * 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
+ */
+package org.eclipse.cdt.core;
+
+/**
+ * The purpose of IProblemMarkerFilter is to provide filtering function for problem markers.
+ * ProblemMarkerFilter extension point are required to implements this interface.
+ *
+ * @since 5.6
+ */
+public interface IProblemMarkerFilter {
+
+ /**
+ * Decide if a problem marker should be reported or ignored.
+ *
+ * @param markerInfo description of the problem marker that is going to be reported
+ * @return true if markers should be reported, false if should be ignored
+ */
+ boolean acceptMarker(ProblemMarkerInfo markerInfo);
+}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterDesc.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterDesc.java
new file mode 100644
index 00000000000..b794a21f5df
--- /dev/null
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterDesc.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2014 BlackBerry Limited and others.
+ * 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
+ */
+package org.eclipse.cdt.internal.core;
+
+import java.util.Arrays;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.IProblemMarkerFilter;
+import org.eclipse.cdt.core.ProblemMarkerInfo;
+import org.eclipse.core.expressions.EvaluationContext;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.ExpressionConverter;
+import org.eclipse.core.expressions.ExpressionTagNames;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+
+/**
+ * The purpose of ProblemMarkerFilterDesc is to manage information about
+ * one instance ProblemMarkerFilter extension point.
+ */
+class ProblemMarkerFilterDesc {
+
+ /**
+ * XML attribute for name of class that implements this extension point
+ */
+ private static final String ATTR_CLASS = "class"; //$NON-NLS-1$
+
+ /**
+ * Variable name for projectNatures for enablement expression
+ */
+ private static final String VAR_PROJECTNATURES = "projectNatures"; //$NON-NLS-1$
+
+ /**
+ * Configuration element for this extension point
+ */
+ private final IConfigurationElement element;
+
+ /**
+ * Expression that allows conditionally enable/disable extension point
+ */
+ private final Expression enablementExpression;
+
+ /**
+ * Status of this extension point.
+ * False = disabled because of expression error
+ * True = enabled because of missing enablementExpression
+ * null = evaluate the expression for particular project
+ */
+ private Boolean fStatus = null;
+
+ /**
+ * Unique id of this extension point
+ */
+ private String id;
+
+ /**
+ *
+ */
+ private IProblemMarkerFilter filter;
+
+ /**
+ * Filter that accept any marker.
+ *
+ */
+ private static final IProblemMarkerFilter NULL_FILTER = new IProblemMarkerFilter() {
+
+ @Override
+ public boolean acceptMarker(ProblemMarkerInfo markerInfo) {
+ return true;
+ }
+
+ };
+
+ /**
+ * Constructor
+ *
+ * @param element configuration element with optional enablementExpression
+ */
+ ProblemMarkerFilterDesc(IConfigurationElement element) {
+ this.element = element;
+
+ Expression expr = null;
+ IConfigurationElement[] children = element.getChildren(ExpressionTagNames.ENABLEMENT);
+ switch (children.length) {
+ case 0:
+ fStatus = Boolean.TRUE;
+ break;
+ case 1:
+ try {
+ ExpressionConverter parser = ExpressionConverter.getDefault();
+ expr = parser.perform(children[0]);
+ } catch (CoreException e) {
+ CCorePlugin.log("Error in enablement expression of " + id, e); //$NON-NLS-1$
+ fStatus = Boolean.FALSE;
+ }
+ break;
+ default:
+ CCorePlugin.log("Too many enablement expressions for " + id); //$NON-NLS-1$
+ fStatus = Boolean.FALSE;
+ break;
+ }
+ enablementExpression = expr;
+ }
+
+ /**
+ * Evaluate enablement expression
+ *
+ * @param project project for which we had to evaluate the expression
+ * @return value of enablement expression
+ */
+ public boolean matches(IProject project) {
+ // If the enablement expression is missing or structurally invalid, then return immediately
+ if (fStatus != null)
+ return fStatus.booleanValue();
+
+ if (enablementExpression != null)
+ try {
+ EvaluationContext evalContext = new EvaluationContext(null, project);
+ String[] natures = project.getDescription().getNatureIds();
+ evalContext.addVariable(VAR_PROJECTNATURES, Arrays.asList(natures));
+ return enablementExpression.evaluate(evalContext) == EvaluationResult.TRUE;
+ } catch (CoreException e) {
+ CCorePlugin.log("Error while evaluating enablement expression for " + id, e); //$NON-NLS-1$
+ }
+
+ return false;
+ }
+
+ /**
+ * Return filter interface
+ * @return Filter interface or NULL_FILER if filter could not be created
+ */
+ IProblemMarkerFilter getFilter() {
+ if (filter == null)
+ synchronized (this) {
+ if (filter == null) {
+ try {
+ filter = (IProblemMarkerFilter) element.createExecutableExtension(ATTR_CLASS);
+ } catch (CoreException e) {
+ String id = element.getDeclaringExtension().getNamespaceIdentifier() + '.'
+ + element.getDeclaringExtension().getSimpleIdentifier();
+ CCorePlugin.log("Error in class attribute of " + id, e); //$NON-NLS-1$
+
+ // mark the filter with an empty implementation to prevent future load attempts
+ filter = NULL_FILTER;
+ }
+ }
+ }
+
+ return filter;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterManager.java
new file mode 100644
index 00000000000..5409cd262a8
--- /dev/null
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/ProblemMarkerFilterManager.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014 BlackBerry Limited and others.
+ * 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
+ */
+package org.eclipse.cdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.core.ErrorParserManager;
+import org.eclipse.cdt.core.IProblemMarkerFilter;
+import org.eclipse.cdt.core.ProblemMarkerInfo;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.Platform;
+
+/**
+ * The purpose of ProblemMarkerFilterManager is to manage ProblemMarkerFilter extension points.
+ * {@link ErrorParserManager} use this manager to filter out unnecessary problem markers
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProblemMarkerFilterManager {
+
+ /**
+ * Name of ProblemMarkerFilter extension point
+ */
+ private final static String EXTENSION_POINT = "ProblemMarkerFilter"; //$NON-NLS-1$
+
+ /**
+ * Singleton instance of ProblemMarkerFilterManager
+ */
+ private final static ProblemMarkerFilterManager INSTANCE = new ProblemMarkerFilterManager();
+
+ /**
+ * List of all executable extension registered in Extension Registry
+ */
+ private final List<ProblemMarkerFilterDesc> filters = new ArrayList<ProblemMarkerFilterDesc>();
+
+ /**
+ * Cache of active filters for known projects.
+ * This cache allow to skip evaluation of enablementExpression for every marker.
+ */
+ private final Map<IProject, List<ProblemMarkerFilterDesc>> filtersCache = new WeakHashMap<IProject, List<ProblemMarkerFilterDesc>>();
+
+ /**
+ * Return singleton instance of ProblemMarkerFilterManager
+ *
+ * @return singleton instance of ProblemMarkerFilterManager
+ */
+ public static ProblemMarkerFilterManager getInstance() {
+ return INSTANCE;
+ }
+
+ /**
+ * Constructor.
+ *
+ * Creates instances of executable extension for ProblemMarkerFilter extension point
+ *
+ */
+ private ProblemMarkerFilterManager() {
+ IExtensionRegistry reg = Platform.getExtensionRegistry();
+ IConfigurationElement[] extensions = reg
+ .getConfigurationElementsFor(CCorePlugin.PLUGIN_ID, EXTENSION_POINT);
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement element = extensions[i];
+ ProblemMarkerFilterDesc filterDesc = new ProblemMarkerFilterDesc(element);
+ filters.add(filterDesc);
+ }
+ }
+
+ /**
+ * Called by {@link ErrorParserManager#addProblemMarker(ProblemMarkerInfo)} to filter out unnecessary problem markers
+ *
+ * Problem marker is ignored if any plug-in that implements ProblemMarkerFilter extension point rejects it.
+ *
+ * @see IProblemMarkerFilter#acceptMarker(ProblemMarkerInfo)
+ *
+ * @param markerInfo description of the problem marker that is going to be added
+ * @return true if markers should be reported, false if should be ignored
+ */
+ public boolean acceptMarker(ProblemMarkerInfo markerInfo) {
+ IProject project = markerInfo.file.getProject();
+ if (project == null || !project.isOpen())
+ return true;
+ List<ProblemMarkerFilterDesc> enabledFilters = findEnabledFilters(project);
+ for (ProblemMarkerFilterDesc filterDesc: enabledFilters) {
+ if ( ! filterDesc.getFilter().acceptMarker(markerInfo) ) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Try to find enabled filter for project and cache results
+ * @param project project for which we want know enabled filters
+ * @return list of enabled filters
+ */
+ private List<ProblemMarkerFilterDesc> findEnabledFilters(IProject project) {
+ synchronized (filtersCache) {
+ List<ProblemMarkerFilterDesc> result = filtersCache.get(project);
+ if (result == null) {
+ result = new ArrayList<ProblemMarkerFilterDesc>();
+ for (ProblemMarkerFilterDesc filterDesc: filters) {
+ if ( filterDesc.matches(project) ) {
+ result.add(filterDesc);
+ }
+ }
+ filtersCache.put(project, result);
+ }
+ return result;
+ }
+ }
+
+}

Back to the top