QmlJS: Update QML parser using the one from qtdeclarative 5.15

We need to do this because the new "required" keyword should be
recognized by Qt Creator.

This is not a verbatim copy of the QML parser from qtdeclarative. A few
data structures have changed that would require large scale changes in
otherwise unrelated parts of the code. For example, all Visitors need to
handle recursion depth errors now and the DiagnosticMessage only has
line and column now, no longer begin and legth.

Change-Id: Iea5b04e27b07e0cba55d64b844315af9828acbf7
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Ulf Hermann
2019-10-04 16:11:02 +02:00
parent 979d14525c
commit 58d35f8a64
14 changed files with 4344 additions and 3513 deletions

View File

@@ -51,21 +51,6 @@ ClassExpression *asAnonymousClassDefinition(Node *n)
return c;
}
void Node::accept(Visitor *visitor)
{
if (visitor->preVisit(this)) {
accept0(visitor);
}
visitor->postVisit(this);
}
void Node::accept(Node *node, Visitor *visitor)
{
if (node)
node->accept(visitor);
}
ExpressionNode *Node::expressionCast()
{
return nullptr;
@@ -106,6 +91,12 @@ ClassExpression *Node::asClassDefinition()
return nullptr;
}
bool Node::ignoreRecursionDepth() const
{
static const bool doIgnore = qEnvironmentVariableIsSet("QV4_CRASH_ON_STACKOVERFLOW");
return doIgnore;
}
ExpressionNode *ExpressionNode::expressionCast()
{
return this;
@@ -132,7 +123,7 @@ FormalParameterList *ExpressionNode::reparseAsFormalParameterList(MemoryPool *po
}
AST::PatternElement *binding = nullptr;
if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(expr)) {
binding = new (pool) AST::PatternElement(idExpr->name, rhs);
binding = new (pool) AST::PatternElement(idExpr->name, /*type annotation*/nullptr, rhs);
binding->identifierToken = idExpr->identifierToken;
} else if (AST::Pattern *p = expr->patternCast()) {
SourceLocation loc;
@@ -239,12 +230,11 @@ void StringLiteral::accept0(Visitor *visitor)
void TemplateLiteral::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
if (next)
accept(next, visitor);
bool accepted = true;
for (TemplateLiteral *it = this; it && accepted; it = it->next) {
accepted = visitor->visit(it);
visitor->endVisit(it);
}
visitor->endVisit(this);
}
void NumericLiteral::accept0(Visitor *visitor)
@@ -451,6 +441,8 @@ bool PatternProperty::convertLiteralToAssignmentPattern(MemoryPool *pool, Source
*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);
}
@@ -960,6 +952,7 @@ void FunctionDeclaration::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(formals, visitor);
accept(typeAnnotation, visitor);
accept(body, visitor);
}
@@ -970,6 +963,7 @@ void FunctionExpression::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(formals, visitor);
accept(typeAnnotation, visitor);
accept(body, visitor);
}
@@ -981,9 +975,9 @@ FunctionExpression *FunctionExpression::asFunctionDefinition()
return this;
}
QStringList FormalParameterList::formals() const
BoundNames FormalParameterList::formals() const
{
QStringList formals;
BoundNames formals;
int i = 0;
for (const FormalParameterList *it = this; it; it = it->next) {
if (it->element) {
@@ -991,18 +985,18 @@ QStringList FormalParameterList::formals() const
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[duplicateIndex].id += QLatin1String("#") + QString::number(i);
}
formals += name;
formals += {name, it->element->typeAnnotation};
}
++i;
}
return formals;
}
QStringList FormalParameterList::boundNames() const
BoundNames FormalParameterList::boundNames() const
{
QStringList names;
BoundNames names;
for (const FormalParameterList *it = this; it; it = it->next) {
if (it->element)
it->element->boundNames(&names);
@@ -1012,13 +1006,13 @@ QStringList FormalParameterList::boundNames() const
void FormalParameterList::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(element, visitor);
if (next)
accept(next, visitor);
bool accepted = true;
for (FormalParameterList *it = this; it && accepted; it = it->next) {
accepted = visitor->visit(it);
if (accepted)
accept(it->element, visitor);
visitor->endVisit(it);
}
visitor->endVisit(this);
}
FormalParameterList *FormalParameterList::finish(QmlJS::MemoryPool *pool)
@@ -1270,6 +1264,35 @@ void UiQualifiedId::accept0(Visitor *visitor)
visitor->endVisit(this);
}
void Type::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(typeId, visitor);
accept(typeArguments, visitor);
}
visitor->endVisit(this);
}
void TypeArgumentList::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
for (TypeArgumentList *it = this; it; it = it->next)
accept(it->typeId, visitor);
}
visitor->endVisit(this);
}
void TypeAnnotation::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(type, visitor);
}
visitor->endVisit(this);
}
void UiImport::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
@@ -1289,12 +1312,14 @@ void UiPragma::accept0(Visitor *visitor)
void UiHeaderItemList::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(headerItem, visitor);
accept(next, visitor);
}
bool accepted = true;
for (UiHeaderItemList *it = this; it && accepted; it = it->next) {
accepted = visitor->visit(it);
if (accepted)
accept(it->headerItem, visitor);
visitor->endVisit(this);
visitor->endVisit(it);
}
}
@@ -1338,13 +1363,14 @@ void PatternElement::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(bindingTarget, visitor);
accept(typeAnnotation, visitor);
accept(initializer, visitor);
}
visitor->endVisit(this);
}
void PatternElement::boundNames(QStringList *names)
void PatternElement::boundNames(BoundNames *names)
{
if (bindingTarget) {
if (PatternElementList *e = elementList())
@@ -1352,23 +1378,24 @@ void PatternElement::boundNames(QStringList *names)
else if (PatternPropertyList *p = propertyList())
p->boundNames(names);
} else {
names->append(bindingIdentifier.toString());
names->append({bindingIdentifier.toString(), typeAnnotation});
}
}
void PatternElementList::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(elision, visitor);
accept(element, visitor);
if (next)
accept(next, visitor);
bool accepted = true;
for (PatternElementList *it = this; it && accepted; it = it->next) {
accepted = visitor->visit(it);
if (accepted) {
accept(it->elision, visitor);
accept(it->element, visitor);
}
visitor->endVisit(it);
}
visitor->endVisit(this);
}
void PatternElementList::boundNames(QStringList *names)
void PatternElementList::boundNames(BoundNames *names)
{
for (PatternElementList *it = this; it; it = it->next) {
if (it->element)
@@ -1381,29 +1408,30 @@ void PatternProperty::accept0(Visitor *visitor)
if (visitor->visit(this)) {
accept(name, visitor);
accept(bindingTarget, visitor);
accept(typeAnnotation, visitor);
accept(initializer, visitor);
}
visitor->endVisit(this);
}
void PatternProperty::boundNames(QStringList *names)
void PatternProperty::boundNames(BoundNames *names)
{
PatternElement::boundNames(names);
}
void PatternPropertyList::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(property, visitor);
if (next)
accept(next, visitor);
bool accepted = true;
for (PatternPropertyList *it = this; it && accepted; it = it->next) {
accepted = visitor->visit(it);
if (accepted)
accept(it->property, visitor);
visitor->endVisit(it);
}
visitor->endVisit(this);
}
void PatternPropertyList::boundNames(QStringList *names)
void PatternPropertyList::boundNames(BoundNames *names)
{
for (PatternPropertyList *it = this; it; it = it->next)
it->property->boundNames(names);
@@ -1445,13 +1473,14 @@ void ClassDeclaration::accept0(Visitor *visitor)
void ClassElementList::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(property, visitor);
if (next)
accept(next, visitor);
}
bool accepted = true;
for (ClassElementList *it = this; it && accepted; it = it->next) {
accepted = visitor->visit(it);
if (accepted)
accept(it->property, visitor);
visitor->endVisit(this);
visitor->endVisit(it);
}
}
ClassElementList *ClassElementList::finish()
@@ -1471,6 +1500,37 @@ LeftHandSideExpression *LeftHandSideExpression::leftHandSideExpressionCast()
return this;
}
void UiVersionSpecifier::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
}
visitor->endVisit(this);
}
QString Type::toString() const
{
QString result;
toString(&result);
return result;
}
void Type::toString(QString *out) const
{
for (QmlJS::AST::UiQualifiedId *it = typeId; it; it = it->next) {
out->append(it->name);
if (it->next)
out->append(QLatin1Char('.'));
}
if (typeArguments) {
out->append(QLatin1Char('<'));
if (auto subType = static_cast<TypeArgumentList*>(typeArguments)->typeId)
subType->toString(out);
out->append(QLatin1Char('>'));
};
}
} } // namespace QmlJS::AST
QT_QML_END_NAMESPACE