diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-03-25 20:16:27 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-05-02 14:17:08 +0000 |
commit | 17f72f2d07352940b67a60c2ff6f7ef848793488 (patch) | |
tree | 4a2cf7429acaaf8c8c9d8620f989ad07ccd120b7 | |
parent | 1e974dd01c074ae9f32a5a1210f2fc55dba8dd3c (diff) |
Fix destructuring of arrow function parameters
Change-Id: I64b49ae77ecd81eafb320cda04a1a7bf4b2dc90c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r-- | src/qml/parser/qqmljs.g | 35 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast.cpp | 42 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 8 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 103 |
4 files changed, 54 insertions, 134 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index ce641accd8..bb0f53f4ab 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -387,7 +387,6 @@ protected: AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr); AST::UiQualifiedPragmaId *reparseAsQualifiedPragmaId(AST::ExpressionNode *expr); - AST::FormalParameterList *reparseAsFormalParameterList(AST::ExpressionNode *expr); void pushToken(int token); int lookaheadToken(Lexer *lexer); @@ -553,34 +552,6 @@ AST::UiQualifiedPragmaId *Parser::reparseAsQualifiedPragmaId(AST::ExpressionNode return 0; } -AST::FormalParameterList *Parser::reparseAsFormalParameterList(AST::ExpressionNode *expr) -{ - AST::FormalParameterList *f = nullptr; - if (AST::Expression *commaExpr = AST::cast<AST::Expression *>(expr)) { - f = reparseAsFormalParameterList(commaExpr->left); - if (!f) - return nullptr; - - expr = commaExpr->right; - } - - AST::ExpressionNode *rhs = nullptr; - if (AST::BinaryExpression *assign = AST::cast<AST::BinaryExpression *>(expr)) { - if (assign->op != QSOperator::Assign) - return nullptr; - expr = assign->left; - rhs = assign->right; - } - AST::PatternElement *binding = nullptr; - if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(expr)) { - binding = new (pool) AST::PatternElement(idExpr->name, rhs); - binding->identifierToken = idExpr->identifierToken; - } - if (!binding) - return nullptr; - return new (pool) AST::FormalParameterList(f, binding); -} - void Parser::pushToken(int token) { last_token->token = yytoken; @@ -1506,7 +1477,7 @@ CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN BindingRestElement T CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN Expression_In T_COMMA BindingRestElementOpt T_RPAREN; /. case $rule_number: { - AST::FormalParameterList *list = reparseAsFormalParameterList(sym(2).Expression); + AST::FormalParameterList *list = sym(2).Expression->reparseAsFormalParameterList(pool); if (!list) { syntaxError(loc(1), "Invalid Arrow parameter list."); return false; @@ -2867,6 +2838,7 @@ BindingPattern: T_LBRACE ObjectBindingPattern T_RBRACE; auto *node = new (pool) AST::ObjectPattern(sym(2).PatternPropertyList); node->lbraceToken = loc(1); node->rbraceToken = loc(3); + node->parseMode = AST::Pattern::Binding; sym(1).Node = node; } break; ./ @@ -2877,6 +2849,7 @@ BindingPattern: T_LBRACKET ArrayBindingPattern T_RBRACKET; auto *node = new (pool) AST::ArrayPattern(sym(2).PatternElementList); node->lbracketToken = loc(1); node->rbracketToken = loc(3); + node->parseMode = AST::Pattern::Binding; sym(1).Node = node; } break; ./ @@ -3612,7 +3585,7 @@ ArrowParameters: CoverParenthesizedExpressionAndArrowParameterList; case $rule_number: { if (coverExpressionType != CE_FormalParameterList) { AST::NestedExpression *ne = static_cast<AST::NestedExpression *>(sym(1).Node); - AST::FormalParameterList *list = reparseAsFormalParameterList(ne->expression); + AST::FormalParameterList *list = ne->expression->reparseAsFormalParameterList(pool); if (!list) { syntaxError(loc(1), "Invalid Arrow parameter list."); return false; diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp index eef7a33f26..c86fb24e82 100644 --- a/src/qml/parser/qqmljsast.cpp +++ b/src/qml/parser/qqmljsast.cpp @@ -110,6 +110,42 @@ ExpressionNode *ExpressionNode::expressionCast() return this; } +FormalParameterList *ExpressionNode::reparseAsFormalParameterList(MemoryPool *pool) +{ + AST::ExpressionNode *expr = this; + AST::FormalParameterList *f = nullptr; + if (AST::Expression *commaExpr = AST::cast<AST::Expression *>(expr)) { + f = commaExpr->left->reparseAsFormalParameterList(pool); + if (!f) + return nullptr; + + expr = commaExpr->right; + } + + AST::ExpressionNode *rhs = nullptr; + if (AST::BinaryExpression *assign = AST::cast<AST::BinaryExpression *>(expr)) { + if (assign->op != QSOperator::Assign) + return nullptr; + expr = assign->left; + rhs = assign->right; + } + AST::PatternElement *binding = nullptr; + if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(expr)) { + binding = new (pool) AST::PatternElement(idExpr->name, rhs); + binding->identifierToken = idExpr->identifierToken; + } else if (AST::Pattern *p = expr->patternCast()) { + SourceLocation loc; + QString s; + if (!p->convertLiteralToAssignmentPattern(pool, &loc, &s)) + return nullptr; + binding = new (pool) AST::PatternElement(p, rhs); + binding->identifierToken = p->firstSourceLocation(); + } + if (!binding) + return nullptr; + return new (pool) AST::FormalParameterList(f, binding); +} + BinaryExpression *BinaryExpression::binaryExpressionCast() { return this; @@ -319,6 +355,8 @@ PropertyName: */ bool ArrayPattern::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) { + if (parseMode == Binding) + return true; for (auto *it = elements; it; it = it->next) { if (it->element->type == PatternElement::SpreadElement && it->next) { *errorLocation = it->element->firstSourceLocation(); @@ -328,15 +366,19 @@ bool ArrayPattern::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLoc if (!it->element->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage)) return false; } + parseMode = Binding; return true; } bool ObjectPattern::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) { + if (parseMode == Binding) + return true; for (auto *it = properties; it; it = it->next) { if (!it->property->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage)) return false; } + parseMode = Binding; return true; } diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index e14e058e83..c83a459506 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -279,6 +279,9 @@ public: ExpressionNode() {} ExpressionNode *expressionCast() override; + + AST::FormalParameterList *reparseAsFormalParameterList(MemoryPool *pool); + }; class QML_PARSER_EXPORT LeftHandSideExpression : public ExpressionNode @@ -527,8 +530,13 @@ public: class QML_PARSER_EXPORT Pattern : public LeftHandSideExpression { public: + enum ParseMode { + Literal, + Binding + }; Pattern *patternCast() override; virtual bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) = 0; + ParseMode parseMode = Literal; }; class QML_PARSER_EXPORT ArrayPattern : public Pattern diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index e61862f134..e025646443 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -4119,38 +4119,15 @@ language/expressions/arrow-function/dflt-params-ref-self language/expressions/arrow-function/dstr-ary-init-iter-close language/expressions/arrow-function/dstr-ary-init-iter-get-err language/expressions/arrow-function/dstr-ary-init-iter-no-close -language/expressions/arrow-function/dstr-ary-name-iter-val -language/expressions/arrow-function/dstr-ary-ptrn-elem-ary-elem-init -language/expressions/arrow-function/dstr-ary-ptrn-elem-ary-elem-iter language/expressions/arrow-function/dstr-ary-ptrn-elem-ary-elision-init language/expressions/arrow-function/dstr-ary-ptrn-elem-ary-elision-iter language/expressions/arrow-function/dstr-ary-ptrn-elem-ary-empty-init -language/expressions/arrow-function/dstr-ary-ptrn-elem-ary-empty-iter language/expressions/arrow-function/dstr-ary-ptrn-elem-ary-rest-init language/expressions/arrow-function/dstr-ary-ptrn-elem-ary-rest-iter -language/expressions/arrow-function/dstr-ary-ptrn-elem-ary-val-null -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-exhausted -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-fn-name-arrow language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-fn-name-class -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-fn-name-cover -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-fn-name-fn language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-fn-name-gen -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-hole -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-skipped -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-throws -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-undef -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-init-unresolvable -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-iter-complete -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-iter-done language/expressions/arrow-function/dstr-ary-ptrn-elem-id-iter-step-err -language/expressions/arrow-function/dstr-ary-ptrn-elem-id-iter-val language/expressions/arrow-function/dstr-ary-ptrn-elem-id-iter-val-err -language/expressions/arrow-function/dstr-ary-ptrn-elem-obj-id -language/expressions/arrow-function/dstr-ary-ptrn-elem-obj-id-init -language/expressions/arrow-function/dstr-ary-ptrn-elem-obj-prop-id -language/expressions/arrow-function/dstr-ary-ptrn-elem-obj-prop-id-init -language/expressions/arrow-function/dstr-ary-ptrn-elem-obj-val-null -language/expressions/arrow-function/dstr-ary-ptrn-elem-obj-val-undef language/expressions/arrow-function/dstr-ary-ptrn-elision language/expressions/arrow-function/dstr-ary-ptrn-elision-exhausted language/expressions/arrow-function/dstr-ary-ptrn-elision-step-err @@ -4170,38 +4147,15 @@ language/expressions/arrow-function/dstr-ary-ptrn-rest-obj-prop-id language/expressions/arrow-function/dstr-dflt-ary-init-iter-close language/expressions/arrow-function/dstr-dflt-ary-init-iter-get-err language/expressions/arrow-function/dstr-dflt-ary-init-iter-no-close -language/expressions/arrow-function/dstr-dflt-ary-name-iter-val -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-ary-elem-init -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-ary-elem-iter language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-ary-elision-init language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-ary-elision-iter language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-ary-empty-init -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-ary-empty-iter language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-ary-rest-init language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-ary-rest-iter -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-ary-val-null -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-exhausted -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-fn-name-arrow language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-fn-name-class -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-fn-name-cover -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-fn-name-fn language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-fn-name-gen -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-hole -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-skipped -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-throws -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-undef -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-init-unresolvable -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-iter-complete -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-iter-done language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-iter-step-err -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-iter-val language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-id-iter-val-err -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-obj-id -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-obj-id-init -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-obj-prop-id -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-obj-prop-id-init -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-obj-val-null -language/expressions/arrow-function/dstr-dflt-ary-ptrn-elem-obj-val-undef language/expressions/arrow-function/dstr-dflt-ary-ptrn-elision language/expressions/arrow-function/dstr-dflt-ary-ptrn-elision-exhausted language/expressions/arrow-function/dstr-dflt-ary-ptrn-elision-step-err @@ -4218,66 +4172,10 @@ language/expressions/arrow-function/dstr-dflt-ary-ptrn-rest-id-iter-step-err language/expressions/arrow-function/dstr-dflt-ary-ptrn-rest-id-iter-val-err language/expressions/arrow-function/dstr-dflt-ary-ptrn-rest-obj-id language/expressions/arrow-function/dstr-dflt-ary-ptrn-rest-obj-prop-id -language/expressions/arrow-function/dstr-dflt-obj-init-null -language/expressions/arrow-function/dstr-dflt-obj-init-undefined -language/expressions/arrow-function/dstr-dflt-obj-ptrn-empty -language/expressions/arrow-function/dstr-dflt-obj-ptrn-id-get-value-err -language/expressions/arrow-function/dstr-dflt-obj-ptrn-id-init-fn-name-arrow language/expressions/arrow-function/dstr-dflt-obj-ptrn-id-init-fn-name-class -language/expressions/arrow-function/dstr-dflt-obj-ptrn-id-init-fn-name-cover -language/expressions/arrow-function/dstr-dflt-obj-ptrn-id-init-fn-name-fn language/expressions/arrow-function/dstr-dflt-obj-ptrn-id-init-fn-name-gen -language/expressions/arrow-function/dstr-dflt-obj-ptrn-id-init-skipped -language/expressions/arrow-function/dstr-dflt-obj-ptrn-id-init-throws -language/expressions/arrow-function/dstr-dflt-obj-ptrn-id-init-unresolvable -language/expressions/arrow-function/dstr-dflt-obj-ptrn-id-trailing-comma -language/expressions/arrow-function/dstr-dflt-obj-ptrn-list-err -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-ary -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-ary-init -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-ary-trailing-comma -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-ary-value-null -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-eval-err -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-id -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-id-get-value-err -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-id-init -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-id-init-skipped -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-id-init-throws -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-id-init-unresolvable -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-id-trailing-comma -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-obj -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-obj-init -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-obj-value-null -language/expressions/arrow-function/dstr-dflt-obj-ptrn-prop-obj-value-undef -language/expressions/arrow-function/dstr-obj-init-null -language/expressions/arrow-function/dstr-obj-init-undefined -language/expressions/arrow-function/dstr-obj-ptrn-empty -language/expressions/arrow-function/dstr-obj-ptrn-id-get-value-err -language/expressions/arrow-function/dstr-obj-ptrn-id-init-fn-name-arrow language/expressions/arrow-function/dstr-obj-ptrn-id-init-fn-name-class -language/expressions/arrow-function/dstr-obj-ptrn-id-init-fn-name-cover -language/expressions/arrow-function/dstr-obj-ptrn-id-init-fn-name-fn language/expressions/arrow-function/dstr-obj-ptrn-id-init-fn-name-gen -language/expressions/arrow-function/dstr-obj-ptrn-id-init-skipped -language/expressions/arrow-function/dstr-obj-ptrn-id-init-throws -language/expressions/arrow-function/dstr-obj-ptrn-id-init-unresolvable -language/expressions/arrow-function/dstr-obj-ptrn-id-trailing-comma -language/expressions/arrow-function/dstr-obj-ptrn-list-err -language/expressions/arrow-function/dstr-obj-ptrn-prop-ary -language/expressions/arrow-function/dstr-obj-ptrn-prop-ary-init -language/expressions/arrow-function/dstr-obj-ptrn-prop-ary-trailing-comma -language/expressions/arrow-function/dstr-obj-ptrn-prop-ary-value-null -language/expressions/arrow-function/dstr-obj-ptrn-prop-eval-err -language/expressions/arrow-function/dstr-obj-ptrn-prop-id -language/expressions/arrow-function/dstr-obj-ptrn-prop-id-get-value-err -language/expressions/arrow-function/dstr-obj-ptrn-prop-id-init -language/expressions/arrow-function/dstr-obj-ptrn-prop-id-init-skipped -language/expressions/arrow-function/dstr-obj-ptrn-prop-id-init-throws -language/expressions/arrow-function/dstr-obj-ptrn-prop-id-init-unresolvable -language/expressions/arrow-function/dstr-obj-ptrn-prop-id-trailing-comma -language/expressions/arrow-function/dstr-obj-ptrn-prop-obj -language/expressions/arrow-function/dstr-obj-ptrn-prop-obj-init -language/expressions/arrow-function/dstr-obj-ptrn-prop-obj-value-null -language/expressions/arrow-function/dstr-obj-ptrn-prop-obj-value-undef language/expressions/arrow-function/length-dflt language/expressions/arrow-function/lexical-arguments language/expressions/arrow-function/lexical-new.target @@ -4294,7 +4192,6 @@ language/expressions/arrow-function/scope-param-elem-var-open language/expressions/arrow-function/scope-param-rest-elem-var-close language/expressions/arrow-function/scope-param-rest-elem-var-open language/expressions/arrow-function/scope-paramsbody-var-open -language/expressions/arrow-function/syntax/arrowparameters-cover-initialize-2 language/expressions/arrow-function/throw-new language/expressions/assignment/destructuring/iterator-destructuring-property-reference-target-evaluation-order language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order |