diff options
Diffstat (limited to 'src/qml/parser/qqmljs.g')
-rw-r--r-- | src/qml/parser/qqmljs.g | 707 |
1 files changed, 362 insertions, 345 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index f10bde5ff1..57954d7d1a 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -1,41 +1,5 @@ ----------------------------------------------------------------------------- --- -- Copyright (C) 2016 The Qt Company Ltd. --- Contact: http://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$ --- ----------------------------------------------------------------------------- +-- SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only %parser QQmlJSGrammar %decl qqmljsparser_p.h @@ -81,6 +45,7 @@ %token T_COMPATIBILITY_SEMICOLON %token T_ARROW "=>" %token T_QUESTION_QUESTION "??" +%token T_QUESTION_DOT "?." %token T_ENUM "enum" %token T_ELLIPSIS "..." %token T_YIELD "yield" @@ -108,8 +73,19 @@ %token T_GET "get" %token T_SET "set" +-- token representing no token +%token T_NONE + %token T_ERROR +-- states for line by line parsing +%token T_EOL +%token T_PARTIAL_COMMENT "non closed multiline comment" +%token T_PARTIAL_SINGLE_QUOTE_STRING_LITERAL "multiline single quote string literal" +%token T_PARTIAL_DOUBLE_QUOTE_STRING_LITERAL "multiline double quote string literal" +%token T_PARTIAL_TEMPLATE_HEAD "(template head)" +%token T_PARTIAL_TEMPLATE_MIDDLE "(template middle)" + --- feed tokens %token T_FEED_UI_PROGRAM %token T_FEED_UI_OBJECT_MEMBER @@ -131,44 +107,9 @@ %start TopLevel -/./**************************************************************************** -** -** 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$ -** -****************************************************************************/ +/.// Copyright (C) 2016 The Qt Company Ltd. +// Contact: https://www.qt.io/licensing/ +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include <private/qqmljsengine_p.h> #include <private/qqmljslexer_p.h> @@ -182,44 +123,9 @@ ./ -/:/**************************************************************************** -** -** 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$ -** -****************************************************************************/ +/:// Copyright (C) 2016 The Qt Company Ltd. +// Contact: https://www.qt.io/licensing/ +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only // @@ -306,14 +212,15 @@ public: AST::ExportClause *ExportClause; AST::ExportDeclaration *ExportDeclaration; AST::TypeAnnotation *TypeAnnotation; - AST::TypeArgumentList *TypeArgumentList; AST::Type *Type; AST::UiProgram *UiProgram; AST::UiHeaderItemList *UiHeaderItemList; + AST::UiPragmaValueList *UiPragmaValueList; AST::UiPragma *UiPragma; AST::UiImport *UiImport; AST::UiParameterList *UiParameterList; + AST::UiPropertyAttributes *UiPropertyAttributes; AST::UiPublicMember *UiPublicMember; AST::UiObjectDefinition *UiObjectDefinition; AST::UiObjectInitializer *UiObjectInitializer; @@ -395,6 +302,18 @@ public: inline int errorColumnNumber() const { return diagnosticMessage().loc.startColumn; } + inline bool identifierInsertionEnabled() const + { return m_identifierInsertionEnabled; } + + inline void setIdentifierInsertionEnabled(bool enable) + { m_identifierInsertionEnabled = enable; } + + inline bool incompleteBindingsEnabled() const + { return m_incompleteBindingsEnabled; } + + inline void setIncompleteBindingsEnabled(bool enable) + { m_incompleteBindingsEnabled = enable; } + protected: bool parse(int startToken); @@ -415,6 +334,7 @@ protected: AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr); void pushToken(int token); + void pushTokenWithEmptyLocation(int token); int lookaheadToken(Lexer *lexer); static DiagnosticMessage compileError(const SourceLocation &location, @@ -444,8 +364,8 @@ protected: Value *sym_stack = nullptr; int *state_stack = nullptr; SourceLocation *location_stack = nullptr; - QList<QStringView> string_stack; - QList<QStringView> rawString_stack; + std::vector<QStringView> string_stack; + std::vector<QStringView> rawString_stack; AST::Node *program = nullptr; @@ -466,12 +386,14 @@ protected: QStringView yytokenraw; SourceLocation yylloc; SourceLocation yyprevlloc; + int yyprevtoken = -1; SavedToken token_buffer[TOKEN_BUFFER_SIZE]; SavedToken *first_token = nullptr; SavedToken *last_token = nullptr; int functionNestingLevel = 0; + int classNestingLevel = 0; enum CoverExpressionType { CE_Invalid, @@ -482,6 +404,8 @@ protected: CoverExpressionType coverExpressionType = CE_Invalid; QList<DiagnosticMessage> diagnostic_messages; + bool m_identifierInsertionEnabled = false; + bool m_incompleteBindingsEnabled = false; }; } // end of namespace QQmlJS @@ -557,11 +481,13 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr) { QVarLengthArray<QStringView, 4> nameIds; QVarLengthArray<SourceLocation, 4> locations; + QVarLengthArray<SourceLocation, 4> dotLocations; AST::ExpressionNode *it = expr; while (AST::FieldMemberExpression *m = AST::cast<AST::FieldMemberExpression *>(it)) { nameIds.append(m->name); locations.append(m->identifierToken); + dotLocations.append(m->dotToken); it = m->base; } @@ -573,6 +499,7 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr) for (int i = nameIds.size() - 1; i != -1; --i) { currentId = new (pool) AST::UiQualifiedId(currentId, nameIds[i]); currentId->identifierToken = locations[i]; + currentId->dotToken = dotLocations[i]; } return currentId->finish(); @@ -594,9 +521,19 @@ void Parser::pushToken(int token) yytoken = token; } +void Parser::pushTokenWithEmptyLocation(int token) +{ + pushToken(token); + yylloc = yyprevlloc; + yylloc.offset += yylloc.length; + yylloc.startColumn += yylloc.length; + yylloc.length = 0; +} + int Parser::lookaheadToken(Lexer *lexer) { if (yytoken < 0) { + yyprevtoken = yytoken; yytoken = lexer->lex(); yylval = lexer->tokenValue(); yytokenspell = lexer->tokenSpell(); @@ -692,6 +629,7 @@ bool Parser::parse(int startToken) #endif if (action > 0) { if (action != ACCEPT_STATE) { + yyprevtoken = yytoken; yytoken = -1; sym(1).dval = yylval; stringRef(1) = yytokenspell; @@ -809,20 +747,56 @@ UiHeaderItemList: UiHeaderItemList UiImport; ./ PragmaId: JsIdentifier; +PragmaValue: JsIdentifier + | T_STRING_LITERAL; Semicolon: T_AUTOMATIC_SEMICOLON; Semicolon: T_SEMICOLON; +UiPragmaValueList: PragmaValue; +/. + case $rule_number: { + AST::UiPragmaValueList *list + = new (pool) AST::UiPragmaValueList(stringRef(1)); + list->location = loc(1); + sym(1).Node = list; + } break; +./ + +UiPragmaValueList: UiPragmaValueList T_COMMA PragmaValue; +/. + case $rule_number: { + AST::UiPragmaValueList *list + = new (pool) AST::UiPragmaValueList(sym(1).UiPragmaValueList, stringRef(3)); + list->location = loc(3); + sym(1).Node = list; + } break; +./ + UiPragma: T_PRAGMA PragmaId Semicolon; /. case $rule_number: { AST::UiPragma *pragma = new (pool) AST::UiPragma(stringRef(2)); pragma->pragmaToken = loc(1); + pragma->pragmaIdToken = loc(2); pragma->semicolonToken = loc(3); sym(1).Node = pragma; } break; ./ +UiPragma: T_PRAGMA PragmaId T_COLON UiPragmaValueList Semicolon; +/. + case $rule_number: { + AST::UiPragma *pragma = new (pool) AST::UiPragma( + stringRef(2), sym(4).UiPragmaValueList->finish()); + pragma->pragmaToken = loc(1); + pragma->pragmaIdToken = loc(2); + pragma->colonToken = loc(3); + pragma->semicolonToken = loc(5); + sym(1).Node = pragma; + } break; +./ + ImportId: MemberExpression; UiImport: UiImportHead Semicolon; @@ -1177,6 +1151,20 @@ case $rule_number: } break; ./ +UiObjectMember: UiQualifiedId Semicolon; +/. + case $rule_number: { + if (!m_incompleteBindingsEnabled) { + diagnostic_messages.append(compileError(loc(1), QLatin1String("Incomplete binding, expected token `:` or `{`"))); + return false; + } + AST::EmptyStatement *statement = new (pool) AST::EmptyStatement; + statement->semicolonToken = loc(2); + AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding(sym(1).UiQualifiedId, statement); + sym(1).Node = node; + } break; +./ + UiPropertyType: T_VAR; /. case $rule_number: Q_FALLTHROUGH(); ./ UiPropertyType: T_RESERVED_WORD; @@ -1213,10 +1201,10 @@ UiParameterListOpt: UiParameterList; } break; ./ -UiParameterList: QmlIdentifier T_COLON UiPropertyType; +UiParameterList: QmlIdentifier T_COLON Type; /. case $rule_number: { - AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(3).UiQualifiedId->finish(), stringRef(1)); + AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(3).Type, stringRef(1)); node->identifierToken = loc(1); node->colonToken = loc(2); node->propertyTypeToken = loc(3); @@ -1224,20 +1212,20 @@ UiParameterList: QmlIdentifier T_COLON UiPropertyType; } break; ./ -UiParameterList: UiPropertyType QmlIdentifier; +UiParameterList: Type QmlIdentifier; /. case $rule_number: { - AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiQualifiedId->finish(), stringRef(2)); + AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).Type, stringRef(2)); node->propertyTypeToken = loc(1); node->identifierToken = loc(2); sym(1).Node = node; } break; ./ -UiParameterList: UiParameterList T_COMMA QmlIdentifier T_COLON UiPropertyType; +UiParameterList: UiParameterList T_COMMA QmlIdentifier T_COLON Type; /. case $rule_number: { - AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(5).UiQualifiedId->finish(), stringRef(3)); + AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(5).Type, stringRef(3)); node->propertyTypeToken = loc(5); node->commaToken = loc(2); node->identifierToken = loc(3); @@ -1246,10 +1234,10 @@ UiParameterList: UiParameterList T_COMMA QmlIdentifier T_COLON UiPropertyType; } break; ./ -UiParameterList: UiParameterList T_COMMA UiPropertyType QmlIdentifier; +UiParameterList: UiParameterList T_COMMA Type QmlIdentifier; /. case $rule_number: { - AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(3).UiQualifiedId->finish(), stringRef(4)); + AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(3).Type, stringRef(4)); node->propertyTypeToken = loc(3); node->commaToken = loc(2); node->identifierToken = loc(4); @@ -1262,7 +1250,7 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN Semic case $rule_number: { AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); node->type = AST::UiPublicMember::Signal; - node->propertyToken = loc(1); + node->setPropertyToken(loc(1)); node->typeToken = loc(2); node->identifierToken = loc(2); node->parameters = sym(4).UiParameterList; @@ -1276,7 +1264,7 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER Semicolon; case $rule_number: { AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2)); node->type = AST::UiPublicMember::Signal; - node->propertyToken = loc(1); + node->setPropertyToken(loc(1)); node->typeToken = loc(2); node->identifierToken = loc(2); node->semicolonToken = loc(3); @@ -1284,126 +1272,97 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER Semicolon; } break; ./ -UiObjectMemberListPropertyNoInitialiser: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier 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; -./ +------------------------------------------------------------------------------- +-- There is some ambiguity in whether required default property should be parsed +-- as required (default (property)) or as ((required (default)) property) +-- by reducing after each attribute modifier, we ensure that T_PROPERTY (which +-- is always available is used as the base case (so we only have to allocate the +-- node in the T_PROPERY case, and all other rules can assume that the node is +-- already available). +-------------------------------------------------------------------------------- -UiObjectMember: UiObjectMemberListPropertyNoInitialiser; +AttrRequired: T_REQUIRED %prec REDUCE_HERE; +AttrReadonly: T_READONLY %prec REDUCE_HERE; +AttrDefault: T_DEFAULT %prec REDUCE_HERE; -UiObjectMember: T_READONLY UiObjectMemberListPropertyNoInitialiser; +UiPropertyAttributes: AttrRequired UiPropertyAttributes; /. case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->isReadonlyMember = true; - node->readonlyToken = loc(1); - sym(1).Node = node; + AST::UiPropertyAttributes *node = sym(2).UiPropertyAttributes; + if (node->isRequired()) + diagnostic_messages.append(compileError(node->requiredToken(), QLatin1String("Duplicated 'required' attribute is not allowed."), QtCriticalMsg)); + node->m_requiredToken = loc(1); + sym(1).UiPropertyAttributes = node; } break; ./ -UiObjectMemberPropertyNoInitialiser: T_PROPERTY UiPropertyType QmlIdentifier Semicolon; +UiPropertyAttributes: AttrDefault UiPropertyAttributes; /. 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; + AST::UiPropertyAttributes *node = sym(2).UiPropertyAttributes; + if (node->isDefaultMember()) + diagnostic_messages.append(compileError(node->requiredToken(), QLatin1String("Duplicated 'default' attribute is not allowed."), QtCriticalMsg)); + node->m_defaultToken = loc(1); + sym(1).UiPropertyAttributes = node; } break; ./ - -UiObjectMember: UiObjectMemberPropertyNoInitialiser; - -UiObjectMember: T_DEFAULT UiObjectMemberPropertyNoInitialiser; +UiPropertyAttributes: AttrReadonly UiPropertyAttributes; /. case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->isDefaultMember = true; - node->defaultToken = loc(1); - sym(1).Node = node; + AST::UiPropertyAttributes *node = sym(2).UiPropertyAttributes; + if (node->isReadonly()) + diagnostic_messages.append(compileError(node->requiredToken(), QLatin1String("Duplicated 'readonly' attribute is not allowed."), QtCriticalMsg)); + node->m_readonlyToken = loc(1); + sym(1).UiPropertyAttributes = node; } break; ./ - -UiObjectMember: T_REQUIRED UiObjectMemberListPropertyNoInitialiser; +UiPropertyAttributes: T_PROPERTY; /. case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->isRequired = true; - node->requiredToken = loc(1); - sym(1).Node = node; + AST::UiPropertyAttributes *node = new (pool) AST::UiPropertyAttributes(); + node->m_propertyToken = loc(1); + sym(1).UiPropertyAttributes = node; } break; ./ -UiObjectMember: T_DEFAULT T_REQUIRED UiObjectMemberListPropertyNoInitialiser; +UiObjectMemberListPropertyNoInitialiser: UiPropertyAttributes T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier Semicolon; /. case $rule_number: { - AST::UiPublicMember *node = sym(3).UiPublicMember; - node->isRequired = true; - node->requiredToken = loc(2); - node->isDefaultMember = true; - node->defaultToken = loc(1); - sym(1).Node = node; - } break; -./ - -UiObjectMember: T_REQUIRED T_DEFAULT UiObjectMemberListPropertyNoInitialiser; -/. - case $rule_number: { - AST::UiPublicMember *node = sym(3).UiPublicMember; - node->isRequired = true; - node->requiredToken = loc(1); - node->isDefaultMember = true; - node->defaultToken = loc(2); + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6)); + auto attributes = sym(1).UiPropertyAttributes; + node->setAttributes(attributes); + if (attributes->isReadonly()) + diagnostic_messages.append(compileError(attributes->readonlyToken(), QLatin1String("Read-only properties require an initializer."), QtWarningMsg)); + node->typeModifier = stringRef(2); + node->typeModifierToken = loc(2); + node->typeToken = loc(4); + node->identifierToken = loc(6); + node->semicolonToken = loc(7); sym(1).Node = node; } break; ./ -UiObjectMember: T_DEFAULT UiObjectMemberListPropertyNoInitialiser; -/. - case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->isDefaultMember = true; - node->defaultToken = loc(1); - sym(1).Node = node; - } break; -./ +UiObjectMember: UiObjectMemberListPropertyNoInitialiser; -UiObjectMember: T_DEFAULT T_REQUIRED UiObjectMemberPropertyNoInitialiser; +UiObjectMemberPropertyNoInitialiser: UiPropertyAttributes UiPropertyType QmlIdentifier Semicolon; /. case $rule_number: { - AST::UiPublicMember *node = sym(3).UiPublicMember; - node->isDefaultMember = true; - node->defaultToken = loc(1); - node->isRequired = true; - node->requiredToken = loc(2); + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); + auto attributes = sym(1).UiPropertyAttributes; + if (attributes->isReadonly()) + diagnostic_messages.append(compileError(attributes->readonlyToken(), QLatin1String("Read-only properties require an initializer."), QtCriticalMsg)); + node->setAttributes(attributes); + node->typeToken = loc(2); + node->identifierToken = loc(3); + node->semicolonToken = loc(4); sym(1).Node = node; } break; ./ -UiObjectMember: T_REQUIRED T_DEFAULT UiObjectMemberPropertyNoInitialiser; -/. - case $rule_number: { - AST::UiPublicMember *node = sym(3).UiPublicMember; - node->isDefaultMember = true; - node->defaultToken = loc(2); - node->isRequired = true; - node->requiredToken = loc(1); - sym(1).Node = node; - } break; -./ +UiObjectMember: UiObjectMemberPropertyNoInitialiser; OptionalSemicolon: | Semicolon; /. @@ -1423,21 +1382,14 @@ UiRequired: T_REQUIRED QmlIdentifier Semicolon; UiObjectMember: UiRequired; -UiObjectMember: T_REQUIRED UiObjectMemberPropertyNoInitialiser; -/. - case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->requiredToken = loc(1); - node->isRequired = true; - sym(1).Node = node; - } break; -./ - -UiObjectMemberWithScriptStatement: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon; +UiObjectMemberWithScriptStatement: UiPropertyAttributes UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon; /. case $rule_number: { AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3), sym(5).Statement); - node->propertyToken = loc(1); + auto attributes = sym(1).UiPropertyAttributes; + if (attributes->isRequired()) + diagnostic_messages.append(compileError(attributes->requiredToken(), QLatin1String("Required properties with initializer do not make sense."), QtCriticalMsg)); + node->setAttributes(attributes); node->typeToken = loc(2); node->identifierToken = loc(3); node->colonToken = loc(4); @@ -1445,47 +1397,48 @@ UiObjectMemberWithScriptStatement: T_PROPERTY UiPropertyType QmlIdentifier T_COL } break; ./ -UiObjectMember: UiObjectMemberWithScriptStatement; - -UiObjectMember: T_READONLY UiObjectMemberWithScriptStatement; +UiObjectMemberWithScriptStatement: UiPropertyAttributes T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon; /. case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->isReadonlyMember = true; - node->readonlyToken = loc(1); + AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6), sym(8).Statement); + node->typeModifier = stringRef(2); + auto attributes = sym(1).UiPropertyAttributes; + if (attributes->isRequired()) + diagnostic_messages.append(compileError(attributes->requiredToken(), QLatin1String("Required properties with initializer do not make sense."), QtCriticalMsg)); + node->setAttributes(attributes); + node->typeModifierToken = loc(2); + node->typeToken = loc(4); + node->identifierToken = loc(6); + node->colonToken = loc(7); sym(1).Node = node; } break; ./ -UiObjectMember: T_DEFAULT UiObjectMemberWithScriptStatement; -/. - case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->isDefaultMember = true; - node->defaultToken = loc(1); - sym(1).Node = node; - } break; -./ +UiObjectMember: UiObjectMemberWithScriptStatement; -UiObjectMemberWithArray: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET Semicolon; +UiObjectMemberWithArray: UiPropertyAttributes T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON ExpressionStatementLookahead T_LBRACKET UiArrayMemberList T_RBRACKET Semicolon; /. case $rule_number: { AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6)); + auto attributes = sym(1).UiPropertyAttributes; + if (attributes->isRequired()) + diagnostic_messages.append(compileError(attributes->requiredToken(), QLatin1String("Required properties with initializer do not make sense."), QtCriticalMsg)); + node->setAttributes(attributes); 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 ':' + node->colonToken = loc(7); AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6)); propertyName->identifierToken = loc(6); - propertyName->next = 0; + propertyName->next = nullptr; - AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(propertyName, sym(9).UiArrayMemberList->finish()); + AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(propertyName, sym(10).UiArrayMemberList->finish()); binding->colonToken = loc(7); - binding->lbracketToken = loc(8); - binding->rbracketToken = loc(10); + binding->lbracketToken = loc(9); + binding->rbracketToken = loc(11); node->binding = binding; @@ -1495,28 +1448,22 @@ UiObjectMemberWithArray: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIde UiObjectMember: UiObjectMemberWithArray; -UiObjectMember: T_READONLY UiObjectMemberWithArray; -/. - case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->isReadonlyMember = true; - node->readonlyToken = loc(1); - sym(1).Node = node; - } break; -./ - -UiObjectMemberExpressionStatementLookahead: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer Semicolon; +UiObjectMemberExpressionStatementLookahead: UiPropertyAttributes UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer Semicolon; /. case $rule_number: { AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3)); - node->propertyToken = loc(1); + auto attributes = sym(1).UiPropertyAttributes; + if (attributes->isRequired()) + diagnostic_messages.append(compileError(attributes->requiredToken(), QLatin1String("Required properties with initializer do not make sense."), QtWarningMsg)); + node->setAttributes(attributes); node->typeToken = loc(2); node->identifierToken = loc(3); node->semicolonToken = loc(4); // insert a fake ';' before ':' + node->colonToken = loc(4); AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3)); propertyName->identifierToken = loc(3); - propertyName->next = 0; + propertyName->next = nullptr; AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding( propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer); @@ -1530,16 +1477,6 @@ UiObjectMemberExpressionStatementLookahead: T_PROPERTY UiPropertyType QmlIdentif UiObjectMember: UiObjectMemberExpressionStatementLookahead; -UiObjectMember: T_READONLY UiObjectMemberExpressionStatementLookahead; -/. - case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->isReadonlyMember = true; - node->readonlyToken = loc(1); - sym(1).Node = node; - } break; -./ - UiObjectMember: GeneratorDeclaration; /. case $rule_number: { @@ -1590,6 +1527,8 @@ UiObjectMember: T_ENUM T_IDENTIFIER T_LBRACE EnumMemberList T_RBRACE; case $rule_number: { AST::UiEnumDeclaration *enumDeclaration = new (pool) AST::UiEnumDeclaration(stringRef(2), sym(4).UiEnumMemberList->finish()); enumDeclaration->enumToken = loc(1); + enumDeclaration->identifierToken = loc(2); + enumDeclaration->lbraceToken = loc(3); enumDeclaration->rbraceToken = loc(5); sym(1).Node = enumDeclaration; break; @@ -1605,6 +1544,7 @@ UiObjectMember: T_COMPONENT T_IDENTIFIER T_COLON UiObjectDefinition; } auto inlineComponent = new (pool) AST::UiInlineComponent(stringRef(2), sym(4).UiObjectDefinition); inlineComponent->componentToken = loc(1); + inlineComponent->identifierToken = loc(2); sym(1).Node = inlineComponent; } break; ./ @@ -1630,6 +1570,18 @@ EnumMemberList: T_IDENTIFIER T_EQ T_NUMERIC_LITERAL; } ./ + +EnumMemberList: T_IDENTIFIER T_EQ T_MINUS T_NUMERIC_LITERAL; +/. + case $rule_number: { + AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1), -sym(4).dval); + node->memberToken = loc(1); + node->valueToken = combine(loc(3), loc(4)); + sym(1).Node = node; + break; + } +./ + EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER; /. case $rule_number: { @@ -1651,6 +1603,18 @@ EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER T_EQ T_NUMERIC_LITERAL; } ./ + +EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER T_EQ T_MINUS T_NUMERIC_LITERAL; +/. + case $rule_number: { + AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3), -sym(6).dval); + node->memberToken = loc(3); + node->valueToken = combine(loc(5), loc(6)); + sym(1).Node = node; + break; + } +./ + QmlIdentifier: T_IDENTIFIER | T_PROPERTY | T_SIGNAL @@ -1684,28 +1648,35 @@ BindingIdentifier: IdentifierReference; -- Types -------------------------------------------------------------------------------------------------------- -TypeArguments: Type; +Type: UiQualifiedId T_LT SimpleType T_GT; /. case $rule_number: { - sym(1).TypeArgumentList = new (pool) AST::TypeArgumentList(sym(1).Type); + sym(1).Type = new (pool) AST::Type(sym(1).UiQualifiedId, sym(3).Type); } break; ./ -TypeArguments: TypeArguments T_COMMA Type; +Type: SimpleType; + +SimpleType: T_RESERVED_WORD; /. case $rule_number: { - sym(1).TypeArgumentList = new (pool) AST::TypeArgumentList(sym(1).TypeArgumentList, sym(3).Type); + AST::UiQualifiedId *id = new (pool) AST::UiQualifiedId(stringRef(1)); + id->identifierToken = loc(1); + sym(1).Type = new (pool) AST::Type(id->finish()); } break; ./ -Type: UiQualifiedId T_LT TypeArguments T_GT; +SimpleType: UiQualifiedId; /. case $rule_number: { - sym(1).Type = new (pool) AST::Type(sym(1).UiQualifiedId, sym(3).TypeArgumentList->finish()); + sym(1).Type = new (pool) AST::Type(sym(1).UiQualifiedId); } break; ./ -Type: T_RESERVED_WORD; +SimpleType: T_VAR; +/. case $rule_number: Q_FALLTHROUGH(); ./ + +SimpleType: T_VOID; /. case $rule_number: { AST::UiQualifiedId *id = new (pool) AST::UiQualifiedId(stringRef(1)); @@ -1714,13 +1685,6 @@ Type: T_RESERVED_WORD; } break; ./ -Type: UiQualifiedId; -/. - case $rule_number: { - sym(1).Type = new (pool) AST::Type(sym(1).UiQualifiedId); - } break; -./ - TypeAnnotation: T_COLON Type; /. case $rule_number: { @@ -1729,14 +1693,6 @@ TypeAnnotation: T_COLON Type; } break; ./ - -TypeExpression: Type; -/. - case $rule_number: { - sym(1).Expression = new (pool) AST::TypeExpression(sym(1).Type); - } break; -./ - TypeAnnotationOpt: TypeAnnotation; TypeAnnotationOpt: ; /. @@ -2100,7 +2056,6 @@ PropertyDefinition: IdentifierReference; 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; ./ @@ -2121,8 +2076,8 @@ CoverInitializedName: IdentifierReference Initializer_In; if (auto *c = asAnonymousClassDefinition(sym(2).Expression)) c->name = stringRef(1); AST::BinaryExpression *assignment = new (pool) AST::BinaryExpression(left, QSOperator::Assign, sym(2).Expression); + assignment->operatorToken = loc(2); AST::PatternProperty *node = new (pool) AST::PatternProperty(name, assignment); - node->colonToken = loc(1); sym(1).Node = node; } break; @@ -2235,7 +2190,9 @@ Initializer: T_EQ AssignmentExpression; Initializer_In: T_EQ AssignmentExpression_In; /. case $rule_number: { - sym(1) = sym(2); + auto node = new (pool) AST::InitializerExpression(sym(2).Expression); + node->equalToken = loc(1); + sym(1).Expression = node; } break; ./ @@ -2253,7 +2210,14 @@ InitializerOpt: Initializer; InitializerOpt_In: Initializer_In; TemplateLiteral: T_NO_SUBSTITUTION_TEMPLATE; -/. case $rule_number: Q_FALLTHROUGH(); ./ +/. + case $rule_number: { + AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), rawStringRef(1), nullptr); + node->literalToken = loc(1); + node->hasNoSubstitution = true; + sym(1).Node = node; + } break; +./ TemplateSpans: T_TEMPLATE_TAIL; /. @@ -2301,7 +2265,16 @@ MemberExpression: MemberExpression T_LBRACKET Expression_In T_RBRACKET; sym(1).Node = node; } break; ./ - +MemberExpression: MemberExpression T_QUESTION_DOT T_LBRACKET Expression_In T_RBRACKET; +/. + case $rule_number: { + AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(4).Expression); + node->lbracketToken = loc(3); + node->rbracketToken = loc(5); + node->isOptional = true; + sym(1).Node = node; + } break; +./ -- the identifier has to be "target", catched at codegen time NewTarget: T_NEW T_DOT T_IDENTIFIER; @@ -2324,6 +2297,17 @@ MemberExpression: MemberExpression T_DOT IdentifierName; } break; ./ +MemberExpression: MemberExpression T_QUESTION_DOT IdentifierName; +/. + case $rule_number: { + AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3)); + node->dotToken = loc(2); + node->identifierToken = loc(3); + node->isOptional = true; + sym(1).Node = node; + } break; +./ + MemberExpression: MetaProperty; MemberExpression: T_NEW MemberExpression T_LPAREN Arguments T_RPAREN; @@ -2372,6 +2356,17 @@ CallExpression: MemberExpression T_LPAREN Arguments T_RPAREN; } break; ./ +CallExpression: MemberExpression T_QUESTION_DOT T_LPAREN Arguments T_RPAREN; +/. + case $rule_number: { + AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(4).ArgumentList); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->isOptional = true; + sym(1).Node = node; + } break; +./ + CallExpression: Super T_LPAREN Arguments T_RPAREN; /. case $rule_number: Q_FALLTHROUGH(); ./ CallExpression: CallExpression T_LPAREN Arguments T_RPAREN; @@ -2384,6 +2379,18 @@ CallExpression: CallExpression T_LPAREN Arguments T_RPAREN; } break; ./ +CallExpression: CallExpression T_QUESTION_DOT T_LPAREN Arguments T_RPAREN; +/. + case $rule_number: { + AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(4).ArgumentList); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->isOptional = true; + sym(1).Node = node; + } break; +./ + + CallExpression: CallExpression T_LBRACKET Expression_In T_RBRACKET; /. case $rule_number: { @@ -2394,6 +2401,17 @@ CallExpression: CallExpression T_LBRACKET Expression_In T_RBRACKET; } break; ./ +CallExpression: CallExpression T_QUESTION_DOT T_LBRACKET Expression_In T_RBRACKET; +/. + case $rule_number: { + AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(4).Expression); + node->lbracketToken = loc(3); + node->rbracketToken = loc(5); + node->isOptional = true; + sym(1).Node = node; + } break; +./ + CallExpression: CallExpression T_DOT IdentifierName; /. case $rule_number: { @@ -2404,6 +2422,17 @@ CallExpression: CallExpression T_DOT IdentifierName; } break; ./ +CallExpression: CallExpression T_QUESTION_DOT IdentifierName; +/. + case $rule_number: { + AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3)); + node->dotToken = loc(2); + node->identifierToken = loc(3); + node->isOptional = true; + sym(1).Node = node; + } break; +./ + Arguments: ; /. case $rule_number: { @@ -2697,30 +2726,22 @@ RelationalOperator: T_INSTANCEOF; sym(1).ival = QSOperator::InstanceOf; } break; ./ - -RelationalExpression_In: RelationalExpression_In T_IN ShiftExpression; +RelationalOperator: T_AS; /. 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; + sym(1).ival = QSOperator::As; } break; ./ -TypeAssertExpression_In: RelationalExpression_In T_AS TypeExpression; -/. case $rule_number: Q_FALLTHROUGH(); ./ -TypeAssertExpression: RelationalExpression T_AS TypeExpression; +RelationalExpression_In: RelationalExpression_In T_IN ShiftExpression; /. case $rule_number: { - AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::As, sym(3).Expression); + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::In, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; ./ -RelationalExpression_In: TypeAssertExpression_In; -RelationalExpression: TypeAssertExpression; - EqualityExpression_In: RelationalExpression_In; EqualityExpression: RelationalExpression; @@ -2897,6 +2918,9 @@ AssignmentExpression: LeftHandSideExpression T_EQ AssignmentExpression; AssignmentExpression_In: LeftHandSideExpression T_EQ AssignmentExpression_In; /. case $rule_number: { + if (sym(1).Expression->containsOptionalChain()) { + syntaxError(loc(1), QStringLiteral("Optional chains are not permitted on the left-hand-side in assignments")); + } // need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral if (AST::Pattern *p = sym(1).Expression->patternCast()) { SourceLocation errorLoc; @@ -2927,6 +2951,9 @@ AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpres AssignmentExpression_In: LeftHandSideExpression AssignmentOperator AssignmentExpression_In; /. case $rule_number: { + if (sym(1).Expression->containsOptionalChain()) { + syntaxError(loc(1), QStringLiteral("Optional chains are not permitted on the left-hand-side in assignments")); + } AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; @@ -3355,14 +3382,15 @@ BindingElisionElement: ElisionOpt BindingElement; BindingProperty: BindingIdentifier InitializerOpt_In; /. case $rule_number: { - AST::StringLiteralPropertyName *name = new (pool) AST::StringLiteralPropertyName(stringRef(1)); + AST::IdentifierPropertyName *name = new (pool) AST::IdentifierPropertyName(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); + AST::PatternProperty *node = new (pool) AST::PatternProperty(name, stringRef(1), sym(2).Expression); + sym(1).Node = node; } break; ./ @@ -3370,6 +3398,7 @@ 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); + node->colonToken = loc(2); sym(1).Node = node; } break; ./ @@ -3378,6 +3407,7 @@ BindingProperty: PropertyName T_COLON BindingPattern InitializerOpt_In; /. case $rule_number: { AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(1).PropertyName, sym(3).Pattern, sym(4).Expression); + node->colonToken = loc(2); sym(1).Node = node; } break; ./ @@ -4043,14 +4073,14 @@ ArrowFunction_In: ArrowParameters T_ARROW ConciseBodyLookahead AssignmentExpress /. 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(); + ret->returnToken = sym(4).Node->firstSourceLocation().startZeroLengthLocation(); + ret->semicolonToken = sym(4).Node->lastSourceLocation().endZeroLengthLocation(driver->code()); AST::StatementList *statements = (new (pool) AST::StatementList(ret))->finish(); AST::FunctionExpression *f = new (pool) AST::FunctionExpression(QStringView(), 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(); + f->functionToken = sym(1).Node ? sym(1).Node->firstSourceLocation().startZeroLengthLocation() : loc(1).startZeroLengthLocation(); + f->lbraceToken = sym(4).Node->firstSourceLocation().startZeroLengthLocation(); + f->rbraceToken = sym(4).Node->lastSourceLocation().endZeroLengthLocation(driver->code()); sym(1).Node = f; } break; ./ @@ -4062,8 +4092,8 @@ ArrowFunction_In: ArrowParameters T_ARROW ConciseBodyLookahead T_FORCE_BLOCK Fun case $rule_number: { AST::FunctionExpression *f = new (pool) AST::FunctionExpression(QStringView(), 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->functionToken = sym(1).Node ? sym(1).Node->firstSourceLocation().startZeroLengthLocation() : loc(1).startZeroLengthLocation(); + f->lbraceToken = loc(5); f->rbraceToken = loc(7); sym(1).Node = f; } break; @@ -4136,7 +4166,6 @@ MethodDefinition: T_STAR PropertyName GeneratorLParen StrictFormalParameters T_R f->rbraceToken = loc(9); 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; ./ @@ -4154,7 +4183,6 @@ MethodDefinition: T_GET PropertyName T_LPAREN T_RPAREN TypeAnnotationOpt Functio f->lbraceToken = loc(6); f->rbraceToken = loc(8); AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(2).PropertyName, f, AST::PatternProperty::Getter); - node->colonToken = loc(2); sym(1).Node = node; } break; ./ @@ -4171,7 +4199,6 @@ MethodDefinition: T_SET PropertyName T_LPAREN PropertySetParameterList T_RPAREN f->lbraceToken = loc(7); f->rbraceToken = loc(9); AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(2).PropertyName, f, AST::PatternProperty::Setter); - node->colonToken = loc(2); sym(1).Node = node; } break; ./ @@ -4350,16 +4377,16 @@ ClassDeclaration_Default: ClassDeclaration; ClassLBrace: T_LBRACE; /. case $rule_number: { - lexer->setStaticIsKeyword(true); + if (++classNestingLevel == 1) + lexer->setStaticIsKeyword(true); } break; ./ ClassRBrace: T_RBRACE; -/. case $rule_number: ./ -ClassStaticQualifier: T_STATIC; /. case $rule_number: { - lexer->setStaticIsKeyword(false); + if (--classNestingLevel == 0) + lexer->setStaticIsKeyword(false); } break; ./ @@ -4414,10 +4441,9 @@ ClassElement: MethodDefinition; } break; ./ -ClassElement: ClassStaticQualifier MethodDefinition; +ClassElement: T_STATIC MethodDefinition; /. case $rule_number: { - lexer->setStaticIsKeyword(true); AST::ClassElementList *node = new (pool) AST::ClassElementList(sym(2).PatternProperty, true); sym(1).Node = node; } break; @@ -4802,35 +4828,26 @@ ExportSpecifier: IdentifierName T_AS IdentifierName; if (first_token == last_token) { const int errorState = state_stack[tos]; + // automatic insertion of missing identifiers after dots + if (yytoken != -1 && m_identifierInsertionEnabled && t_action(errorState, T_IDENTIFIER) && yyprevtoken == T_DOT) { +#ifdef PARSER_DEBUG + qDebug() << "Inserting missing identifier between" << spell[yyprevtoken] << "and" + << spell[yytoken]; +#endif + pushTokenWithEmptyLocation(T_IDENTIFIER); + action = errorState; + goto _Lcheck_token; + } + + // 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; - yylloc.offset += yylloc.length; - yylloc.startColumn += yylloc.length; - yylloc.length = 0; - - //const QString msg = QCoreApplication::translate("QQmlParser", "Missing `;'"); - //diagnostic_messages.append(compileError(yyloc, msg, QtWarningMsg)); - - first_token = &token_buffer[0]; - last_token = &token_buffer[1]; - - yytoken = T_SEMICOLON; - yylval = 0; - + pushTokenWithEmptyLocation(T_SEMICOLON); action = errorState; - goto _Lcheck_token; } |