Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Stornelli2019-03-23 09:41:20 -0400
committerMarco Stornelli2019-05-16 00:52:48 -0400
commitf90cd7214dca372e6b7ba008a484359b45753b16 (patch)
tree7b192b7dc6b11470abfffb3273d38d760e00b353
parent86bfd4de7e477f0423585be531bef9a53f32aa6c (diff)
downloadorg.eclipse.cdt-f90cd7214dca372e6b7ba008a484359b45753b16.tar.gz
org.eclipse.cdt-f90cd7214dca372e6b7ba008a484359b45753b16.tar.xz
org.eclipse.cdt-f90cd7214dca372e6b7ba008a484359b45753b16.zip
Bug 545702 - Added new checker to verify copyright information
Change-Id: I57cad8565ce3c752a41f89473a95d5427d10cc8b Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
-rw-r--r--codan/org.eclipse.cdt.codan.checkers/OSGI-INF/l10n/bundle.properties5
-rw-r--r--codan/org.eclipse.cdt.codan.checkers/plugin.xml15
-rw-r--r--codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.java2
-rw-r--r--codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties2
-rw-r--r--codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CopyrightChecker.java132
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CopyrightCheckerTest.java133
-rw-r--r--codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/AutomatedIntegrationSuite.java2
7 files changed, 291 insertions, 0 deletions
diff --git a/codan/org.eclipse.cdt.codan.checkers/OSGI-INF/l10n/bundle.properties b/codan/org.eclipse.cdt.codan.checkers/OSGI-INF/l10n/bundle.properties
index 5f4b76794e..7cd7677c36 100644
--- a/codan/org.eclipse.cdt.codan.checkers/OSGI-INF/l10n/bundle.properties
+++ b/codan/org.eclipse.cdt.codan.checkers/OSGI-INF/l10n/bundle.properties
@@ -149,3 +149,8 @@ checker.name.GotoStatementChecker = Goto statement in source files checker
problem.name.GotoStatementProblem = Goto statement used
problem.messagePattern.GotoStatementProblem = Code that uses goto statements is harder to understand than alternative constructions
problem.description.GotoStatementProblem = This rule will flag goto statements in source files
+
+checker.name.CopyrightChecker = Copyright in source code checker
+problem.name.CopyrightProblem = Lack of copyright information
+problem.messagePattern.CopyrightProblem = Copyright information missing
+problem.description.CopyrightProblem = This rule will flag files without copyright information
diff --git a/codan/org.eclipse.cdt.codan.checkers/plugin.xml b/codan/org.eclipse.cdt.codan.checkers/plugin.xml
index d1d46d6eef..539f7a67ea 100644
--- a/codan/org.eclipse.cdt.codan.checkers/plugin.xml
+++ b/codan/org.eclipse.cdt.codan.checkers/plugin.xml
@@ -484,5 +484,20 @@
name="%problem.name.GotoStatementProblem">
</problem>
</checker>
+ <checker
+ class="org.eclipse.cdt.codan.internal.checkers.CopyrightChecker"
+ id="org.eclipse.cdt.codan.internal.checkers.CopyrightChecker"
+ name="%checker.name.CopyrightChecker">
+ <problem
+ category="org.eclipse.cdt.codan.core.categories.CodeStyle"
+ defaultEnabled="false"
+ defaultSeverity="Warning"
+ description="%problem.description.CopyrightProblem"
+ id="org.eclipse.cdt.codan.internal.checkers.CopyrightProblem"
+ markerType="org.eclipse.cdt.codan.core.codanProblem"
+ messagePattern="%problem.messagePattern.CopyrightProblem"
+ name="%problem.name.CopyrightProblem">
+ </problem>
+ </checker>
</extension>
</plugin>
diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.java
index 1a1543e9fb..9f8b3afef3 100644
--- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.java
+++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.java
@@ -39,6 +39,8 @@ public class CheckersMessages extends NLS {
public static String UnusedSymbolInFileScopeChecker_CharacterSequence;
public static String UnusedSymbolInFileScopeChecker_Exceptions;
+ public static String Copyright_regex;
+
static {
NLS.initializeMessages(CheckersMessages.class.getName(), CheckersMessages.class);
}
diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties
index 56ecf256a6..36347f4011 100644
--- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties
+++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CheckersMessages.properties
@@ -30,3 +30,5 @@ SuspiciousSemicolonChecker_ParamElse=Do not report an error after 'if' when 'els
ProblemBindingChecker_Candidates=Candidates are:
UnusedSymbolInFileScopeChecker_CharacterSequence=Identifier character sequence:
UnusedSymbolInFileScopeChecker_Exceptions=Exceptions (identifier character sequence)
+
+Copyright_regex=Regex to search for copyright information \ No newline at end of file
diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CopyrightChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CopyrightChecker.java
new file mode 100644
index 0000000000..7e3e6426e5
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CopyrightChecker.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Marco Stornelli
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ *******************************************************************************/
+package org.eclipse.cdt.codan.internal.checkers;
+
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import org.eclipse.cdt.codan.checkers.CodanCheckersActivator;
+import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
+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.IProblemWorkingCopy;
+import org.eclipse.cdt.core.dom.ast.IASTComment;
+import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
+import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+
+/**
+ * Checker for lack of copyright information
+ */
+public class CopyrightChecker extends AbstractIndexAstChecker {
+ public static final String ERR_ID = "org.eclipse.cdt.codan.internal.checkers.CopyrightProblem"; //$NON-NLS-1$
+ public static final String PARAM_REGEX = "regex"; //$NON-NLS-1$
+ private static final String DEF_REGEX = ".*Copyright.*"; //$NON-NLS-1$
+ private Pattern fPattern;
+ private StringBuilder builder = new StringBuilder();
+ private int lastOffset;
+ private boolean multiLine = false;
+
+ /**
+ * Internal result
+ * Not found: we didn't find a proper comment
+ * Found: we found a comment at line 1 but without match, we can stop the search
+ * Found match: comment at line 1 with matching regex
+ */
+ private enum Result {
+ NOT_FOUND, FOUND, FOUND_MATCH;
+ }
+
+ @Override
+ public boolean runInEditor() {
+ return false;
+ }
+
+ @Override
+ public void processAst(IASTTranslationUnit ast) {
+ multiLine = false;
+ lastOffset = 0;
+ builder.setLength(0);
+ String regex = getRegex();
+ if (regex == null || regex.isEmpty())
+ regex = DEF_REGEX;
+ try {
+ fPattern = Pattern.compile(regex, Pattern.MULTILINE | Pattern.DOTALL);
+ } catch (PatternSyntaxException e) {
+ CodanCheckersActivator.log(e);
+ return;
+ }
+ IASTComment[] comments = ast.getComments();
+ if (comments == null) {
+ setProblem();
+ return;
+ }
+ Result found = Result.NOT_FOUND;
+ for (IASTComment comment : comments) {
+ found = processComment(comment);
+ if (found == Result.FOUND || found == Result.FOUND_MATCH)
+ break;
+ }
+ if (found == Result.NOT_FOUND && multiLine) {
+ String c = builder.toString();
+ if (!fPattern.matcher(c).matches()) {
+ setProblem();
+ }
+ } else if (found != Result.FOUND_MATCH)
+ setProblem();
+ }
+
+ @Override
+ public void initPreferences(IProblemWorkingCopy problem) {
+ super.initPreferences(problem);
+ addPreference(problem, PARAM_REGEX, CheckersMessages.Copyright_regex, DEF_REGEX);
+ }
+
+ public String getRegex() {
+ final IProblem pt = getProblemById(ERR_ID, getFile());
+ return (String) getPreference(pt, PARAM_REGEX);
+ }
+
+ protected Result processComment(IASTComment comment) {
+ if (comment.isPartOfTranslationUnitFile()) {
+ IASTNodeLocation nodeLocation = comment.getFileLocation();
+ if (nodeLocation == null) {
+ return Result.NOT_FOUND;
+ }
+ String c = comment.getRawSignature();
+ int currentOffset = nodeLocation.getNodeOffset();
+ if (!comment.isBlockComment() && c.startsWith("//") //$NON-NLS-1$
+ && (currentOffset == lastOffset + 1 || (!multiLine && currentOffset == 0))) {
+ builder.append(c);
+ builder.append("\n"); //$NON-NLS-1$
+ lastOffset = nodeLocation.getNodeOffset() + nodeLocation.getNodeLength();
+ multiLine = true;
+ return Result.NOT_FOUND;
+ }
+ if (multiLine) {
+ c = builder.toString();
+ } else if (nodeLocation.getNodeOffset() != 0) {
+ return Result.NOT_FOUND;
+ }
+ if (fPattern.matcher(c).matches())
+ return Result.FOUND_MATCH;
+ return Result.FOUND;
+ }
+ return Result.NOT_FOUND;
+ }
+
+ private void setProblem() {
+ IProblemLocationFactory locFactory = getRuntime().getProblemLocationFactory();
+ IProblemLocation p = locFactory.createProblemLocation(getFile(), 1);
+ reportProblem(ERR_ID, p);
+ }
+} \ No newline at end of file
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CopyrightCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CopyrightCheckerTest.java
new file mode 100644
index 0000000000..e76744dab4
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CopyrightCheckerTest.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Marco Stornelli
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.cdt.codan.core.internal.checkers;
+
+import org.eclipse.cdt.codan.core.tests.CheckerTestCase;
+import org.eclipse.cdt.codan.internal.checkers.CopyrightChecker;
+
+/**
+ * Test for {@link CopyrightChecker} class
+ */
+public class CopyrightCheckerTest extends CheckerTestCase {
+
+ public static final String ERR_ID = CopyrightChecker.ERR_ID;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ enableProblems(ERR_ID);
+ }
+
+ @Override
+ public boolean isCpp() {
+ return true;
+ }
+
+ //int main() {return 0;}
+ public void testWithoutCopyright() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1, ERR_ID);
+ }
+
+ ////Copyright 2019
+ //int main() {return 0;}
+ public void testWithCopyright() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ERR_ID);
+ }
+
+ ////============================================================================
+ //// Name : test.cpp
+ //// Author : Blah
+ //// Version : 1.0
+ //// Copyright : Your copyright notice
+ //// Description : Hello World in C++, Ansi-style
+ ////============================================================================
+ //
+ //int main() {return 0;}
+ public void testWithCopyrightMultiline() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ERR_ID);
+ }
+
+ ////============================================================================
+ //// Name : test.cpp
+ //// Author : Blah
+ //// Version : 1.0
+ //// Description : Hello World in C++, Ansi-style
+ ////============================================================================
+ //
+ //int main() {return 0;}
+ public void testWithoutCopyrightMultiline() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1, ERR_ID);
+ }
+
+ //// Just another comment here
+ //
+ ////============================================================================
+ //// Name : test.cpp
+ //// Author : Blah
+ //// Version : 1.0
+ //// Copyright : Your copyright notice
+ //// Description : Hello World in C++, Ansi-style
+ ////============================================================================
+ //
+ //int main() {return 0;}
+ public void testWithCopyrightMultilineNoHeader() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1, ERR_ID);
+ }
+
+ ////============================================================================
+ //// Name : test.cpp
+ //// Author : Blah
+ //// Version : 1.0
+ //// Copyright : Your copyright notice
+ //// Description : Hello World in C++, Ansi-style
+ ////============================================================================
+ //
+ //// Just another comment here
+ //int main() {return 0;}
+ public void testWithCopyrightMultilinePostComment() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ERR_ID);
+ }
+
+ ///****************************************************************************
+ // * Name : test.cpp
+ // * Author : Blah
+ // * Version : 1.0
+ // * Copyright : Your copyright notice
+ // * Description : Hello World in C++, Ansi-style
+ // ****************************************************************************/
+ //
+ //int main() {return 0;}
+ public void testWithCopyrightBlock() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkNoErrorsOfKind(ERR_ID);
+ }
+
+ //// Just another comment here
+ ///****************************************************************************
+ // * Name : test.cpp
+ // * Author : Blah
+ // * Version : 1.0
+ // * Copyright : Your copyright notice
+ // * Description : Hello World in C++, Ansi-style
+ // ****************************************************************************/
+ //
+ //int main() {return 0;}
+ public void testWithCopyrightBlockNoHeader() throws Exception {
+ loadCodeAndRun(getAboveComment());
+ checkErrorLine(1, ERR_ID);
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/AutomatedIntegrationSuite.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/AutomatedIntegrationSuite.java
index 2deb3a5030..0d174e1ff8 100644
--- a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/AutomatedIntegrationSuite.java
+++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/tests/AutomatedIntegrationSuite.java
@@ -23,6 +23,7 @@ import org.eclipse.cdt.codan.core.internal.checkers.CatchByReferenceTest;
import org.eclipse.cdt.codan.core.internal.checkers.ClassMembersInitializationCheckerTest;
import org.eclipse.cdt.codan.core.internal.checkers.CommentCheckerLineTests;
import org.eclipse.cdt.codan.core.internal.checkers.CommentCheckerNestedTests;
+import org.eclipse.cdt.codan.core.internal.checkers.CopyrightCheckerTest;
import org.eclipse.cdt.codan.core.internal.checkers.DecltypeAutoCheckerTest;
import org.eclipse.cdt.codan.core.internal.checkers.FormatStringCheckerTest;
import org.eclipse.cdt.codan.core.internal.checkers.GotoStatementCheckerTest;
@@ -86,6 +87,7 @@ public class AutomatedIntegrationSuite extends TestSuite {
suite.addTestSuite(CommentCheckerLineTests.class);
suite.addTestSuite(CommentCheckerNestedTests.class);
suite.addTestSuite(GotoStatementCheckerTest.class);
+ suite.addTestSuite(CopyrightCheckerTest.class);
// framework
suite.addTest(CodanFastTestSuite.suite());
// quick fixes

Back to the top