aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-03-25 20:16:27 +0200
committerLars Knoll <lars.knoll@qt.io>2018-05-02 14:17:08 +0000
commit17f72f2d07352940b67a60c2ff6f7ef848793488 (patch)
tree4a2cf7429acaaf8c8c9d8620f989ad07ccd120b7
parent1e974dd01c074ae9f32a5a1210f2fc55dba8dd3c (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.g35
-rw-r--r--src/qml/parser/qqmljsast.cpp42
-rw-r--r--src/qml/parser/qqmljsast_p.h8
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations103
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