diff options
Diffstat (limited to 'src/qml/parser')
-rw-r--r-- | src/qml/parser/parser.pri | 17 | ||||
-rw-r--r-- | src/qml/parser/qqmljs.g | 4887 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast.cpp | 690 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 1432 | ||||
-rw-r--r-- | src/qml/parser/qqmljsastfwd_p.h | 69 | ||||
-rw-r--r-- | src/qml/parser/qqmljsastvisitor_p.h | 110 | ||||
-rw-r--r-- | src/qml/parser/qqmljsengine_p.cpp | 9 | ||||
-rw-r--r-- | src/qml/parser/qqmljsengine_p.h | 37 | ||||
-rw-r--r-- | src/qml/parser/qqmljsgrammar.cpp | 1111 | ||||
-rw-r--r-- | src/qml/parser/qqmljsgrammar_p.h | 214 | ||||
-rw-r--r-- | src/qml/parser/qqmljskeywords_p.h | 131 | ||||
-rw-r--r-- | src/qml/parser/qqmljslexer.cpp | 804 | ||||
-rw-r--r-- | src/qml/parser/qqmljslexer_p.h | 96 | ||||
-rw-r--r-- | src/qml/parser/qqmljsmemorypool_p.h | 128 | ||||
-rw-r--r-- | src/qml/parser/qqmljsparser.cpp | 1971 | ||||
-rw-r--r-- | src/qml/parser/qqmljsparser_p.h | 257 | ||||
-rw-r--r-- | src/qml/parser/qqmljssourcelocation_p.h | 87 |
17 files changed, 5616 insertions, 6434 deletions
diff --git a/src/qml/parser/parser.pri b/src/qml/parser/parser.pri index e5b8ae2749..2c0175c94b 100644 --- a/src/qml/parser/parser.pri +++ b/src/qml/parser/parser.pri @@ -3,20 +3,25 @@ HEADERS += \ $$PWD/qqmljsastfwd_p.h \ $$PWD/qqmljsastvisitor_p.h \ $$PWD/qqmljsengine_p.h \ - $$PWD/qqmljsgrammar_p.h \ $$PWD/qqmljslexer_p.h \ $$PWD/qqmljsmemorypool_p.h \ - $$PWD/qqmljsparser_p.h \ $$PWD/qqmljsglobal_p.h \ $$PWD/qqmljskeywords_p.h \ + $$PWD/qqmljsengine_p.h \ + $$PWD/qqmljsglobal_p.h \ + $$PWD/qqmljssourcelocation_p.h SOURCES += \ $$PWD/qqmljsast.cpp \ $$PWD/qqmljsastvisitor.cpp \ $$PWD/qqmljsengine_p.cpp \ - $$PWD/qqmljsgrammar.cpp \ $$PWD/qqmljslexer.cpp \ - $$PWD/qqmljsparser.cpp \ -OTHER_FILES += \ - $$PWD/qqmljs.g +CONFIG += qlalr +QLALRSOURCES = $$PWD/qqmljs.g +QMAKE_QLALRFLAGS = --no-debug --qt + +OTHER_FILES += $$QLALRSOURCES + +# make sure we install the headers generated by qlalr +private_headers.CONFIG += no_check_exist diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index ca84e0c157..b86dba6daa 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -40,8 +40,7 @@ %parser QQmlJSGrammar %decl qqmljsparser_p.h %impl qqmljsparser.cpp -%expect 5 -%expect-rr 2 +%expect 1 %token T_AND "&" T_AND_AND "&&" T_AND_EQ "&=" %token T_BREAK "break" T_CASE "case" T_CATCH "catch" @@ -64,7 +63,8 @@ %token T_RBRACE "}" T_RBRACKET "]" T_REMAINDER "%" %token T_REMAINDER_EQ "%=" T_RETURN "return" T_RPAREN ")" %token T_SEMICOLON ";" T_AUTOMATIC_SEMICOLON T_STAR "*" -%token T_STAR_EQ "*=" T_STRING_LITERAL "string literal" +%token T_STAR_STAR "**" T_STAR_STAR_EQ "**=" T_STAR_EQ "*=" +%token T_STRING_LITERAL "string literal" %token T_PROPERTY "property" T_SIGNAL "signal" T_READONLY "readonly" %token T_SWITCH "switch" T_THIS "this" T_THROW "throw" %token T_TILDE "~" T_TRY "try" T_TYPEOF "typeof" @@ -77,13 +77,29 @@ %token T_MULTILINE_STRING_LITERAL "multiline string literal" %token T_COMMENT "comment" %token T_COMPATIBILITY_SEMICOLON +%token T_ARROW "=>" +%token T_ENUM "enum" +%token T_ELLIPSIS "..." +%token T_YIELD "yield" +%token T_SUPER "super" +%token T_CLASS "class" +%token T_EXTENDS "extends" +%token T_STATIC "static" +%token T_EXPORT "export" +%token T_FROM "from" + +--- template strings +%token T_NO_SUBSTITUTION_TEMPLATE"(no subst template)" +%token T_TEMPLATE_HEAD "(template head)" +%token T_TEMPLATE_MIDDLE "(template middle)" +%token T_TEMPLATE_TAIL "(template tail)" --- context keywords. %token T_PUBLIC "public" %token T_IMPORT "import" %token T_PRAGMA "pragma" %token T_AS "as" -%token T_ON "on" +%token T_OF "of" %token T_GET "get" %token T_SET "set" @@ -94,11 +110,16 @@ %token T_FEED_UI_OBJECT_MEMBER %token T_FEED_JS_STATEMENT %token T_FEED_JS_EXPRESSION -%token T_FEED_JS_SOURCE_ELEMENT -%token T_FEED_JS_PROGRAM +%token T_FEED_JS_SCRIPT +%token T_FEED_JS_MODULE -%nonassoc SHIFT_THERE -%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET +--- Lookahead handling +%token T_FORCE_DECLARATION "(force decl)" +%token T_FORCE_BLOCK "(force block)" +%token T_FOR_LOOKAHEAD_OK "(for lookahead ok)" + +--%left T_PLUS T_MINUS +%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET T_OF T_STATIC T_FROM T_AS %nonassoc REDUCE_HERE %start TopLevel @@ -142,10 +163,10 @@ ** ****************************************************************************/ -#include "qqmljsengine_p.h" -#include "qqmljslexer_p.h" -#include "qqmljsast_p.h" -#include "qqmljsmemorypool_p.h" +#include <private/qqmljsengine_p.h> +#include <private/qqmljslexer_p.h> +#include <private/qqmljsast_p.h> +#include <private/qqmljsmemorypool_p.h> #include <QtCore/qdebug.h> #include <QtCore/qcoreapplication.h> @@ -220,10 +241,10 @@ #ifndef QQMLJSPARSER_P_H #define QQMLJSPARSER_P_H -#include "qqmljsglobal_p.h" -#include "qqmljsgrammar_p.h" -#include "qqmljsast_p.h" -#include "qqmljsengine_p.h" +#include <private/qqmljsglobal_p.h> +#include <private/qqmljsgrammar_p.h> +#include <private/qqmljsast_p.h> +#include <private/qqmljsengine_p.h> #include <QtCore/qlist.h> #include <QtCore/qstring.h> @@ -240,30 +261,42 @@ public: union Value { int ival; double dval; + AST::VariableScope scope; + AST::ForEachType forEachType; AST::ArgumentList *ArgumentList; AST::CaseBlock *CaseBlock; AST::CaseClause *CaseClause; AST::CaseClauses *CaseClauses; AST::Catch *Catch; AST::DefaultClause *DefaultClause; - AST::ElementList *ElementList; AST::Elision *Elision; AST::ExpressionNode *Expression; + AST::TemplateLiteral *Template; AST::Finally *Finally; AST::FormalParameterList *FormalParameterList; - AST::FunctionBody *FunctionBody; AST::FunctionDeclaration *FunctionDeclaration; AST::Node *Node; AST::PropertyName *PropertyName; - AST::PropertyAssignment *PropertyAssignment; - AST::PropertyAssignmentList *PropertyAssignmentList; - AST::SourceElement *SourceElement; - AST::SourceElements *SourceElements; AST::Statement *Statement; AST::StatementList *StatementList; AST::Block *Block; - AST::VariableDeclaration *VariableDeclaration; AST::VariableDeclarationList *VariableDeclarationList; + AST::Pattern *Pattern; + AST::PatternElement *PatternElement; + AST::PatternElementList *PatternElementList; + AST::PatternProperty *PatternProperty; + AST::PatternPropertyList *PatternPropertyList; + AST::ClassElementList *ClassElementList; + 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; @@ -280,7 +313,7 @@ public: AST::UiObjectMemberList *UiObjectMemberList; AST::UiArrayMemberList *UiArrayMemberList; AST::UiQualifiedId *UiQualifiedId; - AST::UiQualifiedPragmaId *UiQualifiedPragmaId; + AST::UiEnumMemberList *UiEnumMemberList; }; public: @@ -288,12 +321,13 @@ public: ~Parser(); // parse a UI program - bool parse() { return parse(T_FEED_UI_PROGRAM); } + bool parse() { ++functionNestingLevel; bool r = parse(T_FEED_UI_PROGRAM); --functionNestingLevel; return r; } bool parseStatement() { return parse(T_FEED_JS_STATEMENT); } bool parseExpression() { return parse(T_FEED_JS_EXPRESSION); } - bool parseSourceElement() { return parse(T_FEED_JS_SOURCE_ELEMENT); } - bool parseUiObjectMember() { return parse(T_FEED_UI_OBJECT_MEMBER); } - bool parseProgram() { return parse(T_FEED_JS_PROGRAM); } + bool parseUiObjectMember() { ++functionNestingLevel; bool r = parse(T_FEED_UI_OBJECT_MEMBER); --functionNestingLevel; return r; } + bool parseProgram() { return parse(T_FEED_JS_SCRIPT); } + bool parseScript() { return parse(T_FEED_JS_SCRIPT); } + bool parseModule() { return parse(T_FEED_JS_MODULE); } AST::UiProgram *ast() const { return AST::cast<AST::UiProgram *>(program); } @@ -358,42 +392,68 @@ protected: inline QStringRef &stringRef(int index) { return string_stack [tos + index - 1]; } + inline QStringRef &rawStringRef(int index) + { return rawString_stack [tos + index - 1]; } + inline AST::SourceLocation &loc(int index) { return location_stack [tos + index - 1]; } AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr); - AST::UiQualifiedPragmaId *reparseAsQualifiedPragmaId(AST::ExpressionNode *expr); + + void pushToken(int token); + int lookaheadToken(Lexer *lexer); + + void syntaxError(const AST::SourceLocation &location, const char *message) { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location, QLatin1String(message))); + } + void syntaxError(const AST::SourceLocation &location, const QString &message) { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location, message)); + } protected: Engine *driver; MemoryPool *pool; - int tos; - int stack_size; - Value *sym_stack; - int *state_stack; - AST::SourceLocation *location_stack; - QStringRef *string_stack; + int tos = 0; + int stack_size = 0; + Value *sym_stack = nullptr; + int *state_stack = nullptr; + AST::SourceLocation *location_stack = nullptr; + QVector<QStringRef> string_stack; + QVector<QStringRef> rawString_stack; - AST::Node *program; + AST::Node *program = nullptr; - // error recovery - enum { TOKEN_BUFFER_SIZE = 3 }; + // error recovery and lookahead handling + enum { TOKEN_BUFFER_SIZE = 5 }; struct SavedToken { int token; double dval; AST::SourceLocation loc; QStringRef spell; + QStringRef raw; }; - double yylval; + int yytoken = -1; + double yylval = 0.; QStringRef yytokenspell; + QStringRef yytokenraw; AST::SourceLocation yylloc; AST::SourceLocation yyprevlloc; SavedToken token_buffer[TOKEN_BUFFER_SIZE]; - SavedToken *first_token; - SavedToken *last_token; + SavedToken *first_token = nullptr; + SavedToken *last_token = nullptr; + + int functionNestingLevel = 0; + + enum CoverExpressionType { + CE_Invalid, + CE_ParenthesizedExpression, + CE_FormalParameterList + }; + AST::SourceLocation coverExpressionErrorLocation; + CoverExpressionType coverExpressionType = CE_Invalid; QList<DiagnosticMessage> diagnostic_messages; }; @@ -422,6 +482,8 @@ protected: // qlalr --no-debug --no-lines --qt qqmljs.g // +#define UNIMPLEMENTED syntaxError(loc(1), "Unimplemented"); return false + using namespace QQmlJS; QT_QML_BEGIN_NAMESPACE @@ -436,21 +498,13 @@ void Parser::reallocateStack() sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value))); state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int))); location_stack = reinterpret_cast<AST::SourceLocation*> (realloc(location_stack, stack_size * sizeof(AST::SourceLocation))); - string_stack = reinterpret_cast<QStringRef*> (realloc(string_stack, stack_size * sizeof(QStringRef))); + string_stack.resize(stack_size); + rawString_stack.resize(stack_size); } Parser::Parser(Engine *engine): driver(engine), - pool(engine->pool()), - tos(0), - stack_size(0), - sym_stack(0), - state_stack(0), - location_stack(0), - string_stack(0), - program(0), - first_token(0), - last_token(0) + pool(engine->pool()) { } @@ -460,7 +514,6 @@ Parser::~Parser() free(sym_stack); free(state_stack); free(location_stack); - free(string_stack); } } @@ -502,29 +555,43 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr) return 0; } -AST::UiQualifiedPragmaId *Parser::reparseAsQualifiedPragmaId(AST::ExpressionNode *expr) +void Parser::pushToken(int token) { - if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(expr)) { - AST::UiQualifiedPragmaId *q = new (pool) AST::UiQualifiedPragmaId(idExpr->name); - q->identifierToken = idExpr->identifierToken; + Q_ASSERT(last_token); + Q_ASSERT(last_token < &token_buffer[TOKEN_BUFFER_SIZE]); + last_token->token = yytoken; + last_token->dval = yylval; + last_token->spell = yytokenspell; + last_token->raw = yytokenraw; + last_token->loc = yylloc; + ++last_token; + yytoken = token; +} - return q->finish(); +int Parser::lookaheadToken(Lexer *lexer) +{ + if (yytoken < 0) { + yytoken = lexer->lex(); + yylval = lexer->tokenValue(); + yytokenspell = lexer->tokenSpell(); + yytokenraw = lexer->rawString(); + yylloc = location(lexer); } - - return 0; + return yytoken; } +//#define PARSER_DEBUG bool Parser::parse(int startToken) { Lexer *lexer = driver->lexer(); bool hadErrors = false; - int yytoken = -1; + yytoken = -1; int action = 0; token_buffer[0].token = startToken; first_token = &token_buffer[0]; - if (startToken == T_FEED_JS_PROGRAM && !lexer->qmlMode()) { + if (startToken == T_FEED_JS_SCRIPT && !lexer->qmlMode()) { Directives ignoreDirectives; Directives *directives = driver->directives(); if (!directives) @@ -547,8 +614,16 @@ bool Parser::parse(int startToken) program = 0; do { - if (++tos == stack_size) + if (++tos == stack_size) { reallocateStack(); + if (stack_size > 10000) { + // We're now in some serious right-recursive stuff, which will probably result in + // an AST that's so deep that recursively visiting it will run out of stack space. + const QString msg = QCoreApplication::translate("QQmlParser", "Maximum statement or expression depth exceeded"); + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg)); + return false; + } + } state_stack[tos] = action; @@ -560,22 +635,34 @@ bool Parser::parse(int startToken) yytoken = lexer->lex(); yylval = lexer->tokenValue(); yytokenspell = lexer->tokenSpell(); + yytokenraw = lexer->rawString(); yylloc = location(lexer); } else { yytoken = first_token->token; yylval = first_token->dval; yytokenspell = first_token->spell; + yytokenraw = first_token->raw; yylloc = first_token->loc; ++first_token; + if (first_token == last_token) + first_token = last_token = &token_buffer[0]; } } +#ifdef PARSER_DEBUG + qDebug() << " in state" << action; +#endif + action = t_action(action, yytoken); +#ifdef PARSER_DEBUG + qDebug() << " current token" << yytoken << (yytoken >= 0 ? spell[yytoken] : "(null)") << "new state" << action; +#endif if (action > 0) { if (action != ACCEPT_STATE) { yytoken = -1; sym(1).dval = yylval; stringRef(1) = yytokenspell; + rawStringRef(1) = yytokenraw; loc(1) = yylloc; } else { --tos; @@ -585,6 +672,10 @@ bool Parser::parse(int startToken) const int r = -action - 1; tos -= rhs[r]; +#ifdef PARSER_DEBUG + qDebug() << " reducing through rule " << -action; +#endif + switch (r) { ./ @@ -592,2532 +683,3702 @@ bool Parser::parse(int startToken) -- Declarative UI -------------------------------------------------------------------------------------------------------- -TopLevel: T_FEED_UI_PROGRAM UiProgram ; +TopLevel: T_FEED_UI_PROGRAM UiProgram; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ -TopLevel: T_FEED_JS_STATEMENT Statement ; +TopLevel: T_FEED_JS_STATEMENT Statement; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ -TopLevel: T_FEED_JS_EXPRESSION Expression ; +TopLevel: T_FEED_JS_EXPRESSION Expression; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ -TopLevel: T_FEED_JS_SOURCE_ELEMENT SourceElement ; +TopLevel: T_FEED_UI_OBJECT_MEMBER UiObjectMember; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ -TopLevel: T_FEED_UI_OBJECT_MEMBER UiObjectMember ; +TopLevel: T_FEED_JS_SCRIPT Script; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ -TopLevel: T_FEED_JS_PROGRAM Program ; +TopLevel: T_FEED_JS_MODULE Module; /. -case $rule_number: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + program = sym(1).Node; + } break; ./ + UiProgram: UiHeaderItemListOpt UiRootMember; /. -case $rule_number: { - sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiHeaderItemList, - sym(2).UiObjectMemberList->finish()); -} break; + case $rule_number: { + sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiHeaderItemList, sym(2).UiObjectMemberList->finish()); + } break; ./ -UiHeaderItemListOpt: Empty ; -UiHeaderItemListOpt: UiHeaderItemList ; +UiHeaderItemListOpt: Empty; +UiHeaderItemListOpt: UiHeaderItemList; /. -case $rule_number: { - sym(1).Node = sym(1).UiHeaderItemList->finish(); -} break; + case $rule_number: { + sym(1).Node = sym(1).UiHeaderItemList->finish(); + } break; ./ -UiHeaderItemList: UiPragma ; +UiHeaderItemList: UiPragma; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiPragma); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiPragma); + } break; ./ -UiHeaderItemList: UiImport ; +UiHeaderItemList: UiImport; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiImport); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiImport); + } break; ./ -UiHeaderItemList: UiHeaderItemList UiPragma ; +UiHeaderItemList: UiHeaderItemList UiPragma; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiPragma); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiPragma); + } break; ./ -UiHeaderItemList: UiHeaderItemList UiImport ; +UiHeaderItemList: UiHeaderItemList UiImport; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiImport); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiImport); + } break; ./ -PragmaId: MemberExpression ; - -ImportId: MemberExpression ; +PragmaId: JsIdentifier; -UiPragma: UiPragmaHead T_AUTOMATIC_SEMICOLON ; -UiPragma: UiPragmaHead T_SEMICOLON ; +UiPragma: T_PRAGMA PragmaId T_AUTOMATIC_SEMICOLON; +UiPragma: T_PRAGMA PragmaId T_SEMICOLON; /. -case $rule_number: { - sym(1).UiPragma->semicolonToken = loc(2); -} break; + case $rule_number: { + AST::UiPragma *pragma = new (pool) AST::UiPragma(stringRef(2)); + pragma->pragmaToken = loc(1); + pragma->semicolonToken = loc(3); + sym(1).Node = pragma; + } break; ./ -UiImport: UiImportHead T_AUTOMATIC_SEMICOLON ; -UiImport: UiImportHead T_SEMICOLON ; +ImportId: MemberExpression; + +UiImport: UiImportHead T_AUTOMATIC_SEMICOLON; +UiImport: UiImportHead T_SEMICOLON; /. -case $rule_number: { - sym(1).UiImport->semicolonToken = loc(2); -} break; + case $rule_number: { + sym(1).UiImport->semicolonToken = loc(2); + } break; ./ -UiImport: UiImportHead T_NUMERIC_LITERAL T_AUTOMATIC_SEMICOLON ; -UiImport: UiImportHead T_NUMERIC_LITERAL T_SEMICOLON ; +UiImport: UiImportHead T_NUMERIC_LITERAL T_AUTOMATIC_SEMICOLON; +UiImport: UiImportHead T_NUMERIC_LITERAL T_SEMICOLON; /. -case $rule_number: { - sym(1).UiImport->versionToken = loc(2); - sym(1).UiImport->semicolonToken = loc(3); -} break; + case $rule_number: { + sym(1).UiImport->versionToken = loc(2); + sym(1).UiImport->semicolonToken = loc(3); + } break; ./ -UiImport: UiImportHead T_NUMERIC_LITERAL T_AS JsIdentifier T_AUTOMATIC_SEMICOLON ; -UiImport: UiImportHead T_NUMERIC_LITERAL T_AS JsIdentifier T_SEMICOLON ; +UiImport: UiImportHead T_NUMERIC_LITERAL T_AS QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiImport: UiImportHead T_NUMERIC_LITERAL T_AS QmlIdentifier T_SEMICOLON; /. -case $rule_number: { - sym(1).UiImport->versionToken = loc(2); - sym(1).UiImport->asToken = loc(3); - sym(1).UiImport->importIdToken = loc(4); - sym(1).UiImport->importId = stringRef(4); - sym(1).UiImport->semicolonToken = loc(5); -} break; + case $rule_number: { + sym(1).UiImport->versionToken = loc(2); + sym(1).UiImport->asToken = loc(3); + sym(1).UiImport->importIdToken = loc(4); + sym(1).UiImport->importId = stringRef(4); + sym(1).UiImport->semicolonToken = loc(5); + } break; ./ -UiImport: UiImportHead T_AS JsIdentifier T_AUTOMATIC_SEMICOLON ; -UiImport: UiImportHead T_AS JsIdentifier T_SEMICOLON ; +UiImport: UiImportHead T_AS QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiImport: UiImportHead T_AS QmlIdentifier T_SEMICOLON; /. -case $rule_number: { - sym(1).UiImport->asToken = loc(2); - sym(1).UiImport->importIdToken = loc(3); - sym(1).UiImport->importId = stringRef(3); - sym(1).UiImport->semicolonToken = loc(4); -} break; + case $rule_number: { + sym(1).UiImport->asToken = loc(2); + sym(1).UiImport->importIdToken = loc(3); + sym(1).UiImport->importId = stringRef(3); + sym(1).UiImport->semicolonToken = loc(4); + } break; ./ -UiPragmaHead: T_PRAGMA PragmaId ; +UiImportHead: T_IMPORT ImportId; /. -case $rule_number: { - AST::UiPragma *node = 0; + case $rule_number: { + AST::UiImport *node = 0; - if (AST::UiQualifiedPragmaId *qualifiedId = reparseAsQualifiedPragmaId(sym(2).Expression)) { - node = new (pool) AST::UiPragma(qualifiedId); - } + if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) { + node = new (pool) AST::UiImport(importIdLiteral->value); + node->fileNameToken = loc(2); + } else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) { + node = new (pool) AST::UiImport(qualifiedId); + node->fileNameToken = loc(2); + } - sym(1).Node = node; + sym(1).Node = node; - if (node) { - node->pragmaToken = loc(1); - } else { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), - QLatin1String("Expected a qualified name id"))); + if (node) { + node->importToken = loc(1); + } else { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), + QLatin1String("Expected a qualified name id or a string literal"))); - return false; // ### remove me - } -} break; + return false; // ### remove me + } + } break; ./ - -UiImportHead: T_IMPORT ImportId ; +Empty: ; /. -case $rule_number: { - AST::UiImport *node = 0; - - if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) { - node = new (pool) AST::UiImport(importIdLiteral->value); - node->fileNameToken = loc(2); - } else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) { - node = new (pool) AST::UiImport(qualifiedId); - node->fileNameToken = loc(2); - } - - sym(1).Node = node; + case $rule_number: { + sym(1).Node = nullptr; + } break; +./ - if (node) { - node->importToken = loc(1); - } else { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), - QLatin1String("Expected a qualified name id or a string literal"))); +UiRootMember: UiObjectDefinition; +/. + case $rule_number: { + sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); + } break; +./ - return false; // ### remove me - } -} break; +UiObjectMemberList: UiObjectMember; +/. + case $rule_number: { + sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); + } break; ./ -Empty: ; +UiObjectMemberList: UiObjectMemberList UiObjectMember; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(sym(1).UiObjectMemberList, sym(2).UiObjectMember); + sym(1).Node = node; + } break; ./ -UiRootMember: UiObjectDefinition ; +UiArrayMemberList: UiObjectDefinition; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember); + } break; ./ -UiObjectMemberList: UiObjectMember ; +UiArrayMemberList: UiArrayMemberList T_COMMA UiObjectDefinition; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); -} break; + case $rule_number: { + AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(sym(1).UiArrayMemberList, sym(3).UiObjectMember); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ -UiObjectMemberList: UiObjectMemberList UiObjectMember ; +UiObjectInitializer: T_LBRACE T_RBRACE; /. -case $rule_number: { - AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList( - sym(1).UiObjectMemberList, sym(2).UiObjectMember); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0); + node->lbraceToken = loc(1); + node->rbraceToken = loc(2); + sym(1).Node = node; + } break; ./ -UiArrayMemberList: UiObjectDefinition ; +UiObjectInitializer: T_LBRACE UiObjectMemberList T_RBRACE; /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember); -} break; + case $rule_number: { + AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish()); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + sym(1).Node = node; + } break; ./ -UiArrayMemberList: UiArrayMemberList T_COMMA UiObjectDefinition ; +UiObjectDefinition: UiQualifiedId UiObjectInitializer; /. -case $rule_number: { - AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList( - sym(1).UiArrayMemberList, sym(3).UiObjectMember); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId, sym(2).UiObjectInitializer); + sym(1).Node = node; + } break; ./ -UiObjectInitializer: T_LBRACE T_RBRACE ; +UiObjectMember: UiObjectDefinition; + +UiObjectMember: UiQualifiedId T_COLON ExpressionStatementLookahead T_LBRACKET UiArrayMemberList T_RBRACKET; /. -case $rule_number: { - AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0); - node->lbraceToken = loc(1); - node->rbraceToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding(sym(1).UiQualifiedId, sym(5).UiArrayMemberList->finish()); + node->colonToken = loc(2); + node->lbracketToken = loc(4); + node->rbracketToken = loc(6); + sym(1).Node = node; + } break; ./ -UiObjectInitializer: T_LBRACE UiObjectMemberList T_RBRACE ; +UiObjectMember: UiQualifiedId T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer; /. -case $rule_number: { - AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish()); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding( + sym(1).UiQualifiedId, sym(4).UiQualifiedId, sym(5).UiObjectInitializer); + node->colonToken = loc(2); + sym(1).Node = node; + } break; ./ -UiObjectDefinition: UiQualifiedId UiObjectInitializer ; +UiObjectMember: UiQualifiedId T_ON UiQualifiedId UiObjectInitializer; /. -case $rule_number: { - AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId, - sym(2).UiObjectInitializer); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding( + sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer); + node->colonToken = loc(2); + node->hasOnToken = true; + sym(1).Node = node; + } break; ./ -UiObjectMember: UiObjectDefinition ; -UiObjectMember: UiQualifiedId T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ; +UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_RBRACE; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_COMMA T_RBRACE; /. -case $rule_number: { - AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding( - sym(1).UiQualifiedId, sym(4).UiArrayMemberList->finish()); - node->colonToken = loc(2); - node->lbracketToken = loc(3); - node->rbracketToken = loc(5); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ObjectPattern *l = new (pool) AST::ObjectPattern(sym(3).PatternPropertyList->finish()); + l->lbraceToken = loc(1); + l->rbraceToken = loc(4); + AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(l); + sym(1).Node = node; + } break; ./ -UiObjectMember: UiQualifiedId T_COLON UiQualifiedId UiObjectInitializer ; + +UiScriptStatement: ExpressionStatementLookahead T_FORCE_DECLARATION ExpressionStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead T_FORCE_BLOCK Block; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead T_FORCE_BLOCK UiObjectLiteral; /. -case $rule_number: { - AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding( - sym(1).UiQualifiedId, sym(3).UiQualifiedId, sym(4).UiObjectInitializer); - node->colonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(3).Node; + } break; ./ -UiObjectMember: UiQualifiedId T_ON UiQualifiedId UiObjectInitializer ; + +UiScriptStatement: ExpressionStatementLookahead EmptyStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead ExpressionStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead IfStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead WithStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead SwitchStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiScriptStatement: ExpressionStatementLookahead TryStatement; /. -case $rule_number: { - AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding( - sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer); - node->colonToken = loc(2); - node->hasOnToken = true; - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + } break; ./ -UiScriptStatement: Block ; -UiScriptStatement: EmptyStatement ; -UiScriptStatement: ExpressionStatement ; -UiScriptStatement: IfStatement ; -UiScriptStatement: WithStatement ; -UiScriptStatement: SwitchStatement ; -UiScriptStatement: TryStatement ; - -UiObjectMember: UiQualifiedId T_COLON UiScriptStatement ; +UiObjectMember: UiQualifiedId T_COLON UiScriptStatement; /. case $rule_number: { - AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding( - sym(1).UiQualifiedId, sym(3).Statement); + AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding(sym(1).UiQualifiedId, sym(3).Statement); node->colonToken = loc(2); sym(1).Node = node; -} break; + } break; ./ -UiPropertyType: T_VAR ; +UiPropertyType: T_VAR; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiPropertyType: T_RESERVED_WORD; +/. case $rule_number: Q_FALLTHROUGH(); ./ +UiPropertyType: T_IDENTIFIER; /. -case $rule_number: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); + node->identifierToken = loc(1); + sym(1).Node = node; + } break; ./ -UiPropertyType: T_RESERVED_WORD ; +UiPropertyType: UiPropertyType T_DOT T_IDENTIFIER; /. -case $rule_number: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(sym(1).UiQualifiedId, stringRef(3)); + node->identifierToken = loc(3); + sym(1).Node = node; + } break; ./ -UiPropertyType: T_IDENTIFIER ; +UiParameterListOpt: ; /. -case $rule_number: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -UiPropertyType: UiPropertyType T_DOT T_IDENTIFIER ; +UiParameterListOpt: UiParameterList; /. -case $rule_number: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(sym(1).UiQualifiedId, stringRef(3)); - node->identifierToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(1).UiParameterList->finish(); + } break; ./ -UiParameterListOpt: ; +UiParameterList: UiPropertyType QmlIdentifier; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiQualifiedId->finish(), stringRef(2)); + node->propertyTypeToken = loc(1); + node->identifierToken = loc(2); + sym(1).Node = node; + } break; +./ + +UiParameterList: UiParameterList T_COMMA UiPropertyType QmlIdentifier; +/. + case $rule_number: { + AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(3).UiQualifiedId->finish(), stringRef(4)); + node->propertyTypeToken = loc(3); + node->commaToken = loc(2); + node->identifierToken = loc(4); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); + node->type = AST::UiPublicMember::Signal; + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(2); + node->parameters = sym(4).UiParameterList; + node->semicolonToken = loc(6); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_SIGNAL T_IDENTIFIER T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_SIGNAL T_IDENTIFIER T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); + node->type = AST::UiPublicMember::Signal; + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(2); + node->semicolonToken = loc(3); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6)); + node->typeModifier = stringRef(2); + node->propertyToken = loc(1); + node->typeModifierToken = loc(2); + node->typeToken = loc(4); + node->identifierToken = loc(6); + node->semicolonToken = loc(7); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(3); + node->semicolonToken = loc(4); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4)); + node->isDefaultMember = true; + node->defaultToken = loc(1); + node->propertyToken = loc(2); + node->typeToken = loc(3); + node->identifierToken = loc(4); + node->semicolonToken = loc(5); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_AUTOMATIC_SEMICOLON; +UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_SEMICOLON; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7)); + node->isDefaultMember = true; + node->defaultToken = loc(1); + node->typeModifier = stringRef(3); + node->propertyToken = loc(2); + node->typeModifierToken = loc(2); + node->typeToken = loc(4); + node->identifierToken = loc(7); + node->semicolonToken = loc(8); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3), sym(5).Statement); + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(3); + node->colonToken = loc(4); + sym(1).Node = node; + } break; +./ + +UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement; +/. + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), sym(6).Statement); + node->isReadonlyMember = true; + node->readonlyToken = loc(1); + node->propertyToken = loc(2); + node->typeToken = loc(3); + node->identifierToken = loc(4); + node->colonToken = loc(5); + sym(1).Node = node; + } break; ./ -UiParameterListOpt: UiParameterList ; +UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement; /. -case $rule_number: { - sym(1).Node = sym(1).UiParameterList->finish (); -} break; + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), sym(6).Statement); + node->isDefaultMember = true; + node->defaultToken = loc(1); + node->propertyToken = loc(2); + node->typeToken = loc(3); + node->identifierToken = loc(4); + node->colonToken = loc(5); + sym(1).Node = node; + } break; ./ -UiParameterList: UiPropertyType JsIdentifier ; +UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET; /. -case $rule_number: { - AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiQualifiedId->finish(), stringRef(2)); - node->propertyTypeToken = loc(1); - node->identifierToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6)); + node->typeModifier = stringRef(2); + node->propertyToken = loc(1); + node->typeModifierToken = loc(2); + node->typeToken = loc(4); + node->identifierToken = loc(6); + node->semicolonToken = loc(7); // insert a fake ';' before ':' + + AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6)); + propertyName->identifierToken = loc(6); + propertyName->next = 0; + + AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(propertyName, sym(9).UiArrayMemberList->finish()); + binding->colonToken = loc(7); + binding->lbracketToken = loc(8); + binding->rbracketToken = loc(10); + + node->binding = binding; + + sym(1).Node = node; + } break; ./ -UiParameterList: UiParameterList T_COMMA UiPropertyType JsIdentifier ; +UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer; /. -case $rule_number: { - AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(3).UiQualifiedId->finish(), stringRef(4)); - node->propertyTypeToken = loc(3); - node->commaToken = loc(2); - node->identifierToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); + node->propertyToken = loc(1); + node->typeToken = loc(2); + node->identifierToken = loc(3); + node->semicolonToken = loc(4); // insert a fake ';' before ':' + + AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3)); + propertyName->identifierToken = loc(3); + propertyName->next = 0; + + AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( + propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer); + binding->colonToken = loc(4); + + node->binding = binding; + + sym(1).Node = node; + } break; ./ -UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_SEMICOLON ; +UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); - node->type = AST::UiPublicMember::Signal; - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(2); - node->parameters = sym(4).UiParameterList; - node->semicolonToken = loc(6); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4)); + node->isReadonlyMember = true; + node->readonlyToken = loc(1); + node->propertyToken = loc(2); + node->typeToken = loc(3); + node->identifierToken = loc(4); + node->semicolonToken = loc(5); // insert a fake ';' before ':' + + AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4)); + propertyName->identifierToken = loc(4); + propertyName->next = 0; + + AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( + propertyName, sym(7).UiQualifiedId, sym(8).UiObjectInitializer); + binding->colonToken = loc(5); + + node->binding = binding; + + sym(1).Node = node; + } break; ./ -UiObjectMember: T_SIGNAL T_IDENTIFIER T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_SIGNAL T_IDENTIFIER T_SEMICOLON ; +UiObjectMember: FunctionDeclaration; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); - node->type = AST::UiPublicMember::Signal; - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(2); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); + } break; ./ -UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_SEMICOLON ; +UiObjectMember: VariableStatement; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6)); - node->typeModifier = stringRef(2); - node->propertyToken = loc(1); - node->typeModifierToken = loc(2); - node->typeToken = loc(4); - node->identifierToken = loc(6); - node->semicolonToken = loc(7); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); + } break; ./ -UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_SEMICOLON ; +UiQualifiedId: MemberExpression; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(3); - node->semicolonToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken, + QLatin1String("Ignored annotation"))); + + sym(1).Expression = mem->base; + } + + if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) { + sym(1).UiQualifiedId = qualifiedId; + } else { + sym(1).UiQualifiedId = 0; + + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), + QLatin1String("Expected a qualified name id"))); + + return false; // ### recover + } + } break; ./ -UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_SEMICOLON ; +UiObjectMember: T_ENUM T_IDENTIFIER T_LBRACE EnumMemberList T_RBRACE; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4)); - node->isDefaultMember = true; - node->defaultToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->semicolonToken = loc(5); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiEnumDeclaration *enumDeclaration = new (pool) AST::UiEnumDeclaration(stringRef(2), sym(4).UiEnumMemberList->finish()); + enumDeclaration->enumToken = loc(1); + enumDeclaration->rbraceToken = loc(5); + sym(1).Node = enumDeclaration; + break; + } ./ -UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_AUTOMATIC_SEMICOLON ; -UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_SEMICOLON ; +EnumMemberList: T_IDENTIFIER; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7)); - node->isDefaultMember = true; - node->defaultToken = loc(1); - node->typeModifier = stringRef(3); - node->propertyToken = loc(2); - node->typeModifierToken = loc(2); - node->typeToken = loc(4); - node->identifierToken = loc(7); - node->semicolonToken = loc(8); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1)); + node->memberToken = loc(1); + sym(1).Node = node; + break; + } ./ -UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ; +EnumMemberList: T_IDENTIFIER T_EQ T_NUMERIC_LITERAL; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3), - sym(5).Statement); - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(3); - node->colonToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1), sym(3).dval); + node->memberToken = loc(1); + node->valueToken = loc(3); + sym(1).Node = node; + break; + } ./ -UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ; +EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), - sym(6).Statement); - node->isReadonlyMember = true; - node->readonlyToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->colonToken = loc(5); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3)); + node->memberToken = loc(3); + sym(1).Node = node; + break; + } ./ -UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ; +EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER T_EQ T_NUMERIC_LITERAL; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), - sym(6).Statement); - node->isDefaultMember = true; - node->defaultToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->colonToken = loc(5); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3), sym(5).dval); + node->memberToken = loc(3); + node->valueToken = loc(5); + sym(1).Node = node; + break; + } ./ -UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ; +QmlIdentifier: T_IDENTIFIER; +QmlIdentifier: T_PROPERTY; +QmlIdentifier: T_SIGNAL; +QmlIdentifier: T_READONLY; +QmlIdentifier: T_ON; +QmlIdentifier: T_GET; +QmlIdentifier: T_SET; +QmlIdentifier: T_FROM; +QmlIdentifier: T_OF; + +JsIdentifier: T_IDENTIFIER; +JsIdentifier: T_PROPERTY; +JsIdentifier: T_SIGNAL; +JsIdentifier: T_READONLY; +JsIdentifier: T_ON; +JsIdentifier: T_GET; +JsIdentifier: T_SET; +JsIdentifier: T_FROM; +JsIdentifier: T_STATIC; +JsIdentifier: T_OF; +JsIdentifier: T_AS; + +IdentifierReference: JsIdentifier; +BindingIdentifier: IdentifierReference; + +-------------------------------------------------------------------------------------------------------- +-- Expressions +-------------------------------------------------------------------------------------------------------- + +PrimaryExpression: T_THIS; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6)); - node->typeModifier = stringRef(2); - node->propertyToken = loc(1); - node->typeModifierToken = loc(2); - node->typeToken = loc(4); - node->identifierToken = loc(6); - node->semicolonToken = loc(7); // insert a fake ';' before ':' - - AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6)); - propertyName->identifierToken = loc(6); - propertyName->next = 0; - - AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding( - propertyName, sym(9).UiArrayMemberList->finish()); - binding->colonToken = loc(7); - binding->lbracketToken = loc(8); - binding->rbracketToken = loc(10); - - node->binding = binding; + case $rule_number: { + AST::ThisExpression *node = new (pool) AST::ThisExpression(); + node->thisToken = loc(1); + sym(1).Node = node; + } break; +./ - sym(1).Node = node; -} break; +PrimaryExpression: IdentifierReference; +/. + case $rule_number: { + AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1)); + node->identifierToken = loc(1); + sym(1).Node = node; + } break; ./ -UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON UiQualifiedId UiObjectInitializer ; +PrimaryExpression: Literal; +PrimaryExpression: ArrayLiteral; +PrimaryExpression: ObjectLiteral; +PrimaryExpression: FunctionExpression; +PrimaryExpression: ClassExpression; +PrimaryExpression: GeneratorExpression; +PrimaryExpression: RegularExpressionLiteral; +PrimaryExpression: TemplateLiteral; + +PrimaryExpression: CoverParenthesizedExpressionAndArrowParameterList; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(3); - node->semicolonToken = loc(4); // insert a fake ';' before ':' + case $rule_number: { + if (coverExpressionType != CE_ParenthesizedExpression) { + syntaxError(coverExpressionErrorLocation, "Expected token ')'."); + return false; + } + } break; +./ - AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3)); - propertyName->identifierToken = loc(3); - propertyName->next = 0; +-- Parsing of the CoverParenthesizedExpressionAndArrowParameterList is restricted to the one rule below when this is parsed as a primary expression +CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN Expression_In T_RPAREN; +/. + case $rule_number: { + AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression); + node->lparenToken = loc(1); + node->rparenToken = loc(3); + sym(1).Node = node; + coverExpressionType = CE_ParenthesizedExpression; + } break; +./ - AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( - propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer); - binding->colonToken = loc(4); +CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN T_RPAREN; +/. + case $rule_number: { + sym(1).Node = nullptr; + coverExpressionErrorLocation = loc(2); + coverExpressionType = CE_FormalParameterList; + } break; +./ - node->binding = binding; +CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN BindingRestElement T_RPAREN; +/. + case $rule_number: { + AST::FormalParameterList *node = (new (pool) AST::FormalParameterList(nullptr, sym(2).PatternElement))->finish(pool); + sym(1).Node = node; + coverExpressionErrorLocation = loc(2); + coverExpressionType = CE_FormalParameterList; + } break; +./ - sym(1).Node = node; -} break; +CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN Expression_In T_COMMA BindingRestElementOpt T_RPAREN; +/. + case $rule_number: { + AST::FormalParameterList *list = sym(2).Expression->reparseAsFormalParameterList(pool); + if (!list) { + syntaxError(loc(1), "Invalid Arrow parameter list."); + return false; + } + if (sym(4).Node) { + list = new (pool) AST::FormalParameterList(list, sym(4).PatternElement); + } + coverExpressionErrorLocation = loc(4); + coverExpressionType = CE_FormalParameterList; + sym(1).Node = list->finish(pool); + } break; ./ -UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON UiQualifiedId UiObjectInitializer ; +Literal: T_NULL; /. -case $rule_number: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4)); - node->isReadonlyMember = true; - node->readonlyToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->semicolonToken = loc(5); // insert a fake ';' before ':' + case $rule_number: { + AST::NullExpression *node = new (pool) AST::NullExpression(); + node->nullToken = loc(1); + sym(1).Node = node; + } break; +./ - AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4)); - propertyName->identifierToken = loc(4); - propertyName->next = 0; +Literal: T_TRUE; +/. + case $rule_number: { + AST::TrueLiteral *node = new (pool) AST::TrueLiteral(); + node->trueToken = loc(1); + sym(1).Node = node; + } break; +./ - AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( - propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer); - binding->colonToken = loc(5); +Literal: T_FALSE; +/. + case $rule_number: { + AST::FalseLiteral *node = new (pool) AST::FalseLiteral(); + node->falseToken = loc(1); + sym(1).Node = node; + } break; +./ + +Literal: T_NUMERIC_LITERAL; +/. + case $rule_number: { + AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval); + node->literalToken = loc(1); + sym(1).Node = node; + } break; +./ - node->binding = binding; +Literal: T_MULTILINE_STRING_LITERAL; +/. case $rule_number: Q_FALLTHROUGH(); ./ - sym(1).Node = node; -} break; +Literal: T_STRING_LITERAL; +/. + case $rule_number: { + AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1)); + node->literalToken = loc(1); + sym(1).Node = node; + } break; ./ -UiObjectMember: FunctionDeclaration ; +RegularExpressionLiteral: T_DIVIDE_; +/: +#define J_SCRIPT_REGEXPLITERAL_RULE1 $rule_number +:/ /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); -} break; +{ + Lexer::RegExpBodyPrefix prefix; + case $rule_number: + prefix = Lexer::NoPrefix; + goto scan_regexp; ./ -UiObjectMember: VariableStatement ; +RegularExpressionLiteral: T_DIVIDE_EQ; +/: +#define J_SCRIPT_REGEXPLITERAL_RULE2 $rule_number +:/ /. -case $rule_number: { - sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); -} break; + case $rule_number: + prefix = Lexer::EqualPrefix; + goto scan_regexp; + + scan_regexp: { + bool rx = lexer->scanRegExp(prefix); + if (!rx) { + diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); + return false; + } + + loc(1).length = lexer->tokenLength(); + yylloc = loc(1); // adjust the location of the current token + + AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags()); + node->literalToken = loc(1); + sym(1).Node = node; + } break; +} ./ -JsIdentifier: T_IDENTIFIER; -JsIdentifier: T_PROPERTY ; -JsIdentifier: T_SIGNAL ; -JsIdentifier: T_READONLY ; -JsIdentifier: T_ON ; -JsIdentifier: T_GET ; -JsIdentifier: T_SET ; +ArrayLiteral: T_LBRACKET ElisionOpt T_RBRACKET; +/. + case $rule_number: { + AST::PatternElementList *list = nullptr; + if (sym(2).Elision) + list = (new (pool) AST::PatternElementList(sym(2).Elision, nullptr))->finish(); + AST::ArrayPattern *node = new (pool) AST::ArrayPattern(list); + node->lbracketToken = loc(1); + node->rbracketToken = loc(3); + sym(1).Node = node; + } break; +./ --------------------------------------------------------------------------------------------------------- --- Expressions --------------------------------------------------------------------------------------------------------- +ArrayLiteral: T_LBRACKET ElementList T_RBRACKET; +/. + case $rule_number: { + AST::ArrayPattern *node = new (pool) AST::ArrayPattern(sym(2).PatternElementList->finish()); + node->lbracketToken = loc(1); + node->rbracketToken = loc(3); + sym(1).Node = node; + } break; +./ -PrimaryExpression: T_THIS ; +ArrayLiteral: T_LBRACKET ElementList T_COMMA ElisionOpt T_RBRACKET; /. -case $rule_number: { - AST::ThisExpression *node = new (pool) AST::ThisExpression(); - node->thisToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + auto *list = sym(2).PatternElementList; + if (sym(4).Elision) { + AST::PatternElementList *l = new (pool) AST::PatternElementList(sym(4).Elision, nullptr); + list = list->append(l); + } + AST::ArrayPattern *node = new (pool) AST::ArrayPattern(list->finish()); + node->lbracketToken = loc(1); + node->commaToken = loc(3); + node->rbracketToken = loc(5); + sym(1).Node = node; + Q_ASSERT(node->isValidArrayLiteral()); + } break; ./ -PrimaryExpression: JsIdentifier ; +ElementList: AssignmentExpression_In; /. -case $rule_number: { - AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PatternElement *e = new (pool) AST::PatternElement(sym(1).Expression); + sym(1).Node = new (pool) AST::PatternElementList(nullptr, e); + } break; ./ -PrimaryExpression: T_NULL ; +ElementList: Elision AssignmentExpression_In; /. -case $rule_number: { - AST::NullExpression *node = new (pool) AST::NullExpression(); - node->nullToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PatternElement *e = new (pool) AST::PatternElement(sym(2).Expression); + sym(1).Node = new (pool) AST::PatternElementList(sym(1).Elision->finish(), e); + } break; ./ -PrimaryExpression: T_TRUE ; +ElementList: ElisionOpt SpreadElement; /. -case $rule_number: { - AST::TrueLiteral *node = new (pool) AST::TrueLiteral(); - node->trueToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PatternElementList *node = new (pool) AST::PatternElementList(sym(1).Elision, sym(2).PatternElement); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_FALSE ; +ElementList: ElementList T_COMMA ElisionOpt AssignmentExpression_In; /. -case $rule_number: { - AST::FalseLiteral *node = new (pool) AST::FalseLiteral(); - node->falseToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PatternElement *e = new (pool) AST::PatternElement(sym(4).Expression); + AST::PatternElementList *node = new (pool) AST::PatternElementList(sym(3).Elision, e); + sym(1).Node = sym(1).PatternElementList->append(node); + } break; ./ -PrimaryExpression: T_NUMERIC_LITERAL ; +ElementList: ElementList T_COMMA ElisionOpt SpreadElement; /. -case $rule_number: { - AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval); - node->literalToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PatternElementList *node = new (pool) AST::PatternElementList(sym(3).Elision, sym(4).PatternElement); + sym(1).Node = sym(1).PatternElementList->append(node); + } break; ./ -PrimaryExpression: T_MULTILINE_STRING_LITERAL ; -/.case $rule_number:./ +Elision: T_COMMA; +/. + case $rule_number: { + AST::Elision *node = new (pool) AST::Elision(); + node->commaToken = loc(1); + sym(1).Node = node; + } break; +./ -PrimaryExpression: T_STRING_LITERAL ; +Elision: Elision T_COMMA; /. -case $rule_number: { - AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1)); - node->literalToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::Elision *node = new (pool) AST::Elision(sym(1).Elision); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_DIVIDE_ ; -/: -#define J_SCRIPT_REGEXPLITERAL_RULE1 $rule_number -:/ +ElisionOpt: ; /. -case $rule_number: { - bool rx = lexer->scanRegExp(Lexer::NoPrefix); - if (!rx) { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); - return false; // ### remove me - } - - loc(1).length = lexer->tokenLength(); - yylloc = loc(1); // adjust the location of the current token - - AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral( - driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags()); - node->literalToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -PrimaryExpression: T_DIVIDE_EQ ; -/: -#define J_SCRIPT_REGEXPLITERAL_RULE2 $rule_number -:/ +ElisionOpt: Elision; /. -case $rule_number: { - bool rx = lexer->scanRegExp(Lexer::EqualPrefix); - if (!rx) { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); - return false; - } + case $rule_number: { + sym(1).Node = sym(1).Elision->finish(); + } break; +./ + +SpreadElement: T_ELLIPSIS AssignmentExpression; +/. + case $rule_number: { + AST::PatternElement *node = new (pool) AST::PatternElement(sym(2).Expression, AST::PatternElement::SpreadElement); + sym(1).Node = node; + } break; +./ - loc(1).length = lexer->tokenLength(); - yylloc = loc(1); // adjust the location of the current token +ObjectLiteral: T_LBRACE T_RBRACE; +/. + case $rule_number: { + AST::ObjectPattern *node = new (pool) AST::ObjectPattern(); + node->lbraceToken = loc(1); + node->rbraceToken = loc(2); + sym(1).Node = node; + } break; +./ - AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral( - driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags()); - node->literalToken = loc(1); - sym(1).Node = node; -} break; +ObjectLiteral: T_LBRACE PropertyDefinitionList T_RBRACE; +/. + case $rule_number: { + AST::ObjectPattern *node = new (pool) AST::ObjectPattern(sym(2).PatternPropertyList->finish()); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_LBRACKET T_RBRACKET ; +ObjectLiteral: T_LBRACE PropertyDefinitionList T_COMMA T_RBRACE; /. -case $rule_number: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0); - node->lbracketToken = loc(1); - node->rbracketToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ObjectPattern *node = new (pool) AST::ObjectPattern(sym(2).PatternPropertyList->finish()); + node->lbraceToken = loc(1); + node->rbraceToken = loc(4); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_LBRACKET Elision T_RBRACKET ; + +UiPropertyDefinitionList: UiPropertyDefinition; +/. case $rule_number: Q_FALLTHROUGH(); ./ +PropertyDefinitionList: PropertyDefinition; /. -case $rule_number: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish()); - node->lbracketToken = loc(1); - node->rbracketToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::PatternPropertyList(sym(1).PatternProperty); + } break; ./ -PrimaryExpression: T_LBRACKET ElementList T_RBRACKET ; +UiPropertyDefinitionList: UiPropertyDefinitionList T_COMMA UiPropertyDefinition; +/. case $rule_number: Q_FALLTHROUGH(); ./ +PropertyDefinitionList: PropertyDefinitionList T_COMMA PropertyDefinition; /. -case $rule_number: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ()); - node->lbracketToken = loc(1); - node->rbracketToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PatternPropertyList *node = new (pool) AST::PatternPropertyList(sym(1).PatternPropertyList, sym(3).PatternProperty); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_LBRACKET ElementList T_COMMA T_RBRACKET ; +PropertyDefinition: IdentifierReference; /. -case $rule_number: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (), - (AST::Elision *) 0); - node->lbracketToken = loc(1); - node->commaToken = loc(3); - node->rbracketToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::IdentifierPropertyName *name = new (pool) AST::IdentifierPropertyName(stringRef(1)); + name->propertyNameToken = loc(1); + AST::IdentifierExpression *expr = new (pool) AST::IdentifierExpression(stringRef(1)); + expr->identifierToken = loc(1); + AST::PatternProperty *node = new (pool) AST::PatternProperty(name, expr); + node->colonToken = loc(2); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_LBRACKET ElementList T_COMMA Elision T_RBRACKET ; +-- Using this production should result in a syntax error when used in an ObjectLiteral +PropertyDefinition: CoverInitializedName; + +CoverInitializedName: IdentifierReference Initializer_In; /. -case $rule_number: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (), - sym(4).Elision->finish()); - node->lbracketToken = loc(1); - node->commaToken = loc(3); - node->rbracketToken = loc(5); - sym(1).Node = node; -} break; + case $rule_number: { + AST::IdentifierPropertyName *name = new (pool) AST::IdentifierPropertyName(stringRef(1)); + name->propertyNameToken = loc(1); + AST::IdentifierExpression *left = new (pool) AST::IdentifierExpression(stringRef(1)); + left->identifierToken = loc(1); + // if initializer is an anonymous function expression, we need to assign identifierref as it's name + if (auto *f = asAnonymousFunctionDefinition(sym(2).Expression)) + f->name = stringRef(1); + if (auto *c = asAnonymousClassDefinition(sym(2).Expression)) + c->name = stringRef(1); + AST::BinaryExpression *assignment = new (pool) AST::BinaryExpression(left, QSOperator::Assign, sym(2).Expression); + AST::PatternProperty *node = new (pool) AST::PatternProperty(name, assignment); + node->colonToken = loc(1); + sym(1).Node = node; + + } break; ./ --- PrimaryExpression: T_LBRACE T_RBRACE ; --- /. --- case $rule_number: { --- sym(1).Node = new (pool) AST::ObjectLiteral(); --- } break; --- ./ +UiPropertyDefinition: UiPropertyName T_COLON AssignmentExpression_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +PropertyDefinition: PropertyName T_COLON AssignmentExpression_In; +/. + case $rule_number: { + AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(1).PropertyName, sym(3).Expression); + if (auto *f = asAnonymousFunctionDefinition(sym(3).Expression)) { + if (!AST::cast<AST::ComputedPropertyName *>(sym(1).PropertyName)) + f->name = driver->newStringRef(sym(1).PropertyName->asString()); + } + if (auto *c = asAnonymousClassDefinition(sym(3).Expression)) { + if (!AST::cast<AST::ComputedPropertyName *>(sym(1).PropertyName)) + c->name = driver->newStringRef(sym(1).PropertyName->asString()); + } + node->colonToken = loc(2); + sym(1).Node = node; + } break; +./ + +PropertyDefinition: MethodDefinition; + +PropertyName: LiteralPropertyName; +PropertyName: ComputedPropertyName; + +LiteralPropertyName: IdentifierName; +/. + case $rule_number: { + AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); + node->propertyNameToken = loc(1); + sym(1).Node = node; + } break; +./ -PrimaryExpression: T_LBRACE PropertyAssignmentListOpt T_RBRACE ; +UiPropertyName: T_STRING_LITERAL; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LiteralPropertyName: T_STRING_LITERAL; /. -case $rule_number: { - AST::ObjectLiteral *node = 0; - if (sym(2).Node) - node = new (pool) AST::ObjectLiteral( - sym(2).PropertyAssignmentList->finish ()); - else - node = new (pool) AST::ObjectLiteral(); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1)); + node->propertyNameToken = loc(1); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_LBRACE PropertyAssignmentList T_COMMA T_RBRACE ; +UiPropertyName: T_NUMERIC_LITERAL; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LiteralPropertyName: T_NUMERIC_LITERAL; /. -case $rule_number: { - AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral( - sym(2).PropertyAssignmentList->finish ()); - node->lbraceToken = loc(1); - node->rbraceToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval); + node->propertyNameToken = loc(1); + sym(1).Node = node; + } break; ./ -PrimaryExpression: T_LPAREN Expression T_RPAREN ; +IdentifierName: IdentifierReference; +IdentifierName: ReservedIdentifier; + +ReservedIdentifier: T_BREAK; +ReservedIdentifier: T_CASE; +ReservedIdentifier: T_CATCH; +ReservedIdentifier: T_CONTINUE; +ReservedIdentifier: T_DEFAULT; +ReservedIdentifier: T_DELETE; +ReservedIdentifier: T_DO; +ReservedIdentifier: T_ELSE; +ReservedIdentifier: T_ENUM; +ReservedIdentifier: T_FALSE; +ReservedIdentifier: T_FINALLY; +ReservedIdentifier: T_FOR; +ReservedIdentifier: T_FUNCTION; +ReservedIdentifier: T_IF; +ReservedIdentifier: T_IN; +ReservedIdentifier: T_INSTANCEOF; +ReservedIdentifier: T_NEW; +ReservedIdentifier: T_NULL; +ReservedIdentifier: T_RETURN; +ReservedIdentifier: T_SWITCH; +ReservedIdentifier: T_THIS; +ReservedIdentifier: T_THROW; +ReservedIdentifier: T_TRUE; +ReservedIdentifier: T_TRY; +ReservedIdentifier: T_TYPEOF; +ReservedIdentifier: T_VAR; +ReservedIdentifier: T_VOID; +ReservedIdentifier: T_WHILE; +ReservedIdentifier: T_CONST; +ReservedIdentifier: T_LET; +ReservedIdentifier: T_DEBUGGER; +ReservedIdentifier: T_RESERVED_WORD; +ReservedIdentifier: T_SUPER; +ReservedIdentifier: T_WITH; +ReservedIdentifier: T_CLASS; +ReservedIdentifier: T_EXTENDS; +ReservedIdentifier: T_EXPORT; +ReservedIdentifier: T_IMPORT; + +ComputedPropertyName: T_LBRACKET AssignmentExpression_In T_RBRACKET; +/. + case $rule_number: { + AST::ComputedPropertyName *node = new (pool) AST::ComputedPropertyName(sym(2).Expression); + node->propertyNameToken = loc(1); + sym(1).Node = node; + } break; +./ + +Initializer: T_EQ AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Initializer_In: T_EQ AssignmentExpression_In; /. case $rule_number: { - AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression); - node->lparenToken = loc(1); - node->rparenToken = loc(3); - sym(1).Node = node; + sym(1) = sym(2); } break; ./ -UiQualifiedId: MemberExpression ; +InitializerOpt: ; +/. case $rule_number: Q_FALLTHROUGH(); ./ +InitializerOpt_In: ; /. -case $rule_number: { - if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken, - QLatin1String("Ignored annotation"))); + case $rule_number: { + sym(1).Node = nullptr; + } break; +./ - sym(1).Expression = mem->base; - } +InitializerOpt: Initializer; +InitializerOpt_In: Initializer_In; - if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) { - sym(1).UiQualifiedId = qualifiedId; - } else { - sym(1).UiQualifiedId = 0; +TemplateLiteral: T_NO_SUBSTITUTION_TEMPLATE; +/. case $rule_number: Q_FALLTHROUGH(); ./ - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), - QLatin1String("Expected a qualified name id"))); +TemplateSpans: T_TEMPLATE_TAIL; +/. + case $rule_number: { + AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), rawStringRef(1), nullptr); + node->literalToken = loc(1); + sym(1).Node = node; + } break; +./ - return false; // ### recover - } -} break; +TemplateSpans: T_TEMPLATE_MIDDLE Expression TemplateSpans; +/. case $rule_number: Q_FALLTHROUGH(); ./ + +TemplateLiteral: T_TEMPLATE_HEAD Expression TemplateSpans; +/. + case $rule_number: { + AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), rawStringRef(1), sym(2).Expression); + node->next = sym(3).Template; + node->literalToken = loc(1); + sym(1).Node = node; + } break; ./ -ElementList: AssignmentExpression ; + +MemberExpression: PrimaryExpression; + +Super: T_SUPER; /. -case $rule_number: { - sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression); -} break; + case $rule_number: { + AST::SuperLiteral *node = new (pool) AST::SuperLiteral(); + node->superToken = loc(1); + sym(1).Node = node; + } break; ./ -ElementList: Elision AssignmentExpression ; + +MemberExpression: Super T_LBRACKET Expression_In T_RBRACKET; +/. case $rule_number: Q_FALLTHROUGH(); ./ +MemberExpression: MemberExpression T_LBRACKET Expression_In T_RBRACKET; /. -case $rule_number: { - sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression); -} break; + case $rule_number: { + AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression); + node->lbracketToken = loc(2); + node->rbracketToken = loc(4); + sym(1).Node = node; + } break; ./ -ElementList: ElementList T_COMMA AssignmentExpression ; + +-- the identifier has to be "target", catched at codegen time +NewTarget: T_NEW T_DOT T_IDENTIFIER; +/. case $rule_number: + { + AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1)); + node->identifierToken= loc(1); + sym(1).Node = node; + } Q_FALLTHROUGH(); +./ +MemberExpression: Super T_DOT IdentifierName; +/. case $rule_number: Q_FALLTHROUGH(); ./ +MemberExpression: MemberExpression T_DOT IdentifierName; /. -case $rule_number: { - AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, - (AST::Elision *) 0, sym(3).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3)); + node->dotToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; + } break; ./ -ElementList: ElementList T_COMMA Elision AssignmentExpression ; +MemberExpression: MetaProperty; + +MemberExpression: T_NEW MemberExpression T_LPAREN Arguments T_RPAREN; /. -case $rule_number: { - AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(), - sym(4).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList); + node->newToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + sym(1).Node = node; + } break; ./ -Elision: T_COMMA ; +MetaProperty: NewTarget; + + +NewExpression: MemberExpression; + +NewExpression: T_NEW NewExpression; /. -case $rule_number: { - AST::Elision *node = new (pool) AST::Elision(); - node->commaToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression); + node->newToken = loc(1); + sym(1).Node = node; + } break; ./ -Elision: Elision T_COMMA ; + +CallExpression: CallExpression TemplateLiteral; +/. case $rule_number: Q_FALLTHROUGH(); ./ +MemberExpression: MemberExpression TemplateLiteral; /. -case $rule_number: { - AST::Elision *node = new (pool) AST::Elision(sym(1).Elision); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::TaggedTemplate *node = new (pool) AST::TaggedTemplate(sym(1).Expression, sym(2).Template); + sym(1).Node = node; + } break; ./ -PropertyAssignment: PropertyName T_COLON AssignmentExpression ; +CallExpression: MemberExpression T_LPAREN Arguments T_RPAREN; /. -case $rule_number: { - AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue( - sym(1).PropertyName, sym(3).Expression); - node->colonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + sym(1).Node = node; + } break; ./ -PropertyAssignment: T_GET PropertyName T_LPAREN T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +CallExpression: Super T_LPAREN Arguments T_RPAREN; +/. case $rule_number: Q_FALLTHROUGH(); ./ +CallExpression: CallExpression T_LPAREN Arguments T_RPAREN; /. -case $rule_number: { - AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( - sym(2).PropertyName, sym(6).FunctionBody); - node->getSetToken = loc(1); - node->lparenToken = loc(3); - node->rparenToken = loc(4); - node->lbraceToken = loc(5); - node->rbraceToken = loc(7); - sym(1).Node = node; -} break; + case $rule_number: { + AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + sym(1).Node = node; + } break; ./ -PropertyAssignment: T_SET PropertyName T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +CallExpression: CallExpression T_LBRACKET Expression_In T_RBRACKET; /. -case $rule_number: { - AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( - sym(2).PropertyName, sym(4).FormalParameterList, sym(7).FunctionBody); - node->getSetToken = loc(1); - node->lparenToken = loc(3); - node->rparenToken = loc(5); - node->lbraceToken = loc(6); - node->rbraceToken = loc(8); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression); + node->lbracketToken = loc(2); + node->rbracketToken = loc(4); + sym(1).Node = node; + } break; ./ -PropertyAssignmentList: PropertyAssignment ; +CallExpression: CallExpression T_DOT IdentifierName; /. -case $rule_number: { - sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment); -} break; + case $rule_number: { + AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3)); + node->dotToken = loc(2); + node->identifierToken = loc(3); + sym(1).Node = node; + } break; ./ -PropertyAssignmentList: PropertyAssignmentList T_COMMA PropertyAssignment ; +Arguments: ; /. -case $rule_number: { - AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList( - sym(1).PropertyAssignmentList, sym(3).PropertyAssignment); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -PropertyName: JsIdentifier %prec SHIFT_THERE ; +Arguments: ArgumentList; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Arguments: ArgumentList T_COMMA; /. -case $rule_number: { - AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(1).ArgumentList->finish(); + } break; ./ -PropertyName: T_STRING_LITERAL ; +ArgumentList: AssignmentExpression_In; /. -case $rule_number: { - AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression); + } break; ./ -PropertyName: T_NUMERIC_LITERAL ; +ArgumentList: T_ELLIPSIS AssignmentExpression_In; /. -case $rule_number: { - AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(2).Expression); + node->isSpreadElement = true; + sym(1).Node = node; + } break; ./ -PropertyName: ReservedIdentifier ; +ArgumentList: ArgumentList T_COMMA AssignmentExpression_In; /. -case $rule_number: { - AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ -ReservedIdentifier: T_BREAK ; -ReservedIdentifier: T_CASE ; -ReservedIdentifier: T_CATCH ; -ReservedIdentifier: T_CONTINUE ; -ReservedIdentifier: T_DEFAULT ; -ReservedIdentifier: T_DELETE ; -ReservedIdentifier: T_DO ; -ReservedIdentifier: T_ELSE ; -ReservedIdentifier: T_FALSE ; -ReservedIdentifier: T_FINALLY ; -ReservedIdentifier: T_FOR ; -ReservedIdentifier: T_FUNCTION ; -ReservedIdentifier: T_IF ; -ReservedIdentifier: T_IN ; -ReservedIdentifier: T_INSTANCEOF ; -ReservedIdentifier: T_NEW ; -ReservedIdentifier: T_NULL ; -ReservedIdentifier: T_RETURN ; -ReservedIdentifier: T_SWITCH ; -ReservedIdentifier: T_THIS ; -ReservedIdentifier: T_THROW ; -ReservedIdentifier: T_TRUE ; -ReservedIdentifier: T_TRY ; -ReservedIdentifier: T_TYPEOF ; -ReservedIdentifier: T_VAR ; -ReservedIdentifier: T_VOID ; -ReservedIdentifier: T_WHILE ; -ReservedIdentifier: T_CONST ; -ReservedIdentifier: T_LET ; -ReservedIdentifier: T_DEBUGGER ; -ReservedIdentifier: T_RESERVED_WORD ; -ReservedIdentifier: T_WITH ; - -PropertyIdentifier: JsIdentifier ; -PropertyIdentifier: ReservedIdentifier ; - -MemberExpression: PrimaryExpression ; -MemberExpression: FunctionExpression ; - -MemberExpression: MemberExpression T_LBRACKET Expression T_RBRACKET ; +ArgumentList: ArgumentList T_COMMA T_ELLIPSIS AssignmentExpression_In; /. -case $rule_number: { - AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression); - node->lbracketToken = loc(2); - node->rbracketToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(4).Expression); + node->commaToken = loc(2); + node->isSpreadElement = true; + sym(1).Node = node; + } break; ./ -MemberExpression: MemberExpression T_DOT PropertyIdentifier ; +LeftHandSideExpression: NewExpression; +LeftHandSideExpression: CallExpression; + +UpdateExpression: LeftHandSideExpression; + +UpdateExpression: LeftHandSideExpression T_PLUS_PLUS; /. -case $rule_number: { - AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3)); - node->dotToken = loc(2); - node->identifierToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression); + node->incrementToken = loc(2); + sym(1).Node = node; + } break; ./ -MemberExpression: T_NEW MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ; +UpdateExpression: LeftHandSideExpression T_MINUS_MINUS; /. -case $rule_number: { - AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList); - node->newToken = loc(1); - node->lparenToken = loc(3); - node->rparenToken = loc(5); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression); + node->decrementToken = loc(2); + sym(1).Node = node; + } break; ./ -NewExpression: MemberExpression ; +UpdateExpression: T_PLUS_PLUS UnaryExpression; +/. + case $rule_number: { + AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression); + node->incrementToken = loc(1); + sym(1).Node = node; + } break; +./ -NewExpression: T_NEW NewExpression ; +UpdateExpression: T_MINUS_MINUS UnaryExpression; /. -case $rule_number: { - AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression); - node->newToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression); + node->decrementToken = loc(1); + sym(1).Node = node; + } break; ./ -CallExpression: MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ; +UnaryExpression: UpdateExpression; + +UnaryExpression: T_DELETE UnaryExpression; /. -case $rule_number: { - AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression); + node->deleteToken = loc(1); + sym(1).Node = node; + } break; ./ -CallExpression: CallExpression T_LPAREN ArgumentListOpt T_RPAREN ; +UnaryExpression: T_VOID UnaryExpression; /. -case $rule_number: { - AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression); + node->voidToken = loc(1); + sym(1).Node = node; + } break; ./ -CallExpression: CallExpression T_LBRACKET Expression T_RBRACKET ; +UnaryExpression: T_TYPEOF UnaryExpression; /. -case $rule_number: { - AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression); - node->lbracketToken = loc(2); - node->rbracketToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression); + node->typeofToken = loc(1); + sym(1).Node = node; + } break; ./ -CallExpression: CallExpression T_DOT PropertyIdentifier ; +UnaryExpression: T_PLUS UnaryExpression; /. -case $rule_number: { - AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3)); - node->dotToken = loc(2); - node->identifierToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression); + node->plusToken = loc(1); + sym(1).Node = node; + } break; ./ -ArgumentListOpt: ; +UnaryExpression: T_MINUS UnaryExpression; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression); + node->minusToken = loc(1); + sym(1).Node = node; + } break; ./ -ArgumentListOpt: ArgumentList ; +UnaryExpression: T_TILDE UnaryExpression; /. -case $rule_number: { - sym(1).Node = sym(1).ArgumentList->finish(); -} break; + case $rule_number: { + AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression); + node->tildeToken = loc(1); + sym(1).Node = node; + } break; ./ -ArgumentList: AssignmentExpression ; +UnaryExpression: T_NOT UnaryExpression; /. -case $rule_number: { - sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression); -} break; + case $rule_number: { + AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression); + node->notToken = loc(1); + sym(1).Node = node; + } break; ./ -ArgumentList: ArgumentList T_COMMA AssignmentExpression ; +ExponentiationExpression: UnaryExpression; + +ExponentiationExpression: UpdateExpression T_STAR_STAR ExponentiationExpression; /. -case $rule_number: { - AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Exp, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -LeftHandSideExpression: NewExpression ; -LeftHandSideExpression: CallExpression ; -PostfixExpression: LeftHandSideExpression ; +MultiplicativeExpression: ExponentiationExpression; -PostfixExpression: LeftHandSideExpression T_PLUS_PLUS ; +MultiplicativeExpression: MultiplicativeExpression MultiplicativeOperator ExponentiationExpression; /. -case $rule_number: { - AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression); - node->incrementToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -PostfixExpression: LeftHandSideExpression T_MINUS_MINUS ; +MultiplicativeOperator: T_STAR; /. -case $rule_number: { - AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression); - node->decrementToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::Mul; + } break; ./ -UnaryExpression: PostfixExpression ; +MultiplicativeOperator: T_DIVIDE_; +/. + case $rule_number: { + sym(1).ival = QSOperator::Div; + } break; +./ -UnaryExpression: T_DELETE UnaryExpression ; +MultiplicativeOperator: T_REMAINDER; /. -case $rule_number: { - AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression); - node->deleteToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::Mod; + } break; ./ -UnaryExpression: T_VOID UnaryExpression ; +AdditiveExpression: MultiplicativeExpression; + +AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression; /. -case $rule_number: { - AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression); - node->voidToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Add, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_TYPEOF UnaryExpression ; +AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression; /. -case $rule_number: { - AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression); - node->typeofToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Sub, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_PLUS_PLUS UnaryExpression ; +ShiftExpression: AdditiveExpression; + +ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression; /. -case $rule_number: { - AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression); - node->incrementToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::LShift, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_MINUS_MINUS UnaryExpression ; +ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression; /. -case $rule_number: { - AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression); - node->decrementToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::RShift, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_PLUS UnaryExpression ; +ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression; /. -case $rule_number: { - AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression); - node->plusToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::URShift, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_MINUS UnaryExpression ; +RelationalExpression_In: ShiftExpression; +RelationalExpression: ShiftExpression; + +RelationalExpression_In: RelationalExpression_In RelationalOperator ShiftExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +RelationalExpression: RelationalExpression RelationalOperator ShiftExpression; /. -case $rule_number: { - AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression); - node->minusToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -UnaryExpression: T_TILDE UnaryExpression ; +RelationalOperator: T_LT; /. -case $rule_number: { - AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression); - node->tildeToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::Lt; + } break; +./ +RelationalOperator: T_GT; +/. + case $rule_number: { + sym(1).ival = QSOperator::Gt; + } break; +./ +RelationalOperator: T_LE; +/. + case $rule_number: { + sym(1).ival = QSOperator::Le; + } break; +./ +RelationalOperator: T_GE; +/. + case $rule_number: { + sym(1).ival = QSOperator::Ge; + } break; +./ +RelationalOperator: T_INSTANCEOF; +/. + case $rule_number: { + sym(1).ival = QSOperator::InstanceOf; + } break; ./ -UnaryExpression: T_NOT UnaryExpression ; +RelationalExpression_In: RelationalExpression_In T_IN ShiftExpression; /. -case $rule_number: { - AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression); - node->notToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::In, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -MultiplicativeExpression: UnaryExpression ; +EqualityExpression_In: RelationalExpression_In; +EqualityExpression: RelationalExpression; -MultiplicativeExpression: MultiplicativeExpression T_STAR UnaryExpression ; +EqualityExpression_In: EqualityExpression_In EqualityOperator RelationalExpression_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +EqualityExpression: EqualityExpression EqualityOperator RelationalExpression; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Mul, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -MultiplicativeExpression: MultiplicativeExpression T_DIVIDE_ UnaryExpression ; +EqualityOperator: T_EQ_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Div, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::Equal; + } break; ./ - -MultiplicativeExpression: MultiplicativeExpression T_REMAINDER UnaryExpression ; +EqualityOperator: T_NOT_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Mod, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::NotEqual; + } break; ./ +EqualityOperator: T_EQ_EQ_EQ; +/. + case $rule_number: { + sym(1).ival = QSOperator::StrictEqual; + } break; +./ +EqualityOperator: T_NOT_EQ_EQ; +/. + case $rule_number: { + sym(1).ival = QSOperator::StrictNotEqual; + } break; +./ + -AdditiveExpression: MultiplicativeExpression ; +BitwiseANDExpression: EqualityExpression; +BitwiseANDExpression_In: EqualityExpression_In; -AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression ; +BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +BitwiseANDExpression_In: BitwiseANDExpression_In T_AND EqualityExpression_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Add, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitAnd, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression ; + +BitwiseXORExpression: BitwiseANDExpression; +BitwiseXORExpression_In: BitwiseANDExpression_In; + +BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +BitwiseXORExpression_In: BitwiseXORExpression_In T_XOR BitwiseANDExpression_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Sub, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitXor, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -ShiftExpression: AdditiveExpression ; +BitwiseORExpression: BitwiseXORExpression; +BitwiseORExpression_In: BitwiseXORExpression_In; -ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression ; +BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +BitwiseORExpression_In: BitwiseORExpression_In T_OR BitwiseXORExpression_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::LShift, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitOr, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression ; +LogicalANDExpression: BitwiseORExpression; +LogicalANDExpression_In: BitwiseORExpression_In; + +LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LogicalANDExpression_In: LogicalANDExpression_In T_AND_AND BitwiseORExpression_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::RShift, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::And, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression ; +LogicalORExpression: LogicalANDExpression; +LogicalORExpression_In: LogicalANDExpression_In; + +LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LogicalORExpression_In: LogicalORExpression_In T_OR_OR LogicalANDExpression_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::URShift, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Or, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -RelationalExpression: ShiftExpression ; -RelationalExpression: RelationalExpression T_LT ShiftExpression ; +ConditionalExpression: LogicalORExpression; +ConditionalExpression_In: LogicalORExpression_In; + +ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ConditionalExpression_In: LogicalORExpression_In T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Lt, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, sym(3).Expression, sym(5).Expression); + node->questionToken = loc(2); + node->colonToken = loc(4); + sym(1).Node = node; + } break; ./ -RelationalExpression: RelationalExpression T_GT ShiftExpression ; +AssignmentExpression: ConditionalExpression; +AssignmentExpression_In: ConditionalExpression_In; + +AssignmentExpression: YieldExpression; +AssignmentExpression_In: YieldExpression_In; + +AssignmentExpression: ArrowFunction; +AssignmentExpression_In: ArrowFunction_In; + +AssignmentExpression: LeftHandSideExpression T_EQ AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +AssignmentExpression_In: LeftHandSideExpression T_EQ AssignmentExpression_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Gt, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + // need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral + if (AST::Pattern *p = sym(1).Expression->patternCast()) { + AST::SourceLocation errorLoc; + QString errorMsg; + if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) { + syntaxError(errorLoc, errorMsg); + return false; + } + } + // if lhs is an identifier expression and rhs is an anonymous function expression, we need to assign the name of lhs to the function + if (auto *f = asAnonymousFunctionDefinition(sym(3).Expression)) { + if (auto *id = AST::cast<AST::IdentifierExpression *>(sym(1).Expression)) + f->name = id->name; + } + if (auto *c = asAnonymousClassDefinition(sym(3).Expression)) { + if (auto *id = AST::cast<AST::IdentifierExpression *>(sym(1).Expression)) + c->name = id->name; + } + + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Assign, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -RelationalExpression: RelationalExpression T_LE ShiftExpression ; +AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +AssignmentExpression_In: LeftHandSideExpression AssignmentOperator AssignmentExpression_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Le, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; ./ -RelationalExpression: RelationalExpression T_GE ShiftExpression ; +AssignmentOperator: T_STAR_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Ge, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceMul; + } break; ./ -RelationalExpression: RelationalExpression T_INSTANCEOF ShiftExpression ; +AssignmentOperator: T_STAR_STAR_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::InstanceOf, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceExp; + } break; ./ -RelationalExpression: RelationalExpression T_IN ShiftExpression ; +AssignmentOperator: T_DIVIDE_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::In, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceDiv; + } break; ./ -RelationalExpressionNotIn: ShiftExpression ; +AssignmentOperator: T_REMAINDER_EQ; +/. + case $rule_number: { + sym(1).ival = QSOperator::InplaceMod; + } break; +./ -RelationalExpressionNotIn: RelationalExpressionNotIn T_LT ShiftExpression ; +AssignmentOperator: T_PLUS_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Lt, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceAdd; + } break; ./ -RelationalExpressionNotIn: RelationalExpressionNotIn T_GT ShiftExpression ; +AssignmentOperator: T_MINUS_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Gt, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceSub; + } break; ./ -RelationalExpressionNotIn: RelationalExpressionNotIn T_LE ShiftExpression ; +AssignmentOperator: T_LT_LT_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Le, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceLeftShift; + } break; ./ -RelationalExpressionNotIn: RelationalExpressionNotIn T_GE ShiftExpression ; +AssignmentOperator: T_GT_GT_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Ge, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceRightShift; + } break; ./ -RelationalExpressionNotIn: RelationalExpressionNotIn T_INSTANCEOF ShiftExpression ; +AssignmentOperator: T_GT_GT_GT_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::InstanceOf, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceURightShift; + } break; ./ -EqualityExpression: RelationalExpression ; +AssignmentOperator: T_AND_EQ; +/. + case $rule_number: { + sym(1).ival = QSOperator::InplaceAnd; + } break; +./ -EqualityExpression: EqualityExpression T_EQ_EQ RelationalExpression ; +AssignmentOperator: T_XOR_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Equal, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceXor; + } break; ./ -EqualityExpression: EqualityExpression T_NOT_EQ RelationalExpression ; +AssignmentOperator: T_OR_EQ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::NotEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).ival = QSOperator::InplaceOr; + } break; ./ -EqualityExpression: EqualityExpression T_EQ_EQ_EQ RelationalExpression ; +Expression: AssignmentExpression; +Expression_In: AssignmentExpression_In; + +Expression: Expression T_COMMA AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Expression_In: Expression_In T_COMMA AssignmentExpression_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::StrictEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression); + node->commaToken = loc(2); + sym(1).Node = node; + } break; ./ -EqualityExpression: EqualityExpression T_NOT_EQ_EQ RelationalExpression ; +ExpressionOpt: ; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ExpressionOpt_In: ; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::StrictNotEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -EqualityExpressionNotIn: RelationalExpressionNotIn ; +ExpressionOpt: Expression; +ExpressionOpt_In: Expression_In; + +-- Statements -EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ RelationalExpressionNotIn ; +Statement: ExpressionStatementLookahead T_FORCE_BLOCK BlockStatement; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Equal, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(3).Node; + } break; ./ -EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ RelationalExpressionNotIn; +Statement: ExpressionStatementLookahead VariableStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead EmptyStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead ExpressionStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead IfStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead BreakableStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead ContinueStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead BreakStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead ReturnStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead WithStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead LabelledStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead ThrowStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead TryStatement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +Statement: ExpressionStatementLookahead DebuggerStatement; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::NotEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + } break; ./ -EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ_EQ RelationalExpressionNotIn ; +Declaration: HoistableDeclaration; +Declaration: ClassDeclaration; +Declaration: LexicalDeclaration_In; + +HoistableDeclaration: FunctionDeclaration; +HoistableDeclaration: GeneratorDeclaration; + +HoistableDeclaration_Default: FunctionDeclaration_Default; +HoistableDeclaration_Default: GeneratorDeclaration_Default; + +BreakableStatement: IterationStatement; +BreakableStatement: SwitchStatement; + +BlockStatement: Block; + +Block: T_LBRACE StatementListOpt T_RBRACE; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::StrictEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::Block *node = new (pool) AST::Block(sym(2).StatementList); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + sym(1).Node = node; + } break; ./ -EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ_EQ RelationalExpressionNotIn ; +StatementList: StatementListItem; + +StatementList: StatementList StatementListItem; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::StrictNotEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).StatementList = sym(1).StatementList->append(sym(2).StatementList); + } break; ./ -BitwiseANDExpression: EqualityExpression ; +StatementListItem: Statement; +/. + case $rule_number: { + sym(1).StatementList = new (pool) AST::StatementList(sym(1).Statement); + } break; +./ -BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression ; +StatementListItem: ExpressionStatementLookahead T_FORCE_DECLARATION Declaration T_AUTOMATIC_SEMICOLON; +StatementListItem: ExpressionStatementLookahead T_FORCE_DECLARATION Declaration T_SEMICOLON; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitAnd, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::StatementList(sym(3).FunctionDeclaration); + } break; ./ -BitwiseANDExpressionNotIn: EqualityExpressionNotIn ; +StatementListOpt: ExpressionStatementLookahead; +/. + case $rule_number: { + sym(1).Node = nullptr; + } break; +./ -BitwiseANDExpressionNotIn: BitwiseANDExpressionNotIn T_AND EqualityExpressionNotIn ; +StatementListOpt: StatementList; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitAnd, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(1).StatementList->finish(); + } break; ./ -BitwiseXORExpression: BitwiseANDExpression ; +LetOrConst: T_LET; +/. + case $rule_number: { + sym(1).scope = AST::VariableScope::Let; + } break; +./ +LetOrConst: T_CONST; +/. + case $rule_number: { + sym(1).scope = AST::VariableScope::Const; + } break; +./ -BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression ; +Var: T_VAR; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitXor, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).scope = AST::VariableScope::Var; + } break; ./ -BitwiseXORExpressionNotIn: BitwiseANDExpressionNotIn ; +LexicalDeclaration: LetOrConst BindingList; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LexicalDeclaration_In: LetOrConst BindingList_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VarDeclaration: Var VariableDeclarationList; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VarDeclaration_In: Var VariableDeclarationList_In; +/. + case $rule_number: { + AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(sym(1).scope)); + node->declarationKindToken = loc(1); + sym(1).Node = node; + } break; +./ + +VariableStatement: VarDeclaration_In T_AUTOMATIC_SEMICOLON; +VariableStatement: VarDeclaration_In T_SEMICOLON; -BitwiseXORExpressionNotIn: BitwiseXORExpressionNotIn T_XOR BitwiseANDExpressionNotIn ; +BindingList: LexicalBinding_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +BindingList_In: LexicalBinding_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclarationList: VariableDeclaration; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclarationList_In: VariableDeclaration_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitXor, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).PatternElement); + } break; ./ -BitwiseORExpression: BitwiseXORExpression ; +BindingList: BindingList T_COMMA LexicalBinding; +/. case $rule_number: Q_FALLTHROUGH(); ./ +BindingList_In: BindingList_In T_COMMA LexicalBinding_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclarationList_In: VariableDeclarationList_In T_COMMA VariableDeclaration_In; +/. + case $rule_number: { + AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).PatternElement); + node->commaToken = loc(2); + sym(1).Node = node; + } break; +./ -BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression ; +LexicalBinding: BindingIdentifier InitializerOpt; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LexicalBinding_In: BindingIdentifier InitializerOpt_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclaration: BindingIdentifier InitializerOpt; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclaration_In: BindingIdentifier InitializerOpt_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitOr, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + auto *node = new (pool) AST::PatternElement(stringRef(1), sym(2).Expression); + node->identifierToken = loc(1); + sym(1).Node = node; + // if initializer is an anonymous function expression, we need to assign identifierref as it's name + if (auto *f = asAnonymousFunctionDefinition(sym(2).Expression)) + f->name = stringRef(1); + if (auto *c = asAnonymousClassDefinition(sym(2).Expression)) + c->name = stringRef(1); + } break; ./ -BitwiseORExpressionNotIn: BitwiseXORExpressionNotIn ; +LexicalBinding: BindingPattern Initializer; +/. case $rule_number: Q_FALLTHROUGH(); ./ +LexicalBinding_In: BindingPattern Initializer_In; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclaration: BindingPattern Initializer; +/. case $rule_number: Q_FALLTHROUGH(); ./ +VariableDeclaration_In: BindingPattern Initializer_In; +/. + case $rule_number: { + auto *node = new (pool) AST::PatternElement(sym(1).Pattern, sym(2).Expression); + node->identifierToken = loc(1); + sym(1).Node = node; + } break; +./ -BitwiseORExpressionNotIn: BitwiseORExpressionNotIn T_OR BitwiseXORExpressionNotIn ; +BindingPattern: T_LBRACE ObjectBindingPattern T_RBRACE; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitOr, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + auto *node = new (pool) AST::ObjectPattern(sym(2).PatternPropertyList); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + node->parseMode = AST::Pattern::Binding; + sym(1).Node = node; + } break; ./ -LogicalANDExpression: BitwiseORExpression ; +BindingPattern: T_LBRACKET ArrayBindingPattern T_RBRACKET; +/. + case $rule_number: { + auto *node = new (pool) AST::ArrayPattern(sym(2).PatternElementList); + node->lbracketToken = loc(1); + node->rbracketToken = loc(3); + node->parseMode = AST::Pattern::Binding; + sym(1).Node = node; + } break; +./ + +ObjectBindingPattern: ; +/. + case $rule_number: { + sym(1).Node = nullptr; + } break; +./ + +ObjectBindingPattern: BindingPropertyList; +/. case $rule_number: ./ +ObjectBindingPattern: BindingPropertyList T_COMMA; +/. + case $rule_number: { + sym(1).Node = sym(1).PatternPropertyList->finish(); + } break; +./ + +ArrayBindingPattern: ElisionOpt BindingRestElementOpt; +/. + case $rule_number: { + if (sym(1).Elision || sym(2).Node) { + auto *l = new (pool) AST::PatternElementList(sym(1).Elision, sym(2).PatternElement); + sym(1).Node = l->finish(); + } else { + sym(1).Node = nullptr; + } + } break; +./ -LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression ; +ArrayBindingPattern: BindingElementList; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::And, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(1).PatternElementList->finish(); + } break; ./ -LogicalANDExpressionNotIn: BitwiseORExpressionNotIn ; +ArrayBindingPattern: BindingElementList T_COMMA ElisionOpt BindingRestElementOpt; +/. + case $rule_number: { + if (sym(3).Elision || sym(4).Node) { + auto *l = new (pool) AST::PatternElementList(sym(3).Elision, sym(4).PatternElement); + l = sym(1).PatternElementList->append(l); + sym(1).Node = l; + } + sym(1).Node = sym(1).PatternElementList->finish(); + } break; +./ -LogicalANDExpressionNotIn: LogicalANDExpressionNotIn T_AND_AND BitwiseORExpressionNotIn ; +BindingPropertyList: BindingProperty; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::And, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::PatternPropertyList(sym(1).PatternProperty); + } break; +./ + +BindingPropertyList: BindingPropertyList T_COMMA BindingProperty; +/. + case $rule_number: { + sym(1).Node = new (pool) AST::PatternPropertyList(sym(1).PatternPropertyList, sym(3).PatternProperty); + } break; ./ -LogicalORExpression: LogicalANDExpression ; +BindingElementList: BindingElisionElement; -LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression ; +BindingElementList: BindingElementList T_COMMA BindingElisionElement; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Or, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).PatternElementList = sym(1).PatternElementList->append(sym(3).PatternElementList); + } break; ./ -LogicalORExpressionNotIn: LogicalANDExpressionNotIn ; +BindingElisionElement: ElisionOpt BindingElement; +/. + case $rule_number: { + sym(1).Node = new (pool) AST::PatternElementList(sym(1).Elision, sym(2).PatternElement); + } break; +./ -LogicalORExpressionNotIn: LogicalORExpressionNotIn T_OR_OR LogicalANDExpressionNotIn ; + +BindingProperty: BindingIdentifier InitializerOpt_In; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Or, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::StringLiteralPropertyName *name = new (pool) AST::StringLiteralPropertyName(stringRef(1)); + name->propertyNameToken = loc(1); + // if initializer is an anonymous function expression, we need to assign identifierref as it's name + if (auto *f = asAnonymousFunctionDefinition(sym(2).Expression)) + f->name = stringRef(1); + if (auto *c = asAnonymousClassDefinition(sym(2).Expression)) + c->name = stringRef(1); + sym(1).Node = new (pool) AST::PatternProperty(name, stringRef(1), sym(2).Expression); + } break; ./ -ConditionalExpression: LogicalORExpression ; +BindingProperty: PropertyName T_COLON BindingIdentifier InitializerOpt_In; +/. + case $rule_number: { + AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(1).PropertyName, stringRef(3), sym(4).Expression); + sym(1).Node = node; + } break; +./ -ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression T_COLON AssignmentExpression ; +BindingProperty: PropertyName T_COLON BindingPattern InitializerOpt_In; /. -case $rule_number: { - AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, - sym(3).Expression, sym(5).Expression); - node->questionToken = loc(2); - node->colonToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(1).PropertyName, sym(3).Pattern, sym(4).Expression); + sym(1).Node = node; + } break; ./ -ConditionalExpressionNotIn: LogicalORExpressionNotIn ; +BindingElement: BindingIdentifier InitializerOpt_In; +/. + case $rule_number: { + AST::PatternElement *node = new (pool) AST::PatternElement(stringRef(1), sym(2).Expression); + node->identifierToken = loc(1); + // if initializer is an anonymous function expression, we need to assign identifierref as it's name + if (auto *f = asAnonymousFunctionDefinition(sym(2).Expression)) + f->name = stringRef(1); + if (auto *c = asAnonymousClassDefinition(sym(2).Expression)) + c->name = stringRef(1); + sym(1).Node = node; + } break; +./ -ConditionalExpressionNotIn: LogicalORExpressionNotIn T_QUESTION AssignmentExpressionNotIn T_COLON AssignmentExpressionNotIn ; +BindingElement: BindingPattern InitializerOpt_In; /. -case $rule_number: { - AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, - sym(3).Expression, sym(5).Expression); - node->questionToken = loc(2); - node->colonToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PatternElement *node = new (pool) AST::PatternElement(sym(1).Pattern, sym(2).Expression); + sym(1).Node = node; + } break; ./ -AssignmentExpression: ConditionalExpression ; +BindingRestElement: T_ELLIPSIS BindingIdentifier; +/. + case $rule_number: { + AST::PatternElement *node = new (pool) AST::PatternElement(stringRef(2), nullptr, AST::PatternElement::RestElement); + node->identifierToken = loc(2); + sym(1).Node = node; + } break; +./ -AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression ; +BindingRestElement: T_ELLIPSIS BindingPattern; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - sym(2).ival, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::PatternElement *node = new (pool) AST::PatternElement(sym(2).Pattern, nullptr, AST::PatternElement::RestElement); + sym(1).Node = node; + } break; ./ -AssignmentExpressionNotIn: ConditionalExpressionNotIn ; +BindingRestElementOpt: ; +/. + case $rule_number: { + sym(1).Node = nullptr; + } break; +./ + +BindingRestElementOpt: BindingRestElement; -AssignmentExpressionNotIn: LeftHandSideExpression AssignmentOperator AssignmentExpressionNotIn ; + +EmptyStatement: T_SEMICOLON; /. -case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - sym(2).ival, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::EmptyStatement *node = new (pool) AST::EmptyStatement(); + node->semicolonToken = loc(1); + sym(1).Node = node; + } break; ./ -AssignmentOperator: T_EQ ; +-- Spec says it should have a "[lookahead ∉ { {, function, class, let [ }]" before the Expression statement. +-- This is implemented with the rule below that is run before any statement and inserts a T_EXPRESSION_STATEMENT_OK +-- token if it's ok to parse as an expression statement. +ExpressionStatementLookahead: ; +/: +#define J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE $rule_number +:/ /. -case $rule_number: { - sym(1).ival = QSOperator::Assign; -} break; + case $rule_number: { + int token = lookaheadToken(lexer); + if (token == T_LBRACE) + pushToken(T_FORCE_BLOCK); + else if (token == T_FUNCTION || token == T_CLASS || token == T_LET || token == T_CONST) + pushToken(T_FORCE_DECLARATION); + } break; ./ -AssignmentOperator: T_STAR_EQ ; +ExpressionStatement: Expression_In T_AUTOMATIC_SEMICOLON; +ExpressionStatement: Expression_In T_SEMICOLON; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceMul; -} break; + case $rule_number: { + AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression); + node->semicolonToken = loc(2); + sym(1).Node = node; + } break; ./ -AssignmentOperator: T_DIVIDE_EQ ; +IfStatement: T_IF T_LPAREN Expression_In T_RPAREN Statement T_ELSE Statement; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceDiv; -} break; + case $rule_number: { + AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement); + node->ifToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + node->elseToken = loc(6); + sym(1).Node = node; + } break; ./ -AssignmentOperator: T_REMAINDER_EQ ; +IfStatement: T_IF T_LPAREN Expression_In T_RPAREN Statement; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceMod; -} break; + case $rule_number: { + AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement); + node->ifToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + sym(1).Node = node; + } break; ./ -AssignmentOperator: T_PLUS_EQ ; + +IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression_In T_RPAREN T_AUTOMATIC_SEMICOLON; +IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression_In T_RPAREN T_COMPATIBILITY_SEMICOLON; -- for JSC/V8 compatibility +IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression_In T_RPAREN T_SEMICOLON; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceAdd; -} break; + case $rule_number: { + AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression); + node->doToken = loc(1); + node->whileToken = loc(3); + node->lparenToken = loc(4); + node->rparenToken = loc(6); + node->semicolonToken = loc(7); + sym(1).Node = node; + } break; ./ -AssignmentOperator: T_MINUS_EQ ; +IterationStatement: T_WHILE T_LPAREN Expression_In T_RPAREN Statement; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceSub; -} break; + case $rule_number: { + AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement); + node->whileToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + sym(1).Node = node; + } break; ./ -AssignmentOperator: T_LT_LT_EQ ; +IterationStatement: T_FOR T_LPAREN ExpressionOpt T_SEMICOLON ExpressionOpt_In T_SEMICOLON ExpressionOpt_In T_RPAREN Statement; -- [lookahead != { let [ }] /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceLeftShift; -} break; + case $rule_number: { + AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression, sym(5).Expression, sym(7).Expression, sym(9).Statement); + node->forToken = loc(1); + node->lparenToken = loc(2); + node->firstSemicolonToken = loc(4); + node->secondSemicolonToken = loc(6); + node->rparenToken = loc(8); + sym(1).Node = node; + } break; ./ -AssignmentOperator: T_GT_GT_EQ ; +IterationStatement: T_FOR T_LPAREN VarDeclaration T_SEMICOLON ExpressionOpt_In T_SEMICOLON ExpressionOpt_In T_RPAREN Statement; +/. case $rule_number: Q_FALLTHROUGH(); ./ +IterationStatement: T_FOR T_LPAREN LexicalDeclaration T_SEMICOLON ExpressionOpt_In T_SEMICOLON ExpressionOpt_In T_RPAREN Statement; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceRightShift; -} break; + case $rule_number: { + // ### get rid of the static_cast! + AST::ForStatement *node = new (pool) AST::ForStatement( + static_cast<AST::VariableStatement *>(sym(3).Node)->declarations, sym(5).Expression, + sym(7).Expression, sym(9).Statement); + node->forToken = loc(1); + node->lparenToken = loc(2); + node->firstSemicolonToken = loc(4); + node->secondSemicolonToken = loc(6); + node->rparenToken = loc(8); + sym(1).Node = node; + } break; ./ -AssignmentOperator: T_GT_GT_GT_EQ ; +InOrOf: T_IN; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceURightShift; -} break; + case $rule_number: { + sym(1).forEachType = AST::ForEachType::In; + } break; ./ -AssignmentOperator: T_AND_EQ ; +InOrOf: T_OF; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceAnd; -} break; + case $rule_number: { + sym(1).forEachType = AST::ForEachType::Of; + } break; ./ -AssignmentOperator: T_XOR_EQ ; +IterationStatement: T_FOR T_LPAREN LeftHandSideExpression InOrOf Expression_In T_RPAREN Statement; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceXor; -} break; + case $rule_number: { + // need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral + if (AST::Pattern *p = sym(3).Expression->patternCast()) { + AST::SourceLocation errorLoc; + QString errorMsg; + if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) { + syntaxError(errorLoc, errorMsg); + return false; + } + } + AST::ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression, sym(5).Expression, sym(7).Statement); + node->forToken = loc(1); + node->lparenToken = loc(2); + node->inOfToken = loc(4); + node->rparenToken = loc(6); + node->type = sym(4).forEachType; + sym(1).Node = node; + } break; +./ + +IterationStatement: T_FOR T_LPAREN ForDeclaration InOrOf Expression_In T_RPAREN Statement; +/. + case $rule_number: { + AST::ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).PatternElement, sym(5).Expression, sym(7).Statement); + node->forToken = loc(1); + node->lparenToken = loc(2); + node->inOfToken = loc(4); + node->rparenToken = loc(6); + node->type = sym(4).forEachType; + sym(1).Node = node; + } break; +./ + +ForDeclaration: LetOrConst BindingIdentifier; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ForDeclaration: Var BindingIdentifier; +/. + case $rule_number: { + auto *node = new (pool) AST::PatternElement(stringRef(2), nullptr); + node->identifierToken = loc(2); + node->scope = sym(1).scope; + node->isForDeclaration = true; + sym(1).Node = node; + } break; +./ + +ForDeclaration: LetOrConst BindingPattern; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ForDeclaration: Var BindingPattern; +/. + case $rule_number: { + auto *node = new (pool) AST::PatternElement(sym(2).Pattern, nullptr); + node->scope = sym(1).scope; + node->isForDeclaration = true; + sym(1).Node = node; + } break; +./ + +ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON; +ContinueStatement: T_CONTINUE T_SEMICOLON; +/. + case $rule_number: { + AST::ContinueStatement *node = new (pool) AST::ContinueStatement(); + node->continueToken = loc(1); + node->semicolonToken = loc(2); + sym(1).Node = node; + } break; +./ + +ContinueStatement: T_CONTINUE IdentifierReference T_AUTOMATIC_SEMICOLON; +ContinueStatement: T_CONTINUE IdentifierReference T_SEMICOLON; +/. + case $rule_number: { + AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2)); + node->continueToken = loc(1); + node->identifierToken = loc(2); + node->semicolonToken = loc(3); + sym(1).Node = node; + } break; +./ + +BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON; +BreakStatement: T_BREAK T_SEMICOLON; +/. + case $rule_number: { + AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef()); + node->breakToken = loc(1); + node->semicolonToken = loc(2); + sym(1).Node = node; + } break; +./ + +BreakStatement: T_BREAK IdentifierReference T_AUTOMATIC_SEMICOLON; +BreakStatement: T_BREAK IdentifierReference T_SEMICOLON; +/. + case $rule_number: { + AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2)); + node->breakToken = loc(1); + node->identifierToken = loc(2); + node->semicolonToken = loc(3); + sym(1).Node = node; + } break; +./ + +ReturnStatement: T_RETURN ExpressionOpt_In T_AUTOMATIC_SEMICOLON; +ReturnStatement: T_RETURN ExpressionOpt_In T_SEMICOLON; +/. + case $rule_number: { + if (!functionNestingLevel) { + syntaxError(loc(1), "Return statement not allowed outside of Function declaration."); + return false; + } + AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression); + node->returnToken = loc(1); + node->semicolonToken = loc(3); + sym(1).Node = node; + } break; ./ -AssignmentOperator: T_OR_EQ ; +WithStatement: T_WITH T_LPAREN Expression_In T_RPAREN Statement; /. -case $rule_number: { - sym(1).ival = QSOperator::InplaceOr; -} break; + case $rule_number: { + AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement); + node->withToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + sym(1).Node = node; + } break; ./ -Expression: AssignmentExpression ; +SwitchStatement: T_SWITCH T_LPAREN Expression_In T_RPAREN CaseBlock; +/. + case $rule_number: { + AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock); + node->switchToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + sym(1).Node = node; + } break; +./ -Expression: Expression T_COMMA AssignmentExpression ; +CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE; /. -case $rule_number: { - AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses); + node->lbraceToken = loc(1); + node->rbraceToken = loc(3); + sym(1).Node = node; + } break; ./ -ExpressionOpt: ; +CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses); + node->lbraceToken = loc(1); + node->rbraceToken = loc(5); + sym(1).Node = node; + } break; ./ -ExpressionOpt: Expression ; +CaseClauses: CaseClause; +/. + case $rule_number: { + sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause); + } break; +./ -ExpressionNotIn: AssignmentExpressionNotIn ; +CaseClauses: CaseClauses CaseClause; +/. + case $rule_number: { + sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause); + } break; +./ -ExpressionNotIn: ExpressionNotIn T_COMMA AssignmentExpressionNotIn ; +CaseClausesOpt: ; /. -case $rule_number: { - AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -ExpressionNotInOpt: ; +CaseClausesOpt: CaseClauses; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + sym(1).Node = sym(1).CaseClauses->finish(); + } break; ./ -ExpressionNotInOpt: ExpressionNotIn ; +CaseClause: T_CASE Expression_In T_COLON StatementListOpt; +/. + case $rule_number: { + AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList); + node->caseToken = loc(1); + node->colonToken = loc(3); + sym(1).Node = node; + } break; +./ -Statement: Block ; -Statement: VariableStatement ; -Statement: EmptyStatement ; -Statement: ExpressionStatement ; -Statement: IfStatement ; -Statement: IterationStatement ; -Statement: ContinueStatement ; -Statement: BreakStatement ; -Statement: ReturnStatement ; -Statement: WithStatement ; -Statement: LabelledStatement ; -Statement: SwitchStatement ; -Statement: ThrowStatement ; -Statement: TryStatement ; -Statement: DebuggerStatement ; +DefaultClause: T_DEFAULT T_COLON StatementListOpt; +/. + case $rule_number: { + AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList); + node->defaultToken = loc(1); + node->colonToken = loc(2); + sym(1).Node = node; + } break; +./ + +LabelledStatement: IdentifierReference T_COLON LabelledItem; +/. + case $rule_number: { + AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement); + node->identifierToken = loc(1); + node->colonToken = loc(2); + sym(1).Node = node; + } break; +./ +LabelledItem: Statement; -Block: T_LBRACE StatementListOpt T_RBRACE ; +LabelledItem: ExpressionStatementLookahead T_FORCE_DECLARATION FunctionDeclaration; /. -case $rule_number: { - AST::Block *node = new (pool) AST::Block(sym(2).StatementList); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + syntaxError(loc(3), "FunctionDeclarations are not allowed after a label."); + return false; + } break; ./ -StatementList: Statement ; +ThrowStatement: T_THROW Expression_In T_AUTOMATIC_SEMICOLON; +ThrowStatement: T_THROW Expression_In T_SEMICOLON; /. -case $rule_number: { - sym(1).Node = new (pool) AST::StatementList(sym(1).Statement); -} break; + case $rule_number: { + AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression); + node->throwToken = loc(1); + node->semicolonToken = loc(3); + sym(1).Node = node; + } break; ./ -StatementList: StatementList Statement ; +TryStatement: T_TRY Block Catch; /. -case $rule_number: { - sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement); -} break; + case $rule_number: { + AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch); + node->tryToken = loc(1); + sym(1).Node = node; + } break; ./ -StatementListOpt: ; +TryStatement: T_TRY Block Finally; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally); + node->tryToken = loc(1); + sym(1).Node = node; + } break; ./ -StatementListOpt: StatementList ; +TryStatement: T_TRY Block Catch Finally; /. -case $rule_number: { - sym(1).Node = sym(1).StatementList->finish (); -} break; + case $rule_number: { + AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally); + node->tryToken = loc(1); + sym(1).Node = node; + } break; ./ -VariableStatement: VariableDeclarationKind VariableDeclarationList T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -VariableStatement: VariableDeclarationKind VariableDeclarationList T_SEMICOLON ; +Catch: T_CATCH T_LPAREN CatchParameter T_RPAREN Block; /. -case $rule_number: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - if (sym(1).ival == T_LET) - s = AST::VariableDeclaration::BlockScope; - else if (sym(1).ival == T_CONST) - s = AST::VariableDeclaration::ReadOnlyBlockScope; - - AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(s)); - node->declarationKindToken = loc(1); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::Catch *node = new (pool) AST::Catch(sym(3).PatternElement, sym(5).Block); + node->catchToken = loc(1); + node->lparenToken = loc(2); + node->identifierToken = loc(3); + node->rparenToken = loc(4); + sym(1).Node = node; + } break; ./ -VariableDeclarationKind: T_LET ; +Finally: T_FINALLY Block; /. -case $rule_number: { - sym(1).ival = T_LET; -} break; + case $rule_number: { + AST::Finally *node = new (pool) AST::Finally(sym(2).Block); + node->finallyToken = loc(1); + sym(1).Node = node; + } break; ./ -VariableDeclarationKind: T_CONST ; +CatchParameter: BindingIdentifier; /. -case $rule_number: { - sym(1).ival = T_CONST; -} break; + case $rule_number: { + AST::PatternElement *node = new (pool) AST::PatternElement(stringRef(1)); + node->identifierToken = loc(1); + node->scope = AST::VariableScope::Let; + sym(1).Node = node; + } break; ./ -VariableDeclarationKind: T_VAR ; +CatchParameter: BindingPattern; /. -case $rule_number: { - sym(1).ival = T_VAR; -} break; + case $rule_number: { + AST::PatternElement *node = new (pool) AST::PatternElement(sym(1).Pattern); + node->scope = AST::VariableScope::Let; + sym(1).Node = node; + } break; ./ -VariableDeclarationList: VariableDeclaration ; +DebuggerStatement: T_DEBUGGER T_AUTOMATIC_SEMICOLON; -- automatic semicolon +DebuggerStatement: T_DEBUGGER T_SEMICOLON; /. -case $rule_number: { - sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration); -} break; + case $rule_number: { + AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement(); + node->debuggerToken = loc(1); + node->semicolonToken = loc(2); + sym(1).Node = node; + } break; ./ -VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration ; +-- tell the parser to prefer function declarations to function expressions. +-- That is, the `Function' symbol is used to mark the start of a function +-- declaration. +-- This is still required for parsing QML, where MemberExpression and FunctionDeclaration would +-- otherwise conflict. +Function: T_FUNCTION %prec REDUCE_HERE; + +FunctionDeclaration: Function BindingIdentifier T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList( - sym(1).VariableDeclarationList, sym(3).VariableDeclaration); - node->commaToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList); + node->functionToken = loc(1); + node->identifierToken = loc(2); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->lbraceToken = loc(6); + node->rbraceToken = loc(8); + sym(1).Node = node; + } break; ./ -VariableDeclarationListNotIn: VariableDeclarationNotIn ; + +FunctionDeclaration_Default: FunctionDeclaration; +FunctionDeclaration_Default: Function T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration); -} break; + case $rule_number: { + AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(QStringRef(), sym(3).FormalParameterList, sym(6).StatementList); + node->functionToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + node->lbraceToken = loc(5); + node->rbraceToken = loc(7); + sym(1).Node = node; + } break; ./ -VariableDeclarationListNotIn: VariableDeclarationListNotIn T_COMMA VariableDeclarationNotIn ; +FunctionExpression: T_FUNCTION BindingIdentifier T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration); -} break; + case $rule_number: { + AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList); + node->functionToken = loc(1); + if (! stringRef(2).isNull()) + node->identifierToken = loc(2); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->lbraceToken = loc(6); + node->rbraceToken = loc(8); + sym(1).Node = node; + } break; ./ -VariableDeclaration: JsIdentifier InitialiserOpt ; +FunctionExpression: T_FUNCTION T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).StatementList); + node->functionToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + node->lbraceToken = loc(5); + node->rbraceToken = loc(7); + sym(1).Node = node; + } break; ./ -VariableDeclarationNotIn: JsIdentifier InitialiserNotInOpt ; +StrictFormalParameters: FormalParameters; + +FormalParameters: ; /. -case $rule_number: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -Initialiser: T_EQ AssignmentExpression ; +FormalParameters: BindingRestElement; /. -case $rule_number: { - // ### TODO: AST for initializer - sym(1) = sym(2); -} break; + case $rule_number: { + AST::FormalParameterList *node = (new (pool) AST::FormalParameterList(nullptr, sym(1).PatternElement))->finish(pool); + sym(1).Node = node; + } break; ./ -InitialiserOpt: ; +FormalParameters: FormalParameterList; +/. case $rule_number: ./ +FormalParameters: FormalParameterList T_COMMA; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + sym(1).Node = sym(1).FormalParameterList->finish(pool); + } break; ./ -InitialiserOpt: Initialiser ; +FormalParameters: FormalParameterList T_COMMA BindingRestElement; +/. + case $rule_number: { + AST::FormalParameterList *node = (new (pool) AST::FormalParameterList(sym(1).FormalParameterList, sym(3).PatternElement))->finish(pool); + sym(1).Node = node; + } break; +./ -InitialiserNotIn: T_EQ AssignmentExpressionNotIn ; +FormalParameterList: BindingElement; /. -case $rule_number: { - // ### TODO: AST for initializer - sym(1) = sym(2); -} break; + case $rule_number: { + AST::FormalParameterList *node = new (pool) AST::FormalParameterList(nullptr, sym(1).PatternElement); + sym(1).Node = node; + } break; ./ -InitialiserNotInOpt: ; + +FormalParameterList: FormalParameterList T_COMMA BindingElement; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, sym(3).PatternElement); + sym(1).Node = node; + } break; ./ -InitialiserNotInOpt: InitialiserNotIn ; +FormalParameter: BindingElement; -EmptyStatement: T_SEMICOLON ; +FunctionLBrace: T_LBRACE; /. -case $rule_number: { - AST::EmptyStatement *node = new (pool) AST::EmptyStatement(); - node->semicolonToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + ++functionNestingLevel; + } break; ./ -ExpressionStatement: Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -ExpressionStatement: Expression T_SEMICOLON ; +FunctionRBrace: T_RBRACE; /. -case $rule_number: { - AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + --functionNestingLevel; + } break; ./ -IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement T_ELSE Statement ; + +FunctionBody: StatementListOpt; + +ArrowFunction: ArrowParameters T_ARROW ConciseBodyLookahead AssignmentExpression; -- [lookahead ≠{] +/. case $rule_number: Q_FALLTHROUGH(); ./ +ArrowFunction_In: ArrowParameters T_ARROW ConciseBodyLookahead AssignmentExpression_In; -- [lookahead ≠{] /. -case $rule_number: { - AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement); - node->ifToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - node->elseToken = loc(6); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ReturnStatement *ret = new (pool) AST::ReturnStatement(sym(4).Expression); + ret->returnToken = sym(4).Node->firstSourceLocation(); + ret->semicolonToken = sym(4).Node->lastSourceLocation(); + AST::StatementList *statements = (new (pool) AST::StatementList(ret))->finish(); + AST::FunctionExpression *f = new (pool) AST::FunctionExpression(QStringRef(), sym(1).FormalParameterList, statements); + f->isArrowFunction = true; + f->functionToken = sym(1).Node ? sym(1).Node->firstSourceLocation() : loc(1); + f->lbraceToken = sym(4).Node->firstSourceLocation(); + f->rbraceToken = sym(4).Node->lastSourceLocation(); + sym(1).Node = f; + } break; ./ -IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement ; +ArrowFunction: ArrowParameters T_ARROW ConciseBodyLookahead T_FORCE_BLOCK FunctionLBrace FunctionBody FunctionRBrace; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ArrowFunction_In: ArrowParameters T_ARROW ConciseBodyLookahead T_FORCE_BLOCK FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement); - node->ifToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FunctionExpression *f = new (pool) AST::FunctionExpression(QStringRef(), sym(1).FormalParameterList, sym(6).StatementList); + f->isArrowFunction = true; + f->functionToken = sym(1).Node ? sym(1).Node->firstSourceLocation() : loc(1); + f->lbraceToken = loc(6); + f->rbraceToken = loc(7); + sym(1).Node = f; + } break; ./ +ArrowParameters: BindingIdentifier; +/. + case $rule_number: { + AST::PatternElement *e = new (pool) AST::PatternElement(stringRef(1), nullptr, AST::PatternElement::Binding); + e->identifierToken = loc(1); + sym(1).FormalParameterList = (new (pool) AST::FormalParameterList(nullptr, e))->finish(pool); + } break; +./ -IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_COMPATIBILITY_SEMICOLON ; -- for JSC/V8 compatibility -IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_SEMICOLON ; +-- CoverParenthesizedExpressionAndArrowParameterList for ArrowParameters i being refined to: +-- ArrowFormalParameters: T_LPAREN StrictFormalParameters T_RPAREN +ArrowParameters: CoverParenthesizedExpressionAndArrowParameterList; /. -case $rule_number: { - AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression); - node->doToken = loc(1); - node->whileToken = loc(3); - node->lparenToken = loc(4); - node->rparenToken = loc(6); - node->semicolonToken = loc(7); - sym(1).Node = node; -} break; + case $rule_number: { + if (coverExpressionType != CE_FormalParameterList) { + AST::NestedExpression *ne = static_cast<AST::NestedExpression *>(sym(1).Node); + AST::FormalParameterList *list = ne->expression->reparseAsFormalParameterList(pool); + if (!list) { + syntaxError(loc(1), "Invalid Arrow parameter list."); + return false; + } + sym(1).Node = list->finish(pool); + } + } break; ./ -IterationStatement: T_WHILE T_LPAREN Expression T_RPAREN Statement ; +ConciseBodyLookahead: ; +/: +#define J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE $rule_number +:/ /. -case $rule_number: { - AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement); - node->whileToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + if (lookaheadToken(lexer) == T_LBRACE) + pushToken(T_FORCE_BLOCK); + } break; ./ -IterationStatement: T_FOR T_LPAREN ExpressionNotInOpt T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ; +MethodDefinition: PropertyName T_LPAREN StrictFormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression, - sym(5).Expression, sym(7).Expression, sym(9).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->firstSemicolonToken = loc(4); - node->secondSemicolonToken = loc(6); - node->rparenToken = loc(8); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(1), sym(3).FormalParameterList, sym(6).StatementList); + f->functionToken = sym(1).PropertyName->firstSourceLocation(); + f->lparenToken = loc(2); + f->rparenToken = loc(4); + f->lbraceToken = loc(5); + f->rbraceToken = loc(7); + AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(1).PropertyName, f, AST::PatternProperty::Method); + node->colonToken = loc(2); + sym(1).Node = node; + } break; ./ -IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationListNotIn T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ; +MethodDefinition: T_STAR PropertyName GeneratorLParen StrictFormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace; /. -case $rule_number: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - AST::LocalForStatement *node = new (pool) AST::LocalForStatement( - sym(4).VariableDeclarationList->finish(s), sym(6).Expression, - sym(8).Expression, sym(10).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->varToken = loc(3); - node->firstSemicolonToken = loc(5); - node->secondSemicolonToken = loc(7); - node->rparenToken = loc(9); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList); + f->functionToken = sym(2).PropertyName->firstSourceLocation(); + f->lparenToken = loc(3); + f->rparenToken = loc(5); + f->lbraceToken = loc(6); + f->rbraceToken = loc(8); + f->isGenerator = true; + AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(2).PropertyName, f, AST::PatternProperty::Method); + node->colonToken = loc(2); + sym(1).Node = node; + } break; +./ + + +MethodDefinition: T_GET PropertyName T_LPAREN T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; +/. + case $rule_number: { + AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(2), nullptr, sym(6).StatementList); + f->functionToken = sym(2).PropertyName->firstSourceLocation(); + f->lparenToken = loc(3); + f->rparenToken = loc(4); + f->lbraceToken = loc(5); + f->rbraceToken = loc(7); + AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(2).PropertyName, f, AST::PatternProperty::Getter); + node->colonToken = loc(2); + sym(1).Node = node; + } break; ./ -IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression T_RPAREN Statement ; +MethodDefinition: T_SET PropertyName T_LPAREN PropertySetParameterList T_RPAREN FunctionLBrace FunctionBody FunctionRBrace; /. -case $rule_number: { - AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression, - sym(5).Expression, sym(7).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->inToken = loc(4); - node->rparenToken = loc(6); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList); + f->functionToken = sym(2).PropertyName->firstSourceLocation(); + f->lparenToken = loc(3); + f->rparenToken = loc(5); + f->lbraceToken = loc(6); + f->rbraceToken = loc(8); + AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(2).PropertyName, f, AST::PatternProperty::Setter); + node->colonToken = loc(2); + sym(1).Node = node; + } break; ./ -IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationNotIn T_IN Expression T_RPAREN Statement ; + +PropertySetParameterList: FormalParameter; /. -case $rule_number: { - AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement( - sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->varToken = loc(3); - node->inToken = loc(5); - node->rparenToken = loc(7); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FormalParameterList *node = (new (pool) AST::FormalParameterList(nullptr, sym(1).PatternElement))->finish(pool); + sym(1).Node = node; + } break; ./ -ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -ContinueStatement: T_CONTINUE T_SEMICOLON ; +GeneratorLParen: T_LPAREN; /. -case $rule_number: { - AST::ContinueStatement *node = new (pool) AST::ContinueStatement(); - node->continueToken = loc(1); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + lexer->enterGeneratorBody(); + } break; ./ -ContinueStatement: T_CONTINUE JsIdentifier T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -ContinueStatement: T_CONTINUE JsIdentifier T_SEMICOLON ; +GeneratorRBrace: T_RBRACE; /. -case $rule_number: { - AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2)); - node->continueToken = loc(1); - node->identifierToken = loc(2); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + --functionNestingLevel; + lexer->leaveGeneratorBody(); + } break; ./ -BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -BreakStatement: T_BREAK T_SEMICOLON ; +GeneratorDeclaration: Function T_STAR BindingIdentifier GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace; /. -case $rule_number: { - AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef()); - node->breakToken = loc(1); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(3), sym(5).FormalParameterList, sym(8).StatementList); + node->functionToken = loc(1); + node->identifierToken = loc(3); + node->lparenToken = loc(4); + node->rparenToken = loc(6); + node->lbraceToken = loc(7); + node->rbraceToken = loc(9); + node->isGenerator = true; + sym(1).Node = node; + } break; ./ -BreakStatement: T_BREAK JsIdentifier T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -BreakStatement: T_BREAK JsIdentifier T_SEMICOLON ; +GeneratorDeclaration_Default: GeneratorDeclaration; +GeneratorDeclaration_Default: Function T_STAR GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace; +/. + case $rule_number: { + AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(QStringRef(), sym(4).FormalParameterList, sym(7).StatementList); + node->functionToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->lbraceToken = loc(6); + node->rbraceToken = loc(8); + node->isGenerator = true; + sym(1).Node = node; + } break; +./ + +GeneratorExpression: T_FUNCTION T_STAR BindingIdentifier GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace; /. -case $rule_number: { - AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2)); - node->breakToken = loc(1); - node->identifierToken = loc(2); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(3), sym(5).FormalParameterList, sym(8).StatementList); + node->functionToken = loc(1); + if (!stringRef(3).isNull()) + node->identifierToken = loc(3); + node->lparenToken = loc(4); + node->rparenToken = loc(6); + node->lbraceToken = loc(7); + node->rbraceToken = loc(9); + node->isGenerator = true; + sym(1).Node = node; + } break; ./ -ReturnStatement: T_RETURN ExpressionOpt T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -ReturnStatement: T_RETURN ExpressionOpt T_SEMICOLON ; +GeneratorExpression: T_FUNCTION T_STAR GeneratorLParen FormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace; /. -case $rule_number: { - AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression); - node->returnToken = loc(1); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(4).FormalParameterList, sym(7).StatementList); + node->functionToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->lbraceToken = loc(6); + node->rbraceToken = loc(8); + node->isGenerator = true; + sym(1).Node = node; + } break; ./ -WithStatement: T_WITH T_LPAREN Expression T_RPAREN Statement ; +GeneratorBody: FunctionBody; + +YieldExpression: T_YIELD; +/. case $rule_number: Q_FALLTHROUGH(); ./ +YieldExpression_In: T_YIELD; /. -case $rule_number: { - AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement); - node->withToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::YieldExpression *node = new (pool) AST::YieldExpression(); + node->yieldToken = loc(1); + sym(1).Node = node; + } break; ./ -SwitchStatement: T_SWITCH T_LPAREN Expression T_RPAREN CaseBlock ; +YieldExpression: T_YIELD T_STAR AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +YieldExpression_In: T_YIELD T_STAR AssignmentExpression_In; /. -case $rule_number: { - AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock); - node->switchToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + AST::YieldExpression *node = new (pool) AST::YieldExpression(sym(3).Expression); + node->yieldToken = loc(1); + node->isYieldStar = true; + sym(1).Node = node; + } break; ./ -CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE ; +YieldExpression: T_YIELD AssignmentExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +YieldExpression_In: T_YIELD AssignmentExpression_In; /. -case $rule_number: { - AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + AST::YieldExpression *node = new (pool) AST::YieldExpression(sym(2).Expression); + node->yieldToken = loc(1); + sym(1).Node = node; + } break; ./ -CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE ; + +ClassDeclaration: T_CLASS BindingIdentifier ClassHeritageOpt ClassLBrace ClassBodyOpt ClassRBrace; /. -case $rule_number: { - AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses); - node->lbraceToken = loc(1); - node->rbraceToken = loc(5); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ClassDeclaration *node = new (pool) AST::ClassDeclaration(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; ./ -CaseClauses: CaseClause ; +ClassExpression: T_CLASS BindingIdentifier ClassHeritageOpt ClassLBrace ClassBodyOpt ClassRBrace; /. -case $rule_number: { - sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause); -} break; + 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; ./ -CaseClauses: CaseClauses CaseClause ; +ClassDeclaration_Default: T_CLASS ClassHeritageOpt ClassLBrace ClassBodyOpt ClassRBrace; /. -case $rule_number: { - sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause); -} break; + case $rule_number: { + AST::ClassDeclaration *node = new (pool) AST::ClassDeclaration(QStringRef(), sym(2).Expression, sym(4).ClassElementList); + node->classToken = loc(1); + node->lbraceToken = loc(3); + node->rbraceToken = loc(5); + sym(1).Node = node; + } break; ./ -CaseClausesOpt: ; +ClassExpression: T_CLASS ClassHeritageOpt ClassLBrace ClassBodyOpt ClassRBrace; /. -case $rule_number: { - sym(1).Node = 0; -} break; + 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; ./ -CaseClausesOpt: CaseClauses ; +ClassDeclaration_Default: ClassDeclaration; + +ClassLBrace: T_LBRACE; /. -case $rule_number: { - sym(1).Node = sym(1).CaseClauses->finish (); -} break; + case $rule_number: { + lexer->setStaticIsKeyword(true); + } break; ./ -CaseClause: T_CASE Expression T_COLON StatementListOpt ; +ClassRBrace: T_RBRACE; +/. case $rule_number: ./ +ClassStaticQualifier: T_STATIC; /. -case $rule_number: { - AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList); - node->caseToken = loc(1); - node->colonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + lexer->setStaticIsKeyword(false); + } break; ./ -DefaultClause: T_DEFAULT T_COLON StatementListOpt ; +ClassHeritageOpt: ; /. -case $rule_number: { - AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList); - node->defaultToken = loc(1); - node->colonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -LabelledStatement: JsIdentifier T_COLON Statement ; +ClassHeritageOpt: T_EXTENDS LeftHandSideExpression; /. -case $rule_number: { - AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement); - node->identifierToken = loc(1); - node->colonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = sym(2).Node; + } break; ./ -ThrowStatement: T_THROW Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -ThrowStatement: T_THROW Expression T_SEMICOLON ; +ClassBodyOpt: ; /. -case $rule_number: { - AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression); - node->throwToken = loc(1); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -TryStatement: T_TRY Block Catch ; +ClassBodyOpt: ClassElementList; /. -case $rule_number: { - AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch); - node->tryToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + if (sym(1).Node) + sym(1).Node = sym(1).ClassElementList->finish(); + } break; ./ -TryStatement: T_TRY Block Finally ; +ClassElementList: ClassElement; + +ClassElementList: ClassElementList ClassElement; /. -case $rule_number: { - AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally); - node->tryToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + if (sym(1).Node) { + if (sym(2).Node) + sym(1).ClassElementList = sym(1).ClassElementList->append(sym(2).ClassElementList); + } else if (sym(2).Node) { + sym(1).Node = sym(2).Node; + } + } break; ./ -TryStatement: T_TRY Block Catch Finally ; +ClassElement: MethodDefinition; /. -case $rule_number: { - AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally); - node->tryToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + AST::ClassElementList *node = new (pool) AST::ClassElementList(sym(1).PatternProperty, false); + sym(1).Node = node; + } break; ./ -Catch: T_CATCH T_LPAREN JsIdentifier T_RPAREN Block ; +ClassElement: ClassStaticQualifier MethodDefinition; /. -case $rule_number: { - AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block); - node->catchToken = loc(1); - node->lparenToken = loc(2); - node->identifierToken = loc(3); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; + case $rule_number: { + lexer->setStaticIsKeyword(true); + AST::ClassElementList *node = new (pool) AST::ClassElementList(sym(2).PatternProperty, true); + sym(1).Node = node; + } break; ./ -Finally: T_FINALLY Block ; +ClassElement: T_SEMICOLON; /. -case $rule_number: { - AST::Finally *node = new (pool) AST::Finally(sym(2).Block); - node->finallyToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ -DebuggerStatement: T_DEBUGGER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon -DebuggerStatement: T_DEBUGGER T_SEMICOLON ; +-- Scripts and Modules + +Script: ; /. -case $rule_number: { - AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement(); - node->debuggerToken = loc(1); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = nullptr; + } break; ./ --- tell the parser to prefer function declarations to function expressions. --- That is, the `Function' symbol is used to mark the start of a function --- declaration. -Function: T_FUNCTION %prec REDUCE_HERE ; +Script: ScriptBody; -FunctionDeclaration: Function JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +ScriptBody: StatementList; /. -case $rule_number: { - AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody); - node->functionToken = loc(1); - node->identifierToken = loc(2); - node->lparenToken = loc(3); - node->rparenToken = loc(5); - node->lbraceToken = loc(6); - node->rbraceToken = loc(8); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).Node = new (pool) AST::Program(sym(1).StatementList->finish()); + } break; ./ -FunctionExpression: T_FUNCTION JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +Module: ModuleBodyOpt; +/. case $rule_number: { + sym(1).Node = new (pool) AST::ESModule(sym(1).StatementList); + } break; +./ + +ModuleBody: ModuleItemList; /. -case $rule_number: { - AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody); - node->functionToken = loc(1); - if (! stringRef(2).isNull()) - node->identifierToken = loc(2); - node->lparenToken = loc(3); - node->rparenToken = loc(5); - node->lbraceToken = loc(6); - node->rbraceToken = loc(8); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).StatementList = sym(1).StatementList->finish(); + } break; ./ -FunctionExpression: T_FUNCTION T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +ModuleBodyOpt: ; /. -case $rule_number: { - AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).FunctionBody); - node->functionToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - node->lbraceToken = loc(5); - node->rbraceToken = loc(7); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).StatementList = nullptr; + } break; ./ +ModuleBodyOpt: ModuleBody; + +ModuleItemList: ModuleItem; -FormalParameterList: JsIdentifier ; +ModuleItemList: ModuleItemList ModuleItem; /. -case $rule_number: { - AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).StatementList = sym(1).StatementList->append(sym(2).StatementList); + } break; ./ -FormalParameterList: FormalParameterList T_COMMA JsIdentifier ; +ModuleItem: ImportDeclaration T_AUTOMATIC_SEMICOLON; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ModuleItem: ImportDeclaration T_SEMICOLON; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ModuleItem: ExportDeclaration T_AUTOMATIC_SEMICOLON; +/. case $rule_number: Q_FALLTHROUGH(); ./ +ModuleItem: ExportDeclaration T_SEMICOLON; /. -case $rule_number: { - AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3)); - node->commaToken = loc(2); - node->identifierToken = loc(3); - sym(1).Node = node; -} break; + case $rule_number: { + sym(1).StatementList = new (pool) AST::StatementList(sym(1).Node); + } break; ./ -FormalParameterListOpt: ; +ModuleItem: StatementListItem; + +ImportDeclaration: T_IMPORT ImportClause FromClause; /. -case $rule_number: { - sym(1).Node = 0; -} break; + 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; ./ -FormalParameterListOpt: FormalParameterList ; +ImportClause: ImportedDefaultBinding; /. -case $rule_number: { - sym(1).Node = sym(1).FormalParameterList->finish (); -} break; + 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; ./ -FunctionBodyOpt: ; +ImportedDefaultBinding: ImportedBinding; + +NameSpaceImport: T_STAR T_AS ImportedBinding; /. -case $rule_number: { - sym(1).Node = 0; -} break; + case $rule_number: { + auto import = new (pool) AST::NameSpaceImport(stringRef(3)); + import->starToken = loc(1); + import->importedBindingToken = loc(3); + sym(1).NameSpaceImport = import; + } break; ./ -FunctionBodyOpt: FunctionBody ; +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; +./ -FunctionBody: SourceElements ; +FromClause: T_FROM ModuleSpecifier; /. -case $rule_number: { - sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ()); -} break; + case $rule_number: { + auto clause = new (pool) AST::FromClause(stringRef(2)); + clause->fromToken = loc(1); + clause->moduleSpecifierToken = loc(2); + sym(1).FromClause = clause; + } break; ./ -Program: Empty ; +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; +./ -Program: SourceElements ; +ImportSpecifier: ImportedBinding; /. -case $rule_number: { - sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ()); -} break; + 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; -SourceElements: SourceElement ; +ImportedBinding: BindingIdentifier; + +ExportDeclarationLookahead: ; +/: +#define J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE $rule_number +:/ /. -case $rule_number: { - sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement); -} break; + case $rule_number: { + int token = lookaheadToken(lexer); + if (token == T_FUNCTION || token == T_CLASS) + pushToken(T_FORCE_DECLARATION); + } break; ./ -SourceElements: SourceElements SourceElement ; +ExportDeclaration: T_EXPORT T_STAR FromClause; /. -case $rule_number: { - sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement); -} break; + 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: { + if (auto *f = AST::cast<AST::FunctionDeclaration*>(sym(5).Node)) { + if (f->name.isEmpty()) { + f->name = stringRef(2); + f->identifierToken = loc(2); + } + } + } Q_FALLTHROUGH(); +./ +ExportDeclaration: T_EXPORT T_DEFAULT ExportDeclarationLookahead T_FORCE_DECLARATION ClassDeclaration_Default; +/. + case $rule_number: { + // Emulate 15.2.3.11 + if (auto *cls = AST::cast<AST::ClassDeclaration*>(sym(5).Node)) { + if (cls->name.isEmpty()) { + cls->name = stringRef(2); + cls->identifierToken = loc(2); + } + } + + 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: { + // if lhs is an identifier expression and rhs is an anonymous function expression, we need to assign the name of lhs to the function + if (auto *f = asAnonymousFunctionDefinition(sym(4).Node)) { + f->name = stringRef(2); + } + if (auto *c = asAnonymousClassDefinition(sym(4).Expression)) { + c->name = stringRef(2); + } -SourceElement: Statement ; + 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: { - sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement); -} break; + 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; ./ -SourceElement: FunctionDeclaration ; +ExportsList: ExportSpecifier; /. -case $rule_number: { - sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration); -} break; + 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; ./ -PropertyAssignmentListOpt: ; +ExportSpecifier: IdentifierName; /. -case $rule_number: { - sym(1).Node = 0; -} break; + 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; ./ -PropertyAssignmentListOpt: PropertyAssignmentList ; +-- Old top level code /. + // ------------ end of switch statement } // switch action = nt_action(state_stack[tos], lhs[r] - TERMINAL_COUNT); } // if } while (action != 0); +#ifdef PARSER_DEBUG + qDebug() << "Done or error."; +#endif + if (first_token == last_token) { const int errorState = state_stack[tos]; // automatic insertion of `;' if (yytoken != -1 && ((t_action(errorState, T_AUTOMATIC_SEMICOLON) && lexer->canInsertAutomaticSemicolon(yytoken)) || t_action(errorState, T_COMPATIBILITY_SEMICOLON))) { +#ifdef PARSER_DEBUG + qDebug() << "Inserting automatic semicolon."; +#endif SavedToken &tk = token_buffer[0]; tk.token = yytoken; tk.dval = yylval; tk.spell = yytokenspell; + tk.raw = yytokenraw; tk.loc = yylloc; yylloc = yyprevlloc; @@ -3144,14 +4405,19 @@ PropertyAssignmentListOpt: PropertyAssignmentList ; token_buffer[0].token = yytoken; token_buffer[0].dval = yylval; token_buffer[0].spell = yytokenspell; + token_buffer[0].raw = yytokenraw; token_buffer[0].loc = yylloc; token_buffer[1].token = yytoken = lexer->lex(); token_buffer[1].dval = yylval = lexer->tokenValue(); token_buffer[1].spell = yytokenspell = lexer->tokenSpell(); + token_buffer[1].raw = yytokenraw = lexer->rawString(); token_buffer[1].loc = yylloc = location(lexer); if (t_action(errorState, yytoken)) { +#ifdef PARSER_DEBUG + qDebug() << "Parse error, trying to recover."; +#endif QString msg; int token = token_buffer[0].token; if (token < 0 || token >= TERMINAL_COUNT) @@ -3185,26 +4451,20 @@ PropertyAssignmentListOpt: PropertyAssignmentList ; for (int *tk = tokens; *tk != EOF_SYMBOL; ++tk) { int a = t_action(errorState, *tk); if (a > 0 && t_action(a, yytoken)) { +#ifdef PARSER_DEBUG + qDebug() << "Parse error, trying to recover (2)."; +#endif const QString msg = QCoreApplication::translate("QQmlParser", "Expected token `%1'").arg(QLatin1String(spell[*tk])); diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg)); - yytoken = *tk; - yylval = 0; - yylloc = token_buffer[0].loc; - yylloc.length = 0; - - first_token = &token_buffer[0]; - last_token = &token_buffer[2]; - - action = errorState; + pushToken(*tk); goto _Lcheck_token; } } for (int tk = 1; tk < TERMINAL_COUNT; ++tk) { if (tk == T_AUTOMATIC_SEMICOLON || tk == T_FEED_UI_PROGRAM || - tk == T_FEED_JS_STATEMENT || tk == T_FEED_JS_EXPRESSION || - tk == T_FEED_JS_SOURCE_ELEMENT) + tk == T_FEED_JS_STATEMENT || tk == T_FEED_JS_EXPRESSION) continue; int a = t_action(errorState, tk); @@ -3212,12 +4472,7 @@ PropertyAssignmentListOpt: PropertyAssignmentList ; const QString msg = QCoreApplication::translate("QQmlParser", "Expected token `%1'").arg(QLatin1String(spell[tk])); diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg)); - yytoken = tk; - yylval = 0; - yylloc = token_buffer[0].loc; - yylloc.length = 0; - - action = errorState; + pushToken(tk); goto _Lcheck_token; } } diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp index 7f8cecca8f..4ebb2d3b5c 100644 --- a/src/qml/parser/qqmljsast.cpp +++ b/src/qml/parser/qqmljsast.cpp @@ -45,6 +45,27 @@ QT_QML_BEGIN_NAMESPACE namespace QQmlJS { namespace AST { +FunctionExpression *asAnonymousFunctionDefinition(Node *n) +{ + if (!n) + return nullptr; + FunctionExpression *f = n->asFunctionDefinition(); + if (!f || !f->name.isNull()) + return nullptr; + return f; +} + +ClassExpression *asAnonymousClassDefinition(Node *n) +{ + if (!n) + return nullptr; + ClassExpression *c = n->asClassDefinition(); + if (!c || !c->name.isNull()) + return nullptr; + return c; +} + + void Node::accept(Visitor *visitor) { if (visitor->preVisit(this)) { @@ -61,22 +82,42 @@ void Node::accept(Node *node, Visitor *visitor) ExpressionNode *Node::expressionCast() { - return 0; + return nullptr; } BinaryExpression *Node::binaryExpressionCast() { - return 0; + return nullptr; } Statement *Node::statementCast() { - return 0; + return nullptr; } UiObjectMember *Node::uiObjectMemberCast() { - return 0; + return nullptr; +} + +LeftHandSideExpression *Node::leftHandSideExpressionCast() +{ + return nullptr; +} + +Pattern *Node::patternCast() +{ + return nullptr; +} + +FunctionExpression *Node::asFunctionDefinition() +{ + return nullptr; +} + +ClassExpression *Node::asClassDefinition() +{ + return nullptr; } ExpressionNode *ExpressionNode::expressionCast() @@ -84,6 +125,42 @@ ExpressionNode *ExpressionNode::expressionCast() return this; } +FormalParameterList *ExpressionNode::reparseAsFormalParameterList(MemoryPool *pool) +{ + AST::ExpressionNode *expr = this; + AST::FormalParameterList *f = nullptr; + if (AST::Expression *commaExpr = AST::cast<AST::Expression *>(expr)) { + f = commaExpr->left->reparseAsFormalParameterList(pool); + if (!f) + return nullptr; + + expr = commaExpr->right; + } + + AST::ExpressionNode *rhs = nullptr; + if (AST::BinaryExpression *assign = AST::cast<AST::BinaryExpression *>(expr)) { + if (assign->op != QSOperator::Assign) + return nullptr; + expr = assign->left; + rhs = assign->right; + } + AST::PatternElement *binding = nullptr; + if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(expr)) { + binding = new (pool) AST::PatternElement(idExpr->name, rhs); + binding->identifierToken = idExpr->identifierToken; + } else if (AST::Pattern *p = expr->patternCast()) { + SourceLocation loc; + QString s; + if (!p->convertLiteralToAssignmentPattern(pool, &loc, &s)) + return nullptr; + binding = new (pool) AST::PatternElement(p, rhs); + binding->identifierToken = p->firstSourceLocation(); + } + if (!binding) + return nullptr; + return new (pool) AST::FormalParameterList(f, binding); +} + BinaryExpression *BinaryExpression::binaryExpressionCast() { return this; @@ -107,6 +184,16 @@ void NestedExpression::accept0(Visitor *visitor) visitor->endVisit(this); } +FunctionExpression *NestedExpression::asFunctionDefinition() +{ + return expression->asFunctionDefinition(); +} + +ClassExpression *NestedExpression::asClassDefinition() +{ + return expression->asClassDefinition(); +} + void ThisExpression::accept0(Visitor *visitor) { if (visitor->visit(this)) { @@ -147,7 +234,7 @@ void FalseLiteral::accept0(Visitor *visitor) visitor->endVisit(this); } -void StringLiteral::accept0(Visitor *visitor) +void SuperLiteral::accept0(Visitor *visitor) { if (visitor->visit(this)) { } @@ -155,7 +242,8 @@ void StringLiteral::accept0(Visitor *visitor) visitor->endVisit(this); } -void NumericLiteral::accept0(Visitor *visitor) + +void StringLiteral::accept0(Visitor *visitor) { if (visitor->visit(this)) { } @@ -163,81 +251,231 @@ void NumericLiteral::accept0(Visitor *visitor) visitor->endVisit(this); } -void RegExpLiteral::accept0(Visitor *visitor) +void TemplateLiteral::accept0(Visitor *visitor) { if (visitor->visit(this)) { + if (next) + accept(next, visitor); } visitor->endVisit(this); } -void ArrayLiteral::accept0(Visitor *visitor) +void NumericLiteral::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(elements, visitor); - accept(elision, visitor); } visitor->endVisit(this); } -void ObjectLiteral::accept0(Visitor *visitor) +void RegExpLiteral::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(properties, visitor); } visitor->endVisit(this); } -void ElementList::accept0(Visitor *visitor) +void ArrayPattern::accept0(Visitor *visitor) { - if (visitor->visit(this)) { - for (ElementList *it = this; it; it = it->next) { - accept(it->elision, visitor); - accept(it->expression, visitor); - } - } + if (visitor->visit(this)) + accept(elements, visitor); visitor->endVisit(this); } -void Elision::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->bindingTarget != nullptr) { + if (errorLocation) + *errorLocation = e->firstSourceLocation(); + return false; + } + } + return true; +} + +void ObjectPattern::accept0(Visitor *visitor) { if (visitor->visit(this)) { - // ### + accept(properties, visitor); } visitor->endVisit(this); } -void PropertyNameAndValue::accept0(Visitor *visitor) -{ - if (visitor->visit(this)) { - accept(name, visitor); - accept(value, visitor); +/* + This is the grammar for AssignmentPattern that we need to convert the literal to: + + AssignmentPattern: + ObjectAssignmentPattern + ArrayAssignmentPattern + ArrayAssignmentPattern: + [ ElisionOpt AssignmentRestElementOpt ] + [ AssignmentElementList ] + [ AssignmentElementList , ElisionOpt AssignmentRestElementOpt ] + AssignmentElementList: + AssignmentElisionElement + AssignmentElementList , AssignmentElisionElement + AssignmentElisionElement: + ElisionOpt AssignmentElement + AssignmentRestElement: + ... DestructuringAssignmentTarget + + ObjectAssignmentPattern: + {} + { AssignmentPropertyList } + { AssignmentPropertyList, } + AssignmentPropertyList: + AssignmentProperty + AssignmentPropertyList , AssignmentProperty + AssignmentProperty: + IdentifierReference InitializerOpt_In + PropertyName: + AssignmentElement + + AssignmentElement: + DestructuringAssignmentTarget InitializerOpt_In + DestructuringAssignmentTarget: + LeftHandSideExpression + + It was originally parsed with the following grammar: + +ArrayLiteral: + [ ElisionOpt ] + [ ElementList ] + [ ElementList , ElisionOpt ] +ElementList: + ElisionOpt AssignmentExpression_In + ElisionOpt SpreadElement + ElementList , ElisionOpt AssignmentExpression_In + ElementList , Elisionopt SpreadElement +SpreadElement: + ... AssignmentExpression_In +ObjectLiteral: + {} + { PropertyDefinitionList } + { PropertyDefinitionList , } +PropertyDefinitionList: + PropertyDefinition + PropertyDefinitionList , PropertyDefinition +PropertyDefinition: + IdentifierReference + CoverInitializedName + PropertyName : AssignmentExpression_In + MethodDefinition +PropertyName: + LiteralPropertyName + ComputedPropertyName + +*/ +bool ArrayPattern::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) +{ + if (parseMode == Binding) + return true; + for (auto *it = elements; it; it = it->next) { + if (!it->element) + continue; + if (it->element->type == PatternElement::SpreadElement && it->next) { + *errorLocation = it->element->firstSourceLocation(); + *errorMessage = QString::fromLatin1("'...' can only appear as last element in a destructuring list."); + return false; + } + if (!it->element->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage)) + return false; } + parseMode = Binding; + return true; +} - visitor->endVisit(this); +bool ObjectPattern::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) +{ + if (parseMode == Binding) + return true; + for (auto *it = properties; it; it = it->next) { + if (!it->property->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage)) + return false; + } + parseMode = Binding; + return true; } -void PropertyGetterSetter::accept0(Visitor *visitor) +bool PatternElement::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) { - if (visitor->visit(this)) { - accept(name, visitor); - accept(formals, visitor); - accept(functionBody, visitor); + Q_ASSERT(type == Literal || type == SpreadElement); + Q_ASSERT(bindingIdentifier.isNull()); + Q_ASSERT(bindingTarget == nullptr); + Q_ASSERT(bindingTarget == nullptr); + Q_ASSERT(initializer); + ExpressionNode *init = initializer; + + initializer = nullptr; + LeftHandSideExpression *lhs = init->leftHandSideExpressionCast(); + if (type == SpreadElement) { + if (!lhs) { + *errorLocation = init->firstSourceLocation(); + *errorMessage = QString::fromLatin1("Invalid lhs expression after '...' in destructuring expression."); + return false; + } + } else { + type = PatternElement::Binding; + + if (BinaryExpression *b = init->binaryExpressionCast()) { + if (b->op != QSOperator::Assign) { + *errorLocation = b->operatorToken; + *errorMessage = QString::fromLatin1("Invalid assignment operation in destructuring expression"); + return false; + } + lhs = b->left->leftHandSideExpressionCast(); + initializer = b->right; + Q_ASSERT(lhs); + } else { + lhs = init->leftHandSideExpressionCast(); + } + if (!lhs) { + *errorLocation = init->firstSourceLocation(); + *errorMessage = QString::fromLatin1("Destructuring target is not a left hand side expression."); + return false; + } } - visitor->endVisit(this); + if (auto *i = cast<IdentifierExpression *>(lhs)) { + bindingIdentifier = i->name; + identifierToken = i->identifierToken; + return true; + } + + 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) +{ + Q_ASSERT(type != SpreadElement); + if (type == Binding) + return true; + if (type == Getter || type == Setter) { + *errorLocation = firstSourceLocation(); + *errorMessage = QString::fromLatin1("Invalid getter/setter in destructuring expression."); + return false; + } + if (type == Method) + type = Literal; + Q_ASSERT(type == Literal); + return PatternElement::convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage); } -void PropertyAssignmentList::accept0(Visitor *visitor) + +void Elision::accept0(Visitor *visitor) { if (visitor->visit(this)) { - for (PropertyAssignmentList *it = this; it; it = it->next) { - accept(it->assignment, visitor); - } + // ### } visitor->endVisit(this); @@ -267,6 +505,28 @@ void NumericLiteralPropertyName::accept0(Visitor *visitor) visitor->endVisit(this); } +namespace { +struct LocaleWithoutZeroPadding : public QLocale +{ + LocaleWithoutZeroPadding() + : QLocale(QLocale::C) + { + setNumberOptions(QLocale::OmitLeadingZeroInExponent | QLocale::OmitGroupSeparator); + } +}; +} + +QString NumericLiteralPropertyName::asString()const +{ + // Can't use QString::number here anymore as it does zero padding by default now. + + // In C++11 this initialization is thread-safe (6.7 [stmt.dcl] p4) + static LocaleWithoutZeroPadding locale; + // Because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562 we can't use thread_local + // for the locale variable and therefore rely on toString(double) to be thread-safe. + return locale.toString(id, 'g', 16); +} + void ArrayMemberExpression::accept0(Visitor *visitor) { if (visitor->visit(this)) { @@ -496,15 +756,6 @@ void VariableDeclarationList::accept0(Visitor *visitor) visitor->endVisit(this); } -void VariableDeclaration::accept0(Visitor *visitor) -{ - if (visitor->visit(this)) { - accept(expression, visitor); - } - - visitor->endVisit(this); -} - void EmptyStatement::accept0(Visitor *visitor) { if (visitor->visit(this)) { @@ -557,17 +808,6 @@ void ForStatement::accept0(Visitor *visitor) { if (visitor->visit(this)) { accept(initialiser, visitor); - accept(condition, visitor); - accept(expression, visitor); - accept(statement, visitor); - } - - visitor->endVisit(this); -} - -void LocalForStatement::accept0(Visitor *visitor) -{ - if (visitor->visit(this)) { accept(declarations, visitor); accept(condition, visitor); accept(expression, visitor); @@ -580,7 +820,7 @@ void LocalForStatement::accept0(Visitor *visitor) void ForEachStatement::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(initialiser, visitor); + accept(lhs, visitor); accept(expression, visitor); accept(statement, visitor); } @@ -588,18 +828,15 @@ void ForEachStatement::accept0(Visitor *visitor) visitor->endVisit(this); } -void LocalForEachStatement::accept0(Visitor *visitor) +void ContinueStatement::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(declaration, visitor); - accept(expression, visitor); - accept(statement, visitor); } visitor->endVisit(this); } -void ContinueStatement::accept0(Visitor *visitor) +void BreakStatement::accept0(Visitor *visitor) { if (visitor->visit(this)) { } @@ -607,15 +844,16 @@ void ContinueStatement::accept0(Visitor *visitor) visitor->endVisit(this); } -void BreakStatement::accept0(Visitor *visitor) +void ReturnStatement::accept0(Visitor *visitor) { if (visitor->visit(this)) { + accept(expression, visitor); } visitor->endVisit(this); } -void ReturnStatement::accept0(Visitor *visitor) +void YieldExpression::accept0(Visitor *visitor) { if (visitor->visit(this)) { accept(expression, visitor); @@ -624,6 +862,7 @@ void ReturnStatement::accept0(Visitor *visitor) visitor->endVisit(this); } + void WithStatement::accept0(Visitor *visitor) { if (visitor->visit(this)) { @@ -717,6 +956,7 @@ void TryStatement::accept0(Visitor *visitor) void Catch::accept0(Visitor *visitor) { if (visitor->visit(this)) { + accept(patternElement, visitor); accept(statement, visitor); } @@ -752,57 +992,182 @@ void FunctionExpression::accept0(Visitor *visitor) visitor->endVisit(this); } +FunctionExpression *FunctionExpression::asFunctionDefinition() +{ + return this; +} + +QStringList FormalParameterList::formals() const +{ + QStringList formals; + int i = 0; + for (const FormalParameterList *it = this; it; it = it->next) { + if (it->element) { + QString name = it->element->bindingIdentifier.toString(); + int duplicateIndex = formals.indexOf(name); + if (duplicateIndex >= 0) { + // change the name of the earlier argument to enforce the lookup semantics from the spec + formals[duplicateIndex] += QLatin1String("#") + QString::number(i); + } + formals += name; + } + ++i; + } + return formals; +} + +QStringList FormalParameterList::boundNames() const +{ + QStringList names; + for (const FormalParameterList *it = this; it; it = it->next) { + if (it->element) + it->element->boundNames(&names); + } + return names; +} + void FormalParameterList::accept0(Visitor *visitor) { if (visitor->visit(this)) { - // ### + accept(element, visitor); + if (next) + accept(next, visitor); } visitor->endVisit(this); } -void FunctionBody::accept0(Visitor *visitor) +FormalParameterList *FormalParameterList::finish(QQmlJS::MemoryPool *pool) +{ + FormalParameterList *front = next; + next = nullptr; + + int i = 0; + for (const FormalParameterList *it = this; it; it = it->next) { + if (it->element && it->element->bindingIdentifier.isEmpty()) + it->element->bindingIdentifier = pool->newString(QLatin1String("arg#") + QString::number(i)); + ++i; + } + return front; +} + +void Program::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(elements, visitor); + accept(statements, visitor); } visitor->endVisit(this); } -void Program::accept0(Visitor *visitor) +void ImportSpecifier::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(elements, visitor); + + } + 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 SourceElements::accept0(Visitor *visitor) +void FromClause::accept0(Visitor *visitor) { if (visitor->visit(this)) { - for (SourceElements *it = this; it; it = it->next) { - accept(it->element, visitor); + } + + 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 FunctionSourceElement::accept0(Visitor *visitor) +void ExportClause::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(declaration, visitor); + accept(exportsList, visitor); } visitor->endVisit(this); } -void StatementSourceElement::accept0(Visitor *visitor) +void ExportDeclaration::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(statement, visitor); + accept(fromClause, visitor); + accept(exportClause, visitor); + accept(variableStatementOrDeclaration, visitor); + } + + visitor->endVisit(this); +} + +void ESModule::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(body, visitor); } visitor->endVisit(this); @@ -930,7 +1295,7 @@ void UiImport::accept0(Visitor *visitor) visitor->endVisit(this); } -void UiQualifiedPragmaId::accept0(Visitor *visitor) +void UiPragma::accept0(Visitor *visitor) { if (visitor->visit(this)) { } @@ -938,35 +1303,190 @@ void UiQualifiedPragmaId::accept0(Visitor *visitor) visitor->endVisit(this); } -void UiPragma::accept0(Visitor *visitor) +void UiHeaderItemList::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(pragmaType, visitor); + accept(headerItem, visitor); + accept(next, visitor); } visitor->endVisit(this); } -void UiHeaderItemList::accept0(Visitor *visitor) + +void UiSourceElement::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(headerItem, visitor); - accept(next, visitor); + accept(sourceElement, visitor); } visitor->endVisit(this); } +void UiEnumDeclaration::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(members, visitor); + } + + visitor->endVisit(this); +} -void UiSourceElement::accept0(Visitor *visitor) +void UiEnumMemberList::accept0(Visitor *visitor) { if (visitor->visit(this)) { - accept(sourceElement, visitor); } visitor->endVisit(this); } +void TaggedTemplate::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(base, visitor); + accept(templateLiteral, visitor); + } + + visitor->endVisit(this); +} + +void PatternElement::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(bindingTarget, visitor); + accept(initializer, visitor); + } + + visitor->endVisit(this); +} + +void PatternElement::boundNames(QStringList *names) +{ + if (bindingTarget) { + if (PatternElementList *e = elementList()) + e->boundNames(names); + else if (PatternPropertyList *p = propertyList()) + p->boundNames(names); + } else { + names->append(bindingIdentifier.toString()); + } +} + +void PatternElementList::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(elision, visitor); + accept(element, visitor); + if (next) + accept(next, visitor); + } + + visitor->endVisit(this); +} + +void PatternElementList::boundNames(QStringList *names) +{ + for (PatternElementList *it = this; it; it = it->next) { + if (it->element) + it->element->boundNames(names); + } +} + +void PatternProperty::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(name, visitor); + accept(bindingTarget, visitor); + accept(initializer, visitor); + } + + visitor->endVisit(this); +} + +void PatternProperty::boundNames(QStringList *names) +{ + PatternElement::boundNames(names); +} + +void PatternPropertyList::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(property, visitor); + if (next) + accept(next, visitor); + } + + visitor->endVisit(this); +} + +void PatternPropertyList::boundNames(QStringList *names) +{ + for (PatternPropertyList *it = this; it; it = it->next) + it->property->boundNames(names); +} + +void ComputedPropertyName::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(expression, visitor); + } + + visitor->endVisit(this); +} + +void ClassExpression::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(heritage, visitor); + accept(elements, visitor); + } + + visitor->endVisit(this); +} + +ClassExpression *ClassExpression::asClassDefinition() +{ + return this; +} + +void ClassDeclaration::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; +} + +Pattern *Pattern::patternCast() +{ + return this; +} + +LeftHandSideExpression *LeftHandSideExpression::leftHandSideExpressionCast() +{ + return this; +} + } } // namespace QQmlJS::AST QT_QML_END_NAMESPACE diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index 0de419d697..43aeec6525 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -77,6 +77,8 @@ enum Op { Div, InplaceDiv, Equal, + Exp, + InplaceExp, Ge, Gt, In, @@ -100,7 +102,8 @@ enum Op { Sub, URShift, InplaceURightShift, - InplaceXor + InplaceXor, + Invalid }; } // namespace QSOperator @@ -109,6 +112,13 @@ namespace QQmlJS { namespace AST { +enum class VariableScope { + NoScope, + Var, + Let, + Const +}; + template <typename T1, typename T2> T1 cast(T2 *ast) { @@ -118,6 +128,9 @@ T1 cast(T2 *ast) return 0; } +FunctionExpression *asAnonymousFunctionDefinition(AST::Node *n); +ClassExpression *asAnonymousClassDefinition(AST::Node *n); + class QML_PARSER_EXPORT Node: public Managed { public: @@ -125,7 +138,7 @@ public: Kind_Undefined, Kind_ArgumentList, - Kind_ArrayLiteral, + Kind_ArrayPattern, Kind_ArrayMemberExpression, Kind_BinaryExpression, Kind_Block, @@ -147,6 +160,7 @@ public: Kind_Expression, Kind_ExpressionStatement, Kind_FalseLiteral, + Kind_SuperLiteral, Kind_FieldMemberExpression, Kind_Finally, Kind_ForEachStatement, @@ -155,38 +169,50 @@ public: Kind_FunctionBody, Kind_FunctionDeclaration, Kind_FunctionExpression, - Kind_FunctionSourceElement, + Kind_ClassExpression, + Kind_ClassDeclaration, Kind_IdentifierExpression, Kind_IdentifierPropertyName, + Kind_ComputedPropertyName, Kind_IfStatement, Kind_LabelledStatement, - Kind_LocalForEachStatement, - Kind_LocalForStatement, + 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_NewExpression, Kind_NewMemberExpression, Kind_NotExpression, Kind_NullExpression, + Kind_YieldExpression, Kind_NumericLiteral, Kind_NumericLiteralPropertyName, - Kind_ObjectLiteral, + Kind_ObjectPattern, Kind_PostDecrementExpression, Kind_PostIncrementExpression, Kind_PreDecrementExpression, Kind_PreIncrementExpression, Kind_Program, - Kind_PropertyAssignmentList, + Kind_PropertyDefinitionList, Kind_PropertyGetterSetter, Kind_PropertyName, Kind_PropertyNameAndValue, Kind_RegExpLiteral, Kind_ReturnStatement, - Kind_SourceElement, - Kind_SourceElements, Kind_StatementList, - Kind_StatementSourceElement, Kind_StringLiteral, Kind_StringLiteralPropertyName, Kind_SwitchStatement, + Kind_TemplateLiteral, + Kind_TaggedTemplate, Kind_ThisExpression, Kind_ThrowStatement, Kind_TildeExpression, @@ -202,6 +228,12 @@ public: Kind_WhileStatement, Kind_WithStatement, Kind_NestedExpression, + Kind_ClassElementList, + Kind_PatternElement, + Kind_PatternElementList, + Kind_PatternProperty, + Kind_PatternPropertyList, + Kind_UiArrayBinding, Kind_UiImport, @@ -215,14 +247,14 @@ public: Kind_UiParameterList, Kind_UiPublicMember, Kind_UiQualifiedId, - Kind_UiQualifiedPragmaId, Kind_UiScriptBinding, Kind_UiSourceElement, - Kind_UiHeaderItemList + Kind_UiHeaderItemList, + Kind_UiEnumDeclaration, + Kind_UiEnumMemberList }; - inline Node() - : kind(Kind_Undefined) {} + inline Node() {} // NOTE: node destructors are never called, // instead we block free the memory @@ -233,6 +265,11 @@ public: virtual BinaryExpression *binaryExpressionCast(); virtual Statement *statementCast(); virtual UiObjectMember *uiObjectMemberCast(); + virtual LeftHandSideExpression *leftHandSideExpressionCast(); + virtual Pattern *patternCast(); + // implements the IsFunctionDefinition rules in the spec + virtual FunctionExpression *asFunctionDefinition(); + virtual ClassExpression *asClassDefinition(); void accept(Visitor *visitor); static void accept(Node *node, Visitor *visitor); @@ -245,7 +282,7 @@ public: virtual SourceLocation lastSourceLocation() const = 0; // attributes - int kind; + int kind = Kind_Undefined; }; class QML_PARSER_EXPORT ExpressionNode: public Node @@ -254,6 +291,14 @@ public: ExpressionNode() {} ExpressionNode *expressionCast() override; + + AST::FormalParameterList *reparseAsFormalParameterList(MemoryPool *pool); + +}; + +class QML_PARSER_EXPORT LeftHandSideExpression : public ExpressionNode +{ + LeftHandSideExpression *leftHandSideExpressionCast() override; }; class QML_PARSER_EXPORT Statement: public Node @@ -264,7 +309,7 @@ public: Statement *statementCast() override; }; -class QML_PARSER_EXPORT NestedExpression: public ExpressionNode +class QML_PARSER_EXPORT NestedExpression: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(NestedExpression) @@ -281,13 +326,17 @@ public: SourceLocation lastSourceLocation() const override { return rparenToken; } + FunctionExpression *asFunctionDefinition() override; + ClassExpression *asClassDefinition() override; + + // attributes ExpressionNode *expression; SourceLocation lparenToken; SourceLocation rparenToken; }; -class QML_PARSER_EXPORT ThisExpression: public ExpressionNode +class QML_PARSER_EXPORT ThisExpression: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(ThisExpression) @@ -306,7 +355,7 @@ public: SourceLocation thisToken; }; -class QML_PARSER_EXPORT IdentifierExpression: public ExpressionNode +class QML_PARSER_EXPORT IdentifierExpression: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(IdentifierExpression) @@ -327,7 +376,7 @@ public: SourceLocation identifierToken; }; -class QML_PARSER_EXPORT NullExpression: public ExpressionNode +class QML_PARSER_EXPORT NullExpression: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(NullExpression) @@ -346,7 +395,7 @@ public: SourceLocation nullToken; }; -class QML_PARSER_EXPORT TrueLiteral: public ExpressionNode +class QML_PARSER_EXPORT TrueLiteral: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(TrueLiteral) @@ -365,7 +414,7 @@ public: SourceLocation trueToken; }; -class QML_PARSER_EXPORT FalseLiteral: public ExpressionNode +class QML_PARSER_EXPORT FalseLiteral: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(FalseLiteral) @@ -384,7 +433,27 @@ public: SourceLocation falseToken; }; -class QML_PARSER_EXPORT NumericLiteral: public ExpressionNode +class QML_PARSER_EXPORT SuperLiteral : public LeftHandSideExpression +{ +public: + QQMLJS_DECLARE_AST_NODE(SuperLiteral) + + SuperLiteral() { kind = K; } + + void accept0(Visitor *visitor) override; + + SourceLocation firstSourceLocation() const override + { return superToken; } + + SourceLocation lastSourceLocation() const override + { return superToken; } + +// attributes + SourceLocation superToken; +}; + + +class QML_PARSER_EXPORT NumericLiteral: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(NumericLiteral) @@ -405,7 +474,7 @@ public: SourceLocation literalToken; }; -class QML_PARSER_EXPORT StringLiteral: public ExpressionNode +class QML_PARSER_EXPORT StringLiteral: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(StringLiteral) @@ -426,7 +495,31 @@ public: SourceLocation literalToken; }; -class QML_PARSER_EXPORT RegExpLiteral: public ExpressionNode +class QML_PARSER_EXPORT TemplateLiteral : public LeftHandSideExpression +{ +public: + QQMLJS_DECLARE_AST_NODE(TemplateLiteral) + + TemplateLiteral(const QStringRef &str, const QStringRef &raw, ExpressionNode *e) + : value(str), rawValue(raw), expression(e), next(nullptr) + { kind = K; } + + SourceLocation firstSourceLocation() const override + { return literalToken; } + + SourceLocation lastSourceLocation() const override + { return next ? next->lastSourceLocation() : (expression ? expression->lastSourceLocation() : literalToken); } + + void accept0(Visitor *visitor) override; + + QStringRef value; + QStringRef rawValue; + ExpressionNode *expression; + TemplateLiteral *next; + SourceLocation literalToken; +}; + +class QML_PARSER_EXPORT RegExpLiteral: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(RegExpLiteral) @@ -448,22 +541,26 @@ public: SourceLocation literalToken; }; -class QML_PARSER_EXPORT ArrayLiteral: public ExpressionNode +class QML_PARSER_EXPORT Pattern : public LeftHandSideExpression { public: - QQMLJS_DECLARE_AST_NODE(ArrayLiteral) - - ArrayLiteral(Elision *e): - elements (0), elision (e) - { kind = K; } + enum ParseMode { + Literal, + Binding + }; + Pattern *patternCast() override; + virtual bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) = 0; + ParseMode parseMode = Literal; +}; - ArrayLiteral(ElementList *elts): - elements (elts), elision (0) - { kind = K; } +class QML_PARSER_EXPORT ArrayPattern : public Pattern +{ +public: + QQMLJS_DECLARE_AST_NODE(ArrayPattern) - ArrayLiteral(ElementList *elts, Elision *e): - elements (elts), elision (e) - { kind = K; } + ArrayPattern(PatternElementList *elts) + : elements(elts) + { kind = K; } void accept0(Visitor *visitor) override; @@ -473,24 +570,28 @@ public: SourceLocation lastSourceLocation() const override { return rbracketToken; } + bool isValidArrayLiteral(SourceLocation *errorLocation = nullptr) const; + + bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) override; + // attributes - ElementList *elements; - Elision *elision; + PatternElementList *elements = nullptr; SourceLocation lbracketToken; SourceLocation commaToken; SourceLocation rbracketToken; }; -class QML_PARSER_EXPORT ObjectLiteral: public ExpressionNode +class QML_PARSER_EXPORT ObjectPattern : public Pattern { public: - QQMLJS_DECLARE_AST_NODE(ObjectLiteral) + QQMLJS_DECLARE_AST_NODE(ObjectPattern) - ObjectLiteral(): - properties (0) { kind = K; } + ObjectPattern() + { kind = K; } - ObjectLiteral(PropertyAssignmentList *plist): - properties (plist) { kind = K; } + ObjectPattern(PatternPropertyList *plist) + : properties(plist) + { kind = K; } void accept0(Visitor *visitor) override; @@ -500,8 +601,10 @@ public: SourceLocation lastSourceLocation() const override { return rbraceToken; } + bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) override; + // attributes - PropertyAssignmentList *properties; + PatternPropertyList *properties = nullptr; SourceLocation lbraceToken; SourceLocation rbraceToken; }; @@ -532,7 +635,7 @@ public: inline Elision *finish () { Elision *front = next; - next = 0; + next = nullptr; return front; } @@ -541,53 +644,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 = 0; - 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; -}; - class QML_PARSER_EXPORT PropertyName: public Node { public: @@ -607,116 +663,186 @@ public: SourceLocation propertyNameToken; }; -class QML_PARSER_EXPORT PropertyAssignment: public Node +class QML_PARSER_EXPORT PatternElement : public Node { public: - PropertyAssignment(PropertyName *n) - : name(n) - {} + QQMLJS_DECLARE_AST_NODE(PatternElement) + + enum Type { + // object literal types + Literal, + Method, + 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), initializer(i), type(t) + { + Q_ASSERT(t >= RestElement); + kind = K; + } + + PatternElement(Pattern *pattern, ExpressionNode *i = nullptr, Type t = Binding) + : bindingTarget(pattern), initializer(i), type(t) + { + Q_ASSERT(t >= RestElement); + kind = K; + } + + void accept0(Visitor *visitor) override; + virtual bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage); + + SourceLocation firstSourceLocation() const override + { return identifierToken.isValid() ? identifierToken : (bindingTarget ? bindingTarget->firstSourceLocation() : initializer->firstSourceLocation()); } + + SourceLocation lastSourceLocation() const override + { return initializer ? initializer->lastSourceLocation() : (bindingTarget ? bindingTarget->lastSourceLocation() : identifierToken); } + + 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; } + + virtual void boundNames(QStringList *names); + // attributes - PropertyName *name; + SourceLocation identifierToken; + QStringRef bindingIdentifier; + ExpressionNode *bindingTarget = nullptr; + ExpressionNode *initializer = nullptr; + Type type = Literal; + // when used in a VariableDeclarationList + VariableScope scope = VariableScope::NoScope; + bool isForDeclaration = false; }; -class QML_PARSER_EXPORT PropertyAssignmentList: public Node +class QML_PARSER_EXPORT PatternElementList : public Node { public: - QQMLJS_DECLARE_AST_NODE(PropertyAssignmentList) + QQMLJS_DECLARE_AST_NODE(PatternElementList) - PropertyAssignmentList(PropertyAssignment *assignment) - : assignment(assignment) - , next(this) + PatternElementList(Elision *elision, PatternElement *element) + : elision(elision), element(element), next(this) { kind = K; } - PropertyAssignmentList(PropertyAssignmentList *previous, PropertyAssignment *assignment) - : assignment(assignment) - { - kind = K; - next = previous->next; - previous->next = this; + PatternElementList *append(PatternElementList *n) { + n->next = next; + next = n; + return n; } - inline PropertyAssignmentList *finish () + inline PatternElementList *finish () { - PropertyAssignmentList *front = next; + 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 - PropertyAssignment *assignment; - PropertyAssignmentList *next; - SourceLocation commaToken; + Elision *elision = nullptr; + PatternElement *element = nullptr; + PatternElementList *next; }; -class QML_PARSER_EXPORT PropertyNameAndValue: public PropertyAssignment +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; } + + PatternProperty(PropertyName *name, const QStringRef &n, ExpressionNode *i = nullptr) + : PatternElement(n, i), name(name) + { kind = K; } - PropertyNameAndValue(PropertyName *n, ExpressionNode *v) - : PropertyAssignment(n), value(v) + 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; + bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) override; // attributes + PropertyName *name; SourceLocation colonToken; - ExpressionNode *value; - SourceLocation commaToken; }; -class QML_PARSER_EXPORT PropertyGetterSetter: public PropertyAssignment + +class QML_PARSER_EXPORT PatternPropertyList : public Node { public: - QQMLJS_DECLARE_AST_NODE(PropertyGetterSetter) - - enum Type { - Getter, - Setter - }; + QQMLJS_DECLARE_AST_NODE(PatternPropertyList) - PropertyGetterSetter(PropertyName *n, FunctionBody *b) - : PropertyAssignment(n), type(Getter), formals(0), functionBody (b) + PatternPropertyList(PatternProperty *property) + : property(property), next(this) { kind = K; } - PropertyGetterSetter(PropertyName *n, FormalParameterList *f, FunctionBody *b) - : PropertyAssignment(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; - FunctionBody *functionBody; - SourceLocation rbraceToken; + PatternProperty *property; + PatternPropertyList *next; }; -class QML_PARSER_EXPORT IdentifierPropertyName: public PropertyName +class QML_PARSER_EXPORT IdentifierPropertyName : public PropertyName { public: QQMLJS_DECLARE_AST_NODE(IdentifierPropertyName) @@ -758,13 +884,37 @@ public: void accept0(Visitor *visitor) override; - QString asString() const override { return QString::number(id, 'g', 16); } + QString asString() const override; // attributes double id; }; -class QML_PARSER_EXPORT ArrayMemberExpression: public ExpressionNode +class QML_PARSER_EXPORT ComputedPropertyName : public PropertyName +{ +public: + QQMLJS_DECLARE_AST_NODE(ComputedPropertyName) + + ComputedPropertyName(ExpressionNode *expression) + : expression(expression) + { kind = K; } + + void accept0(Visitor *visitor) override; + + QString asString() const override { return QString(); } + + SourceLocation firstSourceLocation() const override + { return expression->firstSourceLocation(); } + + SourceLocation lastSourceLocation() const override + { return expression->lastSourceLocation(); } + +// attributes + ExpressionNode *expression; +}; + + +class QML_PARSER_EXPORT ArrayMemberExpression: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(ArrayMemberExpression) @@ -788,7 +938,7 @@ public: SourceLocation rbracketToken; }; -class QML_PARSER_EXPORT FieldMemberExpression: public ExpressionNode +class QML_PARSER_EXPORT FieldMemberExpression: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(FieldMemberExpression) @@ -812,7 +962,29 @@ public: SourceLocation identifierToken; }; -class QML_PARSER_EXPORT NewMemberExpression: public ExpressionNode +class QML_PARSER_EXPORT TaggedTemplate : public LeftHandSideExpression +{ +public: + QQMLJS_DECLARE_AST_NODE(TaggedTemplate) + + TaggedTemplate(ExpressionNode *b, TemplateLiteral *t) + : base (b), templateLiteral(t) + { kind = K; } + + void accept0(Visitor *visitor) override; + + SourceLocation firstSourceLocation() const override + { return base->firstSourceLocation(); } + + SourceLocation lastSourceLocation() const override + { return templateLiteral->lastSourceLocation(); } + + // attributes + ExpressionNode *base; + TemplateLiteral *templateLiteral; +}; + +class QML_PARSER_EXPORT NewMemberExpression: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(NewMemberExpression) @@ -837,7 +1009,7 @@ public: SourceLocation rparenToken; }; -class QML_PARSER_EXPORT NewExpression: public ExpressionNode +class QML_PARSER_EXPORT NewExpression: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(NewExpression) @@ -858,7 +1030,7 @@ public: SourceLocation newToken; }; -class QML_PARSER_EXPORT CallExpression: public ExpressionNode +class QML_PARSER_EXPORT CallExpression: public LeftHandSideExpression { public: QQMLJS_DECLARE_AST_NODE(CallExpression) @@ -914,7 +1086,7 @@ public: inline ArgumentList *finish () { ArgumentList *front = next; - next = 0; + next = nullptr; return front; } @@ -922,6 +1094,7 @@ public: ExpressionNode *expression; ArgumentList *next; SourceLocation commaToken; + bool isSpreadElement = false; }; class QML_PARSER_EXPORT PostIncrementExpression: public ExpressionNode @@ -1255,16 +1428,15 @@ class QML_PARSER_EXPORT StatementList: public Node public: QQMLJS_DECLARE_AST_NODE(StatementList) - StatementList(Statement *stmt): - statement (stmt), next (this) - { kind = K; } + // ### This should be a Statement, but FunctionDeclaration currently doesn't inherit it. + StatementList(Node *stmt) + : statement(stmt), next (this) + { kind = K; } - StatementList(StatementList *previous, Statement *stmt): - statement (stmt) - { - kind = K; - next = previous->next; - previous->next = this; + StatementList *append(StatementList *n) { + n->next = next; + next = n; + return n; } void accept0(Visitor *visitor) override; @@ -1278,81 +1450,26 @@ public: inline StatementList *finish () { StatementList *front = next; - next = 0; + next = nullptr; return front; } // attributes - Statement *statement; + Node *statement = nullptr; StatementList *next; }; -class QML_PARSER_EXPORT VariableStatement: public Statement -{ -public: - QQMLJS_DECLARE_AST_NODE(VariableStatement) - - VariableStatement(VariableDeclarationList *vlist): - declarations (vlist) - { kind = K; } - - void accept0(Visitor *visitor) override; - - SourceLocation firstSourceLocation() const override - { return declarationKindToken; } - - SourceLocation lastSourceLocation() const override - { return semicolonToken; } - -// attributes - VariableDeclarationList *declarations; - SourceLocation declarationKindToken; - SourceLocation semicolonToken; -}; - -class QML_PARSER_EXPORT VariableDeclaration: public Node -{ -public: - QQMLJS_DECLARE_AST_NODE(VariableDeclaration) - - enum VariableScope { - FunctionScope, - BlockScope, // let - ReadOnlyBlockScope // const - }; - - VariableDeclaration(const QStringRef &n, ExpressionNode *e, VariableScope s): - name (n), expression (e), scope(s) - { kind = K; } - - bool isLexicallyScoped() const { return scope != FunctionScope; } - - void accept0(Visitor *visitor) override; - - SourceLocation firstSourceLocation() const override - { return identifierToken; } - - SourceLocation lastSourceLocation() const override - { return expression ? expression->lastSourceLocation() : identifierToken; } - -// attributes - QStringRef name; - ExpressionNode *expression; - SourceLocation identifierToken; - VariableScope scope; -}; - class QML_PARSER_EXPORT VariableDeclarationList: public Node { public: QQMLJS_DECLARE_AST_NODE(VariableDeclarationList) - VariableDeclarationList(VariableDeclaration *decl): - declaration (decl), next (this) - { kind = K; } + VariableDeclarationList(PatternElement *decl) + : declaration(decl), next(this) + { kind = K; } - VariableDeclarationList(VariableDeclarationList *previous, VariableDeclaration *decl): - declaration (decl) + VariableDeclarationList(VariableDeclarationList *previous, PatternElement *decl) + : declaration(decl) { kind = K; next = previous->next; @@ -1371,23 +1488,45 @@ public: return declaration->lastSourceLocation(); } - inline VariableDeclarationList *finish(VariableDeclaration::VariableScope s) + inline VariableDeclarationList *finish(VariableScope s) { VariableDeclarationList *front = next; - next = 0; + next = nullptr; VariableDeclarationList *vdl; - for (vdl = front; vdl != 0; vdl = vdl->next) { + for (vdl = front; vdl != nullptr; vdl = vdl->next) { vdl->declaration->scope = s; } return front; } // attributes - VariableDeclaration *declaration; + PatternElement *declaration; VariableDeclarationList *next; SourceLocation commaToken; }; +class QML_PARSER_EXPORT VariableStatement: public Statement +{ +public: + QQMLJS_DECLARE_AST_NODE(VariableStatement) + + VariableStatement(VariableDeclarationList *vlist): + declarations (vlist) + { kind = K; } + + void accept0(Visitor *visitor) override; + + SourceLocation firstSourceLocation() const override + { return declarationKindToken; } + + SourceLocation lastSourceLocation() const override + { return declarations->lastSourceLocation(); } + +// attributes + VariableDeclarationList *declarations; + SourceLocation declarationKindToken; +}; + class QML_PARSER_EXPORT EmptyStatement: public Statement { public: @@ -1421,7 +1560,7 @@ public: { return expression->firstSourceLocation(); } SourceLocation lastSourceLocation() const override - { return semicolonToken; } + { return expression->lastSourceLocation(); } // attributes ExpressionNode *expression; @@ -1433,7 +1572,7 @@ class QML_PARSER_EXPORT IfStatement: public Statement public: QQMLJS_DECLARE_AST_NODE(IfStatement) - IfStatement(ExpressionNode *e, Statement *t, Statement *f = 0): + IfStatement(ExpressionNode *e, Statement *t, Statement *f = nullptr): expression (e), ok (t), ko (f) { kind = K; } @@ -1521,35 +1660,11 @@ public: initialiser (i), condition (c), expression (e), statement (stmt) { kind = K; } - void accept0(Visitor *visitor) override; - - SourceLocation firstSourceLocation() const override - { return forToken; } - - SourceLocation lastSourceLocation() const override - { return statement->lastSourceLocation(); } - -// attributes - ExpressionNode *initialiser; - ExpressionNode *condition; - ExpressionNode *expression; - Statement *statement; - SourceLocation forToken; - SourceLocation lparenToken; - SourceLocation firstSemicolonToken; - SourceLocation secondSemicolonToken; - SourceLocation rparenToken; -}; - -class QML_PARSER_EXPORT LocalForStatement: public Statement -{ -public: - QQMLJS_DECLARE_AST_NODE(LocalForStatement) - - LocalForStatement(VariableDeclarationList *vlist, ExpressionNode *c, ExpressionNode *e, Statement *stmt): + ForStatement(VariableDeclarationList *vlist, ExpressionNode *c, ExpressionNode *e, Statement *stmt): declarations (vlist), condition (c), expression (e), statement (stmt) { kind = K; } + void accept0(Visitor *visitor) override; SourceLocation firstSourceLocation() const override @@ -1559,26 +1674,34 @@ public: { return statement->lastSourceLocation(); } // attributes - VariableDeclarationList *declarations; + ExpressionNode *initialiser = nullptr; + VariableDeclarationList *declarations = nullptr; ExpressionNode *condition; ExpressionNode *expression; Statement *statement; SourceLocation forToken; SourceLocation lparenToken; - SourceLocation varToken; SourceLocation firstSemicolonToken; SourceLocation secondSemicolonToken; SourceLocation rparenToken; }; +enum class ForEachType { + In, + Of +}; + class QML_PARSER_EXPORT ForEachStatement: public Statement { public: QQMLJS_DECLARE_AST_NODE(ForEachStatement) - ForEachStatement(ExpressionNode *i, ExpressionNode *e, Statement *stmt): - initialiser (i), expression (e), statement (stmt) - { kind = K; } + ForEachStatement(ExpressionNode *i, ExpressionNode *e, Statement *stmt) + : lhs(i), expression(e), statement(stmt) + { kind = K; } + ForEachStatement(PatternElement *v, ExpressionNode *e, Statement *stmt) + : lhs(v), expression(e), statement(stmt) + { kind = K; } void accept0(Visitor *visitor) override; @@ -1588,42 +1711,19 @@ public: SourceLocation lastSourceLocation() const override { return statement->lastSourceLocation(); } -// attributes - ExpressionNode *initialiser; - ExpressionNode *expression; - Statement *statement; - SourceLocation forToken; - SourceLocation lparenToken; - SourceLocation inToken; - SourceLocation rparenToken; -}; - -class QML_PARSER_EXPORT LocalForEachStatement: public Statement -{ -public: - QQMLJS_DECLARE_AST_NODE(LocalForEachStatement) - - LocalForEachStatement(VariableDeclaration *v, ExpressionNode *e, Statement *stmt): - declaration (v), expression (e), statement (stmt) - { kind = K; } - - void accept0(Visitor *visitor) override; - - SourceLocation firstSourceLocation() const override - { return forToken; } - - SourceLocation lastSourceLocation() const override - { return statement->lastSourceLocation(); } + PatternElement *declaration() const { + return AST::cast<PatternElement *>(lhs); + } // attributes - VariableDeclaration *declaration; + Node *lhs; ExpressionNode *expression; Statement *statement; SourceLocation forToken; SourceLocation lparenToken; - SourceLocation varToken; - SourceLocation inToken; + SourceLocation inOfToken; SourceLocation rparenToken; + ForEachType type; }; class QML_PARSER_EXPORT ContinueStatement: public Statement @@ -1694,6 +1794,28 @@ public: SourceLocation semicolonToken; }; +class QML_PARSER_EXPORT YieldExpression: public ExpressionNode +{ +public: + QQMLJS_DECLARE_AST_NODE(YieldExpression) + + YieldExpression(ExpressionNode *e = nullptr): + expression (e) { kind = K; } + + void accept0(Visitor *visitor) override; + + SourceLocation firstSourceLocation() const override + { return yieldToken; } + + SourceLocation lastSourceLocation() const override + { return expression ? expression->lastSourceLocation() : yieldToken; } + +// attributes + ExpressionNode *expression; + bool isYieldStar = false; + SourceLocation yieldToken; +}; + class QML_PARSER_EXPORT WithStatement: public Statement { public: @@ -1724,7 +1846,7 @@ class QML_PARSER_EXPORT CaseBlock: public Node public: QQMLJS_DECLARE_AST_NODE(CaseBlock) - CaseBlock(CaseClauses *c, DefaultClause *d = 0, CaseClauses *r = 0): + CaseBlock(CaseClauses *c, DefaultClause *d = nullptr, CaseClauses *r = nullptr): clauses (c), defaultClause (d), moreClauses (r) { kind = K; } @@ -1821,7 +1943,7 @@ public: inline CaseClauses *finish () { CaseClauses *front = next; - next = 0; + next = nullptr; return front; } @@ -1904,9 +2026,9 @@ class QML_PARSER_EXPORT Catch: public Node public: QQMLJS_DECLARE_AST_NODE(Catch) - Catch(const QStringRef &n, Block *stmt): - name (n), statement (stmt) - { kind = K; } + Catch(PatternElement *p, Block *stmt) + : patternElement(p), statement(stmt) + { kind = K; } void accept0(Visitor *visitor) override; @@ -1917,7 +2039,7 @@ public: { return statement->lastSourceLocation(); } // attributes - QStringRef name; + PatternElement *patternElement; Block *statement; SourceLocation catchToken; SourceLocation lparenToken; @@ -1957,11 +2079,11 @@ public: { kind = K; } TryStatement(Statement *stmt, Finally *f): - statement (stmt), catchExpression (0), finallyExpression (f) + statement (stmt), catchExpression (nullptr), finallyExpression (f) { kind = K; } TryStatement(Statement *stmt, Catch *c): - statement (stmt), catchExpression (c), finallyExpression (0) + statement (stmt), catchExpression (c), finallyExpression (nullptr) { kind = K; } void accept0(Visitor *visitor) override; @@ -1991,7 +2113,7 @@ class QML_PARSER_EXPORT FunctionExpression: public ExpressionNode public: QQMLJS_DECLARE_AST_NODE(FunctionExpression) - FunctionExpression(const QStringRef &n, FormalParameterList *f, FunctionBody *b): + FunctionExpression(const QStringRef &n, FormalParameterList *f, StatementList *b): name (n), formals (f), body (b) { kind = K; } @@ -2003,10 +2125,14 @@ public: SourceLocation lastSourceLocation() const override { return rbraceToken; } + FunctionExpression *asFunctionDefinition() override; + // attributes QStringRef name; + bool isArrowFunction = false; + bool isGenerator = false; FormalParameterList *formals; - FunctionBody *body; + StatementList *body; SourceLocation functionToken; SourceLocation identifierToken; SourceLocation lparenToken; @@ -2020,7 +2146,7 @@ class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression public: QQMLJS_DECLARE_AST_NODE(FunctionDeclaration) - FunctionDeclaration(const QStringRef &n, FormalParameterList *f, FunctionBody *b): + FunctionDeclaration(const QStringRef &n, FormalParameterList *f, StatementList *b): FunctionExpression(n, f, b) { kind = K; } @@ -2032,168 +2158,593 @@ class QML_PARSER_EXPORT FormalParameterList: public Node public: QQMLJS_DECLARE_AST_NODE(FormalParameterList) - FormalParameterList(const QStringRef &n): - name (n), next (this) + FormalParameterList(FormalParameterList *previous, PatternElement *e) + : element(e) + { + kind = K; + if (previous) { + next = previous->next; + previous->next = this; + } else { + next = this; + } + } + + FormalParameterList *append(FormalParameterList *n) { + n->next = next; + next = n; + return n; + } + + bool isSimpleParameterList() + { + AST::FormalParameterList *formals = this; + while (formals) { + PatternElement *e = formals->element; + if (e && e->type == PatternElement::RestElement) + return false; + if (e && (e->initializer || e->bindingTarget)) + return false; + formals = formals->next; + } + return true; + } + + int length() + { + // the length property of Function objects + int l = 0; + AST::FormalParameterList *formals = this; + while (formals) { + PatternElement *e = formals->element; + if (!e || e->initializer) + break; + if (e->type == PatternElement::RestElement) + break; + ++l; + formals = formals->next; + } + return l; + } + + bool containsName(const QString &name) const { + for (const FormalParameterList *it = this; it; it = it->next) { + PatternElement *b = it->element; + // ### handle binding patterns + if (b && b->bindingIdentifier == name) + return true; + } + return false; + } + + QStringList formals() const; + + QStringList boundNames() const; + + void accept0(Visitor *visitor) override; + + SourceLocation firstSourceLocation() const override + { return element->firstSourceLocation(); } + + SourceLocation lastSourceLocation() const override + { return next ? next->lastSourceLocation() : element->lastSourceLocation(); } + + FormalParameterList *finish(MemoryPool *pool); + +// attributes + PatternElement *element = nullptr; + 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; } - FormalParameterList(FormalParameterList *previous, const QStringRef &n): - name (n) + void accept0(Visitor *visitor) override; + + SourceLocation firstSourceLocation() const override + { return classToken; } + + SourceLocation lastSourceLocation() const override + { return rbraceToken; } + + ClassExpression *asClassDefinition() override; + +// attributes + QStringRef name; + ExpressionNode *heritage; + ClassElementList *elements; + SourceLocation classToken; + SourceLocation identifierToken; + SourceLocation lbraceToken; + SourceLocation rbraceToken; +}; + +class QML_PARSER_EXPORT ClassDeclaration: public ClassExpression +{ +public: + QQMLJS_DECLARE_AST_NODE(ClassDeclaration) + + ClassDeclaration(const QStringRef &n, ExpressionNode *heritage, ClassElementList *elements) + : ClassExpression(n, heritage, elements) + { kind = K; } + + void accept0(Visitor *visitor) override; +}; + + +class QML_PARSER_EXPORT ClassElementList : public Node +{ +public: + QQMLJS_DECLARE_AST_NODE(ClassElementList) + + ClassElementList(PatternProperty *property, bool isStatic) + : isStatic(isStatic), property(property) { kind = K; - next = previous->next; - previous->next = this; + next = this; + } + + ClassElementList *append(ClassElementList *n) { + n->next = next; + next = n; + return n; } void accept0(Visitor *visitor) override; SourceLocation firstSourceLocation() const override - { return identifierToken; } + { return property->firstSourceLocation(); } SourceLocation lastSourceLocation() const override - { return next ? next->lastSourceLocation() : identifierToken; } + { + if (next) + return next->lastSourceLocation(); + return property->lastSourceLocation(); + } + + ClassElementList *finish(); + + bool isStatic; + ClassElementList *next; + PatternProperty *property; +}; + +class QML_PARSER_EXPORT Program: public Node +{ +public: + QQMLJS_DECLARE_AST_NODE(Program) - inline FormalParameterList *finish () + Program(StatementList *statements) + : statements(statements) + { kind = K; } + + void accept0(Visitor *visitor) override; + + SourceLocation firstSourceLocation() const override + { return statements ? statements->firstSourceLocation() : SourceLocation(); } + + SourceLocation lastSourceLocation() const override + { return statements ? statements->lastSourceLocation() : SourceLocation(); } + +// attributes + StatementList *statements; +}; + +class QML_PARSER_EXPORT ImportSpecifier: public Node +{ +public: + QQMLJS_DECLARE_AST_NODE(ImportSpecifier) + + ImportSpecifier(const QStringRef &importedBinding) + : importedBinding(importedBinding) { - FormalParameterList *front = next; - next = 0; - return front; + 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 - QStringRef name; - FormalParameterList *next; - SourceLocation commaToken; SourceLocation identifierToken; + SourceLocation importedBindingToken; + QStringRef identifier; + QStringRef importedBinding; }; -class QML_PARSER_EXPORT SourceElement: public Node +class QML_PARSER_EXPORT ImportsList: public Node { public: - QQMLJS_DECLARE_AST_NODE(SourceElement) + QQMLJS_DECLARE_AST_NODE(ImportsList) - inline SourceElement() - { kind = K; } + 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 = next; + 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 SourceElements: public Node +class QML_PARSER_EXPORT NamedImports: public Node { public: - QQMLJS_DECLARE_AST_NODE(SourceElements) + QQMLJS_DECLARE_AST_NODE(NamedImports) - SourceElements(SourceElement *elt): - element (elt), next (this) - { kind = K; } + NamedImports() + { + kind = K; + } - SourceElements(SourceElements *previous, SourceElement *elt): - element (elt) + NamedImports(ImportsList *importsList) + : importsList(importsList) { kind = K; - next = previous->next; - previous->next = this; } void accept0(Visitor *visitor) override; SourceLocation firstSourceLocation() const override - { return element->firstSourceLocation(); } - + { return leftBraceToken; } SourceLocation lastSourceLocation() const override - { return next ? next->lastSourceLocation() : element->lastSourceLocation(); } + { return rightBraceToken; } - inline SourceElements *finish () +// 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) { - SourceElements *front = next; - next = 0; - return front; + kind = K; } + void accept0(Visitor *visitor) override; + + virtual SourceLocation firstSourceLocation() const override + { return starToken; } + virtual SourceLocation lastSourceLocation() const override + { return importedBindingToken; } + // attributes - SourceElement *element; - SourceElements *next; + SourceLocation starToken; + SourceLocation importedBindingToken; + QStringRef importedBinding; }; -class QML_PARSER_EXPORT FunctionBody: public Node +class QML_PARSER_EXPORT ImportClause: public Node { public: - QQMLJS_DECLARE_AST_NODE(FunctionBody) + QQMLJS_DECLARE_AST_NODE(ImportClause) - FunctionBody(SourceElements *elts): - elements (elts) - { kind = K; } + 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 elements ? elements->firstSourceLocation() : SourceLocation(); } + { return fromToken; } SourceLocation lastSourceLocation() const override - { return elements ? elements->lastSourceLocation() : SourceLocation(); } + { return moduleSpecifierToken; } // attributes - SourceElements *elements; + SourceLocation fromToken; + SourceLocation moduleSpecifierToken; + QStringRef moduleSpecifier; }; -class QML_PARSER_EXPORT Program: public Node +class QML_PARSER_EXPORT ImportDeclaration: public Statement { public: - QQMLJS_DECLARE_AST_NODE(Program) + QQMLJS_DECLARE_AST_NODE(ImportDeclaration) - Program(SourceElements *elts): - elements (elts) - { kind = K; } + 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 elements ? elements->firstSourceLocation() : SourceLocation(); } + { return importToken; } SourceLocation lastSourceLocation() const override - { return elements ? elements->lastSourceLocation() : SourceLocation(); } + { return moduleSpecifier.isNull() ? fromClause->lastSourceLocation() : moduleSpecifierToken; } // attributes - SourceElements *elements; + SourceLocation importToken; + SourceLocation moduleSpecifierToken; + QStringRef moduleSpecifier; + ImportClause *importClause = nullptr; + FromClause *fromClause = nullptr; }; -class QML_PARSER_EXPORT FunctionSourceElement: public SourceElement +class QML_PARSER_EXPORT ExportSpecifier: public Node { public: - QQMLJS_DECLARE_AST_NODE(FunctionSourceElement) + QQMLJS_DECLARE_AST_NODE(ExportSpecifier) - FunctionSourceElement(FunctionDeclaration *f): - declaration (f) - { kind = K; } + 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 declaration->firstSourceLocation(); } + { 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 declaration->lastSourceLocation(); } + { return next ? next->lastSourceLocation() : exportSpecifier->lastSourceLocation(); } // attributes - FunctionDeclaration *declaration; + ExportSpecifier *exportSpecifier; + ExportsList *next; }; -class QML_PARSER_EXPORT StatementSourceElement: public SourceElement +class QML_PARSER_EXPORT ExportClause: public Node { public: - QQMLJS_DECLARE_AST_NODE(StatementSourceElement) + QQMLJS_DECLARE_AST_NODE(ExportClause) - StatementSourceElement(Statement *stmt): - statement (stmt) - { kind = K; } + ExportClause() + { + kind = K; + } + + ExportClause(ExportsList *exportsList) + : exportsList(exportsList) + { + kind = K; + } void accept0(Visitor *visitor) override; SourceLocation firstSourceLocation() const override - { return statement->firstSourceLocation(); } + { return leftBraceToken; } + SourceLocation lastSourceLocation() const override + { return rightBraceToken; } + +// attributes + SourceLocation leftBraceToken; + SourceLocation rightBraceToken; + ExportsList *exportsList = nullptr; +}; + +class QML_PARSER_EXPORT ExportDeclaration: public Statement +{ +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 statement->lastSourceLocation(); } + { return fromClause ? fromClause->lastSourceLocation() : (exportClause ? exportClause->lastSourceLocation() : variableStatementOrDeclaration->lastSourceLocation()); } // attributes - Statement *statement; + SourceLocation exportToken; + bool exportAll = false; + ExportClause *exportClause = nullptr; + FromClause *fromClause = nullptr; + Node *variableStatementOrDeclaration = nullptr; + bool exportDefault = false; +}; + +class QML_PARSER_EXPORT ESModule: public Node +{ +public: + QQMLJS_DECLARE_AST_NODE(Module) + + ESModule(StatementList *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 + StatementList *body; }; class QML_PARSER_EXPORT DebuggerStatement: public Statement @@ -2237,7 +2788,7 @@ public: UiQualifiedId *finish() { UiQualifiedId *head = next; - next = 0; + next = nullptr; return head; } @@ -2261,7 +2812,7 @@ public: QQMLJS_DECLARE_AST_NODE(UiImport) UiImport(const QStringRef &fileName) - : fileName(fileName), importUri(0) + : fileName(fileName), importUri(nullptr) { kind = K; } UiImport(UiQualifiedId *uri) @@ -2325,7 +2876,7 @@ public: UiObjectMemberList *finish() { UiObjectMemberList *head = next; - next = 0; + next = nullptr; return head; } @@ -2334,51 +2885,13 @@ public: UiObjectMember *member; }; -class QML_PARSER_EXPORT UiQualifiedPragmaId: public Node -{ -public: - QQMLJS_DECLARE_AST_NODE(UiQualifiedPragmaId) - - UiQualifiedPragmaId(const QStringRef &name) - : next(this), name(name) - { kind = K; } - - UiQualifiedPragmaId(UiQualifiedPragmaId *previous, const QStringRef &name) - : name(name) - { - kind = K; - next = previous->next; - previous->next = this; - } - - UiQualifiedPragmaId *finish() - { - UiQualifiedPragmaId *head = next; - next = 0; - return head; - } - - void accept0(Visitor *visitor) override; - - SourceLocation firstSourceLocation() const override - { return identifierToken; } - - SourceLocation lastSourceLocation() const override - { return next ? next->lastSourceLocation() : identifierToken; } - -// attributes - UiQualifiedPragmaId *next; - QStringRef name; - SourceLocation identifierToken; -}; - class QML_PARSER_EXPORT UiPragma: public Node { public: QQMLJS_DECLARE_AST_NODE(UiPragma) - UiPragma(UiQualifiedPragmaId *type) - : pragmaType(type) + UiPragma(QStringRef name) + : name(name) { kind = K; } void accept0(Visitor *visitor) override; @@ -2390,7 +2903,7 @@ public: { return semicolonToken; } // attributes - UiQualifiedPragmaId *pragmaType; + QStringRef name; SourceLocation pragmaToken; SourceLocation semicolonToken; }; @@ -2427,7 +2940,7 @@ public: UiHeaderItemList *finish() { UiHeaderItemList *head = next; - next = 0; + next = nullptr; return head; } @@ -2506,7 +3019,7 @@ public: UiArrayMemberList *finish() { UiArrayMemberList *head = next; - next = 0; + next = nullptr; return head; } @@ -2567,7 +3080,7 @@ public: inline UiParameterList *finish () { UiParameterList *front = next; - next = 0; + next = nullptr; return front; } @@ -2587,13 +3100,13 @@ public: UiPublicMember(UiQualifiedId *memberType, const QStringRef &name) - : type(Property), memberType(memberType), name(name), statement(0), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0) + : type(Property), memberType(memberType), name(name), statement(nullptr), binding(nullptr), isDefaultMember(false), isReadonlyMember(false), parameters(nullptr) { kind = K; } UiPublicMember(UiQualifiedId *memberType, const QStringRef &name, Statement *statement) - : type(Property), memberType(memberType), name(name), statement(statement), binding(0), isDefaultMember(false), isReadonlyMember(false), parameters(0) + : type(Property), memberType(memberType), name(name), statement(statement), binding(nullptr), isDefaultMember(false), isReadonlyMember(false), parameters(nullptr) { kind = K; } void accept0(Visitor *visitor) override; @@ -2785,6 +3298,81 @@ public: SourceLocation rbracketToken; }; +class QML_PARSER_EXPORT UiEnumMemberList: public Node +{ + QQMLJS_DECLARE_AST_NODE(UiEnumMemberList) +public: + UiEnumMemberList(const QStringRef &member, double v = 0.0) + : next(this), member(member), value(v) + { kind = K; } + + UiEnumMemberList(UiEnumMemberList *previous, const QStringRef &member) + : member(member) + { + kind = K; + next = previous->next; + previous->next = this; + value = previous->value + 1; + } + + UiEnumMemberList(UiEnumMemberList *previous, const QStringRef &member, double v) + : member(member), value(v) + { + kind = K; + next = previous->next; + previous->next = this; + } + + SourceLocation firstSourceLocation() const override + { return memberToken; } + + SourceLocation lastSourceLocation() const override + { return next ? next->lastSourceLocation() : + valueToken.isValid() ? valueToken : memberToken; } + + void accept0(Visitor *visitor) override; + + UiEnumMemberList *finish() + { + UiEnumMemberList *head = next; + next = nullptr; + return head; + } + +// attributes + UiEnumMemberList *next; + QStringRef member; + double value; + SourceLocation memberToken; + SourceLocation valueToken; +}; + +class QML_PARSER_EXPORT UiEnumDeclaration: public UiObjectMember +{ +public: + QQMLJS_DECLARE_AST_NODE(UiEnumDeclaration) + + UiEnumDeclaration(const QStringRef &name, + UiEnumMemberList *members) + : name(name) + , members(members) + { kind = K; } + + SourceLocation firstSourceLocation() const override + { return enumToken; } + + SourceLocation lastSourceLocation() const override + { return rbraceToken; } + + void accept0(Visitor *visitor) override; + +// attributes + SourceLocation enumToken; + SourceLocation rbraceToken; + QStringRef name; + UiEnumMemberList *members; +}; + } } // namespace AST diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h index 189eb72a57..7795e0ce71 100644 --- a/src/qml/parser/qqmljsastfwd_p.h +++ b/src/qml/parser/qqmljsastfwd_p.h @@ -41,6 +41,7 @@ #define QQMLJSAST_FWD_P_H #include "qqmljsglobal_p.h" +#include "qqmljssourcelocation_p.h" #include <QtCore/qglobal.h> @@ -59,27 +60,6 @@ QT_QML_BEGIN_NAMESPACE namespace QQmlJS { namespace AST { -class SourceLocation -{ -public: - explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) - : offset(offset), length(length), - startLine(line), startColumn(column) - { } - - bool isValid() const { return length != 0; } - - quint32 begin() const { return offset; } - quint32 end() const { return offset + length; } - -// attributes - // ### encode - quint32 offset; - quint32 length; - quint32 startLine; - quint32 startColumn; -}; - class Visitor; class Node; class ExpressionNode; @@ -89,22 +69,27 @@ class IdentifierExpression; class NullExpression; class TrueLiteral; class FalseLiteral; +class SuperLiteral; class NumericLiteral; class StringLiteral; +class TemplateLiteral; class RegExpLiteral; -class ArrayLiteral; -class ObjectLiteral; -class ElementList; +class Pattern; +class ArrayPattern; +class ObjectPattern; +class PatternElement; +class PatternElementList; +class PatternProperty; +class PatternPropertyList; class Elision; -class PropertyAssignmentList; -class PropertyGetterSetter; -class PropertyNameAndValue; class PropertyName; class IdentifierPropertyName; class StringLiteralPropertyName; class NumericLiteralPropertyName; +class ComputedPropertyName; class ArrayMemberExpression; class FieldMemberExpression; +class TaggedTemplate; class NewMemberExpression; class NewExpression; class CallExpression; @@ -123,20 +108,19 @@ class NotExpression; class BinaryExpression; class ConditionalExpression; class Expression; // ### rename +class YieldExpression; class Block; +class LeftHandSideExpression; class StatementList; class VariableStatement; class VariableDeclarationList; -class VariableDeclaration; class EmptyStatement; class ExpressionStatement; class IfStatement; class DoWhileStatement; class WhileStatement; class ForStatement; -class LocalForStatement; class ForEachStatement; -class LocalForEachStatement; class ContinueStatement; class BreakStatement; class ReturnStatement; @@ -154,14 +138,26 @@ class Finally; class FunctionDeclaration; class FunctionExpression; class FormalParameterList; -class FunctionBody; +class ExportSpecifier; +class ExportsList; +class ExportClause; +class ExportDeclaration; class Program; -class SourceElements; -class SourceElement; -class FunctionSourceElement; -class StatementSourceElement; +class ImportSpecifier; +class ImportsList; +class NamedImports; +class NameSpaceImport; +class NamedImport; +class ImportClause; +class FromClause; +class ImportDeclaration; +class ModuleItem; +class ESModule; class DebuggerStatement; class NestedExpression; +class ClassExpression; +class ClassDeclaration; +class ClassElementList; // ui elements class UiProgram; @@ -179,8 +175,9 @@ class UiObjectMember; class UiObjectMemberList; class UiArrayMemberList; class UiQualifiedId; -class UiQualifiedPragmaId; class UiHeaderItemList; +class UiEnumDeclaration; +class UiEnumMemberList; } } // namespace AST diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h index e582a8f6a7..c925096de6 100644 --- a/src/qml/parser/qqmljsastvisitor_p.h +++ b/src/qml/parser/qqmljsastvisitor_p.h @@ -83,7 +83,8 @@ public: virtual bool visit(UiObjectMemberList *) { return true; } virtual bool visit(UiArrayMemberList *) { return true; } virtual bool visit(UiQualifiedId *) { return true; } - virtual bool visit(UiQualifiedPragmaId *) { return true; } + virtual bool visit(UiEnumDeclaration *) { return true; } + virtual bool visit(UiEnumMemberList *) { return true; } virtual void endVisit(UiProgram *) {} virtual void endVisit(UiImport *) {} @@ -100,7 +101,8 @@ public: virtual void endVisit(UiObjectMemberList *) {} virtual void endVisit(UiArrayMemberList *) {} virtual void endVisit(UiQualifiedId *) {} - virtual void endVisit(UiQualifiedPragmaId *) {} + virtual void endVisit(UiEnumDeclaration *) {} + virtual void endVisit(UiEnumMemberList *) { } // QQmlJS virtual bool visit(ThisExpression *) { return true; } @@ -118,35 +120,41 @@ public: virtual bool visit(FalseLiteral *) { return true; } virtual void endVisit(FalseLiteral *) {} + virtual bool visit(SuperLiteral *) { return true; } + virtual void endVisit(SuperLiteral *) {} + virtual bool visit(StringLiteral *) { return true; } virtual void endVisit(StringLiteral *) {} + virtual bool visit(TemplateLiteral *) { return true; } + virtual void endVisit(TemplateLiteral *) {} + virtual bool visit(NumericLiteral *) { return true; } virtual void endVisit(NumericLiteral *) {} virtual bool visit(RegExpLiteral *) { return true; } virtual void endVisit(RegExpLiteral *) {} - virtual bool visit(ArrayLiteral *) { return true; } - virtual void endVisit(ArrayLiteral *) {} + virtual bool visit(ArrayPattern *) { return true; } + virtual void endVisit(ArrayPattern *) {} - virtual bool visit(ObjectLiteral *) { return true; } - virtual void endVisit(ObjectLiteral *) {} + virtual bool visit(ObjectPattern *) { return true; } + virtual void endVisit(ObjectPattern *) {} - virtual bool visit(ElementList *) { return true; } - virtual void endVisit(ElementList *) {} + virtual bool visit(PatternElementList *) { return true; } + virtual void endVisit(PatternElementList *) {} - virtual bool visit(Elision *) { return true; } - virtual void endVisit(Elision *) {} + virtual bool visit(PatternPropertyList *) { return true; } + virtual void endVisit(PatternPropertyList *) {} - virtual bool visit(PropertyAssignmentList *) { return true; } - virtual void endVisit(PropertyAssignmentList *) {} + virtual bool visit(PatternElement *) { return true; } + virtual void endVisit(PatternElement *) {} - virtual bool visit(PropertyNameAndValue *) { return true; } - virtual void endVisit(PropertyNameAndValue *) {} + virtual bool visit(PatternProperty *) { return true; } + virtual void endVisit(PatternProperty *) {} - virtual bool visit(PropertyGetterSetter *) { return true; } - virtual void endVisit(PropertyGetterSetter *) {} + virtual bool visit(Elision *) { return true; } + virtual void endVisit(Elision *) {} virtual bool visit(NestedExpression *) { return true; } virtual void endVisit(NestedExpression *) {} @@ -160,12 +168,18 @@ public: virtual bool visit(NumericLiteralPropertyName *) { return true; } virtual void endVisit(NumericLiteralPropertyName *) {} + virtual bool visit(ComputedPropertyName *) { return true; } + virtual void endVisit(ComputedPropertyName *) {} + virtual bool visit(ArrayMemberExpression *) { return true; } virtual void endVisit(ArrayMemberExpression *) {} virtual bool visit(FieldMemberExpression *) { return true; } virtual void endVisit(FieldMemberExpression *) {} + virtual bool visit(TaggedTemplate *) { return true; } + virtual void endVisit(TaggedTemplate *) {} + virtual bool visit(NewMemberExpression *) { return true; } virtual void endVisit(NewMemberExpression *) {} @@ -232,9 +246,6 @@ public: virtual bool visit(VariableDeclarationList *) { return true; } virtual void endVisit(VariableDeclarationList *) {} - virtual bool visit(VariableDeclaration *) { return true; } - virtual void endVisit(VariableDeclaration *) {} - virtual bool visit(EmptyStatement *) { return true; } virtual void endVisit(EmptyStatement *) {} @@ -253,15 +264,9 @@ public: virtual bool visit(ForStatement *) { return true; } virtual void endVisit(ForStatement *) {} - virtual bool visit(LocalForStatement *) { return true; } - virtual void endVisit(LocalForStatement *) {} - virtual bool visit(ForEachStatement *) { return true; } virtual void endVisit(ForEachStatement *) {} - virtual bool visit(LocalForEachStatement *) { return true; } - virtual void endVisit(LocalForEachStatement *) {} - virtual bool visit(ContinueStatement *) { return true; } virtual void endVisit(ContinueStatement *) {} @@ -271,6 +276,9 @@ public: virtual bool visit(ReturnStatement *) { return true; } virtual void endVisit(ReturnStatement *) {} + virtual bool visit(YieldExpression *) { return true; } + virtual void endVisit(YieldExpression *) {} + virtual bool visit(WithStatement *) { return true; } virtual void endVisit(WithStatement *) {} @@ -313,20 +321,56 @@ public: virtual bool visit(FormalParameterList *) { return true; } virtual void endVisit(FormalParameterList *) {} - virtual bool visit(FunctionBody *) { return true; } - virtual void endVisit(FunctionBody *) {} + virtual bool visit(ClassExpression *) { return true; } + virtual void endVisit(ClassExpression *) {} + + virtual bool visit(ClassDeclaration *) { return true; } + virtual void endVisit(ClassDeclaration *) {} + + virtual bool visit(ClassElementList *) { return true; } + virtual void endVisit(ClassElementList *) {} virtual bool visit(Program *) { return true; } virtual void endVisit(Program *) {} - virtual bool visit(SourceElements *) { return true; } - virtual void endVisit(SourceElements *) {} + 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(FunctionSourceElement *) { return true; } - virtual void endVisit(FunctionSourceElement *) {} + virtual bool visit(ModuleItem *) { return true; } + virtual void endVisit(ModuleItem *) {} - virtual bool visit(StatementSourceElement *) { return true; } - virtual void endVisit(StatementSourceElement *) {} + virtual bool visit(ESModule *) { return true; } + virtual void endVisit(ESModule *) {} virtual bool visit(DebuggerStatement *) { return true; } virtual void endVisit(DebuggerStatement *) {} diff --git a/src/qml/parser/qqmljsengine_p.cpp b/src/qml/parser/qqmljsengine_p.cpp index 7a6d9c3826..97ce6ebea3 100644 --- a/src/qml/parser/qqmljsengine_p.cpp +++ b/src/qml/parser/qqmljsengine_p.cpp @@ -112,15 +112,8 @@ double integerFromString(const char *buf, int size, int radix) return result; } -double integerFromString(const QString &str, int radix) -{ - QByteArray ba = QStringRef(&str).trimmed().toLatin1(); - return integerFromString(ba.constData(), ba.size(), radix); -} - - Engine::Engine() - : _lexer(0), _directives(0) + : _lexer(nullptr), _directives(nullptr) { } Engine::~Engine() diff --git a/src/qml/parser/qqmljsengine_p.h b/src/qml/parser/qqmljsengine_p.h index 8cbe69a0ba..07b5026eb9 100644 --- a/src/qml/parser/qqmljsengine_p.h +++ b/src/qml/parser/qqmljsengine_p.h @@ -52,8 +52,8 @@ // #include "qqmljsglobal_p.h" -#include "qqmljsastfwd_p.h" #include "qqmljsmemorypool_p.h" +#include "qqmljssourcelocation_p.h" #include <QtCore/qstring.h> #include <QtCore/qset.h> @@ -63,16 +63,41 @@ QT_QML_BEGIN_NAMESPACE namespace QQmlJS { class Lexer; -class Directives; class MemoryPool; +class QML_PARSER_EXPORT Directives { +public: + virtual ~Directives() {} + + virtual void pragmaLibrary() + { + } + + virtual void importFile(const QString &jsfile, const QString &module, int line, int column) + { + Q_UNUSED(jsfile); + Q_UNUSED(module); + Q_UNUSED(line); + Q_UNUSED(column); + } + + virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column) + { + Q_UNUSED(uri); + Q_UNUSED(version); + Q_UNUSED(module); + Q_UNUSED(line); + Q_UNUSED(column); + } +}; + + class QML_PARSER_EXPORT DiagnosticMessage { public: - enum Kind { Warning, Error }; + enum Kind { Hint, Warning, Error }; - DiagnosticMessage() - : kind(Error) {} + DiagnosticMessage() {} DiagnosticMessage(Kind kind, const AST::SourceLocation &loc, const QString &message) : kind(kind), loc(loc), message(message) {} @@ -83,7 +108,7 @@ public: bool isError() const { return kind == Error; } - Kind kind; + Kind kind = Error; AST::SourceLocation loc; QString message; }; diff --git a/src/qml/parser/qqmljsgrammar.cpp b/src/qml/parser/qqmljsgrammar.cpp deleted file mode 100644 index ca5a4bbd85..0000000000 --- a/src/qml/parser/qqmljsgrammar.cpp +++ /dev/null @@ -1,1111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// This file was generated by qlalr - DO NOT EDIT! -#include "qqmljsgrammar_p.h" - -QT_BEGIN_NAMESPACE - -const char *const QQmlJSGrammar::spell [] = { - "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ",", "continue", - "default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===", - "finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier", - "if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=", - "-", "-=", "--", "new", "!", "!=", "!==", "numeric literal", "|", "|=", - "||", "+", "+=", "++", "?", "}", "]", "%", "%=", "return", - ")", ";", 0, "*", "*=", "string literal", "property", "signal", "readonly", "switch", - "this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^", - "^=", "null", "true", "false", "const", "let", "debugger", "reserved word", "multiline string literal", "comment", - 0, "public", "import", "pragma", "as", "on", "get", "set", 0, 0, - 0, 0, 0, 0, 0, 0, 0}; - -const short QQmlJSGrammar::lhs [] = { - 107, 107, 107, 107, 107, 107, 108, 114, 114, 117, - 117, 117, 117, 120, 122, 118, 118, 119, 119, 119, - 119, 119, 119, 119, 119, 123, 124, 116, 115, 127, - 127, 128, 128, 129, 129, 126, 112, 112, 112, 112, - 131, 131, 131, 131, 131, 131, 131, 112, 139, 139, - 139, 139, 140, 140, 141, 141, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 125, 125, 125, 125, - 125, 125, 125, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 130, 146, 146, 146, 146, 145, 145, 150, 150, - 150, 148, 148, 151, 151, 151, 151, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 155, - 155, 121, 121, 121, 121, 121, 158, 158, 159, 159, - 159, 159, 157, 157, 160, 160, 161, 161, 162, 162, - 162, 163, 163, 163, 163, 163, 163, 163, 163, 163, - 163, 164, 164, 164, 164, 165, 165, 165, 166, 166, - 166, 166, 167, 167, 167, 167, 167, 167, 167, 168, - 168, 168, 168, 168, 168, 169, 169, 169, 169, 169, - 170, 170, 170, 170, 170, 171, 171, 172, 172, 173, - 173, 174, 174, 175, 175, 176, 176, 177, 177, 178, - 178, 179, 179, 180, 180, 181, 181, 182, 182, 149, - 149, 183, 183, 184, 184, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 110, 110, 185, 185, 186, - 186, 187, 187, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 132, 196, - 196, 195, 195, 143, 143, 197, 197, 197, 198, 198, - 200, 200, 199, 201, 204, 202, 202, 205, 203, 203, - 133, 134, 134, 135, 135, 188, 188, 188, 188, 188, - 188, 188, 188, 189, 189, 189, 189, 190, 190, 190, - 190, 191, 191, 136, 137, 206, 206, 209, 209, 207, - 207, 210, 208, 192, 193, 193, 138, 138, 138, 211, - 212, 194, 194, 213, 142, 156, 156, 214, 214, 153, - 153, 152, 152, 215, 113, 113, 216, 216, 111, 111, - 147, 147, 217}; - -const short QQmlJSGrammar::rhs [] = { - 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, - 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, - 3, 5, 5, 4, 4, 2, 2, 0, 1, 1, - 2, 1, 3, 2, 3, 2, 1, 5, 4, 4, - 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, - 1, 3, 0, 1, 2, 4, 6, 6, 3, 3, - 7, 7, 4, 4, 5, 5, 8, 8, 5, 6, - 6, 10, 6, 7, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 3, 3, 4, 5, 3, 4, - 3, 1, 1, 2, 3, 4, 1, 2, 3, 7, - 8, 1, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 4, 3, 5, 1, 2, 4, 4, - 4, 3, 0, 1, 1, 3, 1, 1, 1, 2, - 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 1, 3, 3, 3, 1, 3, 3, 1, 3, - 3, 3, 1, 3, 3, 3, 3, 3, 3, 1, - 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, - 1, 3, 3, 3, 3, 1, 3, 1, 3, 1, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 3, 1, 3, 1, 5, 1, 5, 1, - 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 0, 1, 1, - 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, - 2, 0, 1, 3, 3, 1, 1, 1, 1, 3, - 1, 3, 2, 2, 2, 0, 1, 2, 0, 1, - 1, 2, 2, 7, 5, 7, 7, 7, 5, 9, - 10, 7, 8, 2, 2, 3, 3, 2, 2, 3, - 3, 3, 3, 5, 5, 3, 5, 1, 2, 0, - 1, 4, 3, 3, 3, 3, 3, 3, 4, 5, - 2, 2, 2, 1, 8, 8, 7, 1, 3, 0, - 1, 0, 1, 1, 1, 1, 1, 2, 1, 1, - 0, 1, 2}; - -const short QQmlJSGrammar::action_default [] = { - 0, 0, 28, 0, 0, 0, 28, 0, 189, 256, - 220, 228, 224, 168, 240, 216, 3, 153, 85, 169, - 232, 236, 157, 186, 167, 172, 152, 206, 193, 0, - 92, 93, 88, 0, 82, 77, 361, 0, 0, 0, - 0, 90, 0, 0, 86, 89, 81, 0, 0, 78, - 80, 83, 79, 91, 84, 0, 87, 0, 0, 182, - 0, 0, 169, 188, 171, 170, 0, 0, 0, 184, - 185, 183, 187, 0, 217, 0, 0, 0, 0, 207, - 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, - 191, 192, 190, 195, 199, 198, 196, 194, 209, 208, - 210, 0, 225, 0, 221, 0, 0, 163, 150, 162, - 151, 118, 119, 120, 145, 121, 147, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 146, 133, - 134, 148, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 149, 0, 0, 161, 257, 164, 0, 165, - 0, 166, 160, 0, 253, 246, 244, 251, 252, 250, - 249, 255, 248, 247, 245, 254, 241, 0, 229, 0, - 0, 233, 0, 0, 237, 0, 0, 163, 155, 0, - 154, 0, 159, 173, 0, 350, 350, 351, 0, 348, - 0, 349, 0, 352, 264, 271, 270, 278, 266, 0, - 267, 0, 353, 0, 360, 268, 269, 85, 274, 272, - 357, 354, 359, 275, 0, 287, 0, 0, 0, 0, - 344, 0, 361, 286, 258, 301, 0, 0, 0, 288, - 0, 0, 276, 277, 0, 265, 273, 302, 303, 0, - 350, 0, 0, 352, 0, 345, 346, 0, 334, 358, - 0, 318, 319, 320, 321, 0, 314, 315, 316, 317, - 342, 343, 0, 0, 0, 0, 0, 306, 307, 308, - 262, 260, 222, 230, 226, 242, 218, 263, 0, 169, - 234, 238, 211, 200, 0, 0, 219, 0, 0, 0, - 0, 212, 0, 0, 0, 0, 0, 204, 202, 205, - 203, 201, 214, 213, 215, 0, 227, 0, 223, 0, - 261, 169, 0, 243, 258, 259, 0, 258, 0, 0, - 310, 0, 0, 0, 312, 0, 231, 0, 0, 235, - 0, 0, 239, 299, 0, 291, 300, 294, 0, 298, - 0, 258, 292, 0, 258, 0, 0, 311, 0, 0, - 0, 313, 0, 0, 0, 305, 0, 304, 85, 112, - 362, 0, 0, 117, 280, 283, 0, 118, 287, 121, - 147, 123, 124, 88, 128, 129, 82, 130, 286, 133, - 86, 89, 258, 83, 91, 136, 84, 138, 87, 140, - 141, 288, 143, 144, 149, 0, 114, 113, 116, 100, - 115, 99, 0, 109, 281, 279, 0, 0, 0, 352, - 0, 110, 157, 158, 163, 0, 156, 0, 322, 323, - 0, 350, 0, 0, 352, 0, 111, 0, 0, 0, - 325, 330, 328, 331, 0, 0, 329, 330, 0, 326, - 0, 327, 282, 333, 0, 282, 332, 0, 335, 336, - 0, 282, 337, 338, 0, 0, 339, 0, 0, 0, - 340, 341, 175, 174, 0, 0, 0, 309, 0, 0, - 0, 324, 296, 289, 0, 297, 293, 0, 295, 284, - 0, 285, 290, 0, 0, 352, 0, 347, 103, 0, - 0, 107, 94, 0, 96, 105, 0, 97, 106, 108, - 98, 104, 95, 0, 101, 179, 177, 181, 178, 176, - 180, 355, 6, 356, 4, 2, 75, 102, 0, 0, - 78, 80, 79, 37, 5, 0, 76, 0, 51, 50, - 49, 0, 0, 51, 0, 0, 0, 52, 0, 67, - 68, 0, 65, 0, 66, 41, 42, 43, 44, 46, - 47, 71, 45, 0, 51, 0, 0, 0, 0, 0, - 61, 0, 62, 0, 0, 32, 0, 0, 72, 33, - 0, 36, 34, 30, 0, 35, 31, 0, 63, 0, - 64, 157, 0, 69, 73, 0, 0, 0, 0, 157, - 282, 0, 70, 85, 118, 287, 121, 147, 123, 124, - 88, 128, 129, 130, 286, 133, 86, 89, 258, 91, - 136, 84, 138, 87, 140, 141, 288, 143, 144, 149, - 74, 0, 59, 53, 60, 54, 0, 0, 0, 0, - 56, 0, 57, 58, 55, 0, 0, 0, 0, 48, - 0, 38, 39, 0, 40, 8, 0, 0, 9, 0, - 11, 0, 10, 0, 1, 27, 15, 14, 26, 13, - 12, 29, 7, 0, 18, 0, 19, 0, 24, 25, - 0, 20, 21, 0, 22, 23, 16, 17, 363}; - -const short QQmlJSGrammar::goto_default [] = { - 7, 654, 212, 199, 210, 524, 512, 649, 662, 511, - 648, 652, 650, 658, 22, 655, 653, 651, 18, 523, - 574, 564, 571, 566, 551, 194, 198, 200, 205, 236, - 213, 233, 555, 626, 625, 204, 235, 26, 490, 489, - 361, 360, 9, 359, 362, 203, 483, 363, 109, 17, - 148, 24, 13, 147, 19, 25, 59, 23, 8, 28, - 27, 282, 15, 276, 10, 272, 12, 274, 11, 273, - 20, 280, 21, 281, 14, 275, 271, 312, 417, 277, - 278, 206, 196, 195, 209, 208, 232, 197, 366, 365, - 234, 474, 473, 334, 335, 476, 337, 475, 336, 430, - 434, 437, 433, 432, 452, 453, 201, 187, 202, 211, - 0}; - -const short QQmlJSGrammar::action_index [] = { - 308, 1392, 2787, 2787, 2890, 1102, 71, 6, 103, -107, - 10, -35, -64, 287, -107, 310, 11, -107, -107, 815, - 30, 112, 183, 214, -107, -107, -107, 463, 203, 1392, - -107, -107, -107, 536, -107, -107, 2478, 1786, 1392, 1392, - 1392, -107, 1005, 1392, -107, -107, -107, 1392, 1392, -107, - -107, -107, -107, -107, -107, 1392, -107, 1392, 1392, -107, - 1392, 1392, 75, 204, -107, -107, 1392, 1392, 1392, -107, - -107, -107, 221, 1392, 306, 1392, 1392, 1392, 1392, 463, - 1392, 1392, 1392, 1392, 1392, 1392, 200, 1392, 1392, 1392, - 149, 145, 108, 231, 241, 295, 379, 379, 463, 463, - 463, 1392, -70, 1392, 4, 2375, 1392, 1392, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, 105, 1392, -107, -107, -5, -58, -107, - 1392, -107, -107, 1392, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, 1392, -44, 1392, - 1392, 5, 7, 1392, -107, 2375, 1392, 1392, -107, 134, - -107, -43, -107, -107, -16, 541, 541, 15, -36, -107, - 462, -107, -4, 2787, -107, -107, -107, -107, -107, 213, - -107, 449, -107, -20, -107, -107, -107, 31, -107, -107, - -107, 2787, -107, -107, 616, -107, 711, 144, 2890, 21, - 42, 43, 3096, -107, 1392, -107, 62, 1392, 101, -107, - 102, 99, -107, -107, 417, -107, -107, -107, -107, 93, - 441, 56, 92, 2787, 34, -107, -107, 2890, -107, -107, - 118, -107, -107, -107, -107, 125, -107, -107, -107, -107, - -107, -107, -14, 33, 1392, 137, 193, -107, -107, -107, - 1488, -107, 44, -1, -42, -107, 316, -8, -60, 718, - 97, 87, 368, 222, 359, 1392, 313, 1392, 1392, 1392, - 1392, 342, 1392, 1392, 1392, 1392, 1392, 271, 270, 263, - 262, 225, 346, 352, 362, 1392, -51, 1392, 29, 1392, - -107, 815, 1392, -107, 1392, 28, -22, 1392, -19, 2890, - -107, 1392, 160, 2890, -107, 1392, 0, 1392, 1392, 97, - 45, 1392, -107, 37, 142, 25, -107, -107, 1392, -107, - 541, 1392, -107, 9, 1392, 12, 2890, -107, 1392, 128, - 2890, -107, 1392, 124, 2890, 61, 2890, -107, 60, -107, - 67, 26, 73, -107, -107, 2890, 49, 544, 80, 556, - 114, 1392, 2890, 85, 58, 482, 2581, 64, 88, 1005, - 90, 94, 1588, 2581, 96, 70, 197, 1392, 100, 76, - 1392, 104, 1392, 82, 84, 2684, -107, -107, -107, -107, - -107, -107, 1392, -107, -107, -107, 95, 63, 91, 2787, - 53, -107, 217, -107, 1392, 50, -107, 120, -107, -107, - 40, 372, 8, 27, 2787, 3, -107, 1392, 141, 20, - -107, 46, -107, 41, 147, 1392, -107, 39, 36, -107, - -15, -107, 2890, -107, 297, 2890, -107, 175, -107, -107, - 187, 2890, 14, -107, -3, -2, -107, 459, -34, -6, - -107, -107, -107, -107, 1392, 139, 2890, -107, 1392, 132, - 2890, -107, 1, -107, 251, -107, -107, 1392, -107, -107, - 541, -107, -107, -48, -23, 2787, -47, -107, -107, 113, - 1984, -107, -107, 1885, -107, -107, 1687, -107, -107, -107, - -107, -107, -107, 107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, 2787, -107, -107, -107, 131, -50, 910, - 243, -45, -7, -107, -107, 232, -107, 206, -12, -107, - -107, 633, 189, -107, 198, 13, 385, -107, 153, -107, - -107, 184, -107, 2080, -107, -107, -107, -107, -107, -107, - -107, -107, -107, 208, 18, 633, 219, 129, 353, 292, - -107, 48, -107, 910, 122, -107, 81, 910, -107, -107, - 1296, -107, -107, -107, 1199, -107, -107, 224, -107, 2080, - -107, 311, 81, -107, -107, 205, 633, 98, 2176, 304, - 2993, 69, -107, 89, 613, 86, 597, 109, 1392, 2890, - 83, 55, 467, 52, 79, 804, 78, 77, 1588, 66, - 47, 59, 1392, 57, 32, 1392, 54, 1392, 38, 35, - -107, 255, -107, 228, -107, 51, 2, 524, 195, 532, - -107, 133, -107, -107, -107, 2272, 910, 1786, 17, -107, - 152, -107, -107, 16, -107, -107, 910, 910, 119, 910, - -107, 302, -107, 148, -107, -107, 143, 140, -107, -107, - -107, -107, -107, 369, -107, 249, -107, 111, -107, -107, - 364, -107, -107, 65, -107, -107, -107, -107, -107, - - -111, 55, 62, 77, 71, 279, -7, -111, -111, -111, - -111, -111, -111, -111, -111, -111, -111, -111, -111, -74, - -111, -111, -111, -111, -111, -111, -111, -111, -111, 70, - -111, -111, -111, -8, -111, -111, -6, -28, 12, 84, - 85, -111, 93, 100, -111, -111, -111, 101, 104, -111, - -111, -111, -111, -111, -111, 107, -111, 112, 118, -111, - 182, 184, -111, -111, -111, -111, 218, 215, 209, -111, - -111, -111, -111, 202, -111, 195, 193, 192, 191, -111, - 189, 183, 181, 175, 168, 155, -111, 170, 153, 150, - -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, - -111, 151, -111, 142, -111, 172, 30, -4, -111, -111, - -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, - -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, - -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, - -111, -111, -111, -111, -2, -111, -111, -111, -111, -111, - 0, -111, -111, 9, -111, -111, -111, -111, -111, -111, - -111, -111, -111, -111, -111, -111, -111, 125, -111, 122, - 10, -111, -111, 22, -111, 236, 46, 127, -111, -111, - -111, -111, -111, -111, -111, 37, 124, -111, -111, -111, - 39, -111, -111, 42, -111, -111, -111, -111, -111, -111, - -111, 44, -111, -111, -111, -111, -111, -111, -111, -111, - -111, 94, -111, -111, 47, -111, 48, -111, 128, -111, - 50, -111, 91, -111, -3, -111, -111, 66, 53, -111, - -111, -111, -111, -111, 57, -111, -111, -111, -111, -111, - 79, -111, -111, 78, -111, -111, -111, 82, -111, -111, - -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, - -111, -111, -111, -111, 67, -111, -111, -111, -111, -111, - 61, -111, -111, -111, -111, -111, -111, -111, -111, -111, - -111, -111, -111, -111, 59, 258, -111, 259, 268, 269, - 272, -111, 60, 63, 73, 74, 75, -111, -111, -111, - -111, -111, -111, -111, -111, 252, -111, 242, -111, 233, - -111, -111, 232, -111, 87, -111, -111, 89, -111, 133, - -111, 51, -111, 135, -111, 231, -111, 223, 222, -111, - -111, 221, -111, -111, -111, -111, -111, -111, 219, -111, - 92, 102, -111, -111, 110, -111, 171, -111, 40, -111, - 173, -111, 38, -111, 176, -111, 179, -111, -111, -111, - -111, -111, -111, -111, -111, 180, -111, 19, -111, 18, - -111, 145, 185, -111, -111, 17, 166, -111, -111, 65, - -111, -111, 29, 177, -111, -111, -111, 25, -111, 5, - 159, -111, 164, -111, -111, 207, -111, -111, -111, -111, - -111, -111, -18, -111, -111, -111, -111, -111, -111, 212, - -111, -111, -111, -111, 216, -111, -111, -111, -111, -111, - -111, 213, -111, -111, 86, -111, -111, 16, -111, -111, - -111, -111, -111, -85, -111, 14, -111, -84, -111, -111, - -111, -111, 286, -111, -111, 287, -111, -111, -111, -111, - -111, 214, -94, -111, -111, -16, -111, -10, -111, -19, - -111, -111, -111, -111, 2, -111, 83, -111, 105, -111, - 81, -111, -111, -111, -111, -111, -111, -41, -111, -111, - 131, -111, -111, -111, -111, 76, -111, -111, -111, -111, - -35, -111, -111, 64, -111, -111, -29, -111, -111, -111, - -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, - -111, -111, -111, 208, -111, -111, -111, -111, -111, 20, - -111, -111, -111, -111, -111, -111, -111, 13, -111, -111, - -111, 26, 15, -111, -111, -111, 32, -111, -111, -111, - -111, -111, -111, 329, -111, -111, -111, -111, -111, -111, - -111, -111, -111, -111, -111, 54, 56, -111, 58, -111, - -111, -111, -111, 68, -111, -111, -111, 72, -111, -111, - 330, -111, -111, -111, 327, -111, -111, -111, -111, 389, - -111, -111, 52, -111, -111, 31, 49, -111, 371, -111, - 134, 34, -111, -111, 43, -111, 41, -111, 108, 141, - -111, -111, 35, -111, -111, 97, -111, -111, 45, -111, - -111, -111, 36, -111, 21, 129, -111, 146, -111, -111, - -111, -111, -111, -1, -111, -111, -111, 11, -5, 7, - -111, -111, -111, -111, -111, 353, 311, 408, 4, -111, - -111, -111, -111, 1, -111, -111, 8, 6, 249, 248, - -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, - -111, -111, -111, 3, -111, -111, -111, -111, -111, -111, - -14, -111, -111, -111, -111, -111, -111, -111, -111}; - -const short QQmlJSGrammar::action_info [] = { - 309, 314, 152, 150, 101, 73, 678, 167, 487, 103, - 485, 73, 484, 101, 173, 103, 527, 182, 477, 144, - 186, 585, 621, 190, 192, 532, 459, 451, 307, 193, - 285, 451, 167, 457, 455, 246, 144, 307, 247, 317, - 441, 319, 537, 442, 435, 285, 435, 305, 305, 570, - 570, 435, 331, 431, 338, 556, 348, 270, 426, 628, - 424, -142, 631, 263, -139, 451, -137, 247, 423, 264, - 344, 468, 346, -115, 464, 395, 421, 356, 185, 352, - 402, 401, 563, 427, -116, -134, -146, -145, 352, 245, - -126, 270, -126, -145, 270, -146, 247, -134, 427, 325, - 352, -116, 570, -115, 405, 588, 427, -139, 411, 451, - 416, -142, 0, 144, 570, 144, 242, 64, 464, 0, - 468, 493, 0, 408, 409, 243, 675, 674, 65, 240, - 567, 407, 144, 0, 451, 468, 144, 327, 464, 0, - 144, 328, 144, 60, 535, 144, 175, 144, 60, 144, - 340, 0, 0, 558, 61, 175, 0, 438, 175, 61, - 567, 145, 169, 646, 647, 176, 170, 504, 144, 494, - 261, 260, 669, 668, 176, 261, 260, 176, 568, 254, - 253, 419, 418, 144, 354, 60, 259, 258, 350, 60, - 180, 543, 470, 454, 633, 632, 61, 266, 175, 466, - 61, 429, 439, 341, -137, 261, 260, 455, 641, 677, - 676, 646, 647, 535, 540, 539, 66, 176, 533, 177, - 323, 144, 536, 175, 533, 87, 66, 88, 87, 0, - 88, 579, 175, 66, 533, 528, 449, 448, 89, 635, - 0, 89, 176, 0, 414, 544, 542, 87, 533, 88, - 87, 176, 88, 414, 269, 267, 87, 533, 88, 480, - 89, 67, 0, 89, 530, 570, 87, 68, 88, 89, - 530, 67, 554, 0, 238, 237, 529, 68, 67, 89, - 530, 530, 529, 268, 68, 580, 578, 87, 87, 88, - 88, 623, 529, 529, 530, 87, 87, 88, 88, 561, - 89, 89, 105, 530, 445, 144, 529, 0, 89, 89, - 672, 671, 481, 479, 0, 529, 624, 622, 530, 175, - 87, 106, 88, 107, 75, 76, 175, 636, 75, 76, - 529, 287, 288, 89, 287, 288, 0, -102, 176, 0, - 177, 0, 0, 670, -102, 176, 0, 177, 0, 665, - 0, 77, 78, 562, 560, 77, 78, 0, 289, 290, - 0, 289, 290, 666, 664, 292, 293, 0, 0, 292, - 293, 0, 0, 0, 294, 292, 293, 295, 294, 296, - 0, 295, 35, 296, 294, 292, 293, 295, 35, 296, - 0, 292, 293, 35, 294, 0, 663, 295, 35, 296, - 294, 35, 0, 295, 87, 296, 88, 6, 5, 4, - 1, 3, 2, 0, 35, 0, 0, 89, 0, 49, - 52, 50, 0, 0, 0, 49, 52, 50, 0, 0, - 49, 52, 50, 0, 0, 49, 52, 50, 49, 52, - 50, 0, 0, 0, 0, 0, 35, 0, 46, 34, - 51, 49, 52, 50, 46, 34, 51, 0, 0, 46, - 34, 51, 0, 0, 46, 34, 51, 46, 34, 51, - 35, 0, 0, 0, 0, 0, 0, 0, 35, 0, - 46, 34, 51, 49, 52, 50, 80, 81, 35, 0, - 0, 35, 0, 0, 82, 83, 35, 0, 84, 0, - 85, 0, 0, 185, 0, 0, 0, 49, 52, 50, - 0, 35, 46, 34, 51, 49, 52, 50, 185, 0, - 0, 0, 0, 0, 0, 49, 52, 50, 49, 52, - 50, 0, 0, 49, 52, 50, 46, 34, 51, 535, - 0, 0, 0, 0, 46, 34, 51, 535, 49, 52, - 50, 0, 0, 35, 46, 34, 51, 46, 34, 51, - 0, 35, 46, 34, 51, 35, 0, 0, 0, 0, - 35, 0, 185, 35, 0, 0, 0, 46, 34, 51, - 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, - 49, 52, 50, 0, 0, 0, 0, 0, 49, 52, - 50, 0, 49, 52, 50, 252, 251, 49, 52, 50, - 49, 52, 50, 0, 0, 0, 0, 257, 256, 46, - 34, 51, 49, 52, 50, 0, 35, 46, 34, 51, - 0, 46, 34, 51, 0, 0, 46, 34, 51, 46, - 34, 51, 35, 0, 0, 35, 0, 0, 535, 0, - 0, 46, 34, 51, 0, 0, 0, 0, 257, 256, - 0, 0, 35, 49, 52, 50, 0, 0, 0, 0, - 0, 0, 0, 0, 252, 251, 0, 252, 251, 49, - 52, 50, 49, 52, 50, 0, 0, 0, 0, 0, - 0, 0, 46, 34, 51, 0, 0, 0, 0, 49, - 52, 50, 0, 0, 0, 0, 0, 0, 46, 34, - 51, 46, 34, 51, 0, 0, 0, 0, 0, 0, - 0, 154, 0, 0, 0, 0, 0, 0, 46, 34, - 51, 155, 0, 0, 0, 156, 0, 0, 0, 0, - 35, 0, 0, 0, 157, 0, 158, 0, 0, 321, - 0, 0, 0, 0, 0, 0, 0, 159, 0, 160, - 64, 0, 0, 0, 0, 0, 0, 161, 0, 0, - 162, 65, 257, 256, 0, 0, 163, 49, 52, 50, - 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, - 0, 0, 0, 0, 0, 0, 46, 34, 51, 0, - 0, 0, 0, 0, 0, 0, 30, 31, 154, 0, - 0, 0, 0, 0, 0, 0, 33, 0, 155, 0, - 0, 0, 156, 35, 0, 0, 0, 36, 37, 0, - 38, 157, 0, 158, 0, 0, 0, 42, 0, 0, - 0, 45, 0, 0, 159, 0, 160, 64, 0, 0, - 0, 0, 0, 0, 161, 0, 0, 162, 65, 53, - 49, 52, 50, 163, 54, 0, 0, 0, 0, 164, - 0, 0, 0, 0, 0, 44, 56, 32, 0, 0, - 0, 0, 41, 0, 0, 165, 0, 0, 0, 46, - 34, 51, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 33, 0, 0, 0, 0, 0, 0, 35, - 0, 0, 0, 36, 37, 0, 38, 0, 0, 0, - 0, 0, 0, 519, 0, 0, 0, 45, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 53, 49, 52, 50, 0, - 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 44, 56, 32, 0, 0, 0, 0, 41, 0, - 0, 0, 0, 0, 0, 46, 34, 51, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 30, 31, 0, - 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, - 0, 0, 0, 0, 35, 0, 0, 0, 36, 37, - 0, 38, 0, 0, 0, 0, 0, 0, 42, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 53, 49, 52, 50, 0, 54, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 44, 56, 32, 0, - 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, - 46, 34, 51, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 518, 0, 30, 31, 0, 0, 0, 0, - 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, - 0, 35, 0, 0, 0, 36, 37, 0, 38, 0, - 0, 0, 0, 0, 0, 519, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 53, 520, 522, - 521, 0, 54, 0, 0, 0, 0, 229, 0, 0, - 0, 0, 0, 44, 56, 32, 215, 223, 0, 0, - 41, 0, 0, 0, 0, 0, 0, 46, 34, 51, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 518, - 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, - 0, 220, 0, 0, 0, 0, 0, 0, 35, 0, - 0, 0, 36, 37, 0, 38, 0, 0, 0, 0, - 0, 0, 519, 0, 0, 0, 45, 0, 0, 0, - 0, 0, 0, 0, 575, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 53, 520, 522, 521, 0, 54, - 0, 0, 0, 0, 229, 0, 0, 0, 0, 0, - 44, 56, 32, 215, 223, 0, 0, 41, 0, 0, - 0, 0, 0, 0, 46, 34, 51, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 518, 0, 30, 31, - 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, - 0, 0, 0, 0, 0, 35, 0, 0, 0, 36, - 37, 0, 38, 0, 0, 0, 0, 0, 0, 519, - 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, - 0, 572, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 53, 520, 522, 521, 0, 54, 0, 0, 0, - 0, 229, 0, 0, 0, 0, 0, 44, 56, 32, - 215, 223, 0, 0, 41, 0, 0, 0, 0, 0, - 0, 46, 34, 51, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 29, 30, 31, 0, 0, 0, 0, - 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, - 0, 35, 0, 0, 0, 36, 37, 0, 38, 0, - 0, 0, 39, 0, 40, 42, 43, 0, 0, 45, - 0, 0, 0, 47, 0, 48, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 53, 49, 52, - 50, 0, 54, 0, 55, 0, 57, 0, 58, 0, - 0, 0, 0, 44, 56, 32, 0, 0, 0, 0, - 41, 0, 0, 0, 0, 0, 0, 46, 34, 51, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, - 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 35, 0, 0, - 0, 36, 37, 0, 38, 0, 0, 0, 39, 0, - 40, 42, 43, 0, 0, 45, 0, 0, 0, 47, - 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 53, 49, 52, 50, 0, 54, 0, - 55, 0, 57, 284, 58, 0, 0, 0, 0, 44, - 56, 32, 0, 0, 0, 0, 41, 0, 0, 0, - 0, 0, 0, 46, 34, 51, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -135, 0, 0, 0, 29, - 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 0, 0, 35, 0, 0, - 0, 36, 37, 0, 38, 0, 0, 0, 39, 0, - 40, 42, 43, 0, 0, 45, 0, 0, 0, 47, - 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 53, 49, 52, 50, 0, 54, 0, - 55, 0, 57, 0, 58, 0, 0, 0, 0, 44, - 56, 32, 0, 0, 0, 0, 41, 0, 0, 0, - 0, 0, 0, 46, 34, 51, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 499, 0, 0, 29, 30, - 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, - 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, - 36, 37, 0, 38, 0, 0, 0, 39, 0, 40, - 42, 43, 0, 0, 45, 0, 0, 0, 47, 0, - 48, 0, 0, 500, 0, 0, 0, 0, 0, 0, - 0, 0, 53, 49, 52, 50, 0, 54, 0, 55, - 0, 57, 0, 58, 0, 0, 0, 0, 44, 56, - 32, 0, 0, 0, 0, 41, 0, 0, 0, 0, - 0, 0, 46, 34, 51, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 491, 0, 0, 29, 30, 31, - 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, - 0, 0, 0, 0, 0, 35, 0, 0, 0, 36, - 37, 0, 38, 0, 0, 0, 39, 0, 40, 42, - 43, 0, 0, 45, 0, 0, 0, 47, 0, 48, - 0, 0, 492, 0, 0, 0, 0, 0, 0, 0, - 0, 53, 49, 52, 50, 0, 54, 0, 55, 0, - 57, 0, 58, 0, 0, 0, 0, 44, 56, 32, - 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, - 0, 46, 34, 51, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 491, 0, 0, 29, 30, 31, 0, - 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, - 0, 0, 0, 0, 35, 0, 0, 0, 36, 37, - 0, 38, 0, 0, 0, 39, 0, 40, 42, 43, - 0, 0, 45, 0, 0, 0, 47, 0, 48, 0, - 0, 497, 0, 0, 0, 0, 0, 0, 0, 0, - 53, 49, 52, 50, 0, 54, 0, 55, 0, 57, - 0, 58, 0, 0, 0, 0, 44, 56, 32, 0, - 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, - 46, 34, 51, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 499, 0, 0, 29, 30, 31, 0, 0, - 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, - 0, 0, 0, 35, 0, 0, 0, 36, 37, 0, - 38, 0, 0, 0, 39, 0, 40, 42, 43, 0, - 0, 45, 0, 0, 0, 47, 0, 48, 0, 0, - 502, 0, 0, 0, 0, 0, 0, 0, 0, 53, - 49, 52, 50, 0, 54, 0, 55, 0, 57, 0, - 58, 0, 0, 0, 0, 44, 56, 32, 0, 0, - 0, 0, 41, 0, 0, 0, 0, 0, 0, 46, - 34, 51, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 29, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 33, 0, 0, 0, 0, 0, 0, 35, - 221, 0, 0, 222, 37, 0, 38, 0, 0, 0, - 39, 0, 40, 42, 43, 0, 0, 45, 0, 0, - 0, 47, 0, 48, 0, 0, 0, 0, 0, 0, - 0, 225, 0, 0, 0, 53, 49, 52, 50, 226, - 54, 0, 55, 228, 57, 0, 58, 0, 231, 0, - 0, 44, 56, 32, 0, 0, 0, 0, 41, 0, - 0, 0, 0, 0, 0, 46, 34, 51, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 29, 30, 31, - 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, - 0, 0, 0, 0, 0, 35, 221, 0, 0, 590, - 37, 0, 38, 0, 0, 0, 39, 0, 40, 42, - 43, 0, 0, 45, 0, 0, 0, 47, 0, 48, - 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, - 0, 53, 49, 52, 50, 226, 54, 0, 55, 228, - 57, 0, 58, 0, 231, 0, 0, 44, 56, 32, - 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, - 0, 46, 34, 51, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 29, 30, 31, 0, 0, 0, 0, - 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, - 0, 35, 221, 0, 0, 590, 637, 0, 38, 0, - 0, 0, 39, 0, 40, 42, 43, 0, 0, 45, - 0, 0, 0, 47, 0, 48, 0, 0, 0, 0, - 0, 0, 0, 225, 0, 0, 0, 53, 49, 52, - 50, 226, 54, 0, 55, 228, 57, 0, 58, 0, - 231, 0, 0, 44, 56, 32, 0, 0, 0, 0, - 41, 0, 0, 0, 0, 0, 0, 46, 34, 51, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, - 112, 113, 0, 0, 115, 117, 118, 0, 0, 119, - 0, 120, 0, 0, 0, 122, 123, 124, 0, 0, - 0, 0, 0, 0, 35, 125, 126, 127, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 129, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, - 0, 49, 52, 50, 133, 134, 135, 0, 137, 138, - 139, 140, 141, 142, 0, 0, 130, 136, 121, 114, - 128, 116, 131, 0, 0, 0, 0, 0, 0, 0, - 46, 34, 51, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 111, 112, 113, 0, 0, 115, 117, 118, - 0, 0, 119, 0, 120, 0, 0, 0, 122, 123, - 124, 0, 0, 0, 0, 0, 0, 35, 125, 126, - 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 129, 0, 0, 0, 398, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, - 0, 0, 0, 400, 49, 52, 50, 133, 134, 135, - 0, 137, 138, 139, 140, 141, 142, 0, 0, 130, - 136, 121, 114, 128, 116, 131, 0, 0, 0, 0, - 0, 0, 0, 46, 376, 383, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 111, 112, 113, 0, 0, - 115, 117, 118, 0, 0, 119, 0, 120, 0, 0, - 0, 122, 123, 124, 0, 0, 0, 0, 0, 0, - 35, 125, 126, 127, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 129, 0, 0, 0, 398, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 132, 0, 0, 0, 0, 0, 400, 49, 52, 50, - 133, 134, 135, 0, 137, 138, 139, 140, 141, 142, - 0, 0, 130, 136, 121, 114, 128, 116, 131, 0, - 0, 0, 0, 0, 0, 0, 46, 34, 51, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 111, 112, - 113, 0, 0, 115, 117, 118, 0, 0, 119, 0, - 120, 0, 0, 0, 122, 123, 124, 0, 0, 0, - 0, 0, 0, 35, 125, 126, 127, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, - 0, 398, 0, 0, 0, 0, 0, 0, 0, 399, - 0, 0, 0, 132, 0, 0, 0, 0, 0, 400, - 49, 52, 50, 133, 134, 135, 0, 137, 138, 139, - 140, 141, 142, 0, 0, 130, 136, 121, 114, 128, - 116, 131, 0, 0, 0, 0, 0, 0, 0, 46, - 376, 383, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 214, 0, 0, 0, 0, 216, 0, 29, 30, - 31, 218, 0, 0, 0, 0, 0, 0, 219, 220, - 0, 0, 0, 0, 0, 0, 35, 221, 0, 0, - 222, 37, 0, 38, 0, 0, 0, 39, 0, 40, - 42, 43, 0, 0, 45, 0, 0, 0, 47, 0, - 48, 0, 0, 0, 0, 0, 224, 0, 225, 0, - 0, 0, 53, 49, 52, 50, 226, 54, 227, 55, - 228, 57, 229, 58, 230, 231, 0, 0, 44, 56, - 32, 215, 223, 217, 0, 41, 0, 0, 0, 0, - 0, 0, 46, 34, 51, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 214, 0, 0, 0, 0, 216, - 0, 29, 30, 31, 218, 0, 0, 0, 0, 0, - 0, 219, 33, 0, 0, 0, 0, 0, 0, 35, - 221, 0, 0, 222, 37, 0, 38, 0, 0, 0, - 39, 0, 40, 42, 43, 0, 0, 45, 0, 0, - 0, 47, 0, 48, 0, 0, 0, 0, 0, 224, - 0, 225, 0, 0, 0, 53, 49, 52, 50, 226, - 54, 227, 55, 228, 57, 229, 58, 230, 231, 0, - 0, 44, 56, 32, 215, 223, 217, 0, 41, 0, - 0, 0, 0, 0, 0, 46, 34, 51, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 594, 112, 113, - 0, 0, 596, 117, 598, 30, 31, 599, 0, 120, - 0, 0, 0, 122, 601, 602, 0, 0, 0, 0, - 0, 0, 35, 603, 126, 127, 222, 37, 0, 38, - 0, 0, 0, 39, 0, 40, 605, 43, 0, 0, - 607, 0, 0, 0, 47, 0, 48, 0, 0, 0, - 0, 0, 608, 0, 225, 0, 0, 0, 609, 49, - 52, 50, 610, 611, 612, 55, 614, 615, 616, 617, - 618, 619, 0, 0, 606, 613, 600, 595, 604, 597, - 131, 41, 0, 0, 0, 0, 0, 0, 46, 376, - 383, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 367, 112, 113, 0, 0, 369, 117, 371, 30, 31, - 372, 0, 120, 0, 0, 0, 122, 374, 375, 0, - 0, 0, 0, 0, 0, 35, 377, 126, 127, 222, - 37, 0, 38, 0, 0, 0, 39, 0, 40, 379, - 43, 0, 0, 381, 0, 0, 0, 47, 0, 48, - 0, -282, 0, 0, 0, 382, 0, 225, 0, 0, - 0, 384, 49, 52, 50, 385, 386, 387, 55, 389, - 390, 391, 392, 393, 394, 0, 0, 380, 388, 373, - 368, 378, 370, 131, 41, 0, 0, 0, 0, 0, - 0, 46, 376, 383, 0, 0, 0, 0, 0, 0, - 0, 0, 0, - - 315, 478, 645, 153, 673, 465, 460, 501, 458, 461, - 184, 456, 396, 498, 488, 503, 440, 444, 436, 428, - 657, 667, 656, 644, 403, 630, 642, 629, 447, 634, - 450, 627, 315, 143, 553, 184, 255, 250, 149, 447, - 146, 353, 151, 349, 541, 531, 450, 534, 315, 179, - 538, 166, 172, 184, 322, 189, 620, 191, 16, 255, - 207, 250, 239, 586, 174, 250, 255, 587, 184, 447, - 265, 0, 577, 515, 584, 472, 559, 333, 450, 412, - 207, 514, 517, 471, 248, 467, 517, 565, 557, 207, - 315, 569, 315, 364, 207, 207, 207, 189, 249, 207, - 207, 207, 496, 0, 207, 315, 495, 412, 469, 358, - 333, 412, 207, 315, 62, 279, 413, 62, 0, 297, - 283, 486, 298, 244, 62, 241, 183, 62, 62, 62, - 262, 425, 299, 300, 301, 320, 364, 324, 62, 62, - 505, 506, 189, 262, 413, 0, 207, 0, 413, 472, - 0, 207, 593, 207, 62, 62, 507, 508, 62, 207, - 509, 62, 62, 510, 183, 316, 62, 318, 462, 149, - 188, 513, 62, 347, 463, 351, 62, 181, 355, 62, - 343, 357, 404, 62, 396, 462, 342, 262, 345, 207, - 108, 207, 171, 168, 207, 396, 62, 207, 207, 62, - 62, 183, 463, 207, 62, 62, 104, 62, 92, 62, - 406, 91, 249, 62, 97, 462, 364, 102, 62, 110, - 463, 420, 62, 482, 62, 396, 207, 96, 90, 62, - 207, 189, 207, 0, 95, 62, 62, 62, 62, 63, - 94, 72, 93, 62, 0, 62, 62, 62, 86, 62, - 397, 100, 99, 98, 108, 79, 62, 410, 149, 422, - 660, 659, 517, 62, 74, 71, 415, 661, 0, 62, - 0, 70, 62, 311, 69, 311, 311, 62, 283, 0, - 283, 283, 283, 110, 178, 62, 311, 311, 364, 364, - 283, 283, 283, 517, 329, 339, 62, 332, 330, 0, - 326, 283, 525, 0, 207, 207, 62, 308, 313, 310, - 0, 283, 62, 62, 516, 526, 0, 283, 283, 306, - 291, 286, 62, 62, 0, 517, 62, 283, 283, 302, - 303, 283, 576, 304, 643, 573, 0, 0, 0, 0, - 0, 517, 0, 0, 517, 0, 0, 0, 0, 0, - 525, 0, 0, 525, 545, 546, 547, 548, 552, 549, - 550, 0, 516, 526, 0, 516, 526, 589, 0, 0, - 0, 0, 0, 0, 443, 446, 638, 639, 545, 546, - 547, 548, 552, 549, 550, 589, 0, 0, 0, 0, - 0, 0, 0, 0, 591, 592, 545, 546, 547, 548, - 552, 549, 550, 581, 0, 0, 0, 0, 0, 0, - 0, 0, 582, 583, 545, 546, 547, 548, 552, 549, - 550, 0, 581, 0, 0, 0, 0, 565, 0, 640, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 488, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -const short QQmlJSGrammar::action_check [] = { - 8, 61, 60, 8, 48, 1, 0, 2, 55, 79, - 33, 1, 60, 48, 7, 79, 66, 60, 17, 8, - 36, 66, 29, 8, 60, 37, 60, 33, 79, 33, - 1, 33, 2, 36, 20, 55, 8, 79, 7, 61, - 55, 60, 29, 7, 5, 1, 5, 48, 48, 33, - 33, 5, 7, 33, 17, 37, 31, 36, 55, 8, - 33, 7, 60, 77, 7, 33, 7, 7, 60, 36, - 61, 36, 60, 7, 36, 8, 36, 16, 36, 36, - 7, 55, 34, 36, 7, 7, 7, 7, 36, 55, - 7, 36, 7, 7, 36, 7, 7, 7, 36, 2, - 36, 7, 33, 7, 55, 7, 36, 7, 55, 33, - 60, 7, -1, 8, 33, 8, 60, 42, 36, -1, - 36, 8, -1, 60, 33, 33, 61, 62, 53, 36, - 8, 36, 8, -1, 33, 36, 8, 50, 36, -1, - 8, 54, 8, 40, 15, 8, 15, 8, 40, 8, - 8, -1, -1, 24, 51, 15, -1, 10, 15, 51, - 8, 56, 50, 92, 93, 34, 54, 60, 8, 56, - 61, 62, 61, 62, 34, 61, 62, 34, 56, 61, - 62, 61, 62, 8, 60, 40, 61, 62, 60, 40, - 56, 7, 60, 6, 61, 62, 51, 60, 15, 60, - 51, 60, 55, 61, 7, 61, 62, 20, 56, 61, - 62, 92, 93, 15, 61, 62, 12, 34, 29, 36, - 60, 8, 24, 15, 29, 25, 12, 27, 25, -1, - 27, 7, 15, 12, 29, 29, 61, 62, 38, 7, - -1, 38, 34, -1, 36, 61, 62, 25, 29, 27, - 25, 34, 27, 36, 61, 62, 25, 29, 27, 8, - 38, 57, -1, 38, 75, 33, 25, 63, 27, 38, - 75, 57, 29, -1, 61, 62, 87, 63, 57, 38, - 75, 75, 87, 90, 63, 61, 62, 25, 25, 27, - 27, 36, 87, 87, 75, 25, 25, 27, 27, 7, - 38, 38, 15, 75, 7, 8, 87, -1, 38, 38, - 61, 62, 61, 62, -1, 87, 61, 62, 75, 15, - 25, 34, 27, 36, 18, 19, 15, 95, 18, 19, - 87, 18, 19, 38, 18, 19, -1, 33, 34, -1, - 36, -1, -1, 94, 33, 34, -1, 36, -1, 47, - -1, 45, 46, 61, 62, 45, 46, -1, 45, 46, - -1, 45, 46, 61, 62, 23, 24, -1, -1, 23, - 24, -1, -1, -1, 32, 23, 24, 35, 32, 37, - -1, 35, 29, 37, 32, 23, 24, 35, 29, 37, - -1, 23, 24, 29, 32, -1, 94, 35, 29, 37, - 32, 29, -1, 35, 25, 37, 27, 99, 100, 101, - 102, 103, 104, -1, 29, -1, -1, 38, -1, 66, - 67, 68, -1, -1, -1, 66, 67, 68, -1, -1, - 66, 67, 68, -1, -1, 66, 67, 68, 66, 67, - 68, -1, -1, -1, -1, -1, 29, -1, 95, 96, - 97, 66, 67, 68, 95, 96, 97, -1, -1, 95, - 96, 97, -1, -1, 95, 96, 97, 95, 96, 97, - 29, -1, -1, -1, -1, -1, -1, -1, 29, -1, - 95, 96, 97, 66, 67, 68, 23, 24, 29, -1, - -1, 29, -1, -1, 31, 32, 29, -1, 35, -1, - 37, -1, -1, 36, -1, -1, -1, 66, 67, 68, - -1, 29, 95, 96, 97, 66, 67, 68, 36, -1, - -1, -1, -1, -1, -1, 66, 67, 68, 66, 67, - 68, -1, -1, 66, 67, 68, 95, 96, 97, 15, - -1, -1, -1, -1, 95, 96, 97, 15, 66, 67, - 68, -1, -1, 29, 95, 96, 97, 95, 96, 97, - -1, 29, 95, 96, 97, 29, -1, -1, -1, -1, - 29, -1, 36, 29, -1, -1, -1, 95, 96, 97, - -1, -1, -1, -1, -1, 29, -1, -1, -1, -1, - 66, 67, 68, -1, -1, -1, -1, -1, 66, 67, - 68, -1, 66, 67, 68, 61, 62, 66, 67, 68, - 66, 67, 68, -1, -1, -1, -1, 61, 62, 95, - 96, 97, 66, 67, 68, -1, 29, 95, 96, 97, - -1, 95, 96, 97, -1, -1, 95, 96, 97, 95, - 96, 97, 29, -1, -1, 29, -1, -1, 15, -1, - -1, 95, 96, 97, -1, -1, -1, -1, 61, 62, - -1, -1, 29, 66, 67, 68, -1, -1, -1, -1, - -1, -1, -1, -1, 61, 62, -1, 61, 62, 66, - 67, 68, 66, 67, 68, -1, -1, -1, -1, -1, - -1, -1, 95, 96, 97, -1, -1, -1, -1, 66, - 67, 68, -1, -1, -1, -1, -1, -1, 95, 96, - 97, 95, 96, 97, -1, -1, -1, -1, -1, -1, - -1, 3, -1, -1, -1, -1, -1, -1, 95, 96, - 97, 13, -1, -1, -1, 17, -1, -1, -1, -1, - 29, -1, -1, -1, 26, -1, 28, -1, -1, 31, - -1, -1, -1, -1, -1, -1, -1, 39, -1, 41, - 42, -1, -1, -1, -1, -1, -1, 49, -1, -1, - 52, 53, 61, 62, -1, -1, 58, 66, 67, 68, - -1, -1, 64, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 80, -1, - -1, -1, -1, -1, -1, -1, 95, 96, 97, -1, - -1, -1, -1, -1, -1, -1, 12, 13, 3, -1, - -1, -1, -1, -1, -1, -1, 22, -1, 13, -1, - -1, -1, 17, 29, -1, -1, -1, 33, 34, -1, - 36, 26, -1, 28, -1, -1, -1, 43, -1, -1, - -1, 47, -1, -1, 39, -1, 41, 42, -1, -1, - -1, -1, -1, -1, 49, -1, -1, 52, 53, 65, - 66, 67, 68, 58, 70, -1, -1, -1, -1, 64, - -1, -1, -1, -1, -1, 81, 82, 83, -1, -1, - -1, -1, 88, -1, -1, 80, -1, -1, -1, 95, - 96, 97, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 12, 13, -1, -1, -1, -1, -1, -1, - -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, - -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, - -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, - 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 81, 82, 83, -1, -1, -1, -1, 88, -1, - -1, -1, -1, -1, -1, 95, 96, 97, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 12, 13, -1, - -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, - -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, - -1, 36, -1, -1, -1, -1, -1, -1, 43, -1, - -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 65, 66, 67, 68, -1, 70, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 81, 82, 83, -1, - -1, -1, -1, 88, -1, -1, -1, -1, -1, -1, - 95, 96, 97, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 10, -1, 12, 13, -1, -1, -1, -1, - -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, - -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, - -1, -1, -1, -1, -1, 43, -1, -1, -1, 47, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, - 68, -1, 70, -1, -1, -1, -1, 75, -1, -1, - -1, -1, -1, 81, 82, 83, 84, 85, -1, -1, - 88, -1, -1, -1, -1, -1, -1, 95, 96, 97, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, - -1, 12, 13, -1, -1, -1, -1, -1, -1, -1, - -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, - -1, -1, 33, 34, -1, 36, -1, -1, -1, -1, - -1, -1, 43, -1, -1, -1, 47, -1, -1, -1, - -1, -1, -1, -1, 55, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, - -1, -1, -1, -1, 75, -1, -1, -1, -1, -1, - 81, 82, 83, 84, 85, -1, -1, 88, -1, -1, - -1, -1, -1, -1, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 10, -1, 12, 13, - -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, - -1, -1, -1, -1, -1, 29, -1, -1, -1, 33, - 34, -1, 36, -1, -1, -1, -1, -1, -1, 43, - -1, -1, -1, 47, -1, -1, -1, -1, -1, -1, - -1, 55, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 65, 66, 67, 68, -1, 70, -1, -1, -1, - -1, 75, -1, -1, -1, -1, -1, 81, 82, 83, - 84, 85, -1, -1, 88, -1, -1, -1, -1, -1, - -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 11, 12, 13, -1, -1, -1, -1, - -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, - -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, - -1, -1, 40, -1, 42, 43, 44, -1, -1, 47, - -1, -1, -1, 51, -1, 53, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, - 68, -1, 70, -1, 72, -1, 74, -1, 76, -1, - -1, -1, -1, 81, 82, 83, -1, -1, -1, -1, - 88, -1, -1, -1, -1, -1, -1, 95, 96, 97, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, - 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, - 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, - -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, - 42, 43, 44, -1, -1, 47, -1, -1, -1, 51, - -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, - 72, -1, 74, 75, 76, -1, -1, -1, -1, 81, - 82, 83, -1, -1, -1, -1, 88, -1, -1, -1, - -1, -1, -1, 95, 96, 97, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 7, -1, -1, -1, 11, - 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, - 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, - -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, - 42, 43, 44, -1, -1, 47, -1, -1, -1, 51, - -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, - 72, -1, 74, -1, 76, -1, -1, -1, -1, 81, - 82, 83, -1, -1, -1, -1, 88, -1, -1, -1, - -1, -1, -1, 95, 96, 97, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 8, -1, -1, 11, 12, - 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, - -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, - 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, - 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, - 53, -1, -1, 56, -1, -1, -1, -1, -1, -1, - -1, -1, 65, 66, 67, 68, -1, 70, -1, 72, - -1, 74, -1, 76, -1, -1, -1, -1, 81, 82, - 83, -1, -1, -1, -1, 88, -1, -1, -1, -1, - -1, -1, 95, 96, 97, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 8, -1, -1, 11, 12, 13, - -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, - -1, -1, -1, -1, -1, 29, -1, -1, -1, 33, - 34, -1, 36, -1, -1, -1, 40, -1, 42, 43, - 44, -1, -1, 47, -1, -1, -1, 51, -1, 53, - -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, - -1, 65, 66, 67, 68, -1, 70, -1, 72, -1, - 74, -1, 76, -1, -1, -1, -1, 81, 82, 83, - -1, -1, -1, -1, 88, -1, -1, -1, -1, -1, - -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 8, -1, -1, 11, 12, 13, -1, - -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, - -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, - -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, - -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, - -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, - 65, 66, 67, 68, -1, 70, -1, 72, -1, 74, - -1, 76, -1, -1, -1, -1, 81, 82, 83, -1, - -1, -1, -1, 88, -1, -1, -1, -1, -1, -1, - 95, 96, 97, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 8, -1, -1, 11, 12, 13, -1, -1, - -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, - -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, - 36, -1, -1, -1, 40, -1, 42, 43, 44, -1, - -1, 47, -1, -1, -1, 51, -1, 53, -1, -1, - 56, -1, -1, -1, -1, -1, -1, -1, -1, 65, - 66, 67, 68, -1, 70, -1, 72, -1, 74, -1, - 76, -1, -1, -1, -1, 81, 82, 83, -1, -1, - -1, -1, 88, -1, -1, -1, -1, -1, -1, 95, - 96, 97, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, - -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, - 30, -1, -1, 33, 34, -1, 36, -1, -1, -1, - 40, -1, 42, 43, 44, -1, -1, 47, -1, -1, - -1, 51, -1, 53, -1, -1, -1, -1, -1, -1, - -1, 61, -1, -1, -1, 65, 66, 67, 68, 69, - 70, -1, 72, 73, 74, -1, 76, -1, 78, -1, - -1, 81, 82, 83, -1, -1, -1, -1, 88, -1, - -1, -1, -1, -1, -1, 95, 96, 97, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 11, 12, 13, - -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, - -1, -1, -1, -1, -1, 29, 30, -1, -1, 33, - 34, -1, 36, -1, -1, -1, 40, -1, 42, 43, - 44, -1, -1, 47, -1, -1, -1, 51, -1, 53, - -1, -1, -1, -1, -1, -1, -1, 61, -1, -1, - -1, 65, 66, 67, 68, 69, 70, -1, 72, 73, - 74, -1, 76, -1, 78, -1, -1, 81, 82, 83, - -1, -1, -1, -1, 88, -1, -1, -1, -1, -1, - -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 11, 12, 13, -1, -1, -1, -1, - -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, - -1, 29, 30, -1, -1, 33, 34, -1, 36, -1, - -1, -1, 40, -1, 42, 43, 44, -1, -1, 47, - -1, -1, -1, 51, -1, 53, -1, -1, -1, -1, - -1, -1, -1, 61, -1, -1, -1, 65, 66, 67, - 68, 69, 70, -1, 72, 73, 74, -1, 76, -1, - 78, -1, -1, 81, 82, 83, -1, -1, -1, -1, - 88, -1, -1, -1, -1, -1, -1, 95, 96, 97, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, - 5, 6, -1, -1, 9, 10, 11, -1, -1, 14, - -1, 16, -1, -1, -1, 20, 21, 22, -1, -1, - -1, -1, -1, -1, 29, 30, 31, 32, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 59, -1, -1, -1, -1, -1, - -1, 66, 67, 68, 69, 70, 71, -1, 73, 74, - 75, 76, 77, 78, -1, -1, 81, 82, 83, 84, - 85, 86, 87, -1, -1, -1, -1, -1, -1, -1, - 95, 96, 97, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 4, 5, 6, -1, -1, 9, 10, 11, - -1, -1, 14, -1, 16, -1, -1, -1, 20, 21, - 22, -1, -1, -1, -1, -1, -1, 29, 30, 31, - 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 43, -1, -1, -1, 47, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 59, -1, -1, - -1, -1, -1, 65, 66, 67, 68, 69, 70, 71, - -1, 73, 74, 75, 76, 77, 78, -1, -1, 81, - 82, 83, 84, 85, 86, 87, -1, -1, -1, -1, - -1, -1, -1, 95, 96, 97, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 4, 5, 6, -1, -1, - 9, 10, 11, -1, -1, 14, -1, 16, -1, -1, - -1, 20, 21, 22, -1, -1, -1, -1, -1, -1, - 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 43, -1, -1, -1, 47, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 59, -1, -1, -1, -1, -1, 65, 66, 67, 68, - 69, 70, 71, -1, 73, 74, 75, 76, 77, 78, - -1, -1, 81, 82, 83, 84, 85, 86, 87, -1, - -1, -1, -1, -1, -1, -1, 95, 96, 97, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, - 6, -1, -1, 9, 10, 11, -1, -1, 14, -1, - 16, -1, -1, -1, 20, 21, 22, -1, -1, -1, - -1, -1, -1, 29, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 43, -1, -1, - -1, 47, -1, -1, -1, -1, -1, -1, -1, 55, - -1, -1, -1, 59, -1, -1, -1, -1, -1, 65, - 66, 67, 68, 69, 70, 71, -1, 73, 74, 75, - 76, 77, 78, -1, -1, 81, 82, 83, 84, 85, - 86, 87, -1, -1, -1, -1, -1, -1, -1, 95, - 96, 97, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4, -1, -1, -1, -1, 9, -1, 11, 12, - 13, 14, -1, -1, -1, -1, -1, -1, 21, 22, - -1, -1, -1, -1, -1, -1, 29, 30, -1, -1, - 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, - 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, - 53, -1, -1, -1, -1, -1, 59, -1, 61, -1, - -1, -1, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, -1, -1, 81, 82, - 83, 84, 85, 86, -1, 88, -1, -1, -1, -1, - -1, -1, 95, 96, 97, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4, -1, -1, -1, -1, 9, - -1, 11, 12, 13, 14, -1, -1, -1, -1, -1, - -1, 21, 22, -1, -1, -1, -1, -1, -1, 29, - 30, -1, -1, 33, 34, -1, 36, -1, -1, -1, - 40, -1, 42, 43, 44, -1, -1, 47, -1, -1, - -1, 51, -1, 53, -1, -1, -1, -1, -1, 59, - -1, 61, -1, -1, -1, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, -1, - -1, 81, 82, 83, 84, 85, 86, -1, 88, -1, - -1, -1, -1, -1, -1, 95, 96, 97, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, - -1, -1, 9, 10, 11, 12, 13, 14, -1, 16, - -1, -1, -1, 20, 21, 22, -1, -1, -1, -1, - -1, -1, 29, 30, 31, 32, 33, 34, -1, 36, - -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, - 47, -1, -1, -1, 51, -1, 53, -1, -1, -1, - -1, -1, 59, -1, 61, -1, -1, -1, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, -1, -1, 81, 82, 83, 84, 85, 86, - 87, 88, -1, -1, -1, -1, -1, -1, 95, 96, - 97, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4, 5, 6, -1, -1, 9, 10, 11, 12, 13, - 14, -1, 16, -1, -1, -1, 20, 21, 22, -1, - -1, -1, -1, -1, -1, 29, 30, 31, 32, 33, - 34, -1, 36, -1, -1, -1, 40, -1, 42, 43, - 44, -1, -1, 47, -1, -1, -1, 51, -1, 53, - -1, 55, -1, -1, -1, 59, -1, 61, -1, -1, - -1, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, -1, -1, 81, 82, 83, - 84, 85, 86, 87, 88, -1, -1, -1, -1, -1, - -1, 95, 96, 97, -1, -1, -1, -1, -1, -1, - -1, -1, -1, - - 3, 42, 9, 77, 18, 3, 25, 42, 18, 25, - 18, 105, 18, 42, 42, 3, 100, 3, 103, 3, - 14, 18, 14, 22, 42, 18, 22, 32, 3, 18, - 25, 32, 3, 3, 14, 18, 18, 18, 42, 3, - 42, 3, 42, 3, 18, 32, 25, 32, 3, 3, - 18, 42, 42, 18, 3, 18, 22, 18, 3, 18, - 18, 18, 18, 32, 42, 18, 18, 18, 18, 3, - 3, -1, 18, 2, 22, 18, 18, 18, 25, 14, - 18, 4, 14, 2, 2, 2, 14, 19, 32, 18, - 3, 19, 3, 2, 18, 18, 18, 18, 4, 18, - 18, 18, 38, -1, 18, 3, 42, 14, 3, 18, - 18, 14, 18, 3, 54, 54, 51, 54, -1, 59, - 59, 45, 59, 45, 54, 46, 56, 54, 54, 54, - 2, 45, 59, 59, 59, 2, 2, 2, 54, 54, - 56, 56, 18, 2, 51, -1, 18, -1, 51, 18, - -1, 18, 18, 18, 54, 54, 56, 56, 54, 18, - 56, 54, 54, 56, 56, 78, 54, 78, 56, 42, - 46, 109, 54, 2, 56, 2, 54, 50, 2, 54, - 78, 2, 2, 54, 18, 56, 94, 2, 78, 18, - 18, 18, 70, 68, 18, 18, 54, 18, 18, 54, - 54, 56, 56, 18, 54, 54, 64, 54, 58, 54, - 44, 58, 4, 54, 59, 56, 2, 66, 54, 47, - 56, 44, 54, 92, 54, 18, 18, 59, 58, 54, - 18, 18, 18, -1, 59, 54, 54, 54, 54, 57, - 59, 57, 59, 54, -1, 54, 54, 54, 59, 54, - 43, 60, 60, 60, 18, 60, 54, 45, 42, 46, - 11, 12, 14, 54, 62, 56, 50, 19, -1, 54, - -1, 56, 54, 54, 56, 54, 54, 54, 59, -1, - 59, 59, 59, 47, 48, 54, 54, 54, 2, 2, - 59, 59, 59, 14, 71, 76, 54, 76, 76, -1, - 69, 59, 23, -1, 18, 18, 54, 65, 76, 76, - -1, 59, 54, 54, 35, 36, -1, 59, 59, 67, - 61, 63, 54, 54, -1, 14, 54, 59, 59, 61, - 61, 59, 5, 61, 23, 5, -1, -1, -1, -1, - -1, 14, -1, -1, 14, -1, -1, -1, -1, -1, - 23, -1, -1, 23, 25, 26, 27, 28, 29, 30, - 31, -1, 35, 36, -1, 35, 36, 14, -1, -1, - -1, -1, -1, -1, 88, 88, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 14, -1, -1, -1, -1, - -1, -1, -1, -1, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 14, -1, -1, -1, -1, -1, -1, - -1, -1, 23, 24, 25, 26, 27, 28, 29, 30, - 31, -1, 14, -1, -1, -1, -1, 19, -1, 21, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 42, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1}; - -QT_END_NAMESPACE diff --git a/src/qml/parser/qqmljsgrammar_p.h b/src/qml/parser/qqmljsgrammar_p.h deleted file mode 100644 index b4f762d28b..0000000000 --- a/src/qml/parser/qqmljsgrammar_p.h +++ /dev/null @@ -1,214 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -// This file was generated by qlalr - DO NOT EDIT! -#ifndef QQMLJSGRAMMAR_P_H -#define QQMLJSGRAMMAR_P_H - -#include <QtCore/qglobal.h> - -QT_BEGIN_NAMESPACE - -class QQmlJSGrammar -{ -public: - enum VariousConstants { - EOF_SYMBOL = 0, - REDUCE_HERE = 106, - SHIFT_THERE = 105, - T_AND = 1, - T_AND_AND = 2, - T_AND_EQ = 3, - T_AS = 94, - T_AUTOMATIC_SEMICOLON = 62, - T_BREAK = 4, - T_CASE = 5, - T_CATCH = 6, - T_COLON = 7, - T_COMMA = 8, - T_COMMENT = 89, - T_COMPATIBILITY_SEMICOLON = 90, - T_CONST = 84, - T_CONTINUE = 9, - T_DEBUGGER = 86, - T_DEFAULT = 10, - T_DELETE = 11, - T_DIVIDE_ = 12, - T_DIVIDE_EQ = 13, - T_DO = 14, - T_DOT = 15, - T_ELSE = 16, - T_EQ = 17, - T_EQ_EQ = 18, - T_EQ_EQ_EQ = 19, - T_ERROR = 98, - T_FALSE = 83, - T_FEED_JS_EXPRESSION = 102, - T_FEED_JS_PROGRAM = 104, - T_FEED_JS_SOURCE_ELEMENT = 103, - T_FEED_JS_STATEMENT = 101, - T_FEED_UI_OBJECT_MEMBER = 100, - T_FEED_UI_PROGRAM = 99, - T_FINALLY = 20, - T_FOR = 21, - T_FUNCTION = 22, - T_GE = 23, - T_GET = 96, - T_GT = 24, - T_GT_GT = 25, - T_GT_GT_EQ = 26, - T_GT_GT_GT = 27, - T_GT_GT_GT_EQ = 28, - T_IDENTIFIER = 29, - T_IF = 30, - T_IMPORT = 92, - T_IN = 31, - T_INSTANCEOF = 32, - T_LBRACE = 33, - T_LBRACKET = 34, - T_LE = 35, - T_LET = 85, - T_LPAREN = 36, - T_LT = 37, - T_LT_LT = 38, - T_LT_LT_EQ = 39, - T_MINUS = 40, - T_MINUS_EQ = 41, - T_MINUS_MINUS = 42, - T_MULTILINE_STRING_LITERAL = 88, - T_NEW = 43, - T_NOT = 44, - T_NOT_EQ = 45, - T_NOT_EQ_EQ = 46, - T_NULL = 81, - T_NUMERIC_LITERAL = 47, - T_ON = 95, - T_OR = 48, - T_OR_EQ = 49, - T_OR_OR = 50, - T_PLUS = 51, - T_PLUS_EQ = 52, - T_PLUS_PLUS = 53, - T_PRAGMA = 93, - T_PROPERTY = 66, - T_PUBLIC = 91, - T_QUESTION = 54, - T_RBRACE = 55, - T_RBRACKET = 56, - T_READONLY = 68, - T_REMAINDER = 57, - T_REMAINDER_EQ = 58, - T_RESERVED_WORD = 87, - T_RETURN = 59, - T_RPAREN = 60, - T_SEMICOLON = 61, - T_SET = 97, - T_SIGNAL = 67, - T_STAR = 63, - T_STAR_EQ = 64, - T_STRING_LITERAL = 65, - T_SWITCH = 69, - T_THIS = 70, - T_THROW = 71, - T_TILDE = 72, - T_TRUE = 82, - T_TRY = 73, - T_TYPEOF = 74, - T_VAR = 75, - T_VOID = 76, - T_WHILE = 77, - T_WITH = 78, - T_XOR = 79, - T_XOR_EQ = 80, - - ACCEPT_STATE = 678, - RULE_COUNT = 363, - STATE_COUNT = 679, - TERMINAL_COUNT = 107, - NON_TERMINAL_COUNT = 111, - - GOTO_INDEX_OFFSET = 679, - GOTO_INFO_OFFSET = 3203, - GOTO_CHECK_OFFSET = 3203 - }; - - static const char *const spell []; - static const short lhs []; - static const short rhs []; - static const short goto_default []; - static const short action_default []; - static const short action_index []; - static const short action_info []; - static const short action_check []; - - static inline int nt_action (int state, int nt) - { - const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt; - if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt) - return goto_default [nt]; - - return action_info [GOTO_INFO_OFFSET + yyn]; - } - - static inline int t_action (int state, int token) - { - const int yyn = action_index [state] + token; - - if (yyn < 0 || action_check [yyn] != token) - return - action_default [state]; - - return action_info [yyn]; - } -}; - - -QT_END_NAMESPACE -#endif // QQMLJSGRAMMAR_P_H - diff --git a/src/qml/parser/qqmljskeywords_p.h b/src/qml/parser/qqmljskeywords_p.h index 8b789526a5..b0a4951ece 100644 --- a/src/qml/parser/qqmljskeywords_p.h +++ b/src/qml/parser/qqmljskeywords_p.h @@ -57,10 +57,10 @@ QT_QML_BEGIN_NAMESPACE namespace QQmlJS { -static inline int classify2(const QChar *s, bool qmlMode) { +static inline int classify2(const QChar *s, int parseModeFlags) { if (s[0].unicode() == 'a') { if (s[1].unicode() == 's') { - return qmlMode ? Lexer::T_AS : Lexer::T_IDENTIFIER; + return Lexer::T_AS; } } else if (s[0].unicode() == 'd') { @@ -76,15 +76,18 @@ static inline int classify2(const QChar *s, bool qmlMode) { return Lexer::T_IN; } } - else if (qmlMode && s[0].unicode() == 'o') { + else if (s[0].unicode() == 'o') { if (s[1].unicode() == 'n') { - return qmlMode ? Lexer::T_ON : Lexer::T_IDENTIFIER; + return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_ON : Lexer::T_IDENTIFIER; + } + else if (s[1].unicode() == 'f') { + return Lexer::T_OF; } } return Lexer::T_IDENTIFIER; } -static inline int classify3(const QChar *s, bool qmlMode) { +static inline int classify3(const QChar *s, int parseModeFlags) { if (s[0].unicode() == 'f') { if (s[1].unicode() == 'o') { if (s[2].unicode() == 'r') { @@ -102,7 +105,7 @@ static inline int classify3(const QChar *s, bool qmlMode) { else if (s[0].unicode() == 'i') { if (s[1].unicode() == 'n') { if (s[2].unicode() == 't') { - return qmlMode ? int(Lexer::T_INT) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_INT) : int(Lexer::T_IDENTIFIER); } } } @@ -144,12 +147,12 @@ static inline int classify3(const QChar *s, bool qmlMode) { return Lexer::T_IDENTIFIER; } -static inline int classify4(const QChar *s, bool qmlMode) { +static inline int classify4(const QChar *s, int parseModeFlags) { if (s[0].unicode() == 'b') { if (s[1].unicode() == 'y') { if (s[2].unicode() == 't') { if (s[3].unicode() == 'e') { - return qmlMode ? int(Lexer::T_BYTE) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_BYTE) : int(Lexer::T_IDENTIFIER); } } } @@ -165,7 +168,7 @@ static inline int classify4(const QChar *s, bool qmlMode) { else if (s[1].unicode() == 'h') { if (s[2].unicode() == 'a') { if (s[3].unicode() == 'r') { - return qmlMode ? int(Lexer::T_CHAR) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_CHAR) : int(Lexer::T_IDENTIFIER); } } } @@ -181,7 +184,16 @@ static inline int classify4(const QChar *s, bool qmlMode) { else if (s[1].unicode() == 'n') { if (s[2].unicode() == 'u') { if (s[3].unicode() == 'm') { - return Lexer::T_ENUM; + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_ENUM) : int(Lexer::T_RESERVED_WORD); + } + } + } + } + else if (s[0].unicode() == 'f') { + if (s[1].unicode() == 'r') { + if (s[2].unicode() == 'o') { + if (s[3].unicode() == 'm') { + return int(Lexer::T_FROM); } } } @@ -190,7 +202,7 @@ static inline int classify4(const QChar *s, bool qmlMode) { if (s[1].unicode() == 'o') { if (s[2].unicode() == 't') { if (s[3].unicode() == 'o') { - return qmlMode ? int(Lexer::T_GOTO) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_GOTO) : int(Lexer::T_IDENTIFIER); } } } @@ -199,7 +211,7 @@ static inline int classify4(const QChar *s, bool qmlMode) { if (s[1].unicode() == 'o') { if (s[2].unicode() == 'n') { if (s[3].unicode() == 'g') { - return qmlMode ? int(Lexer::T_LONG) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_LONG) : int(Lexer::T_IDENTIFIER); } } } @@ -250,7 +262,7 @@ static inline int classify4(const QChar *s, bool qmlMode) { return Lexer::T_IDENTIFIER; } -static inline int classify5(const QChar *s, bool qmlMode) { +static inline int classify5(const QChar *s, int parseModeFlags) { if (s[0].unicode() == 'b') { if (s[1].unicode() == 'r') { if (s[2].unicode() == 'e') { @@ -305,7 +317,7 @@ static inline int classify5(const QChar *s, bool qmlMode) { if (s[2].unicode() == 'n') { if (s[3].unicode() == 'a') { if (s[4].unicode() == 'l') { - return qmlMode ? int(Lexer::T_FINAL) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_FINAL) : int(Lexer::T_IDENTIFIER); } } } @@ -314,7 +326,7 @@ static inline int classify5(const QChar *s, bool qmlMode) { if (s[2].unicode() == 'o') { if (s[3].unicode() == 'a') { if (s[4].unicode() == 't') { - return qmlMode ? int(Lexer::T_FLOAT) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_FLOAT) : int(Lexer::T_IDENTIFIER); } } } @@ -325,7 +337,7 @@ static inline int classify5(const QChar *s, bool qmlMode) { if (s[2].unicode() == 'o') { if (s[3].unicode() == 'r') { if (s[4].unicode() == 't') { - return qmlMode ? int(Lexer::T_SHORT) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_SHORT) : int(Lexer::T_IDENTIFIER); } } } @@ -334,7 +346,7 @@ static inline int classify5(const QChar *s, bool qmlMode) { if (s[2].unicode() == 'p') { if (s[3].unicode() == 'e') { if (s[4].unicode() == 'r') { - return qmlMode ? int(Lexer::T_SUPER) : int(Lexer::T_RESERVED_WORD); + return int(Lexer::T_SUPER); } } } @@ -362,10 +374,21 @@ static inline int classify5(const QChar *s, bool qmlMode) { } } } + else if (s[0].unicode() == 'y') { + if (s[1].unicode() == 'i') { + if (s[2].unicode() == 'e') { + if (s[3].unicode() == 'l') { + if (s[4].unicode() == 'd') { + return (parseModeFlags & Lexer::YieldIsKeyword) ? Lexer::T_YIELD : Lexer::T_IDENTIFIER; + } + } + } + } + } return Lexer::T_IDENTIFIER; } -static inline int classify6(const QChar *s, bool qmlMode) { +static inline int classify6(const QChar *s, int parseModeFlags) { if (s[0].unicode() == 'd') { if (s[1].unicode() == 'e') { if (s[2].unicode() == 'l') { @@ -383,7 +406,7 @@ static inline int classify6(const QChar *s, bool qmlMode) { if (s[3].unicode() == 'b') { if (s[4].unicode() == 'l') { if (s[5].unicode() == 'e') { - return qmlMode ? int(Lexer::T_DOUBLE) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_DOUBLE) : int(Lexer::T_IDENTIFIER); } } } @@ -409,7 +432,7 @@ static inline int classify6(const QChar *s, bool qmlMode) { if (s[3].unicode() == 'o') { if (s[4].unicode() == 'r') { if (s[5].unicode() == 't') { - return qmlMode ? int(Lexer::T_IMPORT) : int(Lexer::T_RESERVED_WORD); + return Lexer::T_IMPORT; } } } @@ -422,7 +445,7 @@ static inline int classify6(const QChar *s, bool qmlMode) { if (s[3].unicode() == 'i') { if (s[4].unicode() == 'v') { if (s[5].unicode() == 'e') { - return qmlMode ? int(Lexer::T_NATIVE) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_NATIVE) : int(Lexer::T_IDENTIFIER); } } } @@ -435,7 +458,7 @@ static inline int classify6(const QChar *s, bool qmlMode) { if (s[3].unicode() == 'l') { if (s[4].unicode() == 'i') { if (s[5].unicode() == 'c') { - return qmlMode ? Lexer::T_PUBLIC : Lexer::T_IDENTIFIER; + return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_PUBLIC : Lexer::T_IDENTIFIER; } } } @@ -446,7 +469,7 @@ static inline int classify6(const QChar *s, bool qmlMode) { if (s[3].unicode() == 'g') { if (s[4].unicode() == 'm') { if (s[5].unicode() == 'a') { - return qmlMode ? Lexer::T_PRAGMA : Lexer::T_IDENTIFIER; + return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_PRAGMA : Lexer::T_IDENTIFIER; } } } @@ -467,7 +490,7 @@ static inline int classify6(const QChar *s, bool qmlMode) { } } else if (s[0].unicode() == 's') { - if (qmlMode && s[1].unicode() == 'i') { + if ((parseModeFlags & Lexer::QmlMode) && s[1].unicode() == 'i') { if (s[2].unicode() == 'g') { if (s[3].unicode() == 'n') { if (s[4].unicode() == 'a') { @@ -483,7 +506,7 @@ static inline int classify6(const QChar *s, bool qmlMode) { if (s[3].unicode() == 't') { if (s[4].unicode() == 'i') { if (s[5].unicode() == 'c') { - return qmlMode ? int(Lexer::T_STATIC) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::StaticIsKeyword) ? int(Lexer::T_STATIC) : int(Lexer::T_IDENTIFIER); } } } @@ -507,7 +530,7 @@ static inline int classify6(const QChar *s, bool qmlMode) { if (s[3].unicode() == 'o') { if (s[4].unicode() == 'w') { if (s[5].unicode() == 's') { - return qmlMode ? int(Lexer::T_THROWS) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_THROWS) : int(Lexer::T_IDENTIFIER); } } } @@ -528,7 +551,7 @@ static inline int classify6(const QChar *s, bool qmlMode) { return Lexer::T_IDENTIFIER; } -static inline int classify7(const QChar *s, bool qmlMode) { +static inline int classify7(const QChar *s, int parseModeFlags) { if (s[0].unicode() == 'b') { if (s[1].unicode() == 'o') { if (s[2].unicode() == 'o') { @@ -536,7 +559,7 @@ static inline int classify7(const QChar *s, bool qmlMode) { if (s[4].unicode() == 'e') { if (s[5].unicode() == 'a') { if (s[6].unicode() == 'n') { - return qmlMode ? int(Lexer::T_BOOLEAN) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_BOOLEAN) : int(Lexer::T_IDENTIFIER); } } } @@ -596,7 +619,7 @@ static inline int classify7(const QChar *s, bool qmlMode) { if (s[4].unicode() == 'a') { if (s[5].unicode() == 'g') { if (s[6].unicode() == 'e') { - return qmlMode ? int(Lexer::T_PACKAGE) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_PACKAGE) : int(Lexer::T_IDENTIFIER); } } } @@ -609,7 +632,7 @@ static inline int classify7(const QChar *s, bool qmlMode) { if (s[4].unicode() == 'a') { if (s[5].unicode() == 't') { if (s[6].unicode() == 'e') { - return qmlMode ? int(Lexer::T_PRIVATE) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_PRIVATE) : int(Lexer::T_IDENTIFIER); } } } @@ -620,7 +643,7 @@ static inline int classify7(const QChar *s, bool qmlMode) { return Lexer::T_IDENTIFIER; } -static inline int classify8(const QChar *s, bool qmlMode) { +static inline int classify8(const QChar *s, int parseModeFlags) { if (s[0].unicode() == 'a') { if (s[1].unicode() == 'b') { if (s[2].unicode() == 's') { @@ -629,7 +652,7 @@ static inline int classify8(const QChar *s, bool qmlMode) { if (s[5].unicode() == 'a') { if (s[6].unicode() == 'c') { if (s[7].unicode() == 't') { - return qmlMode ? int(Lexer::T_ABSTRACT) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_ABSTRACT) : int(Lexer::T_IDENTIFIER); } } } @@ -689,7 +712,7 @@ static inline int classify8(const QChar *s, bool qmlMode) { } } } - else if (qmlMode && s[0].unicode() == 'p') { + else if ((parseModeFlags & Lexer::QmlMode) && s[0].unicode() == 'p') { if (s[1].unicode() == 'r') { if (s[2].unicode() == 'o') { if (s[3].unicode() == 'p') { @@ -706,7 +729,7 @@ static inline int classify8(const QChar *s, bool qmlMode) { } } } - else if (qmlMode && s[0].unicode() == 'r') { + else if ((parseModeFlags & Lexer::QmlMode) && s[0].unicode() == 'r') { if (s[1].unicode() == 'e') { if (s[2].unicode() == 'a') { if (s[3].unicode() == 'd') { @@ -731,7 +754,7 @@ static inline int classify8(const QChar *s, bool qmlMode) { if (s[5].unicode() == 'i') { if (s[6].unicode() == 'l') { if (s[7].unicode() == 'e') { - return qmlMode ? int(Lexer::T_VOLATILE) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_VOLATILE) : int(Lexer::T_IDENTIFIER); } } } @@ -743,7 +766,7 @@ static inline int classify8(const QChar *s, bool qmlMode) { return Lexer::T_IDENTIFIER; } -static inline int classify9(const QChar *s, bool qmlMode) { +static inline int classify9(const QChar *s, int parseModeFlags) { if (s[0].unicode() == 'i') { if (s[1].unicode() == 'n') { if (s[2].unicode() == 't') { @@ -753,7 +776,7 @@ static inline int classify9(const QChar *s, bool qmlMode) { if (s[6].unicode() == 'a') { if (s[7].unicode() == 'c') { if (s[8].unicode() == 'e') { - return qmlMode ? int(Lexer::T_INTERFACE) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_INTERFACE) : int(Lexer::T_IDENTIFIER); } } } @@ -772,7 +795,7 @@ static inline int classify9(const QChar *s, bool qmlMode) { if (s[6].unicode() == 't') { if (s[7].unicode() == 'e') { if (s[8].unicode() == 'd') { - return qmlMode ? int(Lexer::T_PROTECTED) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_PROTECTED) : int(Lexer::T_IDENTIFIER); } } } @@ -791,7 +814,7 @@ static inline int classify9(const QChar *s, bool qmlMode) { if (s[6].unicode() == 'e') { if (s[7].unicode() == 'n') { if (s[8].unicode() == 't') { - return qmlMode ? int(Lexer::T_TRANSIENT) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_TRANSIENT) : int(Lexer::T_IDENTIFIER); } } } @@ -804,7 +827,7 @@ static inline int classify9(const QChar *s, bool qmlMode) { return Lexer::T_IDENTIFIER; } -static inline int classify10(const QChar *s, bool qmlMode) { +static inline int classify10(const QChar *s, int parseModeFlags) { if (s[0].unicode() == 'i') { if (s[1].unicode() == 'm') { if (s[2].unicode() == 'p') { @@ -815,7 +838,7 @@ static inline int classify10(const QChar *s, bool qmlMode) { if (s[7].unicode() == 'n') { if (s[8].unicode() == 't') { if (s[9].unicode() == 's') { - return qmlMode ? int(Lexer::T_IMPLEMENTS) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_IMPLEMENTS) : int(Lexer::T_IDENTIFIER); } } } @@ -848,7 +871,7 @@ static inline int classify10(const QChar *s, bool qmlMode) { return Lexer::T_IDENTIFIER; } -static inline int classify12(const QChar *s, bool qmlMode) { +static inline int classify12(const QChar *s, int parseModeFlags) { if (s[0].unicode() == 's') { if (s[1].unicode() == 'y') { if (s[2].unicode() == 'n') { @@ -861,7 +884,7 @@ static inline int classify12(const QChar *s, bool qmlMode) { if (s[9].unicode() == 'z') { if (s[10].unicode() == 'e') { if (s[11].unicode() == 'd') { - return qmlMode ? int(Lexer::T_SYNCHRONIZED) : int(Lexer::T_IDENTIFIER); + return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_SYNCHRONIZED) : int(Lexer::T_IDENTIFIER); } } } @@ -877,18 +900,18 @@ static inline int classify12(const QChar *s, bool qmlMode) { return Lexer::T_IDENTIFIER; } -int Lexer::classify(const QChar *s, int n, bool qmlMode) { +int Lexer::classify(const QChar *s, int n, int parseModeFlags) { switch (n) { - case 2: return classify2(s, qmlMode); - case 3: return classify3(s, qmlMode); - case 4: return classify4(s, qmlMode); - case 5: return classify5(s, qmlMode); - case 6: return classify6(s, qmlMode); - case 7: return classify7(s, qmlMode); - case 8: return classify8(s, qmlMode); - case 9: return classify9(s, qmlMode); - case 10: return classify10(s, qmlMode); - case 12: return classify12(s, qmlMode); + case 2: return classify2(s, parseModeFlags); + case 3: return classify3(s, parseModeFlags); + case 4: return classify4(s, parseModeFlags); + case 5: return classify5(s, parseModeFlags); + case 6: return classify6(s, parseModeFlags); + case 7: return classify7(s, parseModeFlags); + case 8: return classify8(s, parseModeFlags); + case 9: return classify9(s, parseModeFlags); + case 10: return classify10(s, parseModeFlags); + case 12: return classify12(s, parseModeFlags); default: return Lexer::T_IDENTIFIER; } // switch } diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp index 53e67fde03..c53b13f64d 100644 --- a/src/qml/parser/qqmljslexer.cpp +++ b/src/qml/parser/qqmljslexer.cpp @@ -58,6 +58,8 @@ static inline int regExpFlagFromChar(const QChar &ch) case 'g': return Lexer::RegExp_Global; case 'i': return Lexer::RegExp_IgnoreCase; case 'm': return Lexer::RegExp_Multiline; + case 'u': return Lexer::RegExp_Unicode; + case 'y': return Lexer::RegExp_Sticky; } return 0; } @@ -77,21 +79,15 @@ static inline QChar convertHex(QChar c1, QChar c2) return QChar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode())); } -static inline QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4) -{ - return QChar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode()), - (convertHex(c1.unicode()) << 4) + convertHex(c2.unicode())); -} - Lexer::Lexer(Engine *engine) : _engine(engine) - , _codePtr(0) - , _lastLinePtr(0) - , _tokenLinePtr(0) - , _tokenStartPtr(0) + , _codePtr(nullptr) + , _endPtr(nullptr) + , _tokenStartPtr(nullptr) , _char(QLatin1Char('\n')) , _errorCode(NoError) , _currentLineNumber(0) + , _currentColumnNumber(0) , _tokenValue(0) , _parenthesesState(IgnoreParentheses) , _parenthesesCount(0) @@ -100,6 +96,7 @@ Lexer::Lexer(Engine *engine) , _tokenKind(0) , _tokenLength(0) , _tokenLine(0) + , _tokenColumn(0) , _validTokenText(false) , _prohibitAutomaticSemicolon(false) , _restrictedKeyword(false) @@ -133,17 +130,17 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode) _tokenText.reserve(1024); _errorMessage.clear(); _tokenSpell = QStringRef(); + _rawString = QStringRef(); _codePtr = code.unicode(); _endPtr = _codePtr + code.length(); - _lastLinePtr = _codePtr; - _tokenLinePtr = _codePtr; _tokenStartPtr = _codePtr; _char = QLatin1Char('\n'); _errorCode = NoError; _currentLineNumber = lineno; + _currentColumnNumber = 0; _tokenValue = 0; // parentheses state @@ -155,6 +152,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode) _patternFlags = 0; _tokenLength = 0; _tokenLine = lineno; + _tokenColumn = 0; _validTokenText = false; _prohibitAutomaticSemicolon = false; @@ -166,14 +164,22 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode) void Lexer::scanChar() { - unsigned sequenceLength = isLineTerminatorSequence(); + if (_skipLinefeed) { + Q_ASSERT(*_codePtr == QLatin1Char('\n')); + ++_codePtr; + _skipLinefeed = false; + } _char = *_codePtr++; - if (sequenceLength == 2) - _char = *_codePtr++; + ++_currentColumnNumber; - if (unsigned sequenceLength = isLineTerminatorSequence()) { - _lastLinePtr = _codePtr + sequenceLength - 1; // points to the first character after the newline + if (isLineTerminator()) { + if (_char == QLatin1Char('\r')) { + if (_codePtr < _endPtr && *_codePtr == QLatin1Char('\n')) + _skipLinefeed = true; + _char = QLatin1Char('\n'); + } ++_currentLineNumber; + _currentColumnNumber = 0; } } @@ -221,13 +227,34 @@ inline bool isBinop(int tok) return false; } } + +int hexDigit(QChar c) +{ + if (c >= QLatin1Char('0') && c <= QLatin1Char('9')) + return c.unicode() - '0'; + if (c >= QLatin1Char('a') && c <= QLatin1Char('f')) + return c.unicode() - 'a' + 10; + if (c >= QLatin1Char('A') && c <= QLatin1Char('F')) + return c.unicode() - 'A' + 10; + return -1; +} + +int octalDigit(QChar c) +{ + if (c >= QLatin1Char('0') && c <= QLatin1Char('7')) + return c.unicode() - '0'; + return -1; +} + } // anonymous namespace int Lexer::lex() { const int previousTokenKind = _tokenKind; + again: _tokenSpell = QStringRef(); + _rawString = QStringRef(); _tokenKind = scanToken(); _tokenLength = _codePtr - _tokenStartPtr - 1; @@ -238,6 +265,9 @@ int Lexer::lex() // update the flags switch (_tokenKind) { case T_LBRACE: + if (_bracesCount > 0) + ++_bracesCount; + Q_FALLTHROUGH(); case T_SEMICOLON: case T_QUESTION: case T_COLON: @@ -265,9 +295,15 @@ int Lexer::lex() case T_CONTINUE: case T_BREAK: case T_RETURN: + case T_YIELD: case T_THROW: _restrictedKeyword = true; break; + case T_RBRACE: + if (_bracesCount > 0) + --_bracesCount; + if (_bracesCount == 0) + goto again; } // switch // update the parentheses state @@ -294,39 +330,57 @@ int Lexer::lex() return _tokenKind; } -bool Lexer::isUnicodeEscapeSequence(const QChar *chars) -{ - if (isHexDigit(chars[0]) && isHexDigit(chars[1]) && isHexDigit(chars[2]) && isHexDigit(chars[3])) - return true; - - return false; -} - -QChar Lexer::decodeUnicodeEscapeCharacter(bool *ok) +uint Lexer::decodeUnicodeEscapeCharacter(bool *ok) { - if (_char == QLatin1Char('u') && isUnicodeEscapeSequence(&_codePtr[0])) { - scanChar(); // skip u + Q_ASSERT(_char == QLatin1Char('u')); + scanChar(); // skip u + if (_codePtr + 4 <= _endPtr && isHexDigit(_char)) { + uint codePoint = 0; + for (int i = 0; i < 4; ++i) { + int digit = hexDigit(_char); + if (digit < 0) + goto error; + codePoint *= 16; + codePoint += digit; + scanChar(); + } - const QChar c1 = _char; - scanChar(); + *ok = true; + return codePoint; + } else if (_codePtr < _endPtr && _char == QLatin1Char('{')) { + scanChar(); // skip '{' + uint codePoint = 0; + if (!isHexDigit(_char)) + // need at least one hex digit + goto error; - const QChar c2 = _char; - scanChar(); + while (_codePtr <= _endPtr) { + int digit = hexDigit(_char); + if (digit < 0) + break; + codePoint *= 16; + codePoint += digit; + if (codePoint > 0x10ffff) + goto error; + scanChar(); + } - const QChar c3 = _char; - scanChar(); + if (_char != QLatin1Char('}')) + goto error; - const QChar c4 = _char; - scanChar(); + scanChar(); // skip '}' - if (ok) - *ok = true; - return convertUnicode(c1, c2, c3, c4); + *ok = true; + return codePoint; } + error: + _errorCode = IllegalUnicodeEscapeSequence; + _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence"); + *ok = false; - return QChar(); + return 0; } QChar Lexer::decodeHexEscapeCharacter(bool *ok) @@ -350,15 +404,15 @@ QChar Lexer::decodeHexEscapeCharacter(bool *ok) return QChar(); } -static inline bool isIdentifierStart(QChar ch) +static inline bool isIdentifierStart(uint ch) { // fast path for ascii - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || - (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || + if ((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || ch == '$' || ch == '_') return true; - switch (ch.category()) { + switch (QChar::category(ch)) { case QChar::Number_Letter: case QChar::Letter_Uppercase: case QChar::Letter_Lowercase: @@ -372,17 +426,17 @@ static inline bool isIdentifierStart(QChar ch) return false; } -static bool isIdentifierPart(QChar ch) +static bool isIdentifierPart(uint ch) { // fast path for ascii - if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || - (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || - (ch.unicode() >= '0' && ch.unicode() <= '9') || + if ((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9') || ch == '$' || ch == '_' || - ch.unicode() == 0x200c /* ZWNJ */ || ch.unicode() == 0x200d /* ZWJ */) + ch == 0x200c /* ZWNJ */ || ch == 0x200d /* ZWJ */) return true; - switch (ch.category()) { + switch (QChar::category(ch)) { case QChar::Mark_NonSpacing: case QChar::Mark_SpacingCombining: @@ -411,19 +465,23 @@ int Lexer::scanToken() return tk; } + if (_bracesCount == 0) { + // we're inside a Template string + return scanString(TemplateContinuation); + } + + _terminator = false; again: _validTokenText = false; - _tokenLinePtr = _lastLinePtr; while (_char.isSpace()) { - if (unsigned sequenceLength = isLineTerminatorSequence()) { - _tokenLinePtr = _codePtr + sequenceLength - 1; - + if (isLineTerminator()) { if (_restrictedKeyword) { // automatic semicolon insertion _tokenLine = _currentLineNumber; + _tokenColumn = _currentColumnNumber; _tokenStartPtr = _codePtr - 1; return T_SEMICOLON; } else { @@ -437,6 +495,7 @@ again: _tokenStartPtr = _codePtr - 1; _tokenLine = _currentLineNumber; + _tokenColumn = _currentColumnNumber; if (_codePtr > _endPtr) return EOF_SYMBOL; @@ -500,6 +559,9 @@ again: return T_EQ_EQ_EQ; } return T_EQ_EQ; + } else if (_char == QLatin1Char('>')) { + scanChar(); + return T_ARROW; } return T_EQ; @@ -556,50 +618,18 @@ again: return T_DIVIDE_; case '.': - if (_char.isDigit()) { - QVarLengthArray<char,32> chars; - - chars.append(ch.unicode()); // append the `.' - - while (_char.isDigit()) { - chars.append(_char.unicode()); + if (isDecimalDigit(_char.unicode())) + return scanNumber(ch); + if (_char == QLatin1Char('.')) { + scanChar(); + if (_char == QLatin1Char('.')) { scanChar(); - } - - if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { - if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && - _codePtr[1].isDigit())) { - - chars.append(_char.unicode()); - scanChar(); // consume `e' - - if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) { - chars.append(_char.unicode()); - scanChar(); // consume the sign - } - - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); - } - } - } - - chars.append('\0'); - - const char *begin = chars.constData(); - const char *end = 0; - bool ok = false; - - _tokenValue = qstrtod(begin, &end, &ok); - - if (end - begin != chars.size() - 1) { - _errorCode = IllegalExponentIndicator; - _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal syntax for exponential number"); + return T_ELLIPSIS; + } else { + _errorCode = IllegalCharacter; + _errorMessage = QCoreApplication::translate("QQmlParser", "Unexpected token '.'"); return T_ERROR; } - - return T_NUMERIC_LITERAL; } return T_DOT; @@ -610,7 +640,7 @@ again: } else if (_char == QLatin1Char('-')) { scanChar(); - if (_terminator && !_delimited && !_prohibitAutomaticSemicolon) { + if (_terminator && !_delimited && !_prohibitAutomaticSemicolon && _tokenKind != T_LPAREN) { _stackToken = T_MINUS_MINUS; return T_SEMICOLON; } @@ -628,7 +658,7 @@ again: } else if (_char == QLatin1Char('+')) { scanChar(); - if (_terminator && !_delimited && !_prohibitAutomaticSemicolon) { + if (_terminator && !_delimited && !_prohibitAutomaticSemicolon && _tokenKind != T_LPAREN) { _stackToken = T_PLUS_PLUS; return T_SEMICOLON; } @@ -641,6 +671,13 @@ again: if (_char == QLatin1Char('=')) { scanChar(); return T_STAR_EQ; + } else if (_char == QLatin1Char('*')) { + scanChar(); + if (_char == QLatin1Char('=')) { + scanChar(); + return T_STAR_STAR_EQ; + } + return T_STAR_STAR; } return T_STAR; @@ -675,141 +712,12 @@ again: } return T_NOT; + case '`': + _outerTemplateBraceCount.push(_bracesCount); + Q_FALLTHROUGH(); case '\'': - case '"': { - const QChar quote = ch; - bool multilineStringLiteral = false; - - const QChar *startCode = _codePtr; - - if (_engine) { - while (_codePtr <= _endPtr) { - if (isLineTerminator()) { - if (qmlMode()) - break; - _errorCode = IllegalCharacter; - _errorMessage = QCoreApplication::translate("QQmlParser", "Stray newline in string literal"); - return T_ERROR; - } else if (_char == QLatin1Char('\\')) { - break; - } else if (_char == quote) { - _tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode); - scanChar(); - - return T_STRING_LITERAL; - } - scanChar(); - } - } - - _validTokenText = true; - _tokenText.resize(0); - startCode--; - while (startCode != _codePtr - 1) - _tokenText += *startCode++; - - while (_codePtr <= _endPtr) { - if (unsigned sequenceLength = isLineTerminatorSequence()) { - multilineStringLiteral = true; - _tokenText += _char; - if (sequenceLength == 2) - _tokenText += *_codePtr; - scanChar(); - } else if (_char == quote) { - scanChar(); - - if (_engine) - _tokenSpell = _engine->newStringRef(_tokenText); - - return multilineStringLiteral ? T_MULTILINE_STRING_LITERAL : T_STRING_LITERAL; - } else if (_char == QLatin1Char('\\')) { - scanChar(); - if (_codePtr > _endPtr) { - _errorCode = IllegalEscapeSequence; - _errorMessage = QCoreApplication::translate("QQmlParser", "End of file reached at escape sequence"); - return T_ERROR; - } - - QChar u; - - switch (_char.unicode()) { - // unicode escape sequence - case 'u': { - bool ok = false; - u = decodeUnicodeEscapeCharacter(&ok); - if (! ok) { - _errorCode = IllegalUnicodeEscapeSequence; - _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence"); - return T_ERROR; - } - } break; - - // hex escape sequence - case 'x': { - bool ok = false; - u = decodeHexEscapeCharacter(&ok); - if (!ok) { - _errorCode = IllegalHexadecimalEscapeSequence; - _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal hexadecimal escape sequence"); - return T_ERROR; - } - } break; - - // single character escape sequence - case '\\': u = QLatin1Char('\\'); scanChar(); break; - case '\'': u = QLatin1Char('\''); scanChar(); break; - case '\"': u = QLatin1Char('\"'); scanChar(); break; - case 'b': u = QLatin1Char('\b'); scanChar(); break; - case 'f': u = QLatin1Char('\f'); scanChar(); break; - case 'n': u = QLatin1Char('\n'); scanChar(); break; - case 'r': u = QLatin1Char('\r'); scanChar(); break; - case 't': u = QLatin1Char('\t'); scanChar(); break; - case 'v': u = QLatin1Char('\v'); scanChar(); break; - - case '0': - if (! _codePtr->isDigit()) { - scanChar(); - u = QLatin1Char('\0'); - break; - } - // fall through - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - _errorCode = IllegalEscapeSequence; - _errorMessage = QCoreApplication::translate("QQmlParser", "Octal escape sequences are not allowed"); - return T_ERROR; - - case '\r': - case '\n': - case 0x2028u: - case 0x2029u: - scanChar(); - continue; - - default: - // non escape character - u = _char; - scanChar(); - } - - _tokenText += u; - } else { - _tokenText += _char; - scanChar(); - } - } - - _errorCode = UnclosedStringLiteral; - _errorMessage = QCoreApplication::translate("QQmlParser", "Unclosed string at end of line"); - return T_ERROR; - } + case '"': + return scanString(ScanStringMode(ch.unicode())); case '0': case '1': case '2': @@ -823,28 +731,36 @@ again: return scanNumber(ch); default: { - QChar c = ch; + uint c = ch.unicode(); bool identifierWithEscapeChars = false; - if (c == QLatin1Char('\\') && _char == QLatin1Char('u')) { + if (QChar::isHighSurrogate(c) && QChar::isLowSurrogate(_char.unicode())) { + c = QChar::surrogateToUcs4(ushort(c), _char.unicode()); + scanChar(); + } else if (c == '\\' && _char == QLatin1Char('u')) { identifierWithEscapeChars = true; bool ok = false; c = decodeUnicodeEscapeCharacter(&ok); - if (! ok) { - _errorCode = IllegalUnicodeEscapeSequence; - _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence"); + if (!ok) return T_ERROR; - } } if (isIdentifierStart(c)) { if (identifierWithEscapeChars) { _tokenText.resize(0); - _tokenText += c; + if (QChar::requiresSurrogates(c)) { + _tokenText += QChar(QChar::highSurrogate(c)); + _tokenText += QChar(QChar::lowSurrogate(c)); + } else { + _tokenText += QChar(c); + } _validTokenText = true; } - while (true) { - c = _char; - if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) { - if (! identifierWithEscapeChars) { + while (_codePtr <= _endPtr) { + c = _char.unicode(); + if (QChar::isHighSurrogate(c) && QChar::isLowSurrogate(_codePtr->unicode())) { + scanChar(); + c = QChar::surrogateToUcs4(ushort(c), _char.unicode()); + } else if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) { + if (!identifierWithEscapeChars) { identifierWithEscapeChars = true; _tokenText.resize(0); _tokenText.insert(0, _tokenStartPtr, _codePtr - _tokenStartPtr - 1); @@ -854,38 +770,52 @@ again: scanChar(); // skip '\\' bool ok = false; c = decodeUnicodeEscapeCharacter(&ok); - if (! ok) { - _errorCode = IllegalUnicodeEscapeSequence; - _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence"); + if (!ok) return T_ERROR; - } - if (isIdentifierPart(c)) - _tokenText += c; - continue; - } else if (isIdentifierPart(c)) { - if (identifierWithEscapeChars) - _tokenText += c; - scanChar(); + if (!isIdentifierPart(c)) + break; + + if (identifierWithEscapeChars) { + if (QChar::requiresSurrogates(c)) { + _tokenText += QChar(QChar::highSurrogate(c)); + _tokenText += QChar(QChar::lowSurrogate(c)); + } else { + _tokenText += QChar(c); + } + } continue; } - _tokenLength = _codePtr - _tokenStartPtr - 1; + if (!isIdentifierPart(c)) + break; - int kind = T_IDENTIFIER; + if (identifierWithEscapeChars) { + if (QChar::requiresSurrogates(c)) { + _tokenText += QChar(QChar::highSurrogate(c)); + _tokenText += QChar(QChar::lowSurrogate(c)); + } else { + _tokenText += QChar(c); + } + } + scanChar(); + } - if (! identifierWithEscapeChars) - kind = classify(_tokenStartPtr, _tokenLength, _qmlMode); + _tokenLength = _codePtr - _tokenStartPtr - 1; - if (_engine) { - if (kind == T_IDENTIFIER && identifierWithEscapeChars) - _tokenSpell = _engine->newStringRef(_tokenText); - else - _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength); - } + int kind = T_IDENTIFIER; - return kind; + if (!identifierWithEscapeChars) + kind = classify(_tokenStartPtr, _tokenLength, parseModeFlags()); + + if (_engine) { + if (kind == T_IDENTIFIER && identifierWithEscapeChars) + _tokenSpell = _engine->newStringRef(_tokenText); + else + _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength); } + + return kind; } } @@ -895,93 +825,292 @@ again: return T_ERROR; } -int Lexer::scanNumber(QChar ch) +int Lexer::scanString(ScanStringMode mode) { - if (ch != QLatin1Char('0')) { - QVarLengthArray<char, 64> buf; - buf += ch.toLatin1(); - - QChar n = _char; - const QChar *code = _codePtr; - while (n.isDigit()) { - buf += n.toLatin1(); - n = *code++; - } + QChar quote = (mode == TemplateContinuation) ? QChar(TemplateHead) : QChar(mode); + bool multilineStringLiteral = false; + + const QChar *startCode = _codePtr - 1; + // in case we just parsed a \r, we need to reset this flag to get things working + // correctly in the loop below and afterwards + _skipLinefeed = false; - if (n != QLatin1Char('.') && n != QLatin1Char('e') && n != QLatin1Char('E')) { - if (code != _codePtr) { - _codePtr = code - 1; + if (_engine) { + while (_codePtr <= _endPtr) { + if (isLineTerminator()) { + if ((quote == QLatin1Char('`') || qmlMode())) + break; + _errorCode = IllegalCharacter; + _errorMessage = QCoreApplication::translate("QQmlParser", "Stray newline in string literal"); + return T_ERROR; + } else if (_char == QLatin1Char('\\')) { + break; + } else if (_char == '$' && quote == QLatin1Char('`')) { + break; + } else if (_char == quote) { + _tokenSpell = _engine->midRef(startCode - _code.unicode(), _codePtr - startCode - 1); + _rawString = _tokenSpell; scanChar(); + + if (quote == QLatin1Char('`')) + _bracesCount = _outerTemplateBraceCount.pop(); + + if (mode == TemplateHead) + return T_NO_SUBSTITUTION_TEMPLATE; + else if (mode == TemplateContinuation) + return T_TEMPLATE_TAIL; + else + return T_STRING_LITERAL; } - buf.append('\0'); - _tokenValue = strtod(buf.constData(), 0); - return T_NUMERIC_LITERAL; + // don't use scanChar() here, that would transform \r sequences and the midRef() call would create the wrong result + _char = *_codePtr++; + ++_currentColumnNumber; } - } else if (_char.isDigit() && !qmlMode()) { - _errorCode = IllegalCharacter; - _errorMessage = QCoreApplication::translate("QQmlParser", "Decimal numbers can't start with '0'"); - return T_ERROR; } - QVarLengthArray<char,32> chars; - chars.append(ch.unicode()); + // rewind by one char, so things gets scanned correctly + --_codePtr; - if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) { - ch = _char; // remember the x or X to use it in the error message below. + _validTokenText = true; + _tokenText = QString(startCode, _codePtr - startCode); - // parse hex integer literal - chars.append(_char.unicode()); - scanChar(); // consume `x' + auto setRawString = [&](const QChar *end) { + QString raw(startCode, end - startCode - 1); + raw.replace(QLatin1String("\r\n"), QLatin1String("\n")); + raw.replace(QLatin1Char('\r'), QLatin1Char('\n')); + _rawString = _engine->newStringRef(raw); + }; - while (isHexDigit(_char)) { - chars.append(_char.unicode()); + scanChar(); + + while (_codePtr <= _endPtr) { + if (_char == quote) { + scanChar(); + + if (_engine) { + _tokenSpell = _engine->newStringRef(_tokenText); + if (quote == QLatin1Char('`')) + setRawString(_codePtr - 1); + } + + if (quote == QLatin1Char('`')) + _bracesCount = _outerTemplateBraceCount.pop(); + + if (mode == TemplateContinuation) + return T_TEMPLATE_TAIL; + else if (mode == TemplateHead) + return T_NO_SUBSTITUTION_TEMPLATE; + + return multilineStringLiteral ? T_MULTILINE_STRING_LITERAL : T_STRING_LITERAL; + } else if (quote == QLatin1Char('`') && _char == QLatin1Char('$') && *_codePtr == '{') { + scanChar(); + scanChar(); + _bracesCount = 1; + if (_engine) { + _tokenSpell = _engine->newStringRef(_tokenText); + setRawString(_codePtr - 2); + } + + return (mode == TemplateHead ? T_TEMPLATE_HEAD : T_TEMPLATE_MIDDLE); + } else if (_char == QLatin1Char('\\')) { + scanChar(); + if (_codePtr > _endPtr) { + _errorCode = IllegalEscapeSequence; + _errorMessage = QCoreApplication::translate("QQmlParser", "End of file reached at escape sequence"); + return T_ERROR; + } + + QChar u; + + switch (_char.unicode()) { + // unicode escape sequence + case 'u': { + bool ok = false; + uint codePoint = decodeUnicodeEscapeCharacter(&ok); + if (!ok) + return T_ERROR; + if (QChar::requiresSurrogates(codePoint)) { + // need to use a surrogate pair + _tokenText += QChar(QChar::highSurrogate(codePoint)); + u = QChar::lowSurrogate(codePoint); + } else { + u = codePoint; + } + } break; + + // hex escape sequence + case 'x': { + bool ok = false; + u = decodeHexEscapeCharacter(&ok); + if (!ok) { + _errorCode = IllegalHexadecimalEscapeSequence; + _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal hexadecimal escape sequence"); + return T_ERROR; + } + } break; + + // single character escape sequence + case '\\': u = QLatin1Char('\\'); scanChar(); break; + case '\'': u = QLatin1Char('\''); scanChar(); break; + case '\"': u = QLatin1Char('\"'); scanChar(); break; + case 'b': u = QLatin1Char('\b'); scanChar(); break; + case 'f': u = QLatin1Char('\f'); scanChar(); break; + case 'n': u = QLatin1Char('\n'); scanChar(); break; + case 'r': u = QLatin1Char('\r'); scanChar(); break; + case 't': u = QLatin1Char('\t'); scanChar(); break; + case 'v': u = QLatin1Char('\v'); scanChar(); break; + + case '0': + if (! _codePtr->isDigit()) { + scanChar(); + u = QLatin1Char('\0'); + break; + } + Q_FALLTHROUGH(); + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + _errorCode = IllegalEscapeSequence; + _errorMessage = QCoreApplication::translate("QQmlParser", "Octal escape sequences are not allowed"); + return T_ERROR; + + case '\r': + case '\n': + case 0x2028u: + case 0x2029u: + scanChar(); + continue; + + default: + // non escape character + u = _char; + scanChar(); + } + + _tokenText += u; + } else { + _tokenText += _char; scanChar(); } + } + + _errorCode = UnclosedStringLiteral; + _errorMessage = QCoreApplication::translate("QQmlParser", "Unclosed string at end of line"); + return T_ERROR; +} + +int Lexer::scanNumber(QChar ch) +{ + if (ch == QLatin1Char('0')) { + if (_char == QLatin1Char('x') || _char == QLatin1Char('X')) { + ch = _char; // remember the x or X to use it in the error message below. + + // parse hex integer literal + scanChar(); // consume 'x' + + if (!isHexDigit(_char)) { + _errorCode = IllegalNumber; + _errorMessage = QCoreApplication::translate("QQmlParser", "At least one hexadecimal digit is required after '0%1'").arg(ch); + return T_ERROR; + } + + double d = 0.; + while (1) { + int digit = ::hexDigit(_char); + if (digit < 0) + break; + d *= 16; + d += digit; + scanChar(); + } + + _tokenValue = d; + return T_NUMERIC_LITERAL; + } else if (_char == QLatin1Char('o') || _char == QLatin1Char('O')) { + ch = _char; // remember the o or O to use it in the error message below. - if (chars.size() < 3) { - _errorCode = IllegalHexNumber; - _errorMessage = QCoreApplication::translate("QQmlParser", "At least one hexadecimal digit is required after '0%1'").arg(ch); + // parse octal integer literal + scanChar(); // consume 'o' + + if (!isOctalDigit(_char.unicode())) { + _errorCode = IllegalNumber; + _errorMessage = QCoreApplication::translate("QQmlParser", "At least one octal digit is required after '0%1'").arg(ch); + return T_ERROR; + } + + double d = 0.; + while (1) { + int digit = ::octalDigit(_char); + if (digit < 0) + break; + d *= 8; + d += digit; + scanChar(); + } + + _tokenValue = d; + return T_NUMERIC_LITERAL; + } else if (_char == QLatin1Char('b') || _char == QLatin1Char('B')) { + ch = _char; // remember the b or B to use it in the error message below. + + // parse binary integer literal + scanChar(); // consume 'b' + + if (_char.unicode() != '0' && _char.unicode() != '1') { + _errorCode = IllegalNumber; + _errorMessage = QCoreApplication::translate("QQmlParser", "At least one binary digit is required after '0%1'").arg(ch); + return T_ERROR; + } + + double d = 0.; + while (1) { + int digit = 0; + if (_char.unicode() == '1') + digit = 1; + else if (_char.unicode() != '0') + break; + d *= 2; + d += digit; + scanChar(); + } + + _tokenValue = d; + return T_NUMERIC_LITERAL; + } else if (_char.isDigit() && !qmlMode()) { + _errorCode = IllegalCharacter; + _errorMessage = QCoreApplication::translate("QQmlParser", "Decimal numbers can't start with '0'"); return T_ERROR; } - - _tokenValue = integerFromString(chars.constData(), chars.size(), 16); - return T_NUMERIC_LITERAL; } // decimal integer literal - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); // consume the digit - } - - if (_char == QLatin1Char('.')) { - chars.append(_char.unicode()); - scanChar(); // consume `.' + QVarLengthArray<char,32> chars; + chars.append(ch.unicode()); + if (ch != QLatin1Char('.')) { while (_char.isDigit()) { chars.append(_char.unicode()); - scanChar(); + scanChar(); // consume the digit } - if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { - if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && - _codePtr[1].isDigit())) { - - chars.append(_char.unicode()); - scanChar(); // consume `e' + if (_char == QLatin1Char('.')) { + chars.append(_char.unicode()); + scanChar(); // consume `.' + } + } - if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) { - chars.append(_char.unicode()); - scanChar(); // consume the sign - } + while (_char.isDigit()) { + chars.append(_char.unicode()); + scanChar(); + } - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); - } - } - } - } else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { + if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && _codePtr[1].isDigit())) { @@ -1000,16 +1129,10 @@ int Lexer::scanNumber(QChar ch) } } - if (chars.length() == 1) { - // if we ended up with a single digit, then it was a '0' - _tokenValue = 0; - return T_NUMERIC_LITERAL; - } - chars.append('\0'); const char *begin = chars.constData(); - const char *end = 0; + const char *end = nullptr; bool ok = false; _tokenValue = qstrtod(begin, &end, &ok); @@ -1173,16 +1296,6 @@ bool Lexer::isOctalDigit(ushort c) return (c >= '0' && c <= '7'); } -int Lexer::tokenEndLine() const -{ - return _currentLineNumber; -} - -int Lexer::tokenEndColumn() const -{ - return _codePtr - _lastLinePtr; -} - QString Lexer::tokenText() const { if (_validTokenText) @@ -1255,6 +1368,7 @@ static const int uriTokens[] = { QQmlJSGrammar::T_FUNCTION, QQmlJSGrammar::T_IF, QQmlJSGrammar::T_IN, + QQmlJSGrammar::T_OF, QQmlJSGrammar::T_INSTANCEOF, QQmlJSGrammar::T_NEW, QQmlJSGrammar::T_NULL, @@ -1301,7 +1415,7 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error) lex(); // skip T_DOT - if (! (_tokenKind == T_IDENTIFIER || _tokenKind == T_RESERVED_WORD)) + if (! (_tokenKind == T_IDENTIFIER || _tokenKind == T_IMPORT)) return true; // expected a valid QML/JS directive const QString directiveName = tokenText(); @@ -1395,7 +1509,7 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error) // // recognize the mandatory `as' followed by the module name // - if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("as") && tokenStartLine() == lineNumber)) { + if (! (lex() == T_AS && tokenStartLine() == lineNumber)) { if (fileImport) error->message = QCoreApplication::translate("QQmlParser", "File import requires a qualifier"); else diff --git a/src/qml/parser/qqmljslexer_p.h b/src/qml/parser/qqmljslexer_p.h index af5597b625..03f33f6e06 100644 --- a/src/qml/parser/qqmljslexer_p.h +++ b/src/qml/parser/qqmljslexer_p.h @@ -51,10 +51,11 @@ // We mean it. // -#include "qqmljsglobal_p.h" -#include "qqmljsgrammar_p.h" +#include <private/qqmljsglobal_p.h> +#include <private/qqmljsgrammar_p.h> #include <QtCore/qstring.h> +#include <QtCore/qstack.h> QT_QML_BEGIN_NAMESPACE @@ -62,32 +63,7 @@ namespace QQmlJS { class Engine; class DiagnosticMessage; - -class QML_PARSER_EXPORT Directives { -public: - virtual ~Directives() {} - - virtual void pragmaLibrary() - { - } - - virtual void importFile(const QString &jsfile, const QString &module, int line, int column) - { - Q_UNUSED(jsfile); - Q_UNUSED(module); - Q_UNUSED(line); - Q_UNUSED(column); - } - - virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column) - { - Q_UNUSED(uri); - Q_UNUSED(version); - Q_UNUSED(module); - Q_UNUSED(line); - Q_UNUSED(column); - } -}; +class Directives; class QML_PARSER_EXPORT Lexer: public QQmlJSGrammar { @@ -97,11 +73,7 @@ public: T_BOOLEAN = T_RESERVED_WORD, T_BYTE = T_RESERVED_WORD, T_CHAR = T_RESERVED_WORD, - T_CLASS = T_RESERVED_WORD, T_DOUBLE = T_RESERVED_WORD, - T_ENUM = T_RESERVED_WORD, - T_EXPORT = T_RESERVED_WORD, - T_EXTENDS = T_RESERVED_WORD, T_FINAL = T_RESERVED_WORD, T_FLOAT = T_RESERVED_WORD, T_GOTO = T_RESERVED_WORD, @@ -114,8 +86,6 @@ public: T_PRIVATE = T_RESERVED_WORD, T_PROTECTED = T_RESERVED_WORD, T_SHORT = T_RESERVED_WORD, - T_STATIC = T_RESERVED_WORD, - T_SUPER = T_RESERVED_WORD, T_SYNCHRONIZED = T_RESERVED_WORD, T_THROWS = T_RESERVED_WORD, T_TRANSIENT = T_RESERVED_WORD, @@ -125,7 +95,7 @@ public: enum Error { NoError, IllegalCharacter, - IllegalHexNumber, + IllegalNumber, UnclosedStringLiteral, IllegalEscapeSequence, IllegalUnicodeEscapeSequence, @@ -143,13 +113,34 @@ public: enum RegExpFlag { RegExp_Global = 0x01, RegExp_IgnoreCase = 0x02, - RegExp_Multiline = 0x04 + RegExp_Multiline = 0x04, + RegExp_Unicode = 0x08, + RegExp_Sticky = 0x10 + }; + + enum ParseModeFlags { + QmlMode = 0x1, + YieldIsKeyword = 0x2, + StaticIsKeyword = 0x4 }; public: Lexer(Engine *engine); + int parseModeFlags() const { + int flags = 0; + if (qmlMode()) + flags |= QmlMode|StaticIsKeyword; + if (yieldIsKeyWord()) + flags |= YieldIsKeyword; + if (_staticIsKeyword) + flags |= StaticIsKeyword; + return flags; + } + bool qmlMode() const; + bool yieldIsKeyWord() const { return _generatorLevel != 0; } + void setStaticIsKeyword(bool b) { _staticIsKeyword = b; } QString code() const; void setCode(const QString &code, int lineno, bool qmlMode = true); @@ -167,12 +158,10 @@ public: int tokenLength() const { return _tokenLength; } int tokenStartLine() const { return _tokenLine; } - int tokenStartColumn() const { return _tokenStartPtr - _tokenLinePtr + 1; } - - int tokenEndLine() const; - int tokenEndColumn() const; + int tokenStartColumn() const { return _tokenColumn; } inline QStringRef tokenSpell() const { return _tokenSpell; } + inline QStringRef rawString() const { return _rawString; } double tokenValue() const { return _tokenValue; } QString tokenText() const; @@ -189,13 +178,23 @@ public: BalancedParentheses }; + void enterGeneratorBody() { ++_generatorLevel; } + void leaveGeneratorBody() { --_generatorLevel; } + protected: - int classify(const QChar *s, int n, bool qmlMode); + static int classify(const QChar *s, int n, int parseModeFlags); private: inline void scanChar(); int scanToken(); int scanNumber(QChar ch); + enum ScanStringMode { + SingleQuote = '\'', + DoubleQuote = '"', + TemplateHead = '`', + TemplateContinuation = 0 + }; + int scanString(ScanStringMode mode); bool isLineTerminator() const; unsigned isLineTerminatorSequence() const; @@ -203,10 +202,9 @@ private: static bool isDecimalDigit(ushort c); static bool isHexDigit(QChar c); static bool isOctalDigit(ushort c); - static bool isUnicodeEscapeSequence(const QChar *chars); void syncProhibitAutomaticSemicolon(); - QChar decodeUnicodeEscapeCharacter(bool *ok); + uint decodeUnicodeEscapeCharacter(bool *ok); QChar decodeHexEscapeCharacter(bool *ok); private: @@ -216,29 +214,34 @@ private: QString _tokenText; QString _errorMessage; QStringRef _tokenSpell; + QStringRef _rawString; const QChar *_codePtr; const QChar *_endPtr; - const QChar *_lastLinePtr; - const QChar *_tokenLinePtr; const QChar *_tokenStartPtr; QChar _char; Error _errorCode; int _currentLineNumber; + int _currentColumnNumber; double _tokenValue; // parentheses state ParenthesesState _parenthesesState; int _parenthesesCount; + // template string stack + QStack<int> _outerTemplateBraceCount; + int _bracesCount = -1; + int _stackToken; int _patternFlags; int _tokenKind; int _tokenLength; int _tokenLine; + int _tokenColumn; bool _validTokenText; bool _prohibitAutomaticSemicolon; @@ -247,6 +250,9 @@ private: bool _followsClosingBrace; bool _delimited; bool _qmlMode; + bool _skipLinefeed = false; + int _generatorLevel = 0; + bool _staticIsKeyword = false; }; } // end of namespace QQmlJS diff --git a/src/qml/parser/qqmljsmemorypool_p.h b/src/qml/parser/qqmljsmemorypool_p.h index 536f5d4239..bcd6d8672b 100644 --- a/src/qml/parser/qqmljsmemorypool_p.h +++ b/src/qml/parser/qqmljsmemorypool_p.h @@ -71,13 +71,7 @@ class QML_PARSER_EXPORT MemoryPool : public QSharedData void operator =(const MemoryPool &other); public: - MemoryPool() - : _blocks(0), - _allocatedBlocks(0), - _blockCount(-1), - _ptr(0), - _end(0) - { } + MemoryPool() {} ~MemoryPool() { @@ -89,11 +83,12 @@ public: free(_blocks); } + qDeleteAll(strings); } inline void *allocate(size_t size) { - size = (size + 7) & ~7; + size = (size + 7) & ~size_t(7); if (Q_LIKELY(_ptr && (_ptr + size < _end))) { void *addr = _ptr; _ptr += size; @@ -105,15 +100,24 @@ public: void reset() { _blockCount = -1; - _ptr = _end = 0; + _ptr = _end = nullptr; } template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); } + template <typename Tp, typename... Ta> Tp *New(Ta... args) + { return new (this->allocate(sizeof(Tp))) Tp(args...); } + + QStringRef newString(const QString &string) { + strings.append(new QString(string)); + return QStringRef(strings.last()); + } private: Q_NEVER_INLINE void *allocate_helper(size_t size) { - Q_ASSERT(size < BLOCK_SIZE); + size_t currentBlockSize = DEFAULT_BLOCK_SIZE; + while (Q_UNLIKELY(size >= currentBlockSize)) + currentBlockSize *= 2; if (++_blockCount == _allocatedBlocks) { if (! _allocatedBlocks) @@ -121,22 +125,22 @@ private: else _allocatedBlocks *= 2; - _blocks = (char **) realloc(_blocks, sizeof(char *) * _allocatedBlocks); + _blocks = reinterpret_cast<char **>(realloc(_blocks, sizeof(char *) * size_t(_allocatedBlocks))); Q_CHECK_PTR(_blocks); for (int index = _blockCount; index < _allocatedBlocks; ++index) - _blocks[index] = 0; + _blocks[index] = nullptr; } char *&block = _blocks[_blockCount]; if (! block) { - block = (char *) malloc(BLOCK_SIZE); + block = reinterpret_cast<char *>(malloc(currentBlockSize)); Q_CHECK_PTR(block); } _ptr = block; - _end = _ptr + BLOCK_SIZE; + _end = _ptr + currentBlockSize; void *addr = _ptr; _ptr += size; @@ -144,33 +148,107 @@ private: } private: - char **_blocks; - int _allocatedBlocks; - int _blockCount; - char *_ptr; - char *_end; + char **_blocks = nullptr; + int _allocatedBlocks = 0; + int _blockCount = -1; + char *_ptr = nullptr; + char *_end = nullptr; + QVector<QString*> strings; enum { - BLOCK_SIZE = 8 * 1024, + DEFAULT_BLOCK_SIZE = 8 * 1024, DEFAULT_BLOCK_COUNT = 8 }; }; class QML_PARSER_EXPORT Managed { - Managed(const Managed &other); - void operator = (const Managed &other); - + Q_DISABLE_COPY(Managed) public: - Managed() {} - ~Managed() {} + Managed() = default; + ~Managed() = default; void *operator new(size_t size, MemoryPool *pool) { return pool->allocate(size); } void operator delete(void *) {} void operator delete(void *, MemoryPool *) {} }; +template <typename T> +class FixedPoolArray +{ + T *data; + int count = 0; + +public: + FixedPoolArray() + : data(nullptr) + {} + + FixedPoolArray(MemoryPool *pool, int size) + { allocate(pool, size); } + + void allocate(MemoryPool *pool, int size) + { + count = size; + data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T))); + } + + void allocate(MemoryPool *pool, const QVector<T> &vector) + { + count = vector.count(); + data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T))); + + if (QTypeInfo<T>::isComplex) { + for (int i = 0; i < count; ++i) + new (data + i) T(vector.at(i)); + } else { + memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T)); + } + } + + template <typename Container> + void allocate(MemoryPool *pool, const Container &container) + { + count = container.count(); + data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T))); + typename Container::ConstIterator it = container.constBegin(); + for (int i = 0; i < count; ++i) + new (data + i) T(*it++); + } + + int size() const + { return count; } + + const T &at(int index) const { + Q_ASSERT(index >= 0 && index < count); + return data[index]; + } + + T &at(int index) { + Q_ASSERT(index >= 0 && index < count); + return data[index]; + } + + T &operator[](int index) { + return at(index); + } + + + int indexOf(const T &value) const { + for (int i = 0; i < count; ++i) + if (data[i] == value) + return i; + return -1; + } + + const T *begin() const { return data; } + const T *end() const { return data + count; } + + T *begin() { return data; } + T *end() { return data + count; } +}; + } // namespace QQmlJS QT_QML_END_NAMESPACE diff --git a/src/qml/parser/qqmljsparser.cpp b/src/qml/parser/qqmljsparser.cpp deleted file mode 100644 index 636b959097..0000000000 --- a/src/qml/parser/qqmljsparser.cpp +++ /dev/null @@ -1,1971 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmljsengine_p.h" -#include "qqmljslexer_p.h" -#include "qqmljsast_p.h" -#include "qqmljsmemorypool_p.h" - -#include <QtCore/qdebug.h> -#include <QtCore/qcoreapplication.h> - -#include <string.h> - - - -#include "qqmljsparser_p.h" - -#include <QtCore/qvarlengtharray.h> - -// -// W A R N I N G -// ------------- -// -// This file is automatically generated from qqmljs.g. -// Changes should be made to that file, not here. Any change to this file will -// be lost! -// -// To regenerate this file, run: -// qlalr --no-debug --no-lines --qt qqmljs.g -// - -using namespace QQmlJS; - -QT_QML_BEGIN_NAMESPACE - -void Parser::reallocateStack() -{ - if (! stack_size) - stack_size = 128; - else - stack_size <<= 1; - - sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value))); - state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int))); - location_stack = reinterpret_cast<AST::SourceLocation*> (realloc(location_stack, stack_size * sizeof(AST::SourceLocation))); - string_stack = reinterpret_cast<QStringRef*> (realloc(string_stack, stack_size * sizeof(QStringRef))); -} - -Parser::Parser(Engine *engine): - driver(engine), - pool(engine->pool()), - tos(0), - stack_size(0), - sym_stack(0), - state_stack(0), - location_stack(0), - string_stack(0), - program(0), - first_token(0), - last_token(0) -{ -} - -Parser::~Parser() -{ - if (stack_size) { - free(sym_stack); - free(state_stack); - free(location_stack); - free(string_stack); - } -} - -static inline AST::SourceLocation location(Lexer *lexer) -{ - AST::SourceLocation loc; - loc.offset = lexer->tokenOffset(); - loc.length = lexer->tokenLength(); - loc.startLine = lexer->tokenStartLine(); - loc.startColumn = lexer->tokenStartColumn(); - return loc; -} - -AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr) -{ - QVarLengthArray<QStringRef, 4> nameIds; - QVarLengthArray<AST::SourceLocation, 4> locations; - - AST::ExpressionNode *it = expr; - while (AST::FieldMemberExpression *m = AST::cast<AST::FieldMemberExpression *>(it)) { - nameIds.append(m->name); - locations.append(m->identifierToken); - it = m->base; - } - - if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(it)) { - AST::UiQualifiedId *q = new (pool) AST::UiQualifiedId(idExpr->name); - q->identifierToken = idExpr->identifierToken; - - AST::UiQualifiedId *currentId = q; - for (int i = nameIds.size() - 1; i != -1; --i) { - currentId = new (pool) AST::UiQualifiedId(currentId, nameIds[i]); - currentId->identifierToken = locations[i]; - } - - return currentId->finish(); - } - - return 0; -} - -AST::UiQualifiedPragmaId *Parser::reparseAsQualifiedPragmaId(AST::ExpressionNode *expr) -{ - if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(expr)) { - AST::UiQualifiedPragmaId *q = new (pool) AST::UiQualifiedPragmaId(idExpr->name); - q->identifierToken = idExpr->identifierToken; - - return q->finish(); - } - - return 0; -} - - -bool Parser::parse(int startToken) -{ - Lexer *lexer = driver->lexer(); - bool hadErrors = false; - int yytoken = -1; - int action = 0; - - token_buffer[0].token = startToken; - first_token = &token_buffer[0]; - if (startToken == T_FEED_JS_PROGRAM && !lexer->qmlMode()) { - Directives ignoreDirectives; - Directives *directives = driver->directives(); - if (!directives) - directives = &ignoreDirectives; - DiagnosticMessage error; - if (!lexer->scanDirectives(directives, &error)) { - diagnostic_messages.append(error); - return false; - } - token_buffer[1].token = lexer->tokenKind(); - token_buffer[1].dval = lexer->tokenValue(); - token_buffer[1].loc = location(lexer); - token_buffer[1].spell = lexer->tokenSpell(); - last_token = &token_buffer[2]; - } else { - last_token = &token_buffer[1]; - } - - tos = -1; - program = 0; - - do { - if (++tos == stack_size) - reallocateStack(); - - state_stack[tos] = action; - - _Lcheck_token: - if (yytoken == -1 && -TERMINAL_COUNT != action_index[action]) { - yyprevlloc = yylloc; - - if (first_token == last_token) { - yytoken = lexer->lex(); - yylval = lexer->tokenValue(); - yytokenspell = lexer->tokenSpell(); - yylloc = location(lexer); - } else { - yytoken = first_token->token; - yylval = first_token->dval; - yytokenspell = first_token->spell; - yylloc = first_token->loc; - ++first_token; - } - } - - action = t_action(action, yytoken); - if (action > 0) { - if (action != ACCEPT_STATE) { - yytoken = -1; - sym(1).dval = yylval; - stringRef(1) = yytokenspell; - loc(1) = yylloc; - } else { - --tos; - return ! hadErrors; - } - } else if (action < 0) { - const int r = -action - 1; - tos -= rhs[r]; - - switch (r) { - -case 0: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; - -case 1: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; - -case 2: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; - -case 3: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; - -case 4: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; - -case 5: { - sym(1).Node = sym(2).Node; - program = sym(1).Node; -} break; - -case 6: { - sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiHeaderItemList, - sym(2).UiObjectMemberList->finish()); -} break; - -case 8: { - sym(1).Node = sym(1).UiHeaderItemList->finish(); -} break; - -case 9: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiPragma); -} break; - -case 10: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiImport); -} break; - -case 11: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiPragma); -} break; - -case 12: { - sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiImport); -} break; - -case 16: { - sym(1).UiPragma->semicolonToken = loc(2); -} break; - -case 18: { - sym(1).UiImport->semicolonToken = loc(2); -} break; - -case 20: { - sym(1).UiImport->versionToken = loc(2); - sym(1).UiImport->semicolonToken = loc(3); -} break; - -case 22: { - sym(1).UiImport->versionToken = loc(2); - sym(1).UiImport->asToken = loc(3); - sym(1).UiImport->importIdToken = loc(4); - sym(1).UiImport->importId = stringRef(4); - sym(1).UiImport->semicolonToken = loc(5); -} break; - -case 24: { - sym(1).UiImport->asToken = loc(2); - sym(1).UiImport->importIdToken = loc(3); - sym(1).UiImport->importId = stringRef(3); - sym(1).UiImport->semicolonToken = loc(4); -} break; - -case 25: { - AST::UiPragma *node = 0; - - if (AST::UiQualifiedPragmaId *qualifiedId = reparseAsQualifiedPragmaId(sym(2).Expression)) { - node = new (pool) AST::UiPragma(qualifiedId); - } - - sym(1).Node = node; - - if (node) { - node->pragmaToken = loc(1); - } else { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), - QLatin1String("Expected a qualified name id"))); - - return false; // ### remove me - } -} break; - -case 26: { - AST::UiImport *node = 0; - - if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) { - node = new (pool) AST::UiImport(importIdLiteral->value); - node->fileNameToken = loc(2); - } else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) { - node = new (pool) AST::UiImport(qualifiedId); - node->fileNameToken = loc(2); - } - - sym(1).Node = node; - - if (node) { - node->importToken = loc(1); - } else { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), - QLatin1String("Expected a qualified name id or a string literal"))); - - return false; // ### remove me - } -} break; - -case 27: { - sym(1).Node = 0; -} break; - -case 28: { - sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); -} break; - -case 29: { - sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); -} break; - -case 30: { - AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList( - sym(1).UiObjectMemberList, sym(2).UiObjectMember); - sym(1).Node = node; -} break; - -case 31: { - sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember); -} break; - -case 32: { - AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList( - sym(1).UiArrayMemberList, sym(3).UiObjectMember); - node->commaToken = loc(2); - sym(1).Node = node; -} break; - -case 33: { - AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0); - node->lbraceToken = loc(1); - node->rbraceToken = loc(2); - sym(1).Node = node; -} break; - -case 34: { - AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish()); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; - -case 35: { - AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId, - sym(2).UiObjectInitializer); - sym(1).Node = node; -} break; - -case 37: { - AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding( - sym(1).UiQualifiedId, sym(4).UiArrayMemberList->finish()); - node->colonToken = loc(2); - node->lbracketToken = loc(3); - node->rbracketToken = loc(5); - sym(1).Node = node; -} break; - -case 38: { - AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding( - sym(1).UiQualifiedId, sym(3).UiQualifiedId, sym(4).UiObjectInitializer); - node->colonToken = loc(2); - sym(1).Node = node; -} break; - -case 39: { - AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding( - sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer); - node->colonToken = loc(2); - node->hasOnToken = true; - sym(1).Node = node; -} break; - -case 47: -{ - AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding( - sym(1).UiQualifiedId, sym(3).Statement); - node->colonToken = loc(2); - sym(1).Node = node; -} break; - -case 48: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; - -case 49: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; - -case 50: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; - -case 51: { - AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(sym(1).UiQualifiedId, stringRef(3)); - node->identifierToken = loc(3); - sym(1).Node = node; -} break; - -case 52: { - sym(1).Node = 0; -} break; - -case 53: { - sym(1).Node = sym(1).UiParameterList->finish (); -} break; - -case 54: { - AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiQualifiedId->finish(), stringRef(2)); - node->propertyTypeToken = loc(1); - node->identifierToken = loc(2); - sym(1).Node = node; -} break; - -case 55: { - AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(3).UiQualifiedId->finish(), stringRef(4)); - node->propertyTypeToken = loc(3); - node->commaToken = loc(2); - node->identifierToken = loc(4); - sym(1).Node = node; -} break; - -case 57: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); - node->type = AST::UiPublicMember::Signal; - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(2); - node->parameters = sym(4).UiParameterList; - node->semicolonToken = loc(6); - sym(1).Node = node; -} break; - -case 59: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); - node->type = AST::UiPublicMember::Signal; - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(2); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; - -case 61: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6)); - node->typeModifier = stringRef(2); - node->propertyToken = loc(1); - node->typeModifierToken = loc(2); - node->typeToken = loc(4); - node->identifierToken = loc(6); - node->semicolonToken = loc(7); - sym(1).Node = node; -} break; - -case 63: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(3); - node->semicolonToken = loc(4); - sym(1).Node = node; -} break; - -case 65: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4)); - node->isDefaultMember = true; - node->defaultToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->semicolonToken = loc(5); - sym(1).Node = node; -} break; - -case 67: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7)); - node->isDefaultMember = true; - node->defaultToken = loc(1); - node->typeModifier = stringRef(3); - node->propertyToken = loc(2); - node->typeModifierToken = loc(2); - node->typeToken = loc(4); - node->identifierToken = loc(7); - node->semicolonToken = loc(8); - sym(1).Node = node; -} break; - -case 68: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3), - sym(5).Statement); - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(3); - node->colonToken = loc(4); - sym(1).Node = node; -} break; - -case 69: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), - sym(6).Statement); - node->isReadonlyMember = true; - node->readonlyToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->colonToken = loc(5); - sym(1).Node = node; -} break; - -case 70: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), - sym(6).Statement); - node->isDefaultMember = true; - node->defaultToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->colonToken = loc(5); - sym(1).Node = node; -} break; - -case 71: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6)); - node->typeModifier = stringRef(2); - node->propertyToken = loc(1); - node->typeModifierToken = loc(2); - node->typeToken = loc(4); - node->identifierToken = loc(6); - node->semicolonToken = loc(7); // insert a fake ';' before ':' - - AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6)); - propertyName->identifierToken = loc(6); - propertyName->next = 0; - - AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding( - propertyName, sym(9).UiArrayMemberList->finish()); - binding->colonToken = loc(7); - binding->lbracketToken = loc(8); - binding->rbracketToken = loc(10); - - node->binding = binding; - - sym(1).Node = node; -} break; - -case 72: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); - node->propertyToken = loc(1); - node->typeToken = loc(2); - node->identifierToken = loc(3); - node->semicolonToken = loc(4); // insert a fake ';' before ':' - - AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3)); - propertyName->identifierToken = loc(3); - propertyName->next = 0; - - AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( - propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer); - binding->colonToken = loc(4); - - node->binding = binding; - - sym(1).Node = node; -} break; - -case 73: { - AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4)); - node->isReadonlyMember = true; - node->readonlyToken = loc(1); - node->propertyToken = loc(2); - node->typeToken = loc(3); - node->identifierToken = loc(4); - node->semicolonToken = loc(5); // insert a fake ';' before ':' - - AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4)); - propertyName->identifierToken = loc(4); - propertyName->next = 0; - - AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( - propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer); - binding->colonToken = loc(5); - - node->binding = binding; - - sym(1).Node = node; -} break; - -case 74: { - sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); -} break; - -case 75: { - sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); -} break; - -case 83: { - AST::ThisExpression *node = new (pool) AST::ThisExpression(); - node->thisToken = loc(1); - sym(1).Node = node; -} break; - -case 84: { - AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; - -case 85: { - AST::NullExpression *node = new (pool) AST::NullExpression(); - node->nullToken = loc(1); - sym(1).Node = node; -} break; - -case 86: { - AST::TrueLiteral *node = new (pool) AST::TrueLiteral(); - node->trueToken = loc(1); - sym(1).Node = node; -} break; - -case 87: { - AST::FalseLiteral *node = new (pool) AST::FalseLiteral(); - node->falseToken = loc(1); - sym(1).Node = node; -} break; - -case 88: { - AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval); - node->literalToken = loc(1); - sym(1).Node = node; -} break; -case 89: -case 90: { - AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1)); - node->literalToken = loc(1); - sym(1).Node = node; -} break; - -case 91: { - bool rx = lexer->scanRegExp(Lexer::NoPrefix); - if (!rx) { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); - return false; // ### remove me - } - - loc(1).length = lexer->tokenLength(); - yylloc = loc(1); // adjust the location of the current token - - AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral( - driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags()); - node->literalToken = loc(1); - sym(1).Node = node; -} break; - -case 92: { - bool rx = lexer->scanRegExp(Lexer::EqualPrefix); - if (!rx) { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); - return false; - } - - loc(1).length = lexer->tokenLength(); - yylloc = loc(1); // adjust the location of the current token - - AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral( - driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags()); - node->literalToken = loc(1); - sym(1).Node = node; -} break; - -case 93: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0); - node->lbracketToken = loc(1); - node->rbracketToken = loc(2); - sym(1).Node = node; -} break; - -case 94: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish()); - node->lbracketToken = loc(1); - node->rbracketToken = loc(3); - sym(1).Node = node; -} break; - -case 95: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ()); - node->lbracketToken = loc(1); - node->rbracketToken = loc(3); - sym(1).Node = node; -} break; - -case 96: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (), - (AST::Elision *) 0); - node->lbracketToken = loc(1); - node->commaToken = loc(3); - node->rbracketToken = loc(4); - sym(1).Node = node; -} break; - -case 97: { - AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (), - sym(4).Elision->finish()); - node->lbracketToken = loc(1); - node->commaToken = loc(3); - node->rbracketToken = loc(5); - sym(1).Node = node; -} break; - -case 98: { - AST::ObjectLiteral *node = 0; - if (sym(2).Node) - node = new (pool) AST::ObjectLiteral( - sym(2).PropertyAssignmentList->finish ()); - else - node = new (pool) AST::ObjectLiteral(); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; - -case 99: { - AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral( - sym(2).PropertyAssignmentList->finish ()); - node->lbraceToken = loc(1); - node->rbraceToken = loc(4); - sym(1).Node = node; -} break; - -case 100: { - AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression); - node->lparenToken = loc(1); - node->rparenToken = loc(3); - sym(1).Node = node; -} break; - -case 101: { - if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) { - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken, - QLatin1String("Ignored annotation"))); - - sym(1).Expression = mem->base; - } - - if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) { - sym(1).UiQualifiedId = qualifiedId; - } else { - sym(1).UiQualifiedId = 0; - - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1), - QLatin1String("Expected a qualified name id"))); - - return false; // ### recover - } -} break; - -case 102: { - sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression); -} break; - -case 103: { - sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression); -} break; - -case 104: { - AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, - (AST::Elision *) 0, sym(3).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; - -case 105: { - AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(), - sym(4).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; - -case 106: { - AST::Elision *node = new (pool) AST::Elision(); - node->commaToken = loc(1); - sym(1).Node = node; -} break; - -case 107: { - AST::Elision *node = new (pool) AST::Elision(sym(1).Elision); - node->commaToken = loc(2); - sym(1).Node = node; -} break; - -case 108: { - AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue( - sym(1).PropertyName, sym(3).Expression); - node->colonToken = loc(2); - sym(1).Node = node; -} break; - -case 109: { - AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( - sym(2).PropertyName, sym(6).FunctionBody); - node->getSetToken = loc(1); - node->lparenToken = loc(3); - node->rparenToken = loc(4); - node->lbraceToken = loc(5); - node->rbraceToken = loc(7); - sym(1).Node = node; -} break; - -case 110: { - AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( - sym(2).PropertyName, sym(4).FormalParameterList, sym(7).FunctionBody); - node->getSetToken = loc(1); - node->lparenToken = loc(3); - node->rparenToken = loc(5); - node->lbraceToken = loc(6); - node->rbraceToken = loc(8); - sym(1).Node = node; -} break; - -case 111: { - sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment); -} break; - -case 112: { - AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList( - sym(1).PropertyAssignmentList, sym(3).PropertyAssignment); - node->commaToken = loc(2); - sym(1).Node = node; -} break; - -case 113: { - AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; - -case 114: { - AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; - -case 115: { - AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; - -case 116: { - AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); - sym(1).Node = node; -} break; - -case 153: { - AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression); - node->lbracketToken = loc(2); - node->rbracketToken = loc(4); - sym(1).Node = node; -} break; - -case 154: { - AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3)); - node->dotToken = loc(2); - node->identifierToken = loc(3); - sym(1).Node = node; -} break; - -case 155: { - AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList); - node->newToken = loc(1); - node->lparenToken = loc(3); - node->rparenToken = loc(5); - sym(1).Node = node; -} break; - -case 157: { - AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression); - node->newToken = loc(1); - sym(1).Node = node; -} break; - -case 158: { - AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; - -case 159: { - AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; - -case 160: { - AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression); - node->lbracketToken = loc(2); - node->rbracketToken = loc(4); - sym(1).Node = node; -} break; - -case 161: { - AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3)); - node->dotToken = loc(2); - node->identifierToken = loc(3); - sym(1).Node = node; -} break; - -case 162: { - sym(1).Node = 0; -} break; - -case 163: { - sym(1).Node = sym(1).ArgumentList->finish(); -} break; - -case 164: { - sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression); -} break; - -case 165: { - AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; - -case 169: { - AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression); - node->incrementToken = loc(2); - sym(1).Node = node; -} break; - -case 170: { - AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression); - node->decrementToken = loc(2); - sym(1).Node = node; -} break; - -case 172: { - AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression); - node->deleteToken = loc(1); - sym(1).Node = node; -} break; - -case 173: { - AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression); - node->voidToken = loc(1); - sym(1).Node = node; -} break; - -case 174: { - AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression); - node->typeofToken = loc(1); - sym(1).Node = node; -} break; - -case 175: { - AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression); - node->incrementToken = loc(1); - sym(1).Node = node; -} break; - -case 176: { - AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression); - node->decrementToken = loc(1); - sym(1).Node = node; -} break; - -case 177: { - AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression); - node->plusToken = loc(1); - sym(1).Node = node; -} break; - -case 178: { - AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression); - node->minusToken = loc(1); - sym(1).Node = node; -} break; - -case 179: { - AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression); - node->tildeToken = loc(1); - sym(1).Node = node; -} break; - -case 180: { - AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression); - node->notToken = loc(1); - sym(1).Node = node; -} break; - -case 182: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Mul, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 183: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Div, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 184: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Mod, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 186: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Add, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 187: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Sub, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 189: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::LShift, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 190: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::RShift, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 191: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::URShift, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 193: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Lt, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 194: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Gt, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 195: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Le, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 196: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Ge, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 197: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::InstanceOf, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 198: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::In, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 200: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Lt, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 201: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Gt, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 202: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Le, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 203: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Ge, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 204: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::InstanceOf, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 206: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Equal, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 207: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::NotEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 208: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::StrictEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 209: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::StrictNotEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 211: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Equal, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 212: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::NotEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 213: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::StrictEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 214: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::StrictNotEqual, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 216: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitAnd, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 218: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitAnd, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 220: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitXor, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 222: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitXor, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 224: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitOr, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 226: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::BitOr, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 228: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::And, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 230: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::And, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 232: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Or, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 234: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - QSOperator::Or, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 236: { - AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, - sym(3).Expression, sym(5).Expression); - node->questionToken = loc(2); - node->colonToken = loc(4); - sym(1).Node = node; -} break; - -case 238: { - AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, - sym(3).Expression, sym(5).Expression); - node->questionToken = loc(2); - node->colonToken = loc(4); - sym(1).Node = node; -} break; - -case 240: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - sym(2).ival, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 242: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, - sym(2).ival, sym(3).Expression); - node->operatorToken = loc(2); - sym(1).Node = node; -} break; - -case 243: { - sym(1).ival = QSOperator::Assign; -} break; - -case 244: { - sym(1).ival = QSOperator::InplaceMul; -} break; - -case 245: { - sym(1).ival = QSOperator::InplaceDiv; -} break; - -case 246: { - sym(1).ival = QSOperator::InplaceMod; -} break; - -case 247: { - sym(1).ival = QSOperator::InplaceAdd; -} break; - -case 248: { - sym(1).ival = QSOperator::InplaceSub; -} break; - -case 249: { - sym(1).ival = QSOperator::InplaceLeftShift; -} break; - -case 250: { - sym(1).ival = QSOperator::InplaceRightShift; -} break; - -case 251: { - sym(1).ival = QSOperator::InplaceURightShift; -} break; - -case 252: { - sym(1).ival = QSOperator::InplaceAnd; -} break; - -case 253: { - sym(1).ival = QSOperator::InplaceXor; -} break; - -case 254: { - sym(1).ival = QSOperator::InplaceOr; -} break; - -case 256: { - AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; - -case 257: { - sym(1).Node = 0; -} break; - -case 260: { - AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression); - node->commaToken = loc(2); - sym(1).Node = node; -} break; - -case 261: { - sym(1).Node = 0; -} break; - -case 278: { - AST::Block *node = new (pool) AST::Block(sym(2).StatementList); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; - -case 279: { - sym(1).Node = new (pool) AST::StatementList(sym(1).Statement); -} break; - -case 280: { - sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement); -} break; - -case 281: { - sym(1).Node = 0; -} break; - -case 282: { - sym(1).Node = sym(1).StatementList->finish (); -} break; - -case 284: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - if (sym(1).ival == T_LET) - s = AST::VariableDeclaration::BlockScope; - else if (sym(1).ival == T_CONST) - s = AST::VariableDeclaration::ReadOnlyBlockScope; - - AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(s)); - node->declarationKindToken = loc(1); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; - -case 285: { - sym(1).ival = T_LET; -} break; - -case 286: { - sym(1).ival = T_CONST; -} break; - -case 287: { - sym(1).ival = T_VAR; -} break; - -case 288: { - sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration); -} break; - -case 289: { - AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList( - sym(1).VariableDeclarationList, sym(3).VariableDeclaration); - node->commaToken = loc(2); - sym(1).Node = node; -} break; - -case 290: { - sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration); -} break; - -case 291: { - sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration); -} break; - -case 292: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; - -case 293: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; - -case 294: { - // ### TODO: AST for initializer - sym(1) = sym(2); -} break; - -case 295: { - sym(1).Node = 0; -} break; - -case 297: { - // ### TODO: AST for initializer - sym(1) = sym(2); -} break; - -case 298: { - sym(1).Node = 0; -} break; - -case 300: { - AST::EmptyStatement *node = new (pool) AST::EmptyStatement(); - node->semicolonToken = loc(1); - sym(1).Node = node; -} break; - -case 302: { - AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; - -case 303: { - AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement); - node->ifToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - node->elseToken = loc(6); - sym(1).Node = node; -} break; - -case 304: { - AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement); - node->ifToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; - -case 307: { - AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression); - node->doToken = loc(1); - node->whileToken = loc(3); - node->lparenToken = loc(4); - node->rparenToken = loc(6); - node->semicolonToken = loc(7); - sym(1).Node = node; -} break; - -case 308: { - AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement); - node->whileToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; - -case 309: { - AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression, - sym(5).Expression, sym(7).Expression, sym(9).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->firstSemicolonToken = loc(4); - node->secondSemicolonToken = loc(6); - node->rparenToken = loc(8); - sym(1).Node = node; -} break; - -case 310: { - AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope; - AST::LocalForStatement *node = new (pool) AST::LocalForStatement( - sym(4).VariableDeclarationList->finish(s), sym(6).Expression, - sym(8).Expression, sym(10).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->varToken = loc(3); - node->firstSemicolonToken = loc(5); - node->secondSemicolonToken = loc(7); - node->rparenToken = loc(9); - sym(1).Node = node; -} break; - -case 311: { - AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression, - sym(5).Expression, sym(7).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->inToken = loc(4); - node->rparenToken = loc(6); - sym(1).Node = node; -} break; - -case 312: { - AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement( - sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement); - node->forToken = loc(1); - node->lparenToken = loc(2); - node->varToken = loc(3); - node->inToken = loc(5); - node->rparenToken = loc(7); - sym(1).Node = node; -} break; - -case 314: { - AST::ContinueStatement *node = new (pool) AST::ContinueStatement(); - node->continueToken = loc(1); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; - -case 316: { - AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2)); - node->continueToken = loc(1); - node->identifierToken = loc(2); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; - -case 318: { - AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef()); - node->breakToken = loc(1); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; - -case 320: { - AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2)); - node->breakToken = loc(1); - node->identifierToken = loc(2); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; - -case 322: { - AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression); - node->returnToken = loc(1); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; - -case 323: { - AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement); - node->withToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; - -case 324: { - AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock); - node->switchToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; - -case 325: { - AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses); - node->lbraceToken = loc(1); - node->rbraceToken = loc(3); - sym(1).Node = node; -} break; - -case 326: { - AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses); - node->lbraceToken = loc(1); - node->rbraceToken = loc(5); - sym(1).Node = node; -} break; - -case 327: { - sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause); -} break; - -case 328: { - sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause); -} break; - -case 329: { - sym(1).Node = 0; -} break; - -case 330: { - sym(1).Node = sym(1).CaseClauses->finish (); -} break; - -case 331: { - AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList); - node->caseToken = loc(1); - node->colonToken = loc(3); - sym(1).Node = node; -} break; - -case 332: { - AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList); - node->defaultToken = loc(1); - node->colonToken = loc(2); - sym(1).Node = node; -} break; - -case 333: { - AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement); - node->identifierToken = loc(1); - node->colonToken = loc(2); - sym(1).Node = node; -} break; - -case 335: { - AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression); - node->throwToken = loc(1); - node->semicolonToken = loc(3); - sym(1).Node = node; -} break; - -case 336: { - AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch); - node->tryToken = loc(1); - sym(1).Node = node; -} break; - -case 337: { - AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally); - node->tryToken = loc(1); - sym(1).Node = node; -} break; - -case 338: { - AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally); - node->tryToken = loc(1); - sym(1).Node = node; -} break; - -case 339: { - AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block); - node->catchToken = loc(1); - node->lparenToken = loc(2); - node->identifierToken = loc(3); - node->rparenToken = loc(4); - sym(1).Node = node; -} break; - -case 340: { - AST::Finally *node = new (pool) AST::Finally(sym(2).Block); - node->finallyToken = loc(1); - sym(1).Node = node; -} break; - -case 342: { - AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement(); - node->debuggerToken = loc(1); - node->semicolonToken = loc(2); - sym(1).Node = node; -} break; - -case 344: { - AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody); - node->functionToken = loc(1); - node->identifierToken = loc(2); - node->lparenToken = loc(3); - node->rparenToken = loc(5); - node->lbraceToken = loc(6); - node->rbraceToken = loc(8); - sym(1).Node = node; -} break; - -case 345: { - AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody); - node->functionToken = loc(1); - if (! stringRef(2).isNull()) - node->identifierToken = loc(2); - node->lparenToken = loc(3); - node->rparenToken = loc(5); - node->lbraceToken = loc(6); - node->rbraceToken = loc(8); - sym(1).Node = node; -} break; - -case 346: { - AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).FunctionBody); - node->functionToken = loc(1); - node->lparenToken = loc(2); - node->rparenToken = loc(4); - node->lbraceToken = loc(5); - node->rbraceToken = loc(7); - sym(1).Node = node; -} break; - -case 347: { - AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1)); - node->identifierToken = loc(1); - sym(1).Node = node; -} break; - -case 348: { - AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3)); - node->commaToken = loc(2); - node->identifierToken = loc(3); - sym(1).Node = node; -} break; - -case 349: { - sym(1).Node = 0; -} break; - -case 350: { - sym(1).Node = sym(1).FormalParameterList->finish (); -} break; - -case 351: { - sym(1).Node = 0; -} break; - -case 353: { - sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ()); -} break; - -case 355: { - sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ()); -} break; - -case 356: { - sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement); -} break; - -case 357: { - sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement); -} break; - -case 358: { - sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement); -} break; - -case 359: { - sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration); -} break; - -case 360: { - sym(1).Node = 0; -} break; - - } // switch - action = nt_action(state_stack[tos], lhs[r] - TERMINAL_COUNT); - } // if - } while (action != 0); - - if (first_token == last_token) { - const int errorState = state_stack[tos]; - - // automatic insertion of `;' - if (yytoken != -1 && ((t_action(errorState, T_AUTOMATIC_SEMICOLON) && lexer->canInsertAutomaticSemicolon(yytoken)) - || t_action(errorState, T_COMPATIBILITY_SEMICOLON))) { - SavedToken &tk = token_buffer[0]; - tk.token = yytoken; - tk.dval = yylval; - tk.spell = yytokenspell; - tk.loc = yylloc; - - yylloc = yyprevlloc; - yylloc.offset += yylloc.length; - yylloc.startColumn += yylloc.length; - yylloc.length = 0; - - //const QString msg = QCoreApplication::translate("QQmlParser", "Missing `;'"); - //diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, yylloc, msg)); - - first_token = &token_buffer[0]; - last_token = &token_buffer[1]; - - yytoken = T_SEMICOLON; - yylval = 0; - - action = errorState; - - goto _Lcheck_token; - } - - hadErrors = true; - - token_buffer[0].token = yytoken; - token_buffer[0].dval = yylval; - token_buffer[0].spell = yytokenspell; - token_buffer[0].loc = yylloc; - - token_buffer[1].token = yytoken = lexer->lex(); - token_buffer[1].dval = yylval = lexer->tokenValue(); - token_buffer[1].spell = yytokenspell = lexer->tokenSpell(); - token_buffer[1].loc = yylloc = location(lexer); - - if (t_action(errorState, yytoken)) { - QString msg; - int token = token_buffer[0].token; - if (token < 0 || token >= TERMINAL_COUNT) - msg = QCoreApplication::translate("QQmlParser", "Syntax error"); - else - msg = QCoreApplication::translate("QQmlParser", "Unexpected token `%1'").arg(QLatin1String(spell[token])); - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg)); - - action = errorState; - goto _Lcheck_token; - } - - static int tokens[] = { - T_PLUS, - T_EQ, - - T_COMMA, - T_COLON, - T_SEMICOLON, - - T_RPAREN, T_RBRACKET, T_RBRACE, - - T_NUMERIC_LITERAL, - T_IDENTIFIER, - - T_LPAREN, T_LBRACKET, T_LBRACE, - - EOF_SYMBOL - }; - - for (int *tk = tokens; *tk != EOF_SYMBOL; ++tk) { - int a = t_action(errorState, *tk); - if (a > 0 && t_action(a, yytoken)) { - const QString msg = QCoreApplication::translate("QQmlParser", "Expected token `%1'").arg(QLatin1String(spell[*tk])); - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg)); - - yytoken = *tk; - yylval = 0; - yylloc = token_buffer[0].loc; - yylloc.length = 0; - - first_token = &token_buffer[0]; - last_token = &token_buffer[2]; - - action = errorState; - goto _Lcheck_token; - } - } - - for (int tk = 1; tk < TERMINAL_COUNT; ++tk) { - if (tk == T_AUTOMATIC_SEMICOLON || tk == T_FEED_UI_PROGRAM || - tk == T_FEED_JS_STATEMENT || tk == T_FEED_JS_EXPRESSION || - tk == T_FEED_JS_SOURCE_ELEMENT) - continue; - - int a = t_action(errorState, tk); - if (a > 0 && t_action(a, yytoken)) { - const QString msg = QCoreApplication::translate("QQmlParser", "Expected token `%1'").arg(QLatin1String(spell[tk])); - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg)); - - yytoken = tk; - yylval = 0; - yylloc = token_buffer[0].loc; - yylloc.length = 0; - - action = errorState; - goto _Lcheck_token; - } - } - - const QString msg = QCoreApplication::translate("QQmlParser", "Syntax error"); - diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg)); - } - - return false; -} - -QT_QML_END_NAMESPACE - - diff --git a/src/qml/parser/qqmljsparser_p.h b/src/qml/parser/qqmljsparser_p.h deleted file mode 100644 index f382cd7563..0000000000 --- a/src/qml/parser/qqmljsparser_p.h +++ /dev/null @@ -1,257 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -// -// W A R N I N G -// ------------- -// -// This file is automatically generated from qqmljs.g. -// Changes should be made to that file, not here. Any change to this file will -// be lost! -// -// To regenerate this file, run: -// qlalr --no-debug --no-lines --qt qqmljs.g -// - -#ifndef QQMLJSPARSER_P_H -#define QQMLJSPARSER_P_H - -#include "qqmljsglobal_p.h" -#include "qqmljsgrammar_p.h" -#include "qqmljsast_p.h" -#include "qqmljsengine_p.h" - -#include <QtCore/qlist.h> -#include <QtCore/qstring.h> - -QT_QML_BEGIN_NAMESPACE - -namespace QQmlJS { - -class Engine; - -class QML_PARSER_EXPORT Parser: protected QQmlJSGrammar -{ -public: - union Value { - int ival; - double dval; - AST::ArgumentList *ArgumentList; - AST::CaseBlock *CaseBlock; - AST::CaseClause *CaseClause; - AST::CaseClauses *CaseClauses; - AST::Catch *Catch; - AST::DefaultClause *DefaultClause; - AST::ElementList *ElementList; - AST::Elision *Elision; - AST::ExpressionNode *Expression; - AST::Finally *Finally; - AST::FormalParameterList *FormalParameterList; - AST::FunctionBody *FunctionBody; - AST::FunctionDeclaration *FunctionDeclaration; - AST::Node *Node; - AST::PropertyName *PropertyName; - AST::PropertyAssignment *PropertyAssignment; - AST::PropertyAssignmentList *PropertyAssignmentList; - AST::SourceElement *SourceElement; - AST::SourceElements *SourceElements; - AST::Statement *Statement; - AST::StatementList *StatementList; - AST::Block *Block; - AST::VariableDeclaration *VariableDeclaration; - AST::VariableDeclarationList *VariableDeclarationList; - - AST::UiProgram *UiProgram; - AST::UiHeaderItemList *UiHeaderItemList; - AST::UiPragma *UiPragma; - AST::UiImport *UiImport; - AST::UiParameterList *UiParameterList; - AST::UiPublicMember *UiPublicMember; - AST::UiObjectDefinition *UiObjectDefinition; - AST::UiObjectInitializer *UiObjectInitializer; - AST::UiObjectBinding *UiObjectBinding; - AST::UiScriptBinding *UiScriptBinding; - AST::UiArrayBinding *UiArrayBinding; - AST::UiObjectMember *UiObjectMember; - AST::UiObjectMemberList *UiObjectMemberList; - AST::UiArrayMemberList *UiArrayMemberList; - AST::UiQualifiedId *UiQualifiedId; - AST::UiQualifiedPragmaId *UiQualifiedPragmaId; - }; - -public: - Parser(Engine *engine); - ~Parser(); - - // parse a UI program - bool parse() { return parse(T_FEED_UI_PROGRAM); } - bool parseStatement() { return parse(T_FEED_JS_STATEMENT); } - bool parseExpression() { return parse(T_FEED_JS_EXPRESSION); } - bool parseSourceElement() { return parse(T_FEED_JS_SOURCE_ELEMENT); } - bool parseUiObjectMember() { return parse(T_FEED_UI_OBJECT_MEMBER); } - bool parseProgram() { return parse(T_FEED_JS_PROGRAM); } - - AST::UiProgram *ast() const - { return AST::cast<AST::UiProgram *>(program); } - - AST::Statement *statement() const - { - if (! program) - return 0; - - return program->statementCast(); - } - - AST::ExpressionNode *expression() const - { - if (! program) - return 0; - - return program->expressionCast(); - } - - AST::UiObjectMember *uiObjectMember() const - { - if (! program) - return 0; - - return program->uiObjectMemberCast(); - } - - AST::Node *rootNode() const - { return program; } - - QList<DiagnosticMessage> diagnosticMessages() const - { return diagnostic_messages; } - - inline DiagnosticMessage diagnosticMessage() const - { - for (const DiagnosticMessage &d : diagnostic_messages) { - if (d.kind != DiagnosticMessage::Warning) - return d; - } - - return DiagnosticMessage(); - } - - inline QString errorMessage() const - { return diagnosticMessage().message; } - - inline int errorLineNumber() const - { return diagnosticMessage().loc.startLine; } - - inline int errorColumnNumber() const - { return diagnosticMessage().loc.startColumn; } - -protected: - bool parse(int startToken); - - void reallocateStack(); - - inline Value &sym(int index) - { return sym_stack [tos + index - 1]; } - - inline QStringRef &stringRef(int index) - { return string_stack [tos + index - 1]; } - - inline AST::SourceLocation &loc(int index) - { return location_stack [tos + index - 1]; } - - AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr); - AST::UiQualifiedPragmaId *reparseAsQualifiedPragmaId(AST::ExpressionNode *expr); - -protected: - Engine *driver; - MemoryPool *pool; - int tos; - int stack_size; - Value *sym_stack; - int *state_stack; - AST::SourceLocation *location_stack; - QStringRef *string_stack; - - AST::Node *program; - - // error recovery - enum { TOKEN_BUFFER_SIZE = 3 }; - - struct SavedToken { - int token; - double dval; - AST::SourceLocation loc; - QStringRef spell; - }; - - double yylval; - QStringRef yytokenspell; - AST::SourceLocation yylloc; - AST::SourceLocation yyprevlloc; - - SavedToken token_buffer[TOKEN_BUFFER_SIZE]; - SavedToken *first_token; - SavedToken *last_token; - - QList<DiagnosticMessage> diagnostic_messages; -}; - -} // end of namespace QQmlJS - - - -#define J_SCRIPT_REGEXPLITERAL_RULE1 91 - -#define J_SCRIPT_REGEXPLITERAL_RULE2 92 - -QT_QML_END_NAMESPACE - - - -#endif // QQMLJSPARSER_P_H diff --git a/src/qml/parser/qqmljssourcelocation_p.h b/src/qml/parser/qqmljssourcelocation_p.h new file mode 100644 index 0000000000..dc307ba168 --- /dev/null +++ b/src/qml/parser/qqmljssourcelocation_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLJSSOURCELOCATION_P_H +#define QQMLJSSOURCELOCATION_P_H + +#include "qqmljsglobal_p.h" + +#include <QtCore/qglobal.h> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_QML_BEGIN_NAMESPACE + +namespace QQmlJS { namespace AST { + +class SourceLocation +{ +public: + explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) + : offset(offset), length(length), + startLine(line), startColumn(column) + { } + + bool isValid() const { return length != 0; } + + quint32 begin() const { return offset; } + quint32 end() const { return offset + length; } + +// attributes + // ### encode + quint32 offset; + quint32 length; + quint32 startLine; + quint32 startColumn; +}; + +} } // namespace AST + +QT_QML_END_NAMESPACE + +#endif |