QmlJS checks: Accept 'fallthrough' comment to terminate case blocks.

Change-Id: Icf71416e8aa892089b0918529b94f4cd6a1db5a3
Reviewed-by: Leandro Melo <leandro.melo@nokia.com>
This commit is contained in:
Christian Kamm
2011-11-28 14:58:01 +01:00
parent c00cbcf574
commit a920096c97
3 changed files with 83 additions and 11 deletions

View File

@@ -1086,15 +1086,24 @@ bool Check::visit(DoWhileStatement *ast)
return true;
}
bool Check::visit(CaseClause *ast)
bool Check::visit(CaseBlock *ast)
{
checkEndsWithControlFlow(ast->statements, ast->caseToken);
return true;
}
QList< QPair<SourceLocation, StatementList *> > clauses;
for (CaseClauses *it = ast->clauses; it; it = it->next)
clauses += qMakePair(it->clause->caseToken, it->clause->statements);
if (ast->defaultClause)
clauses += qMakePair(ast->defaultClause->defaultToken, ast->defaultClause->statements);
for (CaseClauses *it = ast->moreClauses; it; it = it->next)
clauses += qMakePair(it->clause->caseToken, it->clause->statements);
bool Check::visit(DefaultClause *ast)
{
checkEndsWithControlFlow(ast->statements, ast->defaultToken);
for (int i = 0; i < clauses.size(); ++i) {
SourceLocation nextToken;
if (i + 1 < clauses.size())
nextToken = clauses[i + 1].first;
else
nextToken = ast->rbraceToken;
checkCaseFallthrough(clauses[i].second, clauses[i].first, nextToken);
}
return true;
}
@@ -1435,13 +1444,35 @@ void Check::checkAssignInCondition(AST::ExpressionNode *condition)
}
}
void Check::checkEndsWithControlFlow(StatementList *statements, SourceLocation errorLoc)
void Check::checkCaseFallthrough(StatementList *statements, SourceLocation errorLoc, SourceLocation nextLoc)
{
if (!statements)
return;
ReachesEndCheck check;
if (check(statements)) {
// check for fallthrough comments
if (nextLoc.isValid()) {
quint32 afterLastStatement = 0;
for (StatementList *it = statements; it; it = it->next) {
if (!it->next)
afterLastStatement = it->statement->lastSourceLocation().end();
}
foreach (const SourceLocation &comment, _doc->engine()->comments()) {
if (comment.begin() < afterLastStatement
|| comment.end() > nextLoc.begin())
continue;
const QString &commentText = _doc->source().mid(comment.begin(), comment.length);
if (commentText.contains(QLatin1String("fall through"))
|| commentText.contains(QLatin1String("fall-through"))
|| commentText.contains(QLatin1String("fallthrough"))) {
return;
}
}
}
addMessage(WarnCaseWithoutFlowControl, errorLoc);
}
}