diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2019-07-22 09:02:58 +0200 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2019-07-23 16:37:41 +0200 |
commit | c0e0c755a1c927299607f0af83fadb4a0af6ce20 (patch) | |
tree | a0792012516207c2244d5a3e3bf92b86404c9a86 /src | |
parent | da14688140550879e376e71cf273b16494e6c3c4 (diff) |
Support top level generator functions
Extends grammar to support generator functions in QML components and
adjusts codegen accordingly
The corresponding test case must be blacklisted in tst_qmlmin, as qmlmin
cannot handle yield statements
Fixes: QTBUG-77096
Change-Id: I47d45dd56289cdf073b41932a585259d3052de04
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions_p.h | 2 | ||||
-rw-r--r-- | src/qml/parser/qqmljs.g | 8 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 6 |
5 files changed, 19 insertions, 7 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index aab3f8e9d6..171dc641d3 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -908,7 +908,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node) { - if (QQmlJS::AST::FunctionDeclaration *funDecl = QQmlJS::AST::cast<QQmlJS::AST::FunctionDeclaration *>(node->sourceElement)) { + if (QQmlJS::AST::FunctionExpression *funDecl = node->sourceElement->asFunctionDefinition()) { CompiledFunctionOrExpression *foe = New<CompiledFunctionOrExpression>(); foe->node = funDecl; foe->parentNode = funDecl; @@ -1770,7 +1770,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil for (const CompiledFunctionOrExpression &f : functions) { Q_ASSERT(f.node != document->program); Q_ASSERT(f.parentNode && f.parentNode != document->program); - QQmlJS::AST::FunctionDeclaration *function = QQmlJS::AST::cast<QQmlJS::AST::FunctionDeclaration*>(f.node); + auto function = f.node->asFunctionDefinition(); if (function) { scan.enterQmlFunction(function); @@ -1794,7 +1794,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil QQmlJS::AST::Node *node = qmlFunction.node; Q_ASSERT(node != document->program); - QQmlJS::AST::FunctionDeclaration *function = QQmlJS::AST::cast<QQmlJS::AST::FunctionDeclaration*>(node); + QQmlJS::AST::FunctionExpression *function = node->asFunctionDefinition(); QString name; if (function) diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h index f67db030a2..2de80eac44 100644 --- a/src/qml/compiler/qv4compilerscanfunctions_p.h +++ b/src/qml/compiler/qv4compilerscanfunctions_p.h @@ -88,7 +88,7 @@ public: const QString &name); void leaveEnvironment(); - void enterQmlFunction(QQmlJS::AST::FunctionDeclaration *ast) + void enterQmlFunction(QQmlJS::AST::FunctionExpression *ast) { enterFunction(ast, false); } protected: diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index 82b040232a..6c9760e472 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -1396,6 +1396,14 @@ UiObjectMember: FunctionDeclarationWithTypes; } break; ./ +UiObjectMember: GeneratorExpression; +/. + case $rule_number: { + auto node = new (pool) AST::UiSourceElement(sym(1).Node); + sym(1).Node = node; + } break; +./ + UiObjectMember: VariableStatement; /. case $rule_number: { diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index 1502298d14..39194068bf 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -3351,7 +3351,7 @@ public: SourceLocation firstSourceLocation() const override { - if (FunctionDeclaration *funDecl = cast<FunctionDeclaration *>(sourceElement)) + if (FunctionExpression *funDecl = sourceElement->asFunctionDefinition()) return funDecl->firstSourceLocation(); else if (VariableStatement *varStmt = cast<VariableStatement *>(sourceElement)) return varStmt->firstSourceLocation(); @@ -3361,7 +3361,7 @@ public: SourceLocation lastSourceLocation() const override { - if (FunctionDeclaration *funDecl = cast<FunctionDeclaration *>(sourceElement)) + if (FunctionExpression *funDecl = sourceElement->asFunctionDefinition()) return funDecl->lastSourceLocation(); else if (VariableStatement *varStmt = cast<VariableStatement *>(sourceElement)) return varStmt->lastSourceLocation(); diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index d5681b3449..f89608cd5d 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -57,6 +57,7 @@ #include <private/qqmldebugserviceinterfaces_p.h> #include <private/qqmlscriptdata_p.h> #include <private/qjsvalue_p.h> +#include <private/qv4generatorobject_p.h> #include <qtqml_tracepoints_p.h> @@ -1135,7 +1136,10 @@ void QQmlObjectCreator::setupFunctions() if (!property->isVMEFunction()) continue; - function = QV4::FunctionObject::createScriptFunction(qmlContext, runtimeFunction); + if (runtimeFunction->isGenerator()) + function = QV4::GeneratorFunction::create(qmlContext, runtimeFunction); + else + function = QV4::FunctionObject::createScriptFunction(qmlContext, runtimeFunction); _vmeMetaObject->setVmeMethod(property->coreIndex(), function); } } |