diff options
author | Fawzi Mohamed <fawzi.mohamed@qt.io> | 2021-12-03 15:49:28 +0100 |
---|---|---|
committer | Fawzi Mohamed <fawzi.mohamed@qt.io> | 2021-12-16 08:27:55 +0000 |
commit | 125d7c0cced77ac39623cd05d0c22f690d427542 (patch) | |
tree | 8402171191639ff2bc206e41a93f5727752805e7 /src/libs/qmljs/parser/qmljs.g | |
parent | 16ced8a7d69c99b3ebf21c5fcc768c4043c365e3 (diff) |
Updating qmljs parser to latest qtdeclarative parser
improves support for string templates, required properties,
and other smaller improvements
Task-number: QTCREATORBUG-21869
Change-Id: Ia2359e1f75d4bd7b9ea4f27a920acd2251e36108
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/libs/qmljs/parser/qmljs.g')
-rw-r--r-- | src/libs/qmljs/parser/qmljs.g | 241 |
1 files changed, 95 insertions, 146 deletions
diff --git a/src/libs/qmljs/parser/qmljs.g b/src/libs/qmljs/parser/qmljs.g index ae79830d2e..5f62edf4d1 100644 --- a/src/libs/qmljs/parser/qmljs.g +++ b/src/libs/qmljs/parser/qmljs.g @@ -315,6 +315,7 @@ public: AST::UiPragma *UiPragma; AST::UiImport *UiImport; AST::UiParameterList *UiParameterList; + AST::UiPropertyAttributes *UiPropertyAttributes; AST::UiPublicMember *UiPublicMember; AST::UiObjectDefinition *UiObjectDefinition; AST::UiObjectInitializer *UiObjectInitializer; @@ -824,6 +825,16 @@ UiPragma: T_PRAGMA PragmaId Semicolon; } break; ./ +UiPragma: T_PRAGMA PragmaId T_COLON JsIdentifier Semicolon; +/. + case $rule_number: { + AST::UiPragma *pragma = new (pool) AST::UiPragma(stringRef(2), stringRef(4)); + pragma->pragmaToken = loc(1); + pragma->semicolonToken = loc(5); + sym(1).Node = pragma; + } break; +./ + ImportId: MemberExpression; UiImport: UiImportHead Semicolon; @@ -1262,7 +1273,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 +1287,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 +1295,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; - } break; -./ - -UiObjectMemberPropertyNoInitialiser: T_PROPERTY UiPropertyType QmlIdentifier 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; + 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; ./ - -UiObjectMember: UiObjectMemberPropertyNoInitialiser; - -UiObjectMember: T_DEFAULT UiObjectMemberPropertyNoInitialiser; +UiPropertyAttributes: AttrDefault 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->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: T_REQUIRED UiObjectMemberListPropertyNoInitialiser; +UiPropertyAttributes: AttrReadonly UiPropertyAttributes; /. case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->isRequired = true; - node->requiredToken = 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_DEFAULT T_REQUIRED UiObjectMemberListPropertyNoInitialiser; +UiPropertyAttributes: T_PROPERTY; /. 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; + AST::UiPropertyAttributes *node = new (pool) AST::UiPropertyAttributes(); + node->m_propertyToken = loc(1); + sym(1).UiPropertyAttributes = node; } break; ./ -UiObjectMember: T_REQUIRED T_DEFAULT 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(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 +1405,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); @@ -1447,32 +1422,15 @@ UiObjectMemberWithScriptStatement: T_PROPERTY UiPropertyType QmlIdentifier T_COL UiObjectMember: UiObjectMemberWithScriptStatement; -UiObjectMember: T_READONLY UiObjectMemberWithScriptStatement; -/. - case $rule_number: { - AST::UiPublicMember *node = sym(2).UiPublicMember; - node->isReadonlyMember = true; - node->readonlyToken = loc(1); - 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; -./ - -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 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); @@ -1480,7 +1438,7 @@ UiObjectMemberWithArray: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIde 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()); binding->colonToken = loc(7); @@ -1495,28 +1453,21 @@ 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 ':' 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 +1481,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: { @@ -2113,6 +2054,7 @@ 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; @@ -2245,7 +2187,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; /. @@ -4118,7 +4067,7 @@ ArrowFunction_In: ArrowParameters T_ARROW ConciseBodyLookahead T_FORCE_BLOCK Fun 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().startZeroLengthLocation() : loc(1).startZeroLengthLocation(); - f->lbraceToken = loc(6); + f->lbraceToken = loc(5); f->rbraceToken = loc(7); sym(1).Node = f; } break; |