aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/parser
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-03-21 15:17:24 +0100
committerLars Knoll <lars.knoll@qt.io>2018-04-27 08:11:09 +0000
commit0eeaad2bc8da63779d8659666c9bd99463cbe011 (patch)
tree9c01c87e60a9992a2bd6a7481303ff87a70f66e6 /src/qml/parser
parentc3ad706c6ff19a132bf78501430c850040e967fc (diff)
Add support for 'class' to the AST
Change-Id: I2a9e8fb847dfa45ca77ee43e14f39f2b2def5792 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/parser')
-rw-r--r--src/qml/parser/qqmljs.g85
-rw-r--r--src/qml/parser/qqmljsast.cpp28
-rw-r--r--src/qml/parser/qqmljsast_p.h66
-rw-r--r--src/qml/parser/qqmljsastfwd_p.h2
-rw-r--r--src/qml/parser/qqmljsastvisitor_p.h6
5 files changed, 173 insertions, 14 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 22b123e6e0..0928c9b24c 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -287,6 +287,7 @@ public:
AST::BindingElement *BindingElement;
AST::BindingPropertyList *BindingPropertyList;
AST::BindingElementList *BindingElementList;
+ AST::ClassElementList *ClassElementList;
AST::UiProgram *UiProgram;
AST::UiHeaderItemList *UiHeaderItemList;
@@ -3763,16 +3764,34 @@ YieldExpression_In: T_YIELD AssignmentExpression_In;
./
-ClassDeclaration: T_CLASS BindingIdentifier ClassTail;
-/. case $rule_number: { UNIMPLEMENTED; } ./
-
-ClassDeclaration_Default: ClassDeclaration;
-ClassDeclaration_Default: T_CLASS ClassTail;
-/. case $rule_number: { UNIMPLEMENTED; } ./
+ClassDeclaration: T_CLASS BindingIdentifier ClassHeritageOpt ClassLBrace ClassBodyOpt ClassRBrace;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+ClassExpression: T_CLASS BindingIdentifier ClassHeritageOpt ClassLBrace ClassBodyOpt ClassRBrace;
+/.
+ case $rule_number: {
+ AST::ClassExpression *node = new (pool) AST::ClassExpression(stringRef(2), sym(3).Expression, sym(5).ClassElementList);
+ node->classToken = loc(1);
+ node->identifierToken = loc(2);
+ node->lbraceToken = loc(4);
+ node->rbraceToken = loc(6);
+ sym(1).Node = node;
+ } break;
+./
-ClassExpression: T_CLASS BindingIdentifier ClassTail;
+ClassDeclaration_Default: T_CLASS ClassHeritageOpt ClassLBrace ClassBodyOpt ClassRBrace;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+ClassExpression: T_CLASS ClassHeritageOpt ClassLBrace ClassBodyOpt ClassRBrace;
+/.
+ case $rule_number: {
+ AST::ClassExpression *node = new (pool) AST::ClassExpression(QStringRef(), sym(2).Expression, sym(4).ClassElementList);
+ node->classToken = loc(1);
+ node->lbraceToken = loc(3);
+ node->rbraceToken = loc(5);
+ sym(1).Node = node;
+ } break;
+./
-ClassExpression: T_CLASS ClassTail;
+ClassDeclaration_Default: ClassDeclaration;
ClassLBrace: T_LBRACE;
/.
@@ -3790,30 +3809,68 @@ ClassStaticQualifier: T_STATIC;
} break;
./
-ClassTail: ClassLBrace ClassBodyOpt ClassRBrace;
-ClassTail: ClassHeritage ClassLBrace ClassBodyOpt ClassRBrace;
-
-ClassHeritage: T_EXTENDS LeftHandSideExpression;
+ClassHeritageOpt: ;
+/.
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
+./
-ClassBody: ClassElementList;
+ClassHeritageOpt: T_EXTENDS LeftHandSideExpression;
+/.
+ case $rule_number: {
+ sym(1).Node = sym(2).Node;
+ } break;
+./
ClassBodyOpt: ;
+/.
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
+./
-ClassBodyOpt: ClassBody;
+ClassBodyOpt: ClassElementList;
+/.
+ case $rule_number: {
+ if (sym(1).Node)
+ sym(1).Node = sym(1).ClassElementList->finish();
+ } break;
+./
ClassElementList: ClassElement;
+
ClassElementList: ClassElementList ClassElement;
+/.
+ case $rule_number: {
+ if (sym(2).Node)
+ sym(1).ClassElementList = sym(1).ClassElementList->append(sym(2).ClassElementList);
+ } break;
+./
ClassElement: MethodDefinition;
+/.
+ case $rule_number: {
+ AST::ClassElementList *node = new (pool) AST::ClassElementList(sym(1).PropertyDefinition, false);
+ sym(1).Node = node;
+ } break;
+./
ClassElement: ClassStaticQualifier MethodDefinition;
/.
case $rule_number: {
lexer->setStaticIsKeyword(true);
+ AST::ClassElementList *node = new (pool) AST::ClassElementList(sym(2).PropertyDefinition, true);
+ sym(1).Node = node;
} break;
./
ClassElement: T_SEMICOLON;
+/.
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
+./
-- Scripts and Modules
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 35dd84a161..1a2883e148 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -1129,6 +1129,34 @@ void ComputedPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this);
}
+void ClassExpression::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(heritage, visitor);
+ accept(elements, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void ClassElementList::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(property, visitor);
+ if (next)
+ accept(next, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+ClassElementList *ClassElementList::finish()
+{
+ ClassElementList *front = next;
+ next = nullptr;
+ return front;
+}
+
} } // namespace QQmlJS::AST
QT_QML_END_NAMESPACE
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index e88eee4a37..4eb93cc203 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -159,6 +159,7 @@ public:
Kind_FunctionBody,
Kind_FunctionDeclaration,
Kind_FunctionExpression,
+ Kind_ClassExpression,
Kind_IdentifierExpression,
Kind_IdentifierPropertyName,
Kind_ComputedPropertyName,
@@ -212,6 +213,7 @@ public:
Kind_BindingElementList,
Kind_BindingPropertyList,
Kind_BindingRestElement,
+ Kind_ClassElementList,
Kind_UiArrayBinding,
Kind_UiImport,
@@ -2439,6 +2441,70 @@ public:
FormalParameterList *next;
};
+class QML_PARSER_EXPORT ClassExpression : public ExpressionNode
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ClassExpression)
+
+ ClassExpression(const QStringRef &n, ExpressionNode *heritage, ClassElementList *elements)
+ : name(n), heritage(heritage), elements(elements)
+ { kind = K; }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return classToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return rbraceToken; }
+
+// attributes
+ QStringRef name;
+ ExpressionNode *heritage;
+ ClassElementList *elements;
+ SourceLocation classToken;
+ SourceLocation identifierToken;
+ SourceLocation lbraceToken;
+ SourceLocation rbraceToken;
+};
+
+class QML_PARSER_EXPORT ClassElementList : public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ClassElementList)
+
+ ClassElementList(PropertyDefinition *property, bool isStatic)
+ : isStatic(isStatic), property(property)
+ {
+ kind = K;
+ next = this;
+ }
+
+ ClassElementList *append(ClassElementList *n) {
+ n->next = next;
+ next = n;
+ return n;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return property->firstSourceLocation(); }
+
+ SourceLocation lastSourceLocation() const override
+ {
+ if (next)
+ return next->lastSourceLocation();
+ return property->lastSourceLocation();
+ }
+
+ ClassElementList *finish();
+
+ bool isStatic;
+ ClassElementList *next;
+ PropertyDefinition *property;
+};
+
class QML_PARSER_EXPORT Program: public Node
{
public:
diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h
index 6fc32a44f0..0beaed535f 100644
--- a/src/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/parser/qqmljsastfwd_p.h
@@ -170,6 +170,8 @@ class BindingElementList;
class BindingPropertyList;
class BindingElement;
class BindingRestElement;
+class ClassExpression;
+class ClassElementList;
// ui elements
class UiProgram;
diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h
index 20117b2687..14b5aa135f 100644
--- a/src/qml/parser/qqmljsastvisitor_p.h
+++ b/src/qml/parser/qqmljsastvisitor_p.h
@@ -350,6 +350,12 @@ public:
virtual bool visit(FormalParameterList *) { return true; }
virtual void endVisit(FormalParameterList *) {}
+ virtual bool visit(ClassExpression *) { return true; }
+ virtual void endVisit(ClassExpression *) {}
+
+ virtual bool visit(ClassElementList *) { return true; }
+ virtual void endVisit(ClassElementList *) {}
+
virtual bool visit(Program *) { return true; }
virtual void endVisit(Program *) {}