aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/parser/qqmljsast_p.h
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-03-22 16:34:05 +0100
committerLars Knoll <lars.knoll@qt.io>2018-04-27 08:11:28 +0000
commit02252ae08dc36ba44f65fb932c428849c7369299 (patch)
tree5c7627b08cce5bfa2df5e04b3427bcc93ef2b2fe /src/qml/parser/qqmljsast_p.h
parente07a03365ad07cd4294f487b15a57f31bd0a3d40 (diff)
Rework the AST for Literals and destructuring expressions
Array/ObjectLiterals and destructuring expressions are syntactically very similar. In some cases (when using a destructuring expression as the lhs of an assigment), the parser needs to convert the literal into a destructuring expression. To support these, use the same data structures for both in the AST. Those Patterns can be converted with little additional work from a Literal to an AssignmentPattern and be used in all places where we need destructuring in addition to literals. Change-Id: I177599b46eab0f6e8cb2a40c3b3b11ed00a07d6a Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/parser/qqmljsast_p.h')
-rw-r--r--src/qml/parser/qqmljsast_p.h490
1 files changed, 152 insertions, 338 deletions
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 19f1beb803..5c0ef707d5 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -128,7 +128,7 @@ public:
Kind_Undefined,
Kind_ArgumentList,
- Kind_ArrayLiteral,
+ Kind_ArrayPattern,
Kind_ArrayMemberExpression,
Kind_BinaryExpression,
Kind_Block,
@@ -174,7 +174,7 @@ public:
Kind_YieldExpression,
Kind_NumericLiteral,
Kind_NumericLiteralPropertyName,
- Kind_ObjectLiteral,
+ Kind_ObjectPattern,
Kind_PostDecrementExpression,
Kind_PostIncrementExpression,
Kind_PreDecrementExpression,
@@ -207,13 +207,12 @@ public:
Kind_WhileStatement,
Kind_WithStatement,
Kind_NestedExpression,
- Kind_ArrayBindingPattern,
- Kind_ObjectBindingPattern,
- Kind_BindingElement,
- Kind_BindingElementList,
- Kind_BindingPropertyList,
- Kind_BindingRestElement,
Kind_ClassElementList,
+ Kind_PatternElement,
+ Kind_PatternElementList,
+ Kind_PatternProperty,
+ Kind_PatternPropertyList,
+
Kind_UiArrayBinding,
Kind_UiImport,
@@ -504,20 +503,25 @@ public:
SourceLocation literalToken;
};
-class QML_PARSER_EXPORT ArrayPattern : public ExpressionNode
+class QML_PARSER_EXPORT Pattern : public ExpressionNode
+{
+
+};
+
+class QML_PARSER_EXPORT ArrayPattern : public Pattern
{
public:
- QQMLJS_DECLARE_AST_NODE(ArrayLiteral)
+ QQMLJS_DECLARE_AST_NODE(ArrayPattern)
ArrayPattern(Elision *e)
: elision(e)
{ kind = K; }
- ArrayPattern(ElementList *elts)
+ ArrayPattern(PatternElementList *elts)
: elements(elts)
{ kind = K; }
- ArrayPattern(ElementList *elts, Elision *e)
+ ArrayPattern(PatternElementList *elts, Elision *e)
: elements(elts), elision(e)
{ kind = K; }
@@ -529,24 +533,27 @@ public:
SourceLocation lastSourceLocation() const override
{ return rbracketToken; }
+ bool isValidArrayLiteral(SourceLocation *errorLocation = nullptr) const;
+
// attributes
- ElementList *elements = nullptr;
+ PatternElementList *elements = nullptr;
Elision *elision = nullptr;
SourceLocation lbracketToken;
SourceLocation commaToken;
SourceLocation rbracketToken;
};
-class QML_PARSER_EXPORT ObjectPattern : public ExpressionNode
+class QML_PARSER_EXPORT ObjectPattern : public Pattern
{
public:
- QQMLJS_DECLARE_AST_NODE(ObjectLiteral)
+ QQMLJS_DECLARE_AST_NODE(ObjectPattern)
ObjectPattern()
{ kind = K; }
- ObjectPattern(PropertyDefinitionList *plist):
- properties (plist) { kind = K; }
+ ObjectPattern(PatternPropertyList *plist)
+ : properties(plist)
+ { kind = K; }
void accept0(Visitor *visitor) override;
@@ -557,7 +564,7 @@ public:
{ return rbraceToken; }
// attributes
- PropertyDefinitionList *properties = nullptr;
+ PatternPropertyList *properties = nullptr;
SourceLocation lbraceToken;
SourceLocation rbraceToken;
};
@@ -597,54 +604,6 @@ public:
SourceLocation commaToken;
};
-class QML_PARSER_EXPORT ElementList: public Node
-{
-public:
- QQMLJS_DECLARE_AST_NODE(ElementList)
-
- ElementList(Elision *e, ExpressionNode *expr):
- elision (e), expression (expr), next (this)
- { kind = K; }
-
- ElementList(ElementList *previous, Elision *e, ExpressionNode *expr):
- elision (e), expression (expr)
- {
- kind = K;
- next = previous->next;
- previous->next = this;
- }
-
- inline ElementList *finish ()
- {
- ElementList *front = next;
- next = nullptr;
- return front;
- }
-
- void accept0(Visitor *visitor) override;
-
- SourceLocation firstSourceLocation() const override
- {
- if (elision)
- return elision->firstSourceLocation();
- return expression->firstSourceLocation();
- }
-
- SourceLocation lastSourceLocation() const override
- {
- if (next)
- return next->lastSourceLocation();
- return expression->lastSourceLocation();
- }
-
-// attributes
- Elision *elision;
- ExpressionNode *expression;
- ElementList *next;
- SourceLocation commaToken;
- bool isSpreadElement = false;
-};
-
class QML_PARSER_EXPORT PropertyName: public Node
{
public:
@@ -664,120 +623,172 @@ public:
SourceLocation propertyNameToken;
};
-class QML_PARSER_EXPORT PropertyDefinition: public Node
+class QML_PARSER_EXPORT PatternElement : public Node
{
public:
- PropertyDefinition(PropertyName *n)
- : name(n)
- {}
+ QQMLJS_DECLARE_AST_NODE(PatternElement)
+
+ enum Type {
+ // object literal types
+ Literal,
+ Getter,
+ Setter,
+
+ // used by both bindings and literals
+ SpreadElement,
+ RestElement = SpreadElement,
+
+ // binding types
+ Binding,
+ };
+
+ PatternElement(ExpressionNode *i = nullptr, Type t = Literal)
+ : initializer(i), type(t)
+ { kind = K; }
+
+ PatternElement(const QStringRef &n, ExpressionNode *i = nullptr, Type t = Binding)
+ : bindingIdentifier(n.toString()), initializer(i), type(t)
+ {
+ Q_ASSERT(t >= RestElement);
+ kind = K;
+ }
+
+ PatternElement(Pattern *pattern, ExpressionNode *i = nullptr, Type t = Binding)
+ : bindingPattern(pattern), initializer(i), type(t)
+ {
+ Q_ASSERT(t >= RestElement);
+ kind = K;
+ }
+
+ void accept0(Visitor *visitor) override;
SourceLocation firstSourceLocation() const override
- { return name->firstSourceLocation(); }
+ { return identifierToken.isValid() ? identifierToken : (bindingPattern ? bindingPattern->firstSourceLocation() : initializer->firstSourceLocation()); }
SourceLocation lastSourceLocation() const override
- { return name->lastSourceLocation(); }
+ { return initializer ? initializer->lastSourceLocation() : (bindingPattern ? bindingPattern->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; }
+
+ virtual void boundNames(QStringList *names);
// attributes
- PropertyName *name;
+ SourceLocation identifierToken;
+ QString bindingIdentifier;
+ Pattern *bindingPattern = nullptr;
+ ExpressionNode *initializer = nullptr;
+ Type type = Literal;
};
-class QML_PARSER_EXPORT PropertyDefinitionList: public Node
+class QML_PARSER_EXPORT PatternElementList : public Node
{
public:
- QQMLJS_DECLARE_AST_NODE(PropertyDefinitionList)
+ QQMLJS_DECLARE_AST_NODE(PatternElementList)
- PropertyDefinitionList(PropertyDefinition *assignment)
- : assignment(assignment)
- , next(this)
+ PatternElementList(Elision *elision, PatternElement *element)
+ : elision(elision), element(element), next(this)
{ kind = K; }
- PropertyDefinitionList(PropertyDefinitionList *previous, PropertyDefinition *assignment)
- : assignment(assignment)
- {
- kind = K;
- next = previous->next;
- previous->next = this;
+ PatternElementList *append(PatternElementList *n) {
+ n->next = next;
+ next = n;
+ return n;
}
- inline PropertyDefinitionList *finish ()
+ inline PatternElementList *finish ()
{
- PropertyDefinitionList *front = next;
- next = nullptr;
+ PatternElementList *front = next;
+ next = 0;
return front;
}
void accept0(Visitor *visitor) override;
+ void boundNames(QStringList *names);
+
SourceLocation firstSourceLocation() const override
- { return assignment->firstSourceLocation(); }
+ { return elision ? elision->firstSourceLocation() : element->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : assignment->lastSourceLocation(); }
+ { return next ? next->lastSourceLocation() : (element ? element->lastSourceLocation() : elision->lastSourceLocation()); }
-// attributes
- PropertyDefinition *assignment;
- PropertyDefinitionList *next;
- SourceLocation commaToken;
+ Elision *elision = nullptr;
+ PatternElement *element = nullptr;
+ PatternElementList *next;
};
-class QML_PARSER_EXPORT PropertyNameAndValue: public PropertyDefinition
+class QML_PARSER_EXPORT PatternProperty : public PatternElement
{
public:
- QQMLJS_DECLARE_AST_NODE(PropertyNameAndValue)
+ QQMLJS_DECLARE_AST_NODE(PatternProperty)
+
+ PatternProperty(PropertyName *name, ExpressionNode *i = nullptr, Type t = Literal)
+ : PatternElement(i, t), name(name)
+ { kind = K; }
- PropertyNameAndValue(PropertyName *n, ExpressionNode *v)
- : PropertyDefinition(n), value(v)
+ PatternProperty(PropertyName *name, const QStringRef &n, ExpressionNode *i = nullptr)
+ : PatternElement(n, i), name(name)
+ { kind = K; }
+
+ PatternProperty(PropertyName *name, Pattern *pattern, ExpressionNode *i = nullptr)
+ : PatternElement(pattern, i), name(name)
{ kind = K; }
void accept0(Visitor *visitor) override;
SourceLocation firstSourceLocation() const override
{ return name->firstSourceLocation(); }
-
SourceLocation lastSourceLocation() const override
- { return value->lastSourceLocation(); }
+ {
+ SourceLocation loc = PatternElement::lastSourceLocation();
+ return loc.isValid() ? loc : name->lastSourceLocation();
+ }
+
+ void boundNames(QStringList *names) override;
// attributes
+ PropertyName *name;
SourceLocation colonToken;
- ExpressionNode *value;
- SourceLocation commaToken;
};
-class QML_PARSER_EXPORT PropertyGetterSetter: public PropertyDefinition
+
+class QML_PARSER_EXPORT PatternPropertyList : public Node
{
public:
- QQMLJS_DECLARE_AST_NODE(PropertyGetterSetter)
+ QQMLJS_DECLARE_AST_NODE(PatternPropertyList)
- enum Type {
- Getter,
- Setter
- };
-
- PropertyGetterSetter(PropertyName *n, StatementList *b)
- : PropertyDefinition(n), type(Getter), formals(nullptr), functionBody(b)
+ PatternPropertyList(PatternProperty *property)
+ : property(property), next(this)
{ kind = K; }
- PropertyGetterSetter(PropertyName *n, FormalParameterList *f, StatementList *b)
- : PropertyDefinition(n), type(Setter), formals(f), functionBody(b)
- { kind = K; }
+ PatternPropertyList(PatternPropertyList *previous, PatternProperty *property)
+ : property(property), next(this)
+ {
+ kind = K;
+ next = previous->next;
+ previous->next = this;
+ }
void accept0(Visitor *visitor) override;
+ void boundNames(QStringList *names);
+
+ inline PatternPropertyList *finish ()
+ {
+ PatternPropertyList *front = next;
+ next = 0;
+ return front;
+ }
+
SourceLocation firstSourceLocation() const override
- { return getSetToken; }
+ { return property->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return rbraceToken; }
+ { return next ? next->lastSourceLocation() : property->lastSourceLocation(); }
-// attributes
- Type type;
- SourceLocation getSetToken;
- SourceLocation lparenToken;
- FormalParameterList *formals;
- SourceLocation rparenToken;
- SourceLocation lbraceToken;
- StatementList *functionBody;
- SourceLocation rbraceToken;
+ PatternProperty *property;
+ PatternPropertyList *next;
};
class QML_PARSER_EXPORT IdentifierPropertyName : public PropertyName
@@ -2149,191 +2160,6 @@ public:
SourceLocation rbraceToken;
};
-class QML_PARSER_EXPORT BindingRestElement : public Node
-{
-public:
- QQMLJS_DECLARE_AST_NODE(BindingRestElement)
-
- BindingRestElement(const QStringRef &n)
- : name(n)
- { kind = K; }
-
- void accept0(Visitor *visitor) override;
-
- SourceLocation firstSourceLocation() const override
- { return identifierToken; }
-
- SourceLocation lastSourceLocation() const override
- { return identifierToken; }
-
-// attributes
- SourceLocation identifierToken;
- QStringRef name;
-};
-
-class QML_PARSER_EXPORT BindingPattern : public Node
-{
-public:
-
- SourceLocation firstSourceLocation() const override
- { return first; }
-
- SourceLocation lastSourceLocation() const override
- { return last; }
-
- SourceLocation first;
- SourceLocation last;
-};
-
-class QML_PARSER_EXPORT ObjectBindingPattern : public BindingPattern
-{
-public:
- QQMLJS_DECLARE_AST_NODE(ObjectBindingPattern)
-
- ObjectBindingPattern(BindingPropertyList *p)
- : properties(p)
- { kind = K; }
-
- void accept0(Visitor *visitor) override;
-
- BindingPropertyList *properties;
-};
-
-class QML_PARSER_EXPORT ArrayBindingPattern : public BindingPattern
-{
-public:
- QQMLJS_DECLARE_AST_NODE(ArrayBindingPattern)
-
- ArrayBindingPattern(BindingElementList *e)
- : elements(e)
- { kind = K; }
-
- void accept0(Visitor *visitor) override;
-
- BindingElementList *elements;
-};
-
-class QML_PARSER_EXPORT BindingElement : public Node
-{
-public:
- QQMLJS_DECLARE_AST_NODE(BindingElement)
-
- BindingElement(const QStringRef &n, ExpressionNode *i = nullptr)
- : name(n.toString()), initializer(i)
- { kind = K; }
-
- BindingElement(BindingPattern *binding, ExpressionNode *i = nullptr)
- : binding(binding), initializer(i)
- { kind = K; }
-
- void accept0(Visitor *visitor) override;
-
- SourceLocation firstSourceLocation() const override
- { return identifierToken; }
-
- SourceLocation lastSourceLocation() const override
- { return initializer ? initializer->lastSourceLocation() : (binding ? binding->lastSourceLocation() : identifierToken); }
-
- BindingElementList *elementList() const {
- ArrayBindingPattern *p = cast<ArrayBindingPattern *>(binding);
- return p ? p->elements : nullptr;
- }
- BindingPropertyList *propertyList() const {
- ObjectBindingPattern *p = cast<ObjectBindingPattern *>(binding);
- return p ? p->properties : nullptr;
- }
-
- void boundNames(QStringList *names);
-
-// attributes
- SourceLocation identifierToken;
- BindingPattern *binding = nullptr;
- QString name;
- ExpressionNode *initializer = nullptr;
-};
-
-class QML_PARSER_EXPORT BindingElementList : public Node
-{
-public:
- QQMLJS_DECLARE_AST_NODE(BindingElementList)
-
- BindingElementList(Elision *e, Node *p)
- : elision(e), param(p), next(this)
- { kind = K; }
-
- BindingElementList *append(BindingElementList *n) {
- n->next = next;
- next = n;
- return n;
- }
-
- inline BindingElementList *finish ()
- {
- BindingElementList *front = next;
- next = 0;
- return front;
- }
-
- BindingRestElement *bindingRestElement() const {
- return cast<BindingRestElement *>(param);
- }
-
- BindingElement *bindingElement() const {
- return cast<BindingElement *>(param);
- }
-
- void accept0(Visitor *visitor) override;
-
- void boundNames(QStringList *names);
-
- SourceLocation firstSourceLocation() const override
- { return elision ? elision->firstSourceLocation() : param->firstSourceLocation(); }
-
- SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : (param ? param->lastSourceLocation() : elision->lastSourceLocation()); }
-
- Elision *elision = nullptr;
- Node *param = nullptr;
- BindingElementList *next;
-};
-
-class QML_PARSER_EXPORT BindingPropertyList : public Node
-{
-public:
- QQMLJS_DECLARE_AST_NODE(BindingPropertyList)
-
- BindingPropertyList(PropertyName *n, BindingElement *e)
- : propertyName(n), binding(e), next(this)
- { kind = K; }
-
- void accept0(Visitor *visitor) override;
-
- void boundNames(QStringList *names);
-
- BindingPropertyList *append(BindingPropertyList *n) {
- n->next = next;
- next = n;
- return n;
- }
-
- inline BindingPropertyList *finish ()
- {
- BindingPropertyList *front = next;
- next = 0;
- return front;
- }
-
- SourceLocation firstSourceLocation() const override
- { return propertyName->firstSourceLocation(); }
-
- SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : binding->lastSourceLocation(); }
-
- PropertyName *propertyName;
- BindingElement *binding;
- BindingPropertyList *next;
-};
-
class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression
{
public:
@@ -2351,8 +2177,8 @@ class QML_PARSER_EXPORT FormalParameterList: public Node
public:
QQMLJS_DECLARE_AST_NODE(FormalParameterList)
- FormalParameterList(FormalParameterList *previous, Node *p)
- : param(p)
+ FormalParameterList(FormalParameterList *previous, PatternElement *e)
+ : element(e)
{
kind = K;
if (previous) {
@@ -2369,22 +2195,14 @@ public:
return n;
}
- BindingRestElement *bindingRestElement() const {
- return cast<BindingRestElement *>(param);
- }
-
- BindingElement *bindingElement() const {
- return cast<BindingElement *>(param);
- }
-
bool isSimpleParameterList()
{
AST::FormalParameterList *formals = this;
while (formals) {
- if (formals->bindingRestElement())
+ PatternElement *e = formals->element;
+ if (e && e->type == PatternElement::RestElement)
return false;
- BindingElement *e = formals->bindingElement();
- if (e && (e->initializer || e->binding))
+ if (e && (e->initializer || e->bindingPattern))
return false;
formals = formals->next;
}
@@ -2397,11 +2215,11 @@ public:
int l = 0;
AST::FormalParameterList *formals = this;
while (formals) {
- if (formals->bindingRestElement())
- break;
- BindingElement *e = formals->bindingElement();
+ PatternElement *e = formals->element;
if (!e || e->initializer)
break;
+ if (e->type == PatternElement::RestElement)
+ break;
++l;
formals = formals->next;
}
@@ -2410,14 +2228,10 @@ public:
bool containsName(const QString &name) const {
for (const FormalParameterList *it = this; it; it = it->next) {
- if (QQmlJS::AST::BindingElement *b = it->bindingElement()) {
- // ### handle binding patterns
- if (b->name == name)
- return true;
- } else if (QQmlJS::AST::BindingRestElement *r = it->bindingRestElement()) {
- if (r->name == name)
- return true;
- }
+ PatternElement *b = it->element;
+ // ### handle binding patterns
+ if (b && b->bindingIdentifier == name)
+ return true;
}
return false;
}
@@ -2429,15 +2243,15 @@ public:
void accept0(Visitor *visitor) override;
SourceLocation firstSourceLocation() const override
- { return param->firstSourceLocation(); }
+ { return element->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : param->lastSourceLocation(); }
+ { return next ? next->lastSourceLocation() : element->lastSourceLocation(); }
FormalParameterList *finish();
// attributes
- Node *param = nullptr;
+ PatternElement *element = nullptr;
FormalParameterList *next;
};
@@ -2473,7 +2287,7 @@ class QML_PARSER_EXPORT ClassElementList : public Node
public:
QQMLJS_DECLARE_AST_NODE(ClassElementList)
- ClassElementList(PropertyDefinition *property, bool isStatic)
+ ClassElementList(PatternProperty *property, bool isStatic)
: isStatic(isStatic), property(property)
{
kind = K;
@@ -2502,7 +2316,7 @@ public:
bool isStatic;
ClassElementList *next;
- PropertyDefinition *property;
+ PatternProperty *property;
};
class QML_PARSER_EXPORT Program: public Node