diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-08-16 15:26:40 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-08-24 08:12:47 +0000 |
commit | c907eb1b5bfc22ffcee1cc37ecfa762d7a3edd0a (patch) | |
tree | b35cdebde92a7a8e32a6b62e94fa722142227131 /src/qml/compiler | |
parent | 45ea8df187d5dbe2776d793752d1eb3bf34b8fb3 (diff) |
Fix use of function expressions with signal handlers
Writing
onClicked: function(mouseEvent) { ... }
would get silently "accepted" by the engine, but it wouldn't do anything. We
basically wrapped it in a new function, so that it became
onClicked: function(mouse){ function(mouseEvent() {} }
which is a noop. With older versions this used to produce a syntax error.
However the better fix is to simply support this kind of assignment for more
expressive signal handlers, because now the names of the signal parameters can
be explicitly named (with names of your choice).
Change-Id: I96369f8805fab97509784222f614ee17cf681aba
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Reviewed-by: Michael Brasser <michael.brasser@live.com>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 80aa617c53..c02b91f300 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -1046,16 +1046,29 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio paramList = paramList->finish(); QmlIR::CompiledFunctionOrExpression *foe = obj->functionsAndExpressions->slowAt(binding->value.compiledScriptIndex); - QQmlJS::AST::Statement *statement = static_cast<QQmlJS::AST::Statement*>(foe->node); - QQmlJS::AST::SourceElement *sourceElement = new (pool) QQmlJS::AST::StatementSourceElement(statement); - QQmlJS::AST::SourceElements *elements = new (pool) QQmlJS::AST::SourceElements(sourceElement); - elements = elements->finish(); - - QQmlJS::AST::FunctionBody *body = new (pool) QQmlJS::AST::FunctionBody(elements); + QQmlJS::AST::FunctionDeclaration *functionDeclaration = 0; + if (QQmlJS::AST::ExpressionStatement *es = QQmlJS::AST::cast<QQmlJS::AST::ExpressionStatement*>(foe->node)) { + if (QQmlJS::AST::FunctionExpression *fe = QQmlJS::AST::cast<QQmlJS::AST::FunctionExpression*>(es->expression)) { + functionDeclaration = new (pool) QQmlJS::AST::FunctionDeclaration(fe->name, fe->formals, fe->body); + functionDeclaration->functionToken = fe->functionToken; + functionDeclaration->identifierToken = fe->identifierToken; + functionDeclaration->lparenToken = fe->lparenToken; + functionDeclaration->rparenToken = fe->rparenToken; + functionDeclaration->lbraceToken = fe->lbraceToken; + functionDeclaration->rbraceToken = fe->rbraceToken; + } + } + if (!functionDeclaration) { + QQmlJS::AST::Statement *statement = static_cast<QQmlJS::AST::Statement*>(foe->node); + QQmlJS::AST::SourceElement *sourceElement = new (pool) QQmlJS::AST::StatementSourceElement(statement); + QQmlJS::AST::SourceElements *elements = new (pool) QQmlJS::AST::SourceElements(sourceElement); + elements = elements->finish(); - QQmlJS::AST::FunctionDeclaration *functionDeclaration = new (pool) QQmlJS::AST::FunctionDeclaration(compiler->newStringRef(stringAt(binding->propertyNameIndex)), paramList, body); - functionDeclaration->functionToken = foe->node->firstSourceLocation(); + QQmlJS::AST::FunctionBody *body = new (pool) QQmlJS::AST::FunctionBody(elements); + functionDeclaration = new (pool) QQmlJS::AST::FunctionDeclaration(compiler->newStringRef(stringAt(binding->propertyNameIndex)), paramList, body); + functionDeclaration->functionToken = foe->node->firstSourceLocation(); + } foe->node = functionDeclaration; binding->propertyNameIndex = compiler->registerString(propertyName); binding->flags |= QV4::CompiledData::Binding::IsSignalHandlerExpression; |