Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlena Laskavaia2016-01-08 04:12:51 +0000
committerElena Laskavaia2016-01-11 17:49:09 +0000
commit05daa126a0b6c09907dbe5f842156ec9d15d9d44 (patch)
treec5b260c579b4b556a7963f0bddfd518a196dcc52
parent12843ef1d7d1f60504f58e79c11693210fd8b735 (diff)
downloadorg.eclipse.cdt-05daa126a0b6c09907dbe5f842156ec9d15d9d44.tar.gz
org.eclipse.cdt-05daa126a0b6c09907dbe5f842156ec9d15d9d44.tar.xz
org.eclipse.cdt-05daa126a0b6c09907dbe5f842156ec9d15d9d44.zip
Bug 383576 - Ability to ignore codan errors using line comments
Change-Id: I806e1787fb6cc3be8865cee1d397d581ae4acd8e Signed-off-by: Alena Laskavaia <elaskavaia.cdt@gmail.com>
-rw-r--r--codan/org.eclipse.cdt.codan.core.cxx/META-INF/MANIFEST.MF2
-rw-r--r--codan/org.eclipse.cdt.codan.core.cxx/pom.xml2
-rw-r--r--codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java62
-rw-r--r--codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java40
-rw-r--r--codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java4
-rw-r--r--codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractCheckerWithProblemPreferences.java35
-rw-r--r--codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/Messages.java1
-rw-r--r--codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/Messages.properties1
-rw-r--r--codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/RootProblemPreference.java17
-rw-r--r--codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/SuppressionCommentProblemPreference.java34
10 files changed, 176 insertions, 22 deletions
diff --git a/codan/org.eclipse.cdt.codan.core.cxx/META-INF/MANIFEST.MF b/codan/org.eclipse.cdt.codan.core.cxx/META-INF/MANIFEST.MF
index 880142e5045..dcabf55fa1a 100644
--- a/codan/org.eclipse.cdt.codan.core.cxx/META-INF/MANIFEST.MF
+++ b/codan/org.eclipse.cdt.codan.core.cxx/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.cdt.codan.core.cxx;singleton:=true
-Bundle-Version: 3.3.0.qualifier
+Bundle-Version: 3.4.0.qualifier
Bundle-Activator: org.eclipse.cdt.codan.core.cxx.Activator
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.cdt.core,
diff --git a/codan/org.eclipse.cdt.codan.core.cxx/pom.xml b/codan/org.eclipse.cdt.codan.core.cxx/pom.xml
index 869b140852b..f5159870bd5 100644
--- a/codan/org.eclipse.cdt.codan.core.cxx/pom.xml
+++ b/codan/org.eclipse.cdt.codan.core.cxx/pom.xml
@@ -11,7 +11,7 @@
<relativePath>../../pom.xml</relativePath>
</parent>
- <version>3.3.0-SNAPSHOT</version>
+ <version>3.4.0-SNAPSHOT</version>
<artifactId>org.eclipse.cdt.codan.core.cxx</artifactId>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java
index 64b5fcc8ddd..9fe1930d64d 100644
--- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java
+++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/model/AbstractIndexAstChecker.java
@@ -11,6 +11,9 @@
*******************************************************************************/
package org.eclipse.cdt.codan.core.cxx.model;
+import java.util.ArrayList;
+import java.util.List;
+
import org.eclipse.cdt.codan.core.cxx.Activator;
import org.eclipse.cdt.codan.core.model.AbstractCheckerWithProblemPreferences;
import org.eclipse.cdt.codan.core.model.ICheckerInvocationContext;
@@ -18,6 +21,7 @@ import org.eclipse.cdt.codan.core.model.IProblem;
import org.eclipse.cdt.codan.core.model.IProblemLocation;
import org.eclipse.cdt.codan.core.model.IProblemLocationFactory;
import org.eclipse.cdt.codan.core.model.IRunnableInEditorChecker;
+import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
@@ -35,7 +39,8 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.OperationCanceledException;
/**
- * Convenience implementation of checker that works on index-based AST of a C/C++
+ * Convenience implementation of checker that works on index-based AST of a
+ * C/C++
* program.
*
* Clients may extend this class.
@@ -50,7 +55,6 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem
return false;
if (!(resource instanceof IFile))
return true;
-
processFile((IFile) resource);
return false;
}
@@ -68,7 +72,6 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem
context.add(modelCache);
}
}
-
try {
// Run the checker only if the index is fully initialized. Otherwise it may produce
// false positives.
@@ -87,8 +90,11 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem
}
}
- /* (non-Javadoc)
- * @see IRunnableInEditorChecker#processModel(Object, ICheckerInvocationContext)
+ /*
+ * (non-Javadoc)
+ *
+ * @see IRunnableInEditorChecker#processModel(Object,
+ * ICheckerInvocationContext)
*/
@Override
public synchronized void processModel(Object model, ICheckerInvocationContext context) {
@@ -98,7 +104,6 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem
// Otherwise the checker may produce false positives.
if (ast.isBasedOnIncompleteIndex())
return;
-
setContext(context);
synchronized (context) {
modelCache = context.get(CxxModelsCache.class);
@@ -110,7 +115,7 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem
try {
processAst(ast);
} finally {
- modelCache = null;
+ modelCache = null;
setContext(null);
}
}
@@ -133,6 +138,49 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem
reportProblem(problem, loc, args);
}
+ /**
+ * Checks if problem should be reported, in this case it will check line
+ * comments, later can add filters or what not.
+ *
+ * @param problem - problem kind
+ * @param loc - location
+ * @param args - arguments
+ * @since 3.4
+ */
+ @Override
+ protected boolean shouldProduceProblem(IProblem problem, IProblemLocation loc, Object... args) {
+ String suppressionComment = (String) getSuppressionCommentPreference(problem).getValue();
+ if (suppressionComment.isEmpty())
+ return true;
+ List<IASTComment> lineComments = getLineCommentsForLocation(loc);
+ for (IASTComment astComment : lineComments) {
+ if (astComment.getRawSignature().contains(suppressionComment))
+ return false;
+ }
+ return true;
+ }
+
+ protected List<IASTComment> getLineCommentsForLocation(IProblemLocation loc) {
+ ArrayList<IASTComment> lineComments = new ArrayList<>();
+ try {
+ IASTComment[] commentsArray = modelCache.getAST().getComments();
+ for (IASTComment comm : commentsArray) {
+ IASTFileLocation fileLocation = comm.getFileLocation();
+ if (fileLocation.getStartingLineNumber() == loc.getLineNumber()) {
+ //XXX check on windows portable or os?
+ String problemFile = loc.getFile().getLocation().toPortableString();
+ String commentFile = fileLocation.getFileName();
+ if (problemFile.equals(commentFile)) {
+ lineComments.add(comm);
+ }
+ }
+ }
+ } catch (OperationCanceledException | CoreException e) {
+ Activator.log(e);
+ }
+ return lineComments;
+ }
+
protected IProblemLocation getProblemLocation(IASTNode astNode) {
IASTFileLocation astLocation = astNode.getFileLocation();
return getProblemLocation(astNode, astLocation);
diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java
index 8b7be0ecb62..f3efc03bc2b 100644
--- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java
+++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java
@@ -107,4 +107,44 @@ public class AssignmentInConditionCheckerTest extends CheckerTestCase {
String arg = CodanProblemMarker.getProblemArgument(marker, 0);
assertEquals("a=b", arg); //$NON-NLS-1$
}
+
+ // main() {
+ // int i;
+ // while (i=b()) { // @suppress("Assignment in condition")
+ // }
+ // }
+ public void test_while2supp() {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // main() {
+ // int i;
+ // while (i=b()) { /* @suppress("Assignment in condition") */
+ // }
+ // }
+ public void test_while3supp() {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrors();
+ }
+
+ // #define LOOP() while (i=b() /* @suppress("Assignment in condition") */ ) { }
+ // main() {
+ // int i;
+ // LOOP();
+ // }
+ public void test_whileMacroSupp() {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(4); // TODO: suppression does not work in macro body now
+ }
+
+ // #define LOOP() while (i=b()) { }
+ // main() {
+ // int i;
+ // LOOP(); // err
+ // }
+ public void test_whileMacro() {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(4);
+ }
}
diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java
index 871611809bb..eaf81ce1a2e 100644
--- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java
+++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractChecker.java
@@ -50,7 +50,7 @@ public abstract class AbstractChecker implements IChecker {
* internationalization)
*/
public void reportProblem(String id, IFile file, int lineNumber, Object... args) {
- getProblemReporter().reportProblem(id, createProblemLocation(file, lineNumber), args);
+ reportProblem(id, createProblemLocation(file, lineNumber), args);
}
/**
@@ -103,7 +103,7 @@ public abstract class AbstractChecker implements IChecker {
* - line
*/
public void reportProblem(String id, IFile file, int lineNumber) {
- getProblemReporter().reportProblem(id, createProblemLocation(file, lineNumber), EMPTY_OBJECT_ARRAY);
+ reportProblem(id, createProblemLocation(file, lineNumber), EMPTY_OBJECT_ARRAY);
}
/**
diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractCheckerWithProblemPreferences.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractCheckerWithProblemPreferences.java
index c18a124ade3..7518bb52b3e 100644
--- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractCheckerWithProblemPreferences.java
+++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractCheckerWithProblemPreferences.java
@@ -22,6 +22,7 @@ import org.eclipse.cdt.codan.core.param.LaunchModeProblemPreference;
import org.eclipse.cdt.codan.core.param.ListProblemPreference;
import org.eclipse.cdt.codan.core.param.MapProblemPreference;
import org.eclipse.cdt.codan.core.param.RootProblemPreference;
+import org.eclipse.cdt.codan.core.param.SuppressionCommentProblemPreference;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
@@ -43,6 +44,7 @@ public abstract class AbstractCheckerWithProblemPreferences extends AbstractChec
CheckerLaunchMode.RUN_ON_DEMAND,
CheckerLaunchMode.RUN_ON_FULL_BUILD,
CheckerLaunchMode.RUN_ON_INC_BUILD);
+ getSuppressionCommentPreference(problem).setValue(SuppressionCommentProblemPreference.generateDefaultComment(problem));
}
/**
@@ -66,9 +68,18 @@ public abstract class AbstractCheckerWithProblemPreferences extends AbstractChec
}
/**
+ * @param problem - problem for which preference is extracted
+ * @return suppression comment preference
+ * @since 4.0
+ */
+ public SuppressionCommentProblemPreference getSuppressionCommentPreference(IProblem problem) {
+ return getTopLevelPreference(problem).getSuppressionCommentPreference();
+ }
+
+ /**
* User can scope out some resources for this checker. Checker can use this
* call to test if it should run on this resource at all or not. Test should
- * be done within processResource method not in enabledInContext.
+ * be done within processResource method.
* This test uses user "scope" preference for the all problems that this
* checker can produce.
*
@@ -109,10 +120,7 @@ public abstract class AbstractCheckerWithProblemPreferences extends AbstractChec
@Override
public void reportProblem(String problemId, IProblemLocation loc, Object... args) {
- if (shouldProduceProblem(getProblemById(problemId, loc.getFile()),
- loc.getFile().getFullPath())) {
- super.reportProblem(problemId, loc, args);
- }
+ reportProblem(getProblemById(problemId, loc.getFile()), loc, args);
}
/**
@@ -125,11 +133,26 @@ public abstract class AbstractCheckerWithProblemPreferences extends AbstractChec
* @since 2.0
*/
public void reportProblem(IProblem pr, IProblemLocation loc, Object... args) {
- if (shouldProduceProblem(pr, loc.getFile().getFullPath()))
+ if (shouldProduceProblem(pr, loc, args))
super.reportProblem(pr.getId(), loc, args);
}
/**
+ * Checks if problem should be reported, this implementation only checks
+ * suppression by scope, but subclass should override,
+ * to implement any other filtering, such as suppression by filter or by comment.
+ * Call super to check for scope suppression as well.
+ *
+ * @param problem - problem kind
+ * @param loc - location
+ * @param args - arguments
+ * @since 4.0
+ */
+ protected boolean shouldProduceProblem(IProblem problem, IProblemLocation loc, Object... args) {
+ return shouldProduceProblem(problem, loc.getFile().getFullPath());
+ }
+
+ /**
* Adds a parameter
*
* @param problem
diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/Messages.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/Messages.java
index 4591d288546..bf8a1982f18 100644
--- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/Messages.java
+++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/Messages.java
@@ -18,6 +18,7 @@ import org.eclipse.osgi.util.NLS;
*/
class Messages extends NLS {
public static String FileScopeProblemPreference_Label;
+ public static String SuppressionCommentProblemPreference_Label;
static {
NLS.initializeMessages(Messages.class.getName(), Messages.class);
diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/Messages.properties b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/Messages.properties
index 04c64faf740..c6675dda2b5 100644
--- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/Messages.properties
+++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/Messages.properties
@@ -10,3 +10,4 @@
# IBM Corporation
###############################################################################
FileScopeProblemPreference_Label=Exclusion and Inclusion
+SuppressionCommentProblemPreference_Label=Suppression Comment
diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/RootProblemPreference.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/RootProblemPreference.java
index 7dcf2965135..bab72b6ce74 100644
--- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/RootProblemPreference.java
+++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/RootProblemPreference.java
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.cdt.codan.core.param;
-
/**
* Common problem preference root for most of the codan problems
*
@@ -24,26 +23,34 @@ public class RootProblemPreference extends MapProblemPreference {
public static final String KEY = PARAM;
/**
- * Default constructor
+ * Default constructor
*/
public RootProblemPreference() {
super(KEY, ""); //$NON-NLS-1$
addChildDescriptor(new FileScopeProblemPreference());
addChildDescriptor(new LaunchModeProblemPreference());
+ addChildDescriptor(new SuppressionCommentProblemPreference());
}
/**
* @return scope preference
*/
public FileScopeProblemPreference getScopePreference() {
- return (FileScopeProblemPreference) getChildDescriptor(
- FileScopeProblemPreference.KEY);
+ return (FileScopeProblemPreference) getChildDescriptor(FileScopeProblemPreference.KEY);
}
+
/**
- * @return launch mode
+ * @return launch mode preference
*/
public LaunchModeProblemPreference getLaunchModePreference() {
return (LaunchModeProblemPreference) getChildDescriptor(LaunchModeProblemPreference.KEY);
+ }
+ /**
+ * @return suppression comment preference
+ * @since 4.0
+ */
+ public SuppressionCommentProblemPreference getSuppressionCommentPreference() {
+ return (SuppressionCommentProblemPreference) getChildDescriptor(SuppressionCommentProblemPreference.KEY);
}
}
diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/SuppressionCommentProblemPreference.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/SuppressionCommentProblemPreference.java
new file mode 100644
index 00000000000..8506b974cdd
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/param/SuppressionCommentProblemPreference.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Alena Laskavaia
+ * 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:
+ * Alena Laskavaia - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.param;
+
+import java.text.MessageFormat;
+
+import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
+
+/**
+ * Preference for suppressing a problem using code comments. Automatically added to all problems.
+ * @since 4.0
+ */
+public class SuppressionCommentProblemPreference extends BasicProblemPreference implements IProblemPreference {
+ public static final String KEY = "suppression_comment"; //$NON-NLS-1$;
+ // Even if using English name it is really a keyword, so no externalizable.
+ public static final String KEYWORD = "@suppress(\"{0}\")"; //$NON-NLS-1$;
+
+ public SuppressionCommentProblemPreference() {
+ super(KEY, Messages.SuppressionCommentProblemPreference_Label, PreferenceType.TYPE_STRING);
+ }
+
+ public static String generateDefaultComment(IProblemWorkingCopy problem) {
+ String name = problem.getName();
+ return MessageFormat.format(KEYWORD, name);
+ }
+}

Back to the top