1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

Bug 350144 - suppressing the "No break" problem with regexp

added regex support for suppression comment

Change-Id: I590d171fcce23d547a489e42a791aa484963d4a6
Signed-off-by: Alena Laskavaia <elaskavaia.cdt@gmail.com>
This commit is contained in:
Alena Laskavaia 2017-12-26 14:51:50 -05:00
parent 89ec7fe8b8
commit ce18aad766
3 changed files with 58 additions and 3 deletions

View file

@ -12,6 +12,10 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.codan.internal.checkers; 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.CxxAstUtils;
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker; import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
import org.eclipse.cdt.codan.core.model.ICheckerWithPreferences; 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 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 boolean fCheckEmptyCase; // Should we check an empty case (a case without any statements within it)
private String fNoBreakComment; // The comment suppressing this warning 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 { class SwitchFindingVisitor extends ASTVisitor {
SwitchFindingVisitor() { SwitchFindingVisitor() {
@ -129,9 +135,14 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
comment = getFreestandingComment(body); comment = getFreestandingComment(body);
} }
if (comment != null) { if (comment != null) {
// for backward compatibility leave original rule of checking string as non-regex
String str = getTrimmedComment(comment); String str = getTrimmedComment(comment);
if (str.toLowerCase().contains(fNoBreakComment.toLowerCase())) if (str.toLowerCase().contains(fNoBreakComment.toLowerCase()))
continue; continue;
if (fNoBreakRegex != null && fNoBreakRegex.matcher(str).find()) {
continue;
}
} }
reportProblem(curr); reportProblem(curr);
} }
@ -261,7 +272,8 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
DEFAULT_NO_BREAK_COMMENT); DEFAULT_NO_BREAK_COMMENT);
addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.FALSE); addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.FALSE);
addPreference(problem, PARAM_EMPTY_CASE, CheckersMessages.CaseBreakChecker_EmptyCaseDescription, 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 @Override
@ -269,6 +281,13 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements IChecke
fCheckLastCase = (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_LAST_CASE); fCheckLastCase = (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_LAST_CASE);
fCheckEmptyCase = (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_EMPTY_CASE); fCheckEmptyCase = (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_EMPTY_CASE);
fNoBreakComment = (String) getPreference(getProblemById(ER_ID, getFile()), PARAM_NO_BREAK_COMMENT); 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(); SwitchFindingVisitor visitor = new SwitchFindingVisitor();
ast.accept(visitor); ast.accept(visitor);
} }

View file

@ -8,7 +8,7 @@
# Contributors: # Contributors:
# Alena Laskavaia - initial API and implementation # 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_EmptyCaseDescription=Check also empty 'case' statement (except if last)
CaseBreakChecker_LastCaseDescription=Check also the last 'case' statement CaseBreakChecker_LastCaseDescription=Check also the last 'case' statement
CaseBreakChecker_EnableFallthroughQuickfixDescription=Enable quick fix to add fallthrough attribute (C++17) CaseBreakChecker_EnableFallthroughQuickfixDescription=Enable quick fix to add fallthrough attribute (C++17)

View file

@ -627,6 +627,11 @@ public class CaseBreakCheckerTest extends CheckerTestCase {
pref.setValue(val); 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) { // void foo(int a) {
// switch (a) { // switch (a) {
// case 1: // case 1:
@ -765,4 +770,35 @@ public class CaseBreakCheckerTest extends CheckerTestCase {
loadCodeAndRun(code); loadCodeAndRun(code);
checkNoErrorsOfKind(ER_ID); 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);
}
} }