diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-03-21 12:25:51 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-04-27 08:11:00 +0000 |
commit | c3ad706c6ff19a132bf78501430c850040e967fc (patch) | |
tree | 9d16716001c3cd25bf6c778fe9b5f4dc117c17c4 /src/qml/compiler/qv4compilerscanfunctions.cpp | |
parent | 0de2ac924a3dbbd59b9e726f470113e4c87b0ae7 (diff) | |
download | qtdeclarative-c3ad706c6ff19a132bf78501430c850040e967fc.tar.gz |
Added support for generator functions and yield expressions to the AST
Some smaller changes to the codegen are included as well to ensure
that we catch all uses of generators and properly throw an unimplemented
error on them for now.
Change-Id: Ib915a0e862e128644ff00dfe989507783c912c66
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4compilerscanfunctions.cpp')
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index 5c606e7f7f..57f9105484 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -260,7 +260,7 @@ bool ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName) { if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments"))) _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode")); - return enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : nullptr); + return enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName); } void ScanFunctions::endVisit(FunctionExpression *) @@ -289,7 +289,7 @@ bool ScanFunctions::visit(ObjectLiteral *ast) bool ScanFunctions::visit(PropertyGetterSetter *ast) { TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true); - return enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/nullptr); + return enterFunction(ast, QString(), ast->formals, ast->functionBody, /*enterName */ false); } void ScanFunctions::endVisit(PropertyGetterSetter *) @@ -388,19 +388,23 @@ bool ScanFunctions::visit(Block *ast) { return false; } -bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, FunctionExpression *expr) +bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, bool enterName) { Context *outerContext = _context; enterEnvironment(ast, FunctionCode); + FunctionExpression *expr = AST::cast<FunctionExpression *>(ast); + if (!expr) + expr = AST::cast<FunctionDeclaration *>(ast); if (outerContext) { outerContext->hasNestedFunctions = true; // The identifier of a function expression cannot be referenced from the enclosing environment. - if (expr) { - if (!outerContext->addLocalVar(name, Context::FunctionDefinition, AST::VariableDeclaration::FunctionScope, expr)) { + if (enterName) { + if (!outerContext->addLocalVar(name, Context::FunctionDefinition, AST::VariableScope::Var, expr)) { _cg->throwSyntaxError(ast->firstSourceLocation(), QStringLiteral("Identifier %1 has already been declared").arg(name)); return false; } + outerContext->addLocalVar(name, Context::FunctionDefinition, AST::VariableScope::Var, expr); } if (name == QLatin1String("arguments")) outerContext->usesArgumentsObject = Context::ArgumentsObjectNotUsed; @@ -408,8 +412,12 @@ bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete if (formals->containsName(QStringLiteral("arguments"))) _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed; - if (expr && expr->isArrowFunction) - _context->isArrowFunction = true; + if (expr) { + if (expr->isArrowFunction) + _context->isArrowFunction = true; + else if (expr->isGenerator) + _context->isGenerator = true; + } if (!name.isEmpty() && !formals->containsName(name)) |