1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 329497 - checker for no break at the end of case

This commit is contained in:
Alena Laskavaia 2010-12-01 02:36:00 +00:00
parent acfb30df58
commit 83ea511e24
9 changed files with 800 additions and 5 deletions

View file

@ -56,4 +56,7 @@ problem.description.ReturnStyle = Checks for return statements that do no return
checker.name.SuspiciousSemicolon = Suspicious semicolon
problem.name.SuspiciousSemicolon = Suspicious semicolon
problem.messagePattern.SuspiciousSemicolon = Suspicious semicolon
problem.description.SuspiciousSemicolon = A semicolon is used as a null statement in a condition. For example, 'if(expression);'
problem.description.SuspiciousSemicolon = A semicolon is used as a null statement in a condition. For example, 'if(expression);'
checker.name.CaseBreak = No break at end of case
problem.description.CaseBreak = Looks for "case" statements which end without a "break" statement statement statement
problem.messagePattern.CaseBreak = No break at the end of this case

View file

@ -306,5 +306,19 @@
name="%problem.name.SuspiciousSemicolon">
</problem>
</checker>
<checker
class="org.eclipse.cdt.codan.internal.checkers.CaseBreakChecker"
id="org.eclipse.cdt.codan.internal.checkers.CaseBreak"
name="%checker.name.CaseBreak">
<problem
category="org.eclipse.cdt.codan.core.categories.ProgrammingProblems"
defaultEnabled="true"
defaultSeverity="Warning"
description="%problem.description.CaseBreak"
id="org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem"
messagePattern="%problem.messagePattern.CaseBreak"
name="%checker.name.CaseBreak">
</problem>
</checker>
</extension>
</plugin>

View file

