diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-06-05 13:07:50 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-06-21 13:30:44 +0000 |
commit | ce18e987d4ea623c0db6d10f2a97a16b639a234e (patch) | |
tree | 793ce0624f971de8015d5580e6c06d2b1a1b9aab /src/qml/parser | |
parent | a12da297946b5a6e767b972bc635a3308683b2e5 (diff) |
Fix more issues with destructuring
Fix destructuring targets that are complex lhs expressions.
There are still some failures remaining, but this fixes
another larger chunk of test cases.
Change-Id: Icf08f42d7c70d4e81be5d5d2e27ebe6249d25467
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/parser')
-rw-r--r-- | src/qml/parser/qqmljsast.cpp | 32 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 16 |
2 files changed, 23 insertions, 25 deletions
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp index b63feb3362..e9e33f7561 100644 --- a/src/qml/parser/qqmljsast.cpp +++ b/src/qml/parser/qqmljsast.cpp @@ -268,7 +268,7 @@ void ArrayPattern::accept0(Visitor *visitor) bool ArrayPattern::isValidArrayLiteral(SourceLocation *errorLocation) const { for (PatternElementList *it = elements; it != nullptr; it = it->next) { PatternElement *e = it->element; - if (e && e->bindingPattern != nullptr) { + if (e && e->bindingTarget != nullptr) { if (errorLocation) *errorLocation = e->firstSourceLocation(); return false; @@ -386,8 +386,8 @@ bool PatternElement::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceL { Q_ASSERT(type == Literal || type == SpreadElement); Q_ASSERT(bindingIdentifier.isNull()); - Q_ASSERT(bindingPattern == nullptr); - Q_ASSERT(bindingPattern == nullptr); + Q_ASSERT(bindingTarget == nullptr); + Q_ASSERT(bindingTarget == nullptr); Q_ASSERT(initializer); ExpressionNode *init = initializer; @@ -399,8 +399,7 @@ bool PatternElement::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceL *errorMessage = QString::fromLatin1("Invalid lhs expression after '...' in destructuring expression."); return false; } - // ### Should be binding - initializer = lhs; + bindingTarget = lhs; return true; } type = PatternElement::Binding; @@ -422,21 +421,18 @@ bool PatternElement::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceL *errorMessage = QString::fromLatin1("Destructuring target is not a left hand side expression."); return false; } - - if (auto *p = lhs->patternCast()) { - bindingPattern = p; - if (!p->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage)) - return false; - return true; - } if (auto *i = cast<IdentifierExpression *>(lhs)) { bindingIdentifier = i->name.toString(); identifierToken = i->identifierToken; return true; } - *errorLocation = lastSourceLocation(); - *errorMessage = QLatin1String("Unimplemented!"); - return false; + + bindingTarget = lhs; + if (auto *p = lhs->patternCast()) { + if (!p->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage)) + return false; + } + return true; } bool PatternProperty::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) @@ -1209,7 +1205,7 @@ void TaggedTemplate::accept0(Visitor *visitor) void PatternElement::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(bindingPattern, visitor); + accept(bindingTarget, visitor); accept(initializer, visitor); } @@ -1218,7 +1214,7 @@ void PatternElement::accept0(Visitor *visitor) void PatternElement::boundNames(QStringList *names) { - if (bindingPattern) { + if (bindingTarget) { if (PatternElementList *e = elementList()) e->boundNames(names); else if (PatternPropertyList *p = propertyList()) @@ -1252,7 +1248,7 @@ void PatternProperty::accept0(Visitor *visitor) { if (visitor->visit(this)) { accept(name, visitor); - accept(bindingPattern, visitor); + accept(bindingTarget, visitor); accept(initializer, visitor); } diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index 2d4d5662bd..66a4e357e9 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -678,7 +678,7 @@ public: } PatternElement(Pattern *pattern, ExpressionNode *i = nullptr, Type t = Binding) - : bindingPattern(pattern), initializer(i), type(t) + : bindingTarget(pattern), initializer(i), type(t) { Q_ASSERT(t >= RestElement); kind = K; @@ -688,13 +688,15 @@ public: virtual bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage); SourceLocation firstSourceLocation() const override - { return identifierToken.isValid() ? identifierToken : (bindingPattern ? bindingPattern->firstSourceLocation() : initializer->firstSourceLocation()); } + { return identifierToken.isValid() ? identifierToken : (bindingTarget ? bindingTarget->firstSourceLocation() : initializer->firstSourceLocation()); } SourceLocation lastSourceLocation() const override - { return initializer ? initializer->lastSourceLocation() : (bindingPattern ? bindingPattern->lastSourceLocation() : identifierToken); } + { return initializer ? initializer->lastSourceLocation() : (bindingTarget ? bindingTarget->lastSourceLocation() : identifierToken); } - PatternElementList *elementList() const { ArrayPattern *a = cast<ArrayPattern *>(bindingPattern); return a ? a->elements : nullptr; } - PatternPropertyList *propertyList() const { ObjectPattern *o = cast<ObjectPattern *>(bindingPattern); return o ? o->properties : nullptr; } + ExpressionNode *destructuringTarget() const { return bindingTarget; } + Pattern *destructuringPattern() const { return bindingTarget ? bindingTarget->patternCast() : nullptr; } + PatternElementList *elementList() const { ArrayPattern *a = cast<ArrayPattern *>(bindingTarget); return a ? a->elements : nullptr; } + PatternPropertyList *propertyList() const { ObjectPattern *o = cast<ObjectPattern *>(bindingTarget); return o ? o->properties : nullptr; } bool isVariableDeclaration() const { return scope != VariableScope::NoScope; } bool isLexicallyScoped() const { return scope == VariableScope::Let || scope == VariableScope::Const; } @@ -704,7 +706,7 @@ public: // attributes SourceLocation identifierToken; QString bindingIdentifier; - Pattern *bindingPattern = nullptr; + ExpressionNode *bindingTarget = nullptr; ExpressionNode *initializer = nullptr; Type type = Literal; // when used in a VariableDeclarationList @@ -2164,7 +2166,7 @@ public: PatternElement *e = formals->element; if (e && e->type == PatternElement::RestElement) return false; - if (e && (e->initializer || e->bindingPattern)) + if (e && (e->initializer || e->bindingTarget)) return false; formals = formals->next; } |