diff options
author | Roberto Raggi <roberto.raggi@nokia.com> | 2011-11-28 09:37:03 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-11-29 10:12:44 +0100 |
commit | 7c83628f5e594cc91f4e3bfde32d0062f85d5ec4 (patch) | |
tree | d43242b7646f603e506c872f850118c387dedfe9 /src | |
parent | 328d1d2fd6cba7368230a1232e080d3f3310a7f1 (diff) |
Fix the evaluation of JS switch statements in QML bindings.
Task-number: QTBUG-17012
Change-Id: Ic132cf63ed08592fec9c759df1b8b4d5830acea6
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/declarative/qml/qdeclarativerewrite.cpp | 54 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativerewrite_p.h | 3 |
2 files changed, 57 insertions, 0 deletions
diff --git a/src/declarative/qml/qdeclarativerewrite.cpp b/src/declarative/qml/qdeclarativerewrite.cpp index dab7c3d7e0..9db83f04b6 100644 --- a/src/declarative/qml/qdeclarativerewrite.cpp +++ b/src/declarative/qml/qdeclarativerewrite.cpp @@ -266,6 +266,60 @@ void RewriteBinding::endVisit(AST::LocalForEachStatement *) --_inLoop; } +bool RewriteBinding::visit(AST::CaseBlock *ast) +{ + // Process the initial sequence of the case clauses. + for (AST::CaseClauses *it = ast->clauses; it; it = it->next) { + // Return the value of the last statement in the block, if this is the last `case clause' + // of the switch statement. + bool returnTheValueOfLastStatement = (it->next == 0) && (ast->defaultClause == 0) && (ast->moreClauses == 0); + + if (AST::CaseClause *clause = it->clause) { + accept(clause->expression); + rewriteCaseStatements(clause->statements, returnTheValueOfLastStatement); + } + } + + // Process the default case clause + if (ast->defaultClause) { + // Return the value of the last statement in the block, if this is the last `case clause' + // of the switch statement. + bool rewriteTheLastStatement = (ast->moreClauses == 0); + + rewriteCaseStatements(ast->defaultClause->statements, rewriteTheLastStatement); + } + + // Process trailing `case clauses' + for (AST::CaseClauses *it = ast->moreClauses; it; it = it->next) { + // Return the value of the last statement in the block, if this is the last `case clause' + // of the switch statement. + bool returnTheValueOfLastStatement = (it->next == 0); + + if (AST::CaseClause *clause = it->clause) { + accept(clause->expression); + rewriteCaseStatements(clause->statements, returnTheValueOfLastStatement); + } + } + + return false; +} + +void RewriteBinding::rewriteCaseStatements(AST::StatementList *statements, bool rewriteTheLastStatement) +{ + for (AST::StatementList *it = statements; it; it = it->next) { + if (it->next && AST::cast<AST::BreakStatement *>(it->next->statement) != 0) { + // The value of the first statement followed by a `break'. + accept(it->statement); + break; + } else if (!it->next) { + if (rewriteTheLastStatement) + accept(it->statement); + else if (AST::Block *block = AST::cast<AST::Block *>(it->statement)) + rewriteCaseStatements(block->statements, rewriteTheLastStatement); + } + } +} + QString RewriteSignalHandler::operator()(const QString &code, const QString &name) { return QStringLiteral("(function ") + name + QStringLiteral("() { ") + code + QStringLiteral(" })"); diff --git a/src/declarative/qml/qdeclarativerewrite_p.h b/src/declarative/qml/qdeclarativerewrite_p.h index b5ea44f23f..8ce2ba7bc7 100644 --- a/src/declarative/qml/qdeclarativerewrite_p.h +++ b/src/declarative/qml/qdeclarativerewrite_p.h @@ -93,6 +93,7 @@ protected: void accept(AST::Node *node); QString rewrite(QString code, unsigned position, AST::Statement *node); + void rewriteCaseStatements(AST::StatementList *statements, bool rewriteTheLastStatement); virtual bool visit(AST::Block *ast); virtual bool visit(AST::ExpressionStatement *ast); @@ -115,6 +116,8 @@ protected: virtual bool visit(AST::LocalForEachStatement *ast); virtual void endVisit(AST::LocalForEachStatement *ast); + virtual bool visit(AST::CaseBlock *ast); + private: int _inLoop; }; |