diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-03-21 15:17:24 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-04-27 08:11:09 +0000 |
commit | 0eeaad2bc8da63779d8659666c9bd99463cbe011 (patch) | |
tree | 9c01c87e60a9992a2bd6a7481303ff87a70f66e6 /src/qml/parser | |
parent | c3ad706c6ff19a132bf78501430c850040e967fc (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.g | 85 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast.cpp | 28 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 66 | ||||
-rw-r--r-- | src/qml/parser/qqmljsastfwd_p.h | 2 | ||||
-rw-r--r-- | src/qml/parser/qqmljsastvisitor_p.h | 6 |
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 *) {} |