aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2019-07-22 09:02:58 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2019-07-23 16:37:41 +0200
commitc0e0c755a1c927299607f0af83fadb4a0af6ce20 (patch)
treea0792012516207c2244d5a3e3bf92b86404c9a86 /src
parentda14688140550879e376e71cf273b16494e6c3c4 (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.cpp6
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions_p.h2
-rw-r--r--src/qml/parser/qqmljs.g8
-rw-r--r--src/qml/parser/qqmljsast_p.h4
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp6
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);
}
}