In unitTest, we have to write the location of the violation which is error prone and not really readable.
I suggest something like:
-- 8< --
#define TAG_START "TAG_START"
#define TAG_END "TAG_END"
void ComputeLocalisation(const std::string& s, size_t offset,
int* line, int* column)
{
int c = 1;
int l = 1;
for (size_t i = 0; i != offset; ++i) {
if (s[i] == '\n') {
c = 1;
++l;
} else {
++c;
}
}
*line = l;
*column = c;
}
void testRuleOnCXXCodeWithViolation(RuleBase* rule, std::string code,
const std::string& message = "")
{
const size_t startOffset = code.find(TAG_START);
assert(startOffset != std::string::npos);
code.erase(startOffset, strlen(TAG_START));
const size_t endOffset = code.find(TAG_END, startOffset);
assert(endOffset != std::string::npos);
code.erase(endOffset, strlen(TAG_END));
int startLine;
int startColumn;
int endLine;
int endColumn;
ComputeLocalisation(code, startOffset, &startLine, &startColumn);
ComputeLocalisation(code, endOffset, &endLine, &endColumn);
testRuleOnCXXCode(rule, code, 0, startLine, startColumn, endLine, endColumn, message);
}
------- >8 -------
And so the TestCode will be something like
-- 8< --
testRuleOnCXXCodeWithViolation(new DeleteNullptrIsSafeRule(),
"void m(char* pointer) { " TAG_START "if (pointer) delete " TAG_END "pointer; }");
-- >8 --
instead of
-- 8< --
testRuleOnCXXCode(new DeleteNullptrIsSafeRule(),
// 1 2 3
// 123456789012345678901234567890123456
"void m(char* pointer) { if (pointer) delete pointer; }", 0, 1, 19, 1, 33);
-- >8 --
I know, TAG_END seems miss placed, but this is really visible in the 1st example,
not in the second (and worst without the comment).
clang seems to have a bug with ifStmt->getEndLoc() (or with the delete Stmt, not investigated).