diff --git a/codan/org.eclipse.cdt.codan.checkers/plugin.xml b/codan/org.eclipse.cdt.codan.checkers/plugin.xml index 0f3f1c76678..982aad53851 100644 --- a/codan/org.eclipse.cdt.codan.checkers/plugin.xml +++ b/codan/org.eclipse.cdt.codan.checkers/plugin.xml @@ -398,5 +398,31 @@ name="%problem.name.ClassMembersInitialization"> + + + + + + diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CommentChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CommentChecker.java new file mode 100644 index 00000000000..c02c7167143 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CommentChecker.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2015 QNX Software System 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 + * + * Contributors: + * Elena Laskavaia (QNX Software System) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.checkers; + +import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker; +import org.eclipse.cdt.codan.core.model.IProblemLocation; +import org.eclipse.cdt.codan.core.model.IProblemLocationFactory; +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.IASTComment; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; + +/** + * Checker for some specific code style violations in comments + */ +public class CommentChecker extends AbstractIndexAstChecker { + public static final String COMMENT_NO_LINE = "org.eclipse.cdt.codan.checkers.nolinecomment"; //$NON-NLS-1$ + public static final String COMMENT_NO_START = "org.eclipse.cdt.codan.checkers.nocommentinside"; //$NON-NLS-1$ + private boolean conly; + + @Override + public void processAst(IASTTranslationUnit ast) { + IASTComment[] comments = ast.getComments(); + if (comments == null) + return; + conly = ast.getLinkage().getLinkageID() == ILinkage.C_LINKAGE_ID; + if (!conly && shouldProduceProblem(getProblemById(COMMENT_NO_START, getFile()), + getFile().getFullPath())==false) + return; // c++ file and COMMENT_NO_START is disabled - optimize and bail + for (IASTComment comment : comments) { + processComment(comment); + } + } + + protected void processComment(IASTComment comment) { + boolean blockComment = comment.isBlockComment(); + if (blockComment) { + String commentStr = comment.getRawSignature(); + int pos = commentStr.indexOf("/*", 2); //$NON-NLS-1$ + if (pos >= 0) { + reportProblem(COMMENT_NO_START, getProblemLocation(comment.getFileLocation(), pos)); + } + } else { + if (conly) { + reportProblem(COMMENT_NO_LINE, comment); + } + } + } + + @SuppressWarnings("deprecation") + private IProblemLocation getProblemLocation(IASTFileLocation astLocation, int pos) { + IProblemLocationFactory locFactory = getRuntime().getProblemLocationFactory(); + return locFactory.createProblemLocation(getFile(), astLocation.getNodeOffset() + pos, astLocation.getNodeOffset() + pos + 2); + } +} diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerLineTests.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerLineTests.java new file mode 100644 index 00000000000..b2fe1557964 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerLineTests.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2015 QNX Software System 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 + * + * Contributors: + * Elena Laskavaia (QNX Software System) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.internal.checkers; + +import java.io.File; + +import org.eclipse.cdt.codan.core.test.CheckerTestCase; +import org.eclipse.cdt.codan.internal.checkers.CommentChecker; +import org.junit.Test; + +/** + * Tests for CommentChecker + */ +public class CommentCheckerLineTests extends CheckerTestCase { + @Override + public void setUp() throws Exception { + super.setUp(); + enableProblems(CommentChecker.COMMENT_NO_LINE); + } + + // void foo() { + // return; // error + // } + @Test + public void testLineComment() { + checkSampleAbove(); + } + + // void foo() { + // return; + // } + @Test + public void testNoLineComment() { + checkSampleAbove(); + } + + // char * foo() { + // return "// this is a string"; + // } + @Test + public void testNoLineCommentInString() { + checkSampleAbove(); + } + + // void foo() { + // return; // not an error in c++ + // } + @Test + public void testLineCommentCpp() { + checkSampleAboveCpp(); + } + + // #define AAA // error even in prepro + @Test + public void testLineCommentInPrepro() { + checkSampleAbove(); + } + + // @file:test.h + // int foo();// error too + + + // @file:test.c + // #include "test.h" + // int bar() { + // foo(); + // } + public void testHeader() throws Exception { + loadcode(getContents(2)); + runOnProject(); + checkErrorLine(new File("test.h"), 1); //$NON-NLS-1$ + } +} diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerNestedTests.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerNestedTests.java new file mode 100644 index 00000000000..a79f59542f9 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/CommentCheckerNestedTests.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2015 QNX Software System 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 + * + * Contributors: + * Elena Laskavaia (QNX Software System) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.codan.core.internal.checkers; + +import org.eclipse.cdt.codan.core.test.CheckerTestCase; +import org.eclipse.cdt.codan.internal.checkers.CommentChecker; +import org.junit.Test; + +/** + * Tests for CommentChecker + */ +public class CommentCheckerNestedTests extends CheckerTestCase { + @Override + public void setUp() throws Exception { + super.setUp(); + enableProblems(CommentChecker.COMMENT_NO_START); + } + + // void foo() { + // return; /* /* */ // error + // } + @Test + public void testLineComment() { + checkSampleAbove(); + } + // void foo() { + // return; /* + // /* // error + // */ + // } + @Test + public void testLineComment2() { + checkSampleAbove(); + } + + // void foo() { + // return; /* */ + // } + @Test + public void testNoLineComment() { + checkSampleAbove(); + } +} diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/AutomatedIntegrationSuite.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/AutomatedIntegrationSuite.java index 560042a5be1..f81759ec482 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/AutomatedIntegrationSuite.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/AutomatedIntegrationSuite.java @@ -21,6 +21,8 @@ import org.eclipse.cdt.codan.core.internal.checkers.AssignmentToItselfCheckerTes import org.eclipse.cdt.codan.core.internal.checkers.CaseBreakCheckerTest; 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.FormatStringCheckerTest; import org.eclipse.cdt.codan.core.internal.checkers.NonVirtualDestructorCheckerTest; import org.eclipse.cdt.codan.core.internal.checkers.ProblemBindingCheckerTest; @@ -70,6 +72,8 @@ public class AutomatedIntegrationSuite extends TestSuite { suite.addTestSuite(SuggestedParenthesisCheckerTest.class); suite.addTestSuite(SuspiciousSemicolonCheckerTest.class); suite.addTestSuite(UnusedSymbolInFileScopeCheckerTest.class); + suite.addTestSuite(CommentCheckerLineTests.class); + suite.addTestSuite(CommentCheckerNestedTests.class); // framework suite.addTest(CodanFastTestSuite.suite()); // quick fixes diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/CheckerTestCase.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/CheckerTestCase.java index 8930712e005..dcec3a34fcf 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/CheckerTestCase.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/CheckerTestCase.java @@ -220,6 +220,10 @@ public class CheckerTestCase extends CodanTestCase { } } + /** + * Enable given problems and disable the rest + * @param ids + */ protected void enableProblems(String... ids) { IProblemProfile profile = CodanRuntime.getInstance().getCheckersRegistry().getWorkspaceProfile(); IProblem[] problems = profile.getProblems(); diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/CodanTestCase.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/CodanTestCase.java index 22107d096e0..6ed1ac28ef3 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/CodanTestCase.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/test/CodanTestCase.java @@ -48,7 +48,7 @@ public class CodanTestCase extends BaseTestCase { protected File currentFile; protected ICElement currentCElem; protected IFile currentIFile; - protected ArrayList errLines= new ArrayList(); + protected ArrayList errLines = new ArrayList(); /** * @@ -99,13 +99,17 @@ public class CodanTestCase extends BaseTestCase { * @throws CoreException */ private void removeLeftOverProjects() throws CoreException { - final IWorkspace workspace = ResourcesPlugin.getWorkspace(); - IProject[] projects = workspace.getRoot().getProjects(); - for (int i = 0; i < projects.length; i++) { - IProject p = projects[i]; - if (p.getName().startsWith("Codan")) { - p.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor()); + try { + final IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IProject[] projects = workspace.getRoot().getProjects(); + for (int i = 0; i < projects.length; i++) { + IProject p = projects[i]; + if (p.getName().startsWith("Codan")) { + p.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor()); + } } + } catch (Throwable e) { + // moving on... } } @@ -175,8 +179,7 @@ public class CodanTestCase extends BaseTestCase { protected StringBuilder[] getContents(int sections) { try { - return TestSourceReader.getContentsForTest(getPlugin().getBundle(), getSourcePrefix(), - getClass(), getName(), sections); + return TestSourceReader.getContentsForTest(getPlugin().getBundle(), getSourcePrefix(), getClass(), getName(), sections); } catch (IOException e) { fail(e.getMessage()); return null; @@ -215,11 +218,6 @@ public class CodanTestCase extends BaseTestCase { return loadcode(code, testFile); } - public File loadcode(String code, String filename) { - File testFile = new File(tmpDir, filename); - return loadcode(code, testFile); - } - private File loadcode(String code, File testFile) { try { tempFiles.add(testFile); @@ -246,14 +244,14 @@ public class CodanTestCase extends BaseTestCase { return null; } } - private static Pattern COMMENT_TAG_PATTERN = Pattern.compile("//\\s*(err|ERR|ERROR|error)\\b"); + private void loadErrorComments(String trim) { String[] lines = trim.split("\n"); for (int i = 0; i < lines.length; i++) { String string = lines[i]; if (COMMENT_TAG_PATTERN.matcher(string).find()) { - errLines.add(i+1); + errLines.add(i + 1); } } } @@ -269,4 +267,12 @@ public class CodanTestCase extends BaseTestCase { public File loadcode(String code) { return loadcode(code, isCpp()); } + + public File loadcode(CharSequence... more) { + File file = null; + for (CharSequence cseq : more) { + file = loadcode(cseq.toString(), isCpp()); + } + return file; + } } \ No newline at end of file