@ -0,0 +1,306 @@
/*******************************************************************************
* Copyright (c) 2010 Gil Barash
* 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:
* Gil Barash - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.codan.internal.checkers;
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;
import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTContinueStatement;
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
public class CaseBreakChecker extends AbstractIndexAstChecker implements
ICheckerWithPreferences {
public static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem"; //$NON-NLS-1$
public static final String PARAM_LAST_CASE = "last_case_param"; //$NON-NLS-1$
public static final String PARAM_EMPTY_CASE = "empty_case_param"; //$NON-NLS-1$
public static final String PARAM_NO_BREAK_COMMENT = "no_break_comment"; //$NON-NLS-1$
public static final String DEFAULT_NO_BREAK_COMMENT = "no break"; //$NON-NLS-1$
private CommentsIterator _commentsIt; // Iterator over comments
private Boolean _checkLastCase; // Should we check the last case in the switch?
private Boolean _checkEmptyCase; // Should we check an empty case (a case without any statements within it)
private String _noBreakComment; // The comment suppressing this warning
/**
* This class receives the comments of the AST and iterates over them
*/
class CommentsIterator {
private int _next; // The next comment's index
private IASTComment[] _comments;
CommentsIterator(IASTComment[] comments) {
_comments = comments;
_next = 0;
}
/**
* @return Is there an unvisited comment?
*/
public boolean hasNext() {
return (_next < _comments.length);
}
/**
* @return The next comment (doesn't automatically advance to the next
* comment.
* i.e. Calling this function twice may return the same value).
* See {@link#advance}
*/
public IASTComment getNext() {
return (_comments[_next]);
}
/**
* @param node The node to compare the comment's location to
* @return Is the next comment located after 'node'
*/
public boolean isNextAfterThis(IASTNode node) {
return (_comments[_next].getFileLocation().getNodeOffset() > node
.getFileLocation().getNodeOffset());
}
/**
* @param node The node to compare the comment's location to
* @return Is the next comment located after 'node' ends
*/
public boolean isNextAfterThisEnds(IASTNode node) {
return (_comments[_next].getFileLocation().getNodeOffset() > node
.getFileLocation().getNodeOffset()
+ node.getFileLocation().getNodeLength());
}
/**
* Advance to the next comment
*/
public void advance() {
_next++;
}
}
/**
* This visitor looks for "switch" statements and invokes "SwitchVisitor" on
* them
*/
class SwitchFindingVisitor extends ASTVisitor {
protected IASTStatement _switchStatement; // The "switch" we're visiting (used by inheriting classes to avoid re-visiting the same "switch" again)
SwitchFindingVisitor() {
shouldVisitStatements = true;
_switchStatement = null;
}
@Override
public int visit(IASTStatement statement) {
if (statement instanceof IASTSwitchStatement) {
// Are we already visiting this statement?
if (_switchStatement == null
|| !statement.equals(_switchStatement)) {
SwitchVisitor switch_visitor = new SwitchVisitor(statement);
statement.accept(switch_visitor);
return PROCESS_SKIP;
}
}
return PROCESS_CONTINUE;
}
}
/**
* This visitor visits a switch statement and checks the end of each
* "case" statement (to see that it ends with a "break").
* Because it extends SwitchFindingVisitor is would also check nested
* "switch"s
*/
class SwitchVisitor extends SwitchFindingVisitor {
private IASTStatement _last_case_stmnt;
private boolean _first_case_statement;
private int _last_break_stmnt_offset;
private int _last_normal_stmnt_offset;
private int _last_case_stmnt_offset;
SwitchVisitor(IASTStatement switch_statement) {
shouldVisitStatements = true;
_first_case_statement = true;
_switchStatement = switch_statement;
_last_break_stmnt_offset = 0;
_last_normal_stmnt_offset = 0;
_last_case_stmnt_offset = 0;
_last_case_stmnt = null;
}
/**
* @return Is this an "empty" case (i.e. with no statements in it)
*/
private boolean isEmptyCase() {
return _last_case_stmnt_offset > _last_normal_stmnt_offset;
}
/**
* @return Was a "break" statement the last statement in this case
*/
private boolean breakFoundLast() {
return _last_normal_stmnt_offset < _last_break_stmnt_offset
&& _last_case_stmnt_offset < _last_break_stmnt_offset;
}
/**
* Check the last case we've visited
*
* @param comment The comment ending this case (may be NULL)
*/
private void checkLastCase(IASTComment comment) {
if (comment != null) {
String str = new String(comment.getComment());
if (comment.isBlockComment())
str = str.substring(2, str.length() - 2);
else
str = str.substring(2);
str = str.trim();
if (str.equalsIgnoreCase(_noBreakComment))
return;
}
if (_last_case_stmnt == null)
return; // This is an empty switch
if (breakFoundLast())
return; // There was a "break" before the current statement
if (!isEmptyCase() || _checkEmptyCase) {
reportProblem(ER_ID, _last_case_stmnt, (Object) null);
}
}
@Override
public int visit(IASTStatement statement) {
if (statement instanceof IASTCaseStatement
|| statement instanceof IASTDefaultStatement) {
if (_first_case_statement) {
/*
* This is the first "case", i.e. the beginning of the
* "switch"
*/
_first_case_statement = false;
} else {
/*
* This is not the 1st "case", meaning that a previous case
* has just ended,
* Let's check that case and see how it ended...
*/
IASTComment comment = null;
// Do we have a comment which is before this "case" statement (but after the previous statement)?
while (_commentsIt.hasNext()
&& !_commentsIt.isNextAfterThis(statement)) {
comment = _commentsIt.getNext();
_commentsIt.advance();
}
/*
* 'comment' is the last comment found in this case (after
* the last statement in this "case"
*/
checkLastCase(comment);
}
/* Update variables with the new opened "case" */
_last_case_stmnt_offset = statement.getFileLocation()
.getNodeOffset();
_last_case_stmnt = statement;
} else if (isBreakOrExitStatement(statement)) { // A "break" statement
_last_break_stmnt_offset = statement.getFileLocation()
.getNodeOffset();
} else { // a non-switch related statement
_last_normal_stmnt_offset = statement.getFileLocation()
.getNodeOffset();
}
/* advance comments we already passed */
while (_commentsIt.hasNext()
&& !_commentsIt.isNextAfterThis(statement))
_commentsIt.advance();
return super.visit(statement); // This would handle nested "switch"s
}
@Override
public int leave(IASTStatement statement) {
/*
* Are we leaving the "switch" altogether? (we need to see how the
* last "case" ended)
*/
if (_checkLastCase && statement instanceof IASTCompoundStatement
&& statement.getParent() == _switchStatement) {
IASTComment comment = null;
// is "Next" still in the switch's scope? if it is it was after the last statement
while (_commentsIt.hasNext()
&& !_commentsIt.isNextAfterThisEnds(statement)) {
comment = _commentsIt.getNext();
_commentsIt.advance();
}
/*
* 'comment' is the last comment found in this case (after the
* last statement in this "case"
*/
checkLastCase(comment);
}
return super.leave(statement);
}
}
/************************************************
* This class's functions...
************************************************/
public CaseBreakChecker() {
}
/**
* @param statement
* @return
*/
public boolean isBreakOrExitStatement(IASTStatement statement) {
CxxAstUtils utils = CxxAstUtils.getInstance();
return statement instanceof IASTBreakStatement
|| statement instanceof IASTReturnStatement
|| statement instanceof IASTContinueStatement
|| statement instanceof IASTGotoStatement
|| utils.isThrowStatement(statement) || utils.isExitStatement(statement);
}
public void initPreferences(IProblemWorkingCopy problem) {
super.initPreferences(problem);
addPreference(
problem,
PARAM_NO_BREAK_COMMENT,
CheckersMessages.CaseBreakChecker_DefaultNoBreakCommentDescription,
DEFAULT_NO_BREAK_COMMENT);
addPreference(problem, PARAM_EMPTY_CASE,
CheckersMessages.CaseBreakChecker_EmptyCaseDescription,
Boolean.TRUE);
addPreference(problem, PARAM_LAST_CASE,
CheckersMessages.CaseBreakChecker_LastCaseDescription,
Boolean.TRUE);
}
public void processAst(IASTTranslationUnit ast) {
_checkLastCase = (Boolean) getPreference(
getProblemById(ER_ID, getFile()), PARAM_LAST_CASE);
_checkEmptyCase = (Boolean) getPreference(
getProblemById(ER_ID, getFile()), PARAM_EMPTY_CASE);
_noBreakComment = (String) getPreference(
getProblemById(ER_ID, getFile()), PARAM_NO_BREAK_COMMENT);
SwitchFindingVisitor visitor = new SwitchFindingVisitor();
_commentsIt = new CommentsIterator(ast.getComments());
ast.accept(visitor);
}
}

