summaryrefslogtreecommitdiff
path: root/src/libs/qmljs/qmljscheck.cpp
diff options
context:
space:
mode:
authorChristian Kamm <christian.d.kamm@nokia.com>2011-11-28 14:58:01 +0100
committerChristian Kamm <christian.d.kamm@nokia.com>2011-11-29 08:25:51 +0100
commita920096c97e8a4abc3859a4252fe33317305c3f7 (patch)
tree0cb43d7987af560e8a08a060a112e92449c1fb01 /src/libs/qmljs/qmljscheck.cpp
parentc00cbcf5740c37f0a8f8d294c5c8bbf485a96e1a (diff)
downloadqt-creator-a920096c97e8a4abc3859a4252fe33317305c3f7.tar.gz
QmlJS checks: Accept 'fallthrough' comment to terminate case blocks.
Change-Id: Icf71416e8aa892089b0918529b94f4cd6a1db5a3 Reviewed-by: Leandro Melo <leandro.melo@nokia.com>
Diffstat (limited to 'src/libs/qmljs/qmljscheck.cpp')
-rw-r--r--src/libs/qmljs/qmljscheck.cpp49
1 files changed, 40 insertions, 9 deletions
diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp
index 0b5eb1943c..3b1bde0438 100644
--- a/src/libs/qmljs/qmljscheck.cpp
+++ b/src/libs/qmljs/qmljscheck.cpp
@@ -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;
-}
-
-bool Check::visit(DefaultClause *ast)
-{
- checkEndsWithControlFlow(ast->statements, ast->defaultToken);
+ 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);
+
+ 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);
}
}