aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/parser
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-07-03 13:57:01 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2018-07-31 17:09:44 +0000
commit4caedd14c7926e65378836262808bda6e928936c (patch)
treea0bbadf5e0556be3e050ec943a52b9b06c9b1da5 /src/qml/parser
parent53dba3fddef25d5668ed77c929c5ad611c9da544 (diff)
Build AST nodes when parsing ES6 modules
This introduces the structures in the AST that allow for the extraction of imports, exports as well as location of tokens. The ModuleItemList as entry point is special with regards to the statements (so not import/export declarations) in the sense that the statement list contained in ModuleItemList::item is not linked yet between different ModuleItemList instances. Change-Id: If553a6ebaf53d5f3cf755c8327d3fe0ea7db68c2 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/parser')
-rw-r--r--src/qml/parser/qqmljs.g245
-rw-r--r--src/qml/parser/qqmljsast.cpp124
-rw-r--r--src/qml/parser/qqmljsast_p.h466
-rw-r--r--src/qml/parser/qqmljsastfwd_p.h15
-rw-r--r--src/qml/parser/qqmljsastvisitor_p.h42
5 files changed, 891 insertions, 1 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index cd40a77299..db583ff82c 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -287,6 +287,17 @@ public:
AST::PatternProperty *PatternProperty;
AST::PatternPropertyList *PatternPropertyList;
AST::ClassElementList *ClassElementList;
+ AST::ModuleItemList *ModuleItemList;
+ AST::ImportClause *ImportClause;
+ AST::FromClause *FromClause;
+ AST::NameSpaceImport *NameSpaceImport;
+ AST::ImportsList *ImportsList;
+ AST::NamedImports *NamedImports;
+ AST::ImportSpecifier *ImportSpecifier;
+ AST::ExportSpecifier *ExportSpecifier;
+ AST::ExportsList *ExportsList;
+ AST::ExportClause *ExportClause;
+ AST::ExportDeclaration *ExportDeclaration;
AST::UiProgram *UiProgram;
AST::UiHeaderItemList *UiHeaderItemList;
@@ -4024,15 +4035,39 @@ ScriptBody: StatementList;
./
Module: ModuleBodyOpt;
-/. case $rule_number: { UNIMPLEMENTED; } ./
+/. case $rule_number: {
+ sym(1).Node = new (pool) AST::ESModule(sym(1).ModuleItemList);
+ } break;
+./
ModuleBody: ModuleItemList;
+/.
+ case $rule_number: {
+ sym(1).ModuleItemList = sym(1).ModuleItemList->finish();
+ } break;
+./
ModuleBodyOpt: ;
+/.
+ case $rule_number: {
+ sym(1).ModuleItemList = nullptr;
+ } break;
+./
ModuleBodyOpt: ModuleBody;
ModuleItemList: ModuleItem;
+/.
+ case $rule_number: {
+ sym(1).ModuleItemList = new (pool) AST::ModuleItemList(sym(1).Node);
+ } break;
+./
+
ModuleItemList: ModuleItemList ModuleItem;
+/.
+ case $rule_number: {
+ sym(1).ModuleItemList = new (pool) AST::ModuleItemList(sym(1).ModuleItemList, sym(2).Node);
+ } break;
+./
ModuleItem: ImportDeclaration T_AUTOMATIC_SEMICOLON;
ModuleItem: ImportDeclaration T_SEMICOLON;
@@ -4041,29 +4076,144 @@ ModuleItem: ExportDeclaration T_SEMICOLON;
ModuleItem: StatementListItem;
ImportDeclaration: T_IMPORT ImportClause FromClause;
+/.
+ case $rule_number: {
+ auto decl = new (pool) AST::ImportDeclaration(sym(2).ImportClause, sym(3).FromClause);
+ decl->importToken = loc(1);
+ sym(1).Node = decl;
+ } break;
+./
ImportDeclaration: T_IMPORT ModuleSpecifier;
+/.
+ case $rule_number: {
+ auto decl = new (pool) AST::ImportDeclaration(stringRef(2));
+ decl->importToken = loc(1);
+ decl->moduleSpecifierToken = loc(2);
+ sym(1).Node = decl;
+ } break;
+./
ImportClause: ImportedDefaultBinding;
+/.
+ case $rule_number: {
+ auto clause = new (pool) AST::ImportClause(stringRef(1));
+ clause->importedDefaultBindingToken = loc(1);
+ sym(1).ImportClause = clause;
+ } break;
+./
ImportClause: NameSpaceImport;
+/.
+ case $rule_number: {
+ sym(1).ImportClause = new (pool) AST::ImportClause(sym(1).NameSpaceImport);
+ } break;
+./
ImportClause: NamedImports;
+/.
+ case $rule_number: {
+ sym(1).ImportClause = new (pool) AST::ImportClause(sym(1).NamedImports);
+ } break;
+./
ImportClause: ImportedDefaultBinding T_COMMA NameSpaceImport;
+/.
+ case $rule_number: {
+ auto importClause = new (pool) AST::ImportClause(stringRef(1), sym(3).NameSpaceImport);
+ importClause->importedDefaultBindingToken = loc(1);
+ sym(1).ImportClause = importClause;
+ } break;
+./
ImportClause: ImportedDefaultBinding T_COMMA NamedImports;
+/.
+ case $rule_number: {
+ auto importClause = new (pool) AST::ImportClause(stringRef(1), sym(3).NamedImports);
+ importClause->importedDefaultBindingToken = loc(1);
+ sym(1).ImportClause = importClause;
+ } break;
+./
ImportedDefaultBinding: ImportedBinding;
NameSpaceImport: T_STAR T_AS ImportedBinding;
+/.
+ case $rule_number: {
+ auto import = new (pool) AST::NameSpaceImport(stringRef(3));
+ import->starToken = loc(1);
+ import->importedBindingToken = loc(3);
+ sym(1).NameSpaceImport = import;
+ } break;
+./
NamedImports: T_LBRACE T_RBRACE;
+/.
+ case $rule_number: {
+ auto namedImports = new (pool) AST::NamedImports();
+ namedImports->leftBraceToken = loc(1);
+ namedImports->rightBraceToken = loc(2);
+ sym(1).NamedImports = namedImports;
+ } break;
+./
NamedImports: T_LBRACE ImportsList T_RBRACE;
+/.
+ case $rule_number: {
+ auto namedImports = new (pool) AST::NamedImports(sym(2).ImportsList->finish());
+ namedImports->leftBraceToken = loc(1);
+ namedImports->rightBraceToken = loc(3);
+ sym(1).NamedImports = namedImports;
+ } break;
+./
NamedImports: T_LBRACE ImportsList T_COMMA T_RBRACE;
+/.
+ case $rule_number: {
+ auto namedImports = new (pool) AST::NamedImports(sym(2).ImportsList->finish());
+ namedImports->leftBraceToken = loc(1);
+ namedImports->rightBraceToken = loc(4);
+ sym(1).NamedImports = namedImports;
+ } break;
+./
FromClause: T_FROM ModuleSpecifier;
+/.
+ case $rule_number: {
+ auto clause = new (pool) AST::FromClause(stringRef(2));
+ clause->fromToken = loc(1);
+ clause->moduleSpecifierToken = loc(2);
+ sym(1).FromClause = clause;
+ } break;
+./
ImportsList: ImportSpecifier;
+/.
+ case $rule_number: {
+ auto importsList = new (pool) AST::ImportsList(sym(1).ImportSpecifier);
+ importsList->importSpecifierToken = loc(1);
+ sym(1).ImportsList = importsList;
+ } break;
+./
ImportsList: ImportsList T_COMMA ImportSpecifier;
+/.
+ case $rule_number: {
+ auto importsList = new (pool) AST::ImportsList(sym(1).ImportsList, sym(3).ImportSpecifier);
+ importsList->importSpecifierToken = loc(3);
+ sym(1).ImportsList = importsList;
+ } break;
+./
ImportSpecifier: ImportedBinding;
+/.
+ case $rule_number: {
+ auto importSpecifier = new (pool) AST::ImportSpecifier(stringRef(1));
+ importSpecifier->importedBindingToken = loc(1);
+ sym(1).ImportSpecifier = importSpecifier;
+ } break;
+./
ImportSpecifier: IdentifierName T_AS ImportedBinding;
+/.
+ case $rule_number: {
+ auto importSpecifier = new (pool) AST::ImportSpecifier(stringRef(1), stringRef(3));
+ importSpecifier->identifierToken = loc(1);
+ importSpecifier->importedBindingToken = loc(3);
+ sym(1).ImportSpecifier = importSpecifier;
+ } break;
+./
ModuleSpecifier: T_STRING_LITERAL;
@@ -4082,23 +4232,116 @@ ExportDeclarationLookahead: ;
./
ExportDeclaration: T_EXPORT T_STAR FromClause;
+/.
+ case $rule_number: {
+ auto exportDeclaration = new (pool) AST::ExportDeclaration(sym(3).FromClause);
+ exportDeclaration->exportToken = loc(1);
+ sym(1).ExportDeclaration = exportDeclaration;
+ } break;
+./
ExportDeclaration: T_EXPORT ExportClause FromClause;
+/.
+ case $rule_number: {
+ auto exportDeclaration = new (pool) AST::ExportDeclaration(sym(2).ExportClause, sym(3).FromClause);
+ exportDeclaration->exportToken = loc(1);
+ sym(1).ExportDeclaration = exportDeclaration;
+ } break;
+./
ExportDeclaration: T_EXPORT ExportClause;
+/.
+ case $rule_number: {
+ auto exportDeclaration = new (pool) AST::ExportDeclaration(sym(2).ExportClause);
+ exportDeclaration->exportToken = loc(1);
+ sym(1).ExportDeclaration = exportDeclaration;
+ } break;
+./
ExportDeclaration: T_EXPORT VariableStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
ExportDeclaration: T_EXPORT Declaration;
+/.
+ case $rule_number: {
+ auto exportDeclaration = new (pool) AST::ExportDeclaration(/*exportDefault=*/false, sym(2).Node);
+ exportDeclaration->exportToken = loc(1);
+ sym(1).ExportDeclaration = exportDeclaration;
+ } break;
+./
ExportDeclaration: T_EXPORT T_DEFAULT ExportDeclarationLookahead T_FORCE_DECLARATION HoistableDeclaration_Default;
+/. case $rule_number: Q_FALLTHROUGH(); ./
ExportDeclaration: T_EXPORT T_DEFAULT ExportDeclarationLookahead T_FORCE_DECLARATION ClassDeclaration_Default;
+/.
+ case $rule_number: {
+ auto exportDeclaration = new (pool) AST::ExportDeclaration(/*exportDefault=*/true, sym(5).Node);
+ exportDeclaration->exportToken = loc(1);
+ sym(1).ExportDeclaration = exportDeclaration;
+ } break;
+./
ExportDeclaration: T_EXPORT T_DEFAULT ExportDeclarationLookahead AssignmentExpression_In; -- [lookahead ∉ { function, class }]
+/.
+ case $rule_number: {
+ auto exportDeclaration = new (pool) AST::ExportDeclaration(/*exportDefault=*/true, sym(4).Node);
+ exportDeclaration->exportToken = loc(1);
+ sym(1).ExportDeclaration = exportDeclaration;
+ } break;
+./
ExportClause: T_LBRACE T_RBRACE;
+/.
+ case $rule_number: {
+ auto exportClause = new (pool) AST::ExportClause();
+ exportClause->leftBraceToken = loc(1);
+ exportClause->rightBraceToken = loc(2);
+ sym(1).ExportClause = exportClause;
+ } break;
+./
ExportClause: T_LBRACE ExportsList T_RBRACE;
+/.
+ case $rule_number: {
+ auto exportClause = new (pool) AST::ExportClause(sym(2).ExportsList->finish());
+ exportClause->leftBraceToken = loc(1);
+ exportClause->rightBraceToken = loc(3);
+ sym(1).ExportClause = exportClause;
+ } break;
+./
ExportClause: T_LBRACE ExportsList T_COMMA T_RBRACE;
+/.
+ case $rule_number: {
+ auto exportClause = new (pool) AST::ExportClause(sym(2).ExportsList->finish());
+ exportClause->leftBraceToken = loc(1);
+ exportClause->rightBraceToken = loc(4);
+ sym(1).ExportClause = exportClause;
+ } break;
+./
ExportsList: ExportSpecifier;
+/.
+ case $rule_number: {
+ sym(1).ExportsList = new (pool) AST::ExportsList(sym(1).ExportSpecifier);
+ } break;
+./
ExportsList: ExportsList T_COMMA ExportSpecifier;
+/.
+ case $rule_number: {
+ sym(1).ExportsList = new (pool) AST::ExportsList(sym(1).ExportsList, sym(3).ExportSpecifier);
+ } break;
+./
ExportSpecifier: IdentifierName;
+/.
+ case $rule_number: {
+ auto exportSpecifier = new (pool) AST::ExportSpecifier(stringRef(1));
+ exportSpecifier->identifierToken = loc(1);
+ sym(1).ExportSpecifier = exportSpecifier;
+ } break;
+./
ExportSpecifier: IdentifierName T_AS IdentifierName;
+/.
+ case $rule_number: {
+ auto exportSpecifier = new (pool) AST::ExportSpecifier(stringRef(1), stringRef(3));
+ exportSpecifier->identifierToken = loc(1);
+ exportSpecifier->exportedIdentifierToken = loc(3);
+ sym(1).ExportSpecifier = exportSpecifier;
+ } break;
+./
-- Old top level code
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index d254279cbf..73b6131d52 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -1058,6 +1058,130 @@ void Program::accept0(Visitor *visitor)
visitor->endVisit(this);
}
+void ImportSpecifier::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+
+ }
+ visitor->endVisit(this);
+}
+
+void ImportsList::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ for (ImportsList *it = this; it; it = it->next) {
+ accept(it->importSpecifier, visitor);
+ }
+ }
+
+ visitor->endVisit(this);
+}
+
+void NamedImports::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(importsList, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void FromClause::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ }
+
+ visitor->endVisit(this);
+}
+
+void NameSpaceImport::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ }
+
+ visitor->endVisit(this);
+}
+
+void ImportClause::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(nameSpaceImport, visitor);
+ accept(namedImports, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void ImportDeclaration::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(importClause, visitor);
+ accept(fromClause, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void ExportSpecifier::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+
+ }
+
+ visitor->endVisit(this);
+}
+
+void ExportsList::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ for (ExportsList *it = this; it; it = it->next) {
+ accept(it->exportSpecifier, visitor);
+ }
+ }
+
+ visitor->endVisit(this);
+}
+
+void ExportClause::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(exportsList, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void ExportDeclaration::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(fromClause, visitor);
+ accept(exportClause, visitor);
+ accept(variableStatementOrDeclaration, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void ModuleItemList::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ for (ModuleItemList *it = this; it; it = it->next) {
+ accept(it->item, visitor);
+ }
+ }
+
+ visitor->endVisit(this);
+}
+
+void ESModule::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(body, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
void DebuggerStatement::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 07999404b4..ed4523b019 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -176,6 +176,19 @@ public:
Kind_ComputedPropertyName,
Kind_IfStatement,
Kind_LabelledStatement,
+ Kind_NameSpaceImport,
+ Kind_ImportSpecifier,
+ Kind_ImportsList,
+ Kind_NamedImports,
+ Kind_ImportClause,
+ Kind_FromClause,
+ Kind_ImportDeclaration,
+ Kind_Module,
+ Kind_ExportSpecifier,
+ Kind_ExportsList,
+ Kind_ExportClause,
+ Kind_ExportDeclaration,
+ Kind_ModuleItemList,
Kind_NewExpression,
Kind_NewMemberExpression,
Kind_NotExpression,
@@ -2322,6 +2335,459 @@ public:
StatementList *statements;
};
+class QML_PARSER_EXPORT ImportSpecifier: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ImportSpecifier)
+
+ ImportSpecifier(const QStringRef &importedBinding)
+ : importedBinding(importedBinding)
+ {
+ kind = K;
+ }
+
+ ImportSpecifier(const QStringRef &identifier, const QStringRef &importedBinding)
+ : identifier(identifier), importedBinding(importedBinding)
+ {
+ kind = K;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return identifier.isNull() ? importedBindingToken : identifierToken; }
+ SourceLocation lastSourceLocation() const override
+ { return importedBindingToken; }
+
+// attributes
+ SourceLocation identifierToken;
+ SourceLocation importedBindingToken;
+ QStringRef identifier;
+ QStringRef importedBinding;
+};
+
+class QML_PARSER_EXPORT ImportsList: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ImportsList)
+
+ ImportsList(ImportSpecifier *importSpecifier)
+ : importSpecifier(importSpecifier)
+ {
+ kind = K;
+ next = this;
+ }
+
+ ImportsList(ImportsList *previous, ImportSpecifier *importSpecifier)
+ : importSpecifier(importSpecifier)
+ {
+ kind = K;
+ if (previous) {
+ next = previous->next;
+ previous->next = this;
+ } else {
+ next = this;
+ }
+ }
+
+ ImportsList *finish()
+ {
+ ImportsList *head = this;
+ next = nullptr;
+ return head;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return importSpecifierToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return next ? next->lastSourceLocation() : importSpecifierToken; }
+
+// attributes
+ SourceLocation importSpecifierToken;
+ ImportSpecifier *importSpecifier;
+ ImportsList *next = this;
+};
+
+class QML_PARSER_EXPORT NamedImports: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(NamedImports)
+
+ NamedImports()
+ {
+ kind = K;
+ }
+
+ NamedImports(ImportsList *importsList)
+ : importsList(importsList)
+ {
+ kind = K;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return leftBraceToken; }
+ SourceLocation lastSourceLocation() const override
+ { return rightBraceToken; }
+
+// attributes
+ SourceLocation leftBraceToken;
+ SourceLocation rightBraceToken;
+ ImportsList *importsList = nullptr;
+};
+
+class QML_PARSER_EXPORT NameSpaceImport: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(NameSpaceImport)
+
+ NameSpaceImport(const QStringRef &importedBinding)
+ : importedBinding(importedBinding)
+ {
+ kind = K;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ virtual SourceLocation firstSourceLocation() const override
+ { return starToken; }
+ virtual SourceLocation lastSourceLocation() const override
+ { return importedBindingToken; }
+
+// attributes
+ SourceLocation starToken;
+ SourceLocation importedBindingToken;
+ QStringRef importedBinding;
+};
+
+class QML_PARSER_EXPORT ImportClause: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ImportClause)
+
+ ImportClause(const QStringRef &importedDefaultBinding)
+ : importedDefaultBinding(importedDefaultBinding)
+ {
+ kind = K;
+ }
+
+ ImportClause(NameSpaceImport *nameSpaceImport)
+ : nameSpaceImport(nameSpaceImport)
+ {
+ kind = K;
+ }
+
+ ImportClause(NamedImports *namedImports)
+ : namedImports(namedImports)
+ {
+ kind = K;
+ }
+
+ ImportClause(const QStringRef &importedDefaultBinding, NameSpaceImport *nameSpaceImport)
+ : importedDefaultBinding(importedDefaultBinding)
+ , nameSpaceImport(nameSpaceImport)
+ {
+ kind = K;
+ }
+
+ ImportClause(const QStringRef &importedDefaultBinding, NamedImports *namedImports)
+ : importedDefaultBinding(importedDefaultBinding)
+ , namedImports(namedImports)
+ {
+ kind = K;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ virtual SourceLocation firstSourceLocation() const override
+ { return importedDefaultBinding.isNull() ? (nameSpaceImport ? nameSpaceImport->firstSourceLocation() : namedImports->firstSourceLocation()) : importedDefaultBindingToken; }
+ virtual SourceLocation lastSourceLocation() const override
+ { return importedDefaultBinding.isNull() ? (nameSpaceImport ? nameSpaceImport->lastSourceLocation() : namedImports->lastSourceLocation()) : importedDefaultBindingToken; }
+
+// attributes
+ SourceLocation importedDefaultBindingToken;
+ QStringRef importedDefaultBinding;
+ NameSpaceImport *nameSpaceImport = nullptr;
+ NamedImports *namedImports = nullptr;
+};
+
+class QML_PARSER_EXPORT FromClause: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(FromClause)
+
+ FromClause(const QStringRef &moduleSpecifier)
+ : moduleSpecifier(moduleSpecifier)
+ {
+ kind = K;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return fromToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return moduleSpecifierToken; }
+
+// attributes
+ SourceLocation fromToken;
+ SourceLocation moduleSpecifierToken;
+ QStringRef moduleSpecifier;
+};
+
+class QML_PARSER_EXPORT ImportDeclaration: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ImportDeclaration)
+
+ ImportDeclaration(ImportClause *importClause, FromClause *fromClause)
+ : importClause(importClause), fromClause(fromClause)
+ {
+ kind = K;
+ }
+
+ ImportDeclaration(const QStringRef &moduleSpecifier)
+ : moduleSpecifier(moduleSpecifier)
+ {
+ kind = K;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return importToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return moduleSpecifier.isNull() ? fromClause->lastSourceLocation() : moduleSpecifierToken; }
+
+// attributes
+ SourceLocation importToken;
+ SourceLocation moduleSpecifierToken;
+ QStringRef moduleSpecifier;
+ ImportClause *importClause = nullptr;
+ FromClause *fromClause = nullptr;
+};
+
+class QML_PARSER_EXPORT ExportSpecifier: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ExportSpecifier)
+
+ ExportSpecifier(const QStringRef &identifier)
+ : identifier(identifier), exportedIdentifier(identifier)
+ {
+ kind = K;
+ }
+
+ ExportSpecifier(const QStringRef &identifier, const QStringRef &exportedIdentifier)
+ : identifier(identifier), exportedIdentifier(exportedIdentifier)
+ {
+ kind = K;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return identifierToken; }
+ SourceLocation lastSourceLocation() const override
+ { return exportedIdentifierToken.isValid() ? exportedIdentifierToken : identifierToken; }
+
+// attributes
+ SourceLocation identifierToken;
+ SourceLocation exportedIdentifierToken;
+ QStringRef identifier;
+ QStringRef exportedIdentifier;
+};
+
+class QML_PARSER_EXPORT ExportsList: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ExportsList)
+
+ ExportsList(ExportSpecifier *exportSpecifier)
+ : exportSpecifier(exportSpecifier)
+ {
+ kind = K;
+ next = this;
+ }
+
+ ExportsList(ExportsList *previous, ExportSpecifier *exportSpecifier)
+ : exportSpecifier(exportSpecifier)
+ {
+ kind = K;
+ if (previous) {
+ next = previous->next;
+ previous->next = this;
+ } else {
+ next = this;
+ }
+ }
+
+ ExportsList *finish()
+ {
+ ExportsList *head = next;
+ next = nullptr;
+ return head;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return exportSpecifier->firstSourceLocation(); }
+ SourceLocation lastSourceLocation() const override
+ { return next ? next->lastSourceLocation() : exportSpecifier->lastSourceLocation(); }
+
+// attributes
+ ExportSpecifier *exportSpecifier;
+ ExportsList *next;
+};
+
+class QML_PARSER_EXPORT ExportClause: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ExportClause)
+
+ ExportClause()
+ {
+ kind = K;
+ }
+
+ ExportClause(ExportsList *exportsList)
+ : exportsList(exportsList)
+ {
+ kind = K;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return leftBraceToken; }
+ SourceLocation lastSourceLocation() const override
+ { return rightBraceToken; }
+
+// attributes
+ SourceLocation leftBraceToken;
+ SourceLocation rightBraceToken;
+ ExportsList *exportsList = nullptr;
+};
+
+class QML_PARSER_EXPORT ExportDeclaration: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ExportDeclaration)
+
+ ExportDeclaration(FromClause *fromClause)
+ : fromClause(fromClause)
+ {
+ exportAll = true;
+ kind = K;
+ }
+
+ ExportDeclaration(ExportClause *exportClause, FromClause *fromClause)
+ : exportClause(exportClause), fromClause(fromClause)
+ {
+ kind = K;
+ }
+
+ ExportDeclaration(ExportClause *exportClause)
+ : exportClause(exportClause)
+ {
+ kind = K;
+ }
+
+ ExportDeclaration(bool exportDefault, Node *variableStatementOrDeclaration)
+ : variableStatementOrDeclaration(variableStatementOrDeclaration)
+ , exportDefault(exportDefault)
+ {
+ kind = K;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return exportToken; }
+ SourceLocation lastSourceLocation() const override
+ { return fromClause ? fromClause->lastSourceLocation() : (exportClause ? exportClause->lastSourceLocation() : variableStatementOrDeclaration->lastSourceLocation()); }
+
+// attributes
+ SourceLocation exportToken;
+ bool exportAll = false;
+ ExportClause *exportClause = nullptr;
+ FromClause *fromClause = nullptr;
+ Node *variableStatementOrDeclaration = nullptr;
+ bool exportDefault = false;
+};
+
+class QML_PARSER_EXPORT ModuleItemList: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ModuleItemList)
+
+ ModuleItemList(Node *item)
+ : item(item)
+ {
+ kind = K;
+ next = this;
+ }
+
+ ModuleItemList(ModuleItemList *previous, Node *item)
+ : item(item)
+ {
+ kind = K;
+ if (previous) {
+ next = previous->next;
+ previous->next = this;
+ } else {
+ next = this;
+ }
+ }
+
+ ModuleItemList *finish()
+ {
+ ModuleItemList *head = next;
+ next = nullptr;
+ return head;
+ }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return item->firstSourceLocation(); }
+
+ SourceLocation lastSourceLocation() const override
+ { return next ? next->lastSourceLocation() : item->lastSourceLocation(); }
+
+// attributes
+ Node *item; // ImportDeclaration, ExportDeclaration or StatementList
+ ModuleItemList *next;
+};
+
+class QML_PARSER_EXPORT ESModule: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(Module)
+
+ ESModule(ModuleItemList *body)
+ : body(body)
+ { kind = K; }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return body ? body->firstSourceLocation() : SourceLocation(); }
+
+ SourceLocation lastSourceLocation() const override
+ { return body ? body->lastSourceLocation() : SourceLocation(); }
+
+// attributes
+ ModuleItemList *body;
+};
+
class QML_PARSER_EXPORT DebuggerStatement: public Statement
{
public:
diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h
index 406a06c6db..ce8ff8bfab 100644
--- a/src/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/parser/qqmljsastfwd_p.h
@@ -158,7 +158,22 @@ class Finally;
class FunctionDeclaration;
class FunctionExpression;
class FormalParameterList;
+class ExportSpecifier;
+class ExportsList;
+class ExportClause;
+class ExportDeclaration;
class Program;
+class ImportSpecifier;
+class ImportsList;
+class NamedImports;
+class NameSpaceImport;
+class NamedImport;
+class ImportClause;
+class FromClause;
+class ImportDeclaration;
+class ModuleItem;
+class ModuleItemList;
+class ESModule;
class DebuggerStatement;
class NestedExpression;
class ClassExpression;
diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h
index 6e1fed9dbb..21a2bc6019 100644
--- a/src/qml/parser/qqmljsastvisitor_p.h
+++ b/src/qml/parser/qqmljsastvisitor_p.h
@@ -335,6 +335,48 @@ public:
virtual bool visit(Program *) { return true; }
virtual void endVisit(Program *) {}
+ virtual bool visit(NameSpaceImport *) { return true; }
+ virtual void endVisit(NameSpaceImport *) {}
+
+ virtual bool visit(ImportSpecifier *) { return true; }
+ virtual void endVisit(ImportSpecifier *) {}
+
+ virtual bool visit(ImportsList *) { return true; }
+ virtual void endVisit(ImportsList *) {}
+
+ virtual bool visit(NamedImports *) { return true; }
+ virtual void endVisit(NamedImports *) {}
+
+ virtual bool visit(FromClause *) { return true; }
+ virtual void endVisit(FromClause *) {}
+
+ virtual bool visit(ImportClause *) { return true; }
+ virtual void endVisit(ImportClause *) {}
+
+ virtual bool visit(ImportDeclaration *) { return true; }
+ virtual void endVisit(ImportDeclaration *) {}
+
+ virtual bool visit(ExportSpecifier *) { return true; }
+ virtual void endVisit(ExportSpecifier *) {}
+
+ virtual bool visit(ExportsList *) { return true; }
+ virtual void endVisit(ExportsList *) {}
+
+ virtual bool visit(ExportClause *) { return true; }
+ virtual void endVisit(ExportClause *) {}
+
+ virtual bool visit(ExportDeclaration *) { return true; }
+ virtual void endVisit(ExportDeclaration *) {}
+
+ virtual bool visit(ModuleItem *) { return true; }
+ virtual void endVisit(ModuleItem *) {}
+
+ virtual bool visit(ModuleItemList *) { return true; }
+ virtual void endVisit(ModuleItemList *) {}
+
+ virtual bool visit(ESModule *) { return true; }
+ virtual void endVisit(ESModule *) {}
+
virtual bool visit(DebuggerStatement *) { return true; }
virtual void endVisit(DebuggerStatement *) {}
};