aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-05-08 15:21:27 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-11 07:17:16 +0000
commita8766dcd8c3a046aab1453ec3d28436bb75c895c (patch)
treea3ec1dd79c8a1604e0009b25aa01a9050c15cbb5 /src/qml
parent01a1ad296c2b8325476abd6d28c8cc2463c42eb6 (diff)
Unify ForeachStatement and LocalForeachStatement in the AST
This saves quite some duplicated code, but requires a bit of care when iterating over the AST. Change-Id: Ic530de4be8b36b4079c9d544b4b77982c3b8be60 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4codegen.cpp41
-rw-r--r--src/qml/compiler/qv4codegen_p.h1
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp12
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions_p.h1
-rw-r--r--src/qml/parser/qqmljs.g12
-rw-r--r--src/qml/parser/qqmljsast.cpp13
-rw-r--r--src/qml/parser/qqmljsast_p.h41
-rw-r--r--src/qml/parser/qqmljsastfwd_p.h1
-rw-r--r--src/qml/parser/qqmljsastvisitor_p.h3
9 files changed, 30 insertions, 95 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 8c6964930d..31c0764570 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -79,7 +79,6 @@ static inline void setJumpOutLocation(QV4::Moth::BytecodeGenerator *bytecodeGene
case Statement::Kind_ForEachStatement:
case Statement::Kind_ForStatement:
case Statement::Kind_IfStatement:
- case Statement::Kind_LocalForEachStatement:
case Statement::Kind_LocalForStatement:
case Statement::Kind_WhileStatement:
bytecodeGenerator->setLocation(fallback);
@@ -2611,7 +2610,16 @@ bool Codegen::visit(ForEachStatement *ast)
bytecodeGenerator->addInstruction(iteratorObjInstr);
iterator.storeConsumeAccumulator();
- Reference lhs = expression(ast->initialiser);
+ Reference lhs;
+ if (ExpressionNode *e = ast->lhs->expressionCast()) {
+ lhs = expression(e);
+ } else if (PatternElement *p = AST::cast<PatternElement *>(ast->lhs)) {
+ variableDeclaration(p);
+ lhs = referenceForName(p->bindingIdentifier, true).asLValue();
+ } else {
+ Q_UNREACHABLE();
+ }
+
if (hasError)
return false;
if (!lhs.isLValue()) {
@@ -2625,32 +2633,6 @@ bool Codegen::visit(ForEachStatement *ast)
return false;
}
-bool Codegen::visit(LocalForEachStatement *ast)
-{
- if (hasError)
- return true;
-
- RegisterScope scope(this);
-
- Reference iterator = Reference::fromStackSlot(this);
- Reference expr = expression(ast->expression);
- if (hasError)
- return true;
-
- variableDeclaration(ast->declaration);
-
- expr.loadInAccumulator();
- Instruction::GetIterator iteratorObjInstr;
- iteratorObjInstr.iterator = (ast->type == ForEachType::Of) ? 1 : 0;
- bytecodeGenerator->addInstruction(iteratorObjInstr);
- iterator.storeConsumeAccumulator();
-
- Reference lhs = referenceForName(ast->declaration->bindingIdentifier, true).asLValue();
- foreachBody(lhs, ast->statement, ast->forToken, iterator);
-
- return false;
-}
-
void Codegen::foreachBody(const Reference &lhs, Statement *statements, const SourceLocation &forToken, const Reference &iterator)
{
RegisterScope scope(this);
@@ -2771,8 +2753,7 @@ bool Codegen::visit(LabelledStatement *ast)
AST::cast<AST::DoWhileStatement *>(ast->statement) ||
AST::cast<AST::ForStatement *>(ast->statement) ||
AST::cast<AST::ForEachStatement *>(ast->statement) ||
- AST::cast<AST::LocalForStatement *>(ast->statement) ||
- AST::cast<AST::LocalForEachStatement *>(ast->statement)) {
+ AST::cast<AST::LocalForStatement *>(ast->statement)) {
statement(ast->statement); // labelledStatement will be associated with the ast->statement's loop.
} else {
BytecodeGenerator::Label breakLabel = bytecodeGenerator->newLabel();
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index d742fe06b7..18ccf04dc8 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -603,7 +603,6 @@ protected:
bool visit(AST::ForStatement *ast) override;
bool visit(AST::IfStatement *ast) override;
bool visit(AST::LabelledStatement *ast) override;
- bool visit(AST::LocalForEachStatement *ast) override;
bool visit(AST::LocalForStatement *ast) override;
bool visit(AST::ReturnStatement *ast) override;
bool visit(AST::SwitchStatement *ast) override;
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp
index 4dbd11ef1c..eadbc3ae17 100644
--- a/src/qml/compiler/qv4compilerscanfunctions.cpp
+++ b/src/qml/compiler/qv4compilerscanfunctions.cpp
@@ -342,17 +342,7 @@ bool ScanFunctions::visit(LocalForStatement *ast) {
}
bool ScanFunctions::visit(ForEachStatement *ast) {
- Node::accept(ast->initialiser, this);
- Node::accept(ast->expression, this);
-
- TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
- Node::accept(ast->statement, this);
-
- return false;
-}
-
-bool ScanFunctions::visit(LocalForEachStatement *ast) {
- Node::accept(ast->declaration, this);
+ Node::accept(ast->lhs, this);
Node::accept(ast->expression, this);
TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h
index 31e260b7ad..7d29af4fa3 100644
--- a/src/qml/compiler/qv4compilerscanfunctions_p.h
+++ b/src/qml/compiler/qv4compilerscanfunctions_p.h
@@ -127,7 +127,6 @@ protected:
bool visit(AST::ForStatement *ast) override;
bool visit(AST::LocalForStatement *ast) override;
bool visit(AST::ForEachStatement *ast) override;
- bool visit(AST::LocalForEachStatement *ast) override;
bool visit(AST::ThisExpression *ast) override;
bool visit(AST::Block *ast) override;
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index f162d123f5..5efc392efa 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -3143,6 +3143,15 @@ InOrOf: T_OF;
IterationStatement: T_FOR T_LPAREN LeftHandSideExpression InOrOf Expression_In T_RPAREN Statement;
/.
case $rule_number: {
+ // need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral
+// if (AST::Pattern *p = sym(3).Expression->patternCast()) {
+// AST::SourceLocation errorLoc;
+// QString errorMsg;
+// if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) {
+// syntaxError(errorLoc, errorMsg);
+// return false;
+// }
+// }
AST::ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression, sym(5).Expression, sym(7).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
@@ -3156,10 +3165,9 @@ IterationStatement: T_FOR T_LPAREN LeftHandSideExpression InOrOf Expression_In T
IterationStatement: T_FOR T_LPAREN ForDeclaration InOrOf Expression_In T_RPAREN Statement;
/.
case $rule_number: {
- AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(sym(3).PatternElement, sym(5).Expression, sym(7).Statement);
+ AST::ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).PatternElement, sym(5).Expression, sym(7).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
- node->varToken = loc(3);
node->inOfToken = loc(4);
node->rparenToken = loc(6);
node->type = sym(4).forEachType;
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index cc8b290bc9..bf3e193291 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -791,18 +791,7 @@ void LocalForStatement::accept0(Visitor *visitor)
void ForEachStatement::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
- accept(initialiser, visitor);
- accept(expression, visitor);
- accept(statement, visitor);
- }
-
- visitor->endVisit(this);
-}
-
-void LocalForEachStatement::accept0(Visitor *visitor)
-{
- if (visitor->visit(this)) {
- accept(declaration, visitor);
+ accept(lhs, visitor);
accept(expression, visitor);
accept(statement, visitor);
}
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 36060f7358..83fcb6559c 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -174,7 +174,6 @@ public:
Kind_ComputedPropertyName,
Kind_IfStatement,
Kind_LabelledStatement,
- Kind_LocalForEachStatement,
Kind_LocalForStatement,
Kind_NewExpression,
Kind_NewMemberExpression,
@@ -1711,37 +1710,12 @@ class QML_PARSER_EXPORT ForEachStatement: public Statement
public:
QQMLJS_DECLARE_AST_NODE(ForEachStatement)
- ForEachStatement(ExpressionNode *i, ExpressionNode *e, Statement *stmt):
- initialiser (i), expression (e), statement (stmt)
- { kind = K; }
-
- void accept0(Visitor *visitor) override;
-
- SourceLocation firstSourceLocation() const override
- { return forToken; }
-
- SourceLocation lastSourceLocation() const override
- { return statement->lastSourceLocation(); }
-
-// attributes
- ExpressionNode *initialiser;
- ExpressionNode *expression;
- Statement *statement;
- SourceLocation forToken;
- SourceLocation lparenToken;
- SourceLocation inOfToken;
- SourceLocation rparenToken;
- ForEachType type;
-};
-
-class QML_PARSER_EXPORT LocalForEachStatement: public Statement
-{
-public:
- QQMLJS_DECLARE_AST_NODE(LocalForEachStatement)
-
- LocalForEachStatement(PatternElement *v, ExpressionNode *e, Statement *stmt):
- declaration (v), expression (e), statement (stmt)
- { kind = K; }
+ ForEachStatement(ExpressionNode *i, ExpressionNode *e, Statement *stmt)
+ : lhs(i), expression(e), statement(stmt)
+ { kind = K; }
+ ForEachStatement(PatternElement *v, ExpressionNode *e, Statement *stmt)
+ : lhs(v), expression(e), statement(stmt)
+ { kind = K; }
void accept0(Visitor *visitor) override;
@@ -1752,12 +1726,11 @@ public:
{ return statement->lastSourceLocation(); }
// attributes
- PatternElement *declaration;
+ Node *lhs;
ExpressionNode *expression;
Statement *statement;
SourceLocation forToken;
SourceLocation lparenToken;
- SourceLocation varToken;
SourceLocation inOfToken;
SourceLocation rparenToken;
ForEachType type;
diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h
index 465f227b6d..22cf88919d 100644
--- a/src/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/parser/qqmljsastfwd_p.h
@@ -142,7 +142,6 @@ class WhileStatement;
class ForStatement;
class LocalForStatement;
class ForEachStatement;
-class LocalForEachStatement;
class ContinueStatement;
class BreakStatement;
class ReturnStatement;
diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h
index b3b54364c4..4dfc50d122 100644
--- a/src/qml/parser/qqmljsastvisitor_p.h
+++ b/src/qml/parser/qqmljsastvisitor_p.h
@@ -272,9 +272,6 @@ public:
virtual bool visit(ForEachStatement *) { return true; }
virtual void endVisit(ForEachStatement *) {}
- virtual bool visit(LocalForEachStatement *) { return true; }
- virtual void endVisit(LocalForEachStatement *) {}
-
virtual bool visit(ContinueStatement *) { return true; }
virtual void endVisit(ContinueStatement *) {}