diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-05-08 15:21:27 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-11 07:17:16 +0000 |
commit | a8766dcd8c3a046aab1453ec3d28436bb75c895c (patch) | |
tree | a3ec1dd79c8a1604e0009b25aa01a9050c15cbb5 /src/qml | |
parent | 01a1ad296c2b8325476abd6d28c8cc2463c42eb6 (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.cpp | 41 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen_p.h | 1 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 12 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions_p.h | 1 | ||||
-rw-r--r-- | src/qml/parser/qqmljs.g | 12 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast.cpp | 13 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 41 | ||||
-rw-r--r-- | src/qml/parser/qqmljsastfwd_p.h | 1 | ||||
-rw-r--r-- | src/qml/parser/qqmljsastvisitor_p.h | 3 |
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 *) {} |