forked from qt-creator/qt-creator
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user