View file

@ -17,6 +17,9 @@ import org.eclipse.osgi.util.NLS;
*/
public class CheckersMessages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.codan.internal.checkers.messages"; //$NON-NLS-1$
public static String CaseBreakChecker_DefaultNoBreakCommentDescription;
public static String CaseBreakChecker_EmptyCaseDescription;
public static String CaseBreakChecker_LastCaseDescription;
public static String CatchByReference_ReportForUnknownType;
public static String NamingConventionFunctionChecker_LabelNamePattern;
public static String ReturnChecker_Param0;

View file

@ -8,6 +8,9 @@
# Contributors:
# Alena Laskavaia - initial API and implementation
###############################################################################
CaseBreakChecker_DefaultNoBreakCommentDescription=Comment text to suppress the problem (regular expression):
CaseBreakChecker_EmptyCaseDescription=Check also empty case statement
CaseBreakChecker_LastCaseDescription=Check also the last case statement
CatchByReference_ReportForUnknownType=Report a problem if type cannot be resolved
NamingConventionFunctionChecker_LabelNamePattern=Name Pattern
ReturnChecker_Param0=Also check functions with implicit return value

View file

@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
@ -35,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunction;
@ -408,4 +410,30 @@ public final class CxxAstUtils {
});
return returnSpecifier[0];
}
/**
* @param body
* @return
*/
public boolean isThrowStatement(IASTNode body) {
if (!(body instanceof IASTExpressionStatement))
return false;
IASTExpression expression = ((IASTExpressionStatement) body)
.getExpression();
if (!(expression instanceof IASTUnaryExpression))
return false;
return ((IASTUnaryExpression) expression).getOperator() == IASTUnaryExpression.op_throw;
}
public boolean isExitStatement(IASTNode body) {
if (!(body instanceof IASTExpressionStatement))
return false;
IASTExpression expression = ((IASTExpressionStatement) body)
.getExpression();
if (!(expression instanceof IASTFunctionCallExpression))
return false;
IASTExpression functionNameExpression = ((IASTFunctionCallExpression) expression)
.getFunctionNameExpression();
return functionNameExpression.getRawSignature().equals("exit"); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,429 @@
/*******************************************************************************
* Copyright (c) 2010 Gil Barash
* 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:
* Gil Barash - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.codan.core.internal.checkers;
import org.eclipse.cdt.codan.core.param.IProblemPreference;
import org.eclipse.cdt.codan.core.test.CheckerTestCase;
import org.eclipse.cdt.codan.internal.checkers.CaseBreakChecker;
/**
* Test for {@link#CaseBreakChecker} class
*/
public class CaseBreakCheckerTest extends CheckerTestCase {
// void foo(void) {
// int a;
// switch( a ) {
// case 1:
// }
// }
public void testEmptyLastCaseBad() {
loadCodeAndRun(getAboveComment());
checkErrorLines(4);
}
// void foo(void) {
// int a;
// switch( a ) {
// default:
// }
// }
public void testEmptyLastCaseDefaultBad() {
loadCodeAndRun(getAboveComment());
checkErrorLines(4);
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// b = 2;
// }
// }
public void testLastCaseBad() {
loadCodeAndRun(getAboveComment());
checkErrorLines(4);
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// case 2:
// b = 2;
// break;
// }
// }
public void testEmptyCaseBad() {
loadCodeAndRun(getAboveComment());
checkErrorLines(4);
}
// void foo(void) {
// int a;
// switch( a ) {
// case 1:
// break;
// }
// }
public void testEmptyLastCaseOKbreak() {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
// void foo(void) {
// int a;
// switch( a ) {
// case 1:
// return;
// }
// }
public void testEmptyLastCaseWithReturn() {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
// void foo(int a) {
// while (a--)
// switch( a ) {
// case 1:
// continue;
// }
// }
public void testEmptyLastCaseWithContinue() {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
// void foo(int a) {
//
// switch( a ) {
// case 1:
// throw 1;
// }
// }
public void testEmptyLastCaseWithThrow() {
loadCodeAndRunCpp(getAboveComment());
checkNoErrors();
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// b = 2;
// break;
// }
// }
public void testLastCaseOKbreak() {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// break;
// case 2:
// b = 2;
// break;
// }
// }
public void testEmptyCaseOKbreak() {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
// void foo(void) {
// int a;
// switch( a ) {
// case 1:
// /* no break */
// }
// }
public void testEmptyLastCaseOKcomment() {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
// void foo(int a, int b) {
// switch( a ) {
// case 1:
// switch (b) {
// case 2:
// break;
// }
// case 2:
// break;
// }
// }
public void testEmptyLastCaseTwoSwitches() {
loadCodeAndRun(getAboveComment());
checkErrorLines(3);
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// b = 2;
// /* no break */
// }
// }
public void testLastCaseOKcomment() {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// /* no break */
// case 2:
// b = 2;
// break;
// }
public void testEmptyCaseOKcomment() {
loadCodeAndRun(getAboveComment());
checkNoErrors();
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// b = 2;
// /* no break */
// bye();
// }
// }
public void testLastCaseBadCommentNotLast() {
loadCodeAndRun(getAboveComment());
checkErrorLines(4);
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// b = 2;
// /* no break */
// case 2:
// b = 2;
// /*no break*/
// case 3:
// b = 2;
// //no break
// case 4:
// b = 2;
// // no break
// case 5:
// b = 2;
// /* no brea */
// case 6:
// b = 2;
// /* no break1 */
// }
// }
public void testDifferentComments() {
loadCodeAndRun(getAboveComment());
checkErrorLines(16, 19);
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// // lolo
// case 2:
// case 3:
// }
//
// switch( a ) {
// case 1:
// b = 2;
// // lolo
// case 2:
// b = 2;
// case 3:
// case 4:
// break;
// case 5:
// case 6:
// }
//
// switch( a ) {
// case 1:
// b = 2;
// // lolo
// case 2:
// b = 2;
// case 3:
// b = 2;
// /* no break */
// case 4:
// b = 2;
// case 5:
// b = 2;
// break;
// case 6:
// b = 2;
// /* no break */
// b = 2;
// case 7:
// b = 2;
// }
//
// switch( a ) {
// case 1:
// b = 2;
// // lolo
// case 2:
// b = 2;
// default:
// }
// }
public void testGeneral1() {
loadCodeAndRun(getAboveComment());
checkErrorLines(4, 6, 7, 11, 14, 16, 19, 20, 24, 27, 32, 37, 41, 46,
49, 51);
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// b = 2;
// // lolo
// /* no break */
// case 2:
// b = 2;
// /* no break */
// // lolo
// case 3:
// /* no break */
// b = 2;
// // loo
// case 4:
// b = 2;
// // lolo
// /* no break */
// case 5:
// // lolo
// b = 2;
// /* no break */
// }
// }
public void testGeneralComments1() {
loadCodeAndRun(getAboveComment());
checkErrorLines(8, 12);
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 0:
// switch( b ) {
// case 2:
// }
//
// case 1:
// switch( b ) {
// case 2:
// break;
// }
// case 3:
// switch( b ) {
// case 2:
// break;
// }
// break;
// case 4:
// switch( b ) {
// case 2:
// /* no break */
// }
// case 5:
// switch( b ) {
// case 2:
// }
// /* no break */
// }
// }
public void testNestedSwitches() {
loadCodeAndRun(getAboveComment());
checkErrorLines(4, 6, 9, 20, 27);
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// b = 2;
// }
// }
public void testLastCaseIgnore() {
setLast(false);
loadCodeAndRun(getAboveComment());
checkNoErrors();
setLast(true);
}
// void foo(void) {
// int a, b;
// switch( a ) {
// case 1:
// case 2:
// b = 2;
// break;
// case 3: case 4:
// b = 2;
// break;
// }
// }
public void testEmptyCaseIgnore() {
setEmpty(false);
loadCodeAndRun(getAboveComment());
checkNoErrors();
setEmpty(true);
}
// void foo(void) {
// int a;
// switch( a ) {
// case 1:
// }
// }
public void testEmptyLastCaseIgnore() {
String code = getAboveComment();
setLast(false);
loadCodeAndRun(code);
checkNoErrors();
setLast(true);
setEmpty(false);
loadCodeAndRun(code);
checkNoErrors();
setEmpty(true);
}
private void setLast(boolean val) {
IProblemPreference pref = getPreference(CaseBreakChecker.ER_ID,
CaseBreakChecker.PARAM_LAST_CASE);
pref.setValue(val);
}
private void setEmpty(boolean val) {
IProblemPreference pref = getPreference(CaseBreakChecker.ER_ID,
CaseBreakChecker.PARAM_EMPTY_CASE);
pref.setValue(val);
}
}

View file

@ -16,6 +16,7 @@ import junit.framework.TestSuite;
import org.eclipse.cdt.codan.core.internal.checkers.AssignmentInConditionCheckerTest;
import org.eclipse.cdt.codan.core.internal.checkers.AssignmentToItselfCheckerTest;
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.ReturnCheckerTest;
import org.eclipse.cdt.codan.core.internal.checkers.ReturnStyleCheckerTest;
@ -51,6 +52,7 @@ public class AutomatedIntegrationSuite extends TestSuite {
suite.addTestSuite(AssignmentToItselfCheckerTest.class);
suite.addTestSuite(ReturnStyleCheckerTest.class);
suite.addTestSuite(SuspiciousSemicolonCheckerTest.class);
suite.addTestSuite(CaseBreakCheckerTest.class);
// framework
suite.addTest(CodanFastTestSuite.suite());
// quick fixes

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2010 Alena Laskavaia
* Copyright (c) 2009, 2010 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
@ -27,7 +27,7 @@ import org.eclipse.core.runtime.NullProgressMonitor;
/**
* @author Alena
*
*
*/
public class CheckerTestCase extends CodanTestCase {
protected IMarker[] markers;
@ -36,6 +36,13 @@ public class CheckerTestCase extends CodanTestCase {
return checkErrorLine(currentFile, i);
}
public void checkErrorLines( Object... args ) {
for( Object i : args ) {
checkErrorLine((Integer) i);
}
assertEquals(args.length, markers.length);
}
public IMarker checkErrorLine(int i, String problemId) {
return checkErrorLine(currentFile, i, problemId);
}
@ -95,7 +102,7 @@ public class CheckerTestCase extends CodanTestCase {
}
/**
*
*
*/
public void runOnProject() {
try {
@ -117,7 +124,7 @@ public class CheckerTestCase extends CodanTestCase {
}
/**
*
*
*/
protected void runCodan() {
CodanRuntime