From ce18aad766e9a947679a3daf33966bba75406fdf Mon Sep 17 00:00:00 2001 From: Alena Laskavaia Date: Tue, 26 Dec 2017 14:51:50 -0500 Subject: [PATCH] Bug 350144 - suppressing the "No break" problem with regexp added regex support for suppression comment Change-Id: I590d171fcce23d547a489e42a791aa484963d4a6 Signed-off-by: Alena Laskavaia --- .../internal/checkers/CaseBreakChecker.java | 23 ++++++++++-- .../checkers/CheckersMessages.properties | 2 +- .../checkers/CaseBreakCheckerTest.java | 36 +++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java index c87a33737d9..6639afaf65d 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/CaseBreakChecker.java @@ -12,6 +12,10 @@ *******************************************************************************/ 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.CxxAstUtils; import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker; import org.eclipse.cdt.codan.core.model.ICheckerWithPreferences; @@ -50,9 +54,11 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke private boolean fCheckLastCase; // Should we check the last case in the switch? private boolean fCheckEmptyCase; // Should we check an empty case (a case without any statements within it) private String fNoBreakComment; // The comment suppressing this warning + private Pattern fNoBreakRegex; /** - * This visitor looks for "switch" statements and invokes "SwitchVisitor" on them. + * This visitor looks for "switch" statements and invokes "SwitchVisitor" on + * them. */ class SwitchFindingVisitor extends ASTVisitor { SwitchFindingVisitor() { @@ -129,9 +135,14 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke comment = getFreestandingComment(body); } if (comment != null) { + // for backward compatibility leave original rule of checking string as non-regex String str = getTrimmedComment(comment); if (str.toLowerCase().contains(fNoBreakComment.toLowerCase())) continue; + + if (fNoBreakRegex != null && fNoBreakRegex.matcher(str).find()) { + continue; + } } reportProblem(curr); } @@ -261,7 +272,8 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke DEFAULT_NO_BREAK_COMMENT); addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.FALSE); addPreference(problem, PARAM_EMPTY_CASE, CheckersMessages.CaseBreakChecker_EmptyCaseDescription, Boolean.FALSE); - addPreference(problem, PARAM_ENABLE_FALLTHROUGH_QUICKFIX, CheckersMessages.CaseBreakChecker_EnableFallthroughQuickfixDescription, Boolean.FALSE); + addPreference(problem, PARAM_ENABLE_FALLTHROUGH_QUICKFIX, CheckersMessages.CaseBreakChecker_EnableFallthroughQuickfixDescription, + Boolean.FALSE); } @Override @@ -269,6 +281,13 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke fCheckLastCase = (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_LAST_CASE); fCheckEmptyCase = (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_EMPTY_CASE); fNoBreakComment = (String) getPreference(getProblemById(ER_ID, getFile()), PARAM_NO_BREAK_COMMENT); + try { + if (fNoBreakComment != null) + fNoBreakRegex = Pattern.compile(fNoBreakComment, Pattern.CASE_INSENSITIVE); + } catch (PatternSyntaxException e) { + CodanCheckersActivator.log(e); + fNoBreakRegex = null; + } SwitchFindingVisitor visitor = new SwitchFindingVisitor(); ast.accept(visitor); } 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 d76c6c75a29..a86c5151c82 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 @@ -8,7 +8,7 @@ # Contributors: # Alena Laskavaia - initial API and implementation ############################################################################### -CaseBreakChecker_DefaultNoBreakCommentDescription=Comment text to suppress the problem: +CaseBreakChecker_DefaultNoBreakCommentDescription=Comment text to suppress the problem (or regular expression): CaseBreakChecker_EmptyCaseDescription=Check also empty 'case' statement (except if last) CaseBreakChecker_LastCaseDescription=Check also the last 'case' statement CaseBreakChecker_EnableFallthroughQuickfixDescription=Enable quick fix to add fallthrough attribute (C++17) diff --git a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java index b8c5e878d62..e343c21372a 100644 --- a/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.tests/src/org/eclipse/cdt/codan/core/internal/checkers/CaseBreakCheckerTest.java @@ -627,6 +627,11 @@ public class CaseBreakCheckerTest extends CheckerTestCase { pref.setValue(val); } + private void setComment(String str) { + IProblemPreference pref = getPreference(CaseBreakChecker.ER_ID, CaseBreakChecker.PARAM_NO_BREAK_COMMENT); + pref.setValue(str); + } + // void foo(int a) { // switch (a) { // case 1: @@ -765,4 +770,35 @@ public class CaseBreakCheckerTest extends CheckerTestCase { loadCodeAndRun(code); checkNoErrorsOfKind(ER_ID); } + + // void foo(void) { + // int a, b; + // switch (a) { + // case 1: + // b = 2; + // // lolo + // /* fallthru */ + // case 2: + // b = 2; + // /* falls thru */ + // // lolo + // case 3: + // /* no break */ + // b = 2; + // // loo + // case 4: + // b = 2; + // // lolo + // /* fallthrough */ + // case 5: + // // lolo + // b = 2; + // /* fall-thru */ + // } + // } + public void testCommentsParam() throws Exception { + setComment("fall(s)?[ \\t-]*thr(ough|u)"); + loadCodeAndRun(getAboveComment()); + checkErrorLines(9, 14); + } }