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:
File diff suppressed because it is too large
Load Diff
@@ -51,21 +51,6 @@ ClassExpression *asAnonymousClassDefinition(Node *n)
|
|||||||
return c;
|
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()
|
ExpressionNode *Node::expressionCast()
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -106,6 +91,12 @@ ClassExpression *Node::asClassDefinition()
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Node::ignoreRecursionDepth() const
|
||||||
|
{
|
||||||
|
static const bool doIgnore = qEnvironmentVariableIsSet("QV4_CRASH_ON_STACKOVERFLOW");
|
||||||
|
return doIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
ExpressionNode *ExpressionNode::expressionCast()
|
ExpressionNode *ExpressionNode::expressionCast()
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
@@ -132,7 +123,7 @@ FormalParameterList *ExpressionNode::reparseAsFormalParameterList(MemoryPool *po
|
|||||||
}
|
}
|
||||||
AST::PatternElement *binding = nullptr;
|
AST::PatternElement *binding = nullptr;
|
||||||
if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(expr)) {
|
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;
|
binding->identifierToken = idExpr->identifierToken;
|
||||||
} else if (AST::Pattern *p = expr->patternCast()) {
|
} else if (AST::Pattern *p = expr->patternCast()) {
|
||||||
SourceLocation loc;
|
SourceLocation loc;
|
||||||
@@ -239,12 +230,11 @@ void StringLiteral::accept0(Visitor *visitor)
|
|||||||
|
|
||||||
void TemplateLiteral::accept0(Visitor *visitor)
|
void TemplateLiteral::accept0(Visitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
bool accepted = true;
|
||||||
if (next)
|
for (TemplateLiteral *it = this; it && accepted; it = it->next) {
|
||||||
accept(next, visitor);
|
accepted = visitor->visit(it);
|
||||||
|
visitor->endVisit(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitor->endVisit(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NumericLiteral::accept0(Visitor *visitor)
|
void NumericLiteral::accept0(Visitor *visitor)
|
||||||
@@ -451,6 +441,8 @@ bool PatternProperty::convertLiteralToAssignmentPattern(MemoryPool *pool, Source
|
|||||||
*errorMessage = QString::fromLatin1("Invalid getter/setter in destructuring expression.");
|
*errorMessage = QString::fromLatin1("Invalid getter/setter in destructuring expression.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (type == Method)
|
||||||
|
type = Literal;
|
||||||
Q_ASSERT(type == Literal);
|
Q_ASSERT(type == Literal);
|
||||||
return PatternElement::convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage);
|
return PatternElement::convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage);
|
||||||
}
|
}
|
||||||
@@ -960,6 +952,7 @@ void FunctionDeclaration::accept0(Visitor *visitor)
|
|||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
accept(formals, visitor);
|
accept(formals, visitor);
|
||||||
|
accept(typeAnnotation, visitor);
|
||||||
accept(body, visitor);
|
accept(body, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -970,6 +963,7 @@ void FunctionExpression::accept0(Visitor *visitor)
|
|||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
accept(formals, visitor);
|
accept(formals, visitor);
|
||||||
|
accept(typeAnnotation, visitor);
|
||||||
accept(body, visitor);
|
accept(body, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -981,9 +975,9 @@ FunctionExpression *FunctionExpression::asFunctionDefinition()
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList FormalParameterList::formals() const
|
BoundNames FormalParameterList::formals() const
|
||||||
{
|
{
|
||||||
QStringList formals;
|
BoundNames formals;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const FormalParameterList *it = this; it; it = it->next) {
|
for (const FormalParameterList *it = this; it; it = it->next) {
|
||||||
if (it->element) {
|
if (it->element) {
|
||||||
@@ -991,18 +985,18 @@ QStringList FormalParameterList::formals() const
|
|||||||
int duplicateIndex = formals.indexOf(name);
|
int duplicateIndex = formals.indexOf(name);
|
||||||
if (duplicateIndex >= 0) {
|
if (duplicateIndex >= 0) {
|
||||||
// change the name of the earlier argument to enforce the lookup semantics from the spec
|
// 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;
|
++i;
|
||||||
}
|
}
|
||||||
return formals;
|
return formals;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList FormalParameterList::boundNames() const
|
BoundNames FormalParameterList::boundNames() const
|
||||||
{
|
{
|
||||||
QStringList names;
|
BoundNames names;
|
||||||
for (const FormalParameterList *it = this; it; it = it->next) {
|
for (const FormalParameterList *it = this; it; it = it->next) {
|
||||||
if (it->element)
|
if (it->element)
|
||||||
it->element->boundNames(&names);
|
it->element->boundNames(&names);
|
||||||
@@ -1012,13 +1006,13 @@ QStringList FormalParameterList::boundNames() const
|
|||||||
|
|
||||||
void FormalParameterList::accept0(Visitor *visitor)
|
void FormalParameterList::accept0(Visitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
bool accepted = true;
|
||||||
accept(element, visitor);
|
for (FormalParameterList *it = this; it && accepted; it = it->next) {
|
||||||
if (next)
|
accepted = visitor->visit(it);
|
||||||
accept(next, visitor);
|
if (accepted)
|
||||||
|
accept(it->element, visitor);
|
||||||
|
visitor->endVisit(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitor->endVisit(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FormalParameterList *FormalParameterList::finish(QmlJS::MemoryPool *pool)
|
FormalParameterList *FormalParameterList::finish(QmlJS::MemoryPool *pool)
|
||||||
@@ -1270,6 +1264,35 @@ void UiQualifiedId::accept0(Visitor *visitor)
|
|||||||
visitor->endVisit(this);
|
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)
|
void UiImport::accept0(Visitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
@@ -1289,12 +1312,14 @@ void UiPragma::accept0(Visitor *visitor)
|
|||||||
|
|
||||||
void UiHeaderItemList::accept0(Visitor *visitor)
|
void UiHeaderItemList::accept0(Visitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
bool accepted = true;
|
||||||
accept(headerItem, visitor);
|
for (UiHeaderItemList *it = this; it && accepted; it = it->next) {
|
||||||
accept(next, visitor);
|
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)) {
|
if (visitor->visit(this)) {
|
||||||
accept(bindingTarget, visitor);
|
accept(bindingTarget, visitor);
|
||||||
|
accept(typeAnnotation, visitor);
|
||||||
accept(initializer, visitor);
|
accept(initializer, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitor->endVisit(this);
|
visitor->endVisit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternElement::boundNames(QStringList *names)
|
void PatternElement::boundNames(BoundNames *names)
|
||||||
{
|
{
|
||||||
if (bindingTarget) {
|
if (bindingTarget) {
|
||||||
if (PatternElementList *e = elementList())
|
if (PatternElementList *e = elementList())
|
||||||
@@ -1352,23 +1378,24 @@ void PatternElement::boundNames(QStringList *names)
|
|||||||
else if (PatternPropertyList *p = propertyList())
|
else if (PatternPropertyList *p = propertyList())
|
||||||
p->boundNames(names);
|
p->boundNames(names);
|
||||||
} else {
|
} else {
|
||||||
names->append(bindingIdentifier.toString());
|
names->append({bindingIdentifier.toString(), typeAnnotation});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternElementList::accept0(Visitor *visitor)
|
void PatternElementList::accept0(Visitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
bool accepted = true;
|
||||||
accept(elision, visitor);
|
for (PatternElementList *it = this; it && accepted; it = it->next) {
|
||||||
accept(element, visitor);
|
accepted = visitor->visit(it);
|
||||||
if (next)
|
if (accepted) {
|
||||||
accept(next, visitor);
|
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) {
|
for (PatternElementList *it = this; it; it = it->next) {
|
||||||
if (it->element)
|
if (it->element)
|
||||||
@@ -1381,29 +1408,30 @@ void PatternProperty::accept0(Visitor *visitor)
|
|||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
accept(name, visitor);
|
accept(name, visitor);
|
||||||
accept(bindingTarget, visitor);
|
accept(bindingTarget, visitor);
|
||||||
|
accept(typeAnnotation, visitor);
|
||||||
accept(initializer, visitor);
|
accept(initializer, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitor->endVisit(this);
|
visitor->endVisit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternProperty::boundNames(QStringList *names)
|
void PatternProperty::boundNames(BoundNames *names)
|
||||||
{
|
{
|
||||||
PatternElement::boundNames(names);
|
PatternElement::boundNames(names);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PatternPropertyList::accept0(Visitor *visitor)
|
void PatternPropertyList::accept0(Visitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
bool accepted = true;
|
||||||
accept(property, visitor);
|
for (PatternPropertyList *it = this; it && accepted; it = it->next) {
|
||||||
if (next)
|
accepted = visitor->visit(it);
|
||||||
accept(next, visitor);
|
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)
|
for (PatternPropertyList *it = this; it; it = it->next)
|
||||||
it->property->boundNames(names);
|
it->property->boundNames(names);
|
||||||
@@ -1445,13 +1473,14 @@ void ClassDeclaration::accept0(Visitor *visitor)
|
|||||||
|
|
||||||
void ClassElementList::accept0(Visitor *visitor)
|
void ClassElementList::accept0(Visitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
bool accepted = true;
|
||||||
accept(property, visitor);
|
for (ClassElementList *it = this; it && accepted; it = it->next) {
|
||||||
if (next)
|
accepted = visitor->visit(it);
|
||||||
accept(next, visitor);
|
if (accepted)
|
||||||
}
|
accept(it->property, visitor);
|
||||||
|
|
||||||
visitor->endVisit(this);
|
visitor->endVisit(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassElementList *ClassElementList::finish()
|
ClassElementList *ClassElementList::finish()
|
||||||
@@ -1471,6 +1500,37 @@ LeftHandSideExpression *LeftHandSideExpression::leftHandSideExpressionCast()
|
|||||||
return this;
|
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
|
} } // namespace QmlJS::AST
|
||||||
|
|
||||||
QT_QML_END_NAMESPACE
|
QT_QML_END_NAMESPACE
|
||||||
|
@@ -218,7 +218,9 @@ public:
|
|||||||
Kind_PatternElementList,
|
Kind_PatternElementList,
|
||||||
Kind_PatternProperty,
|
Kind_PatternProperty,
|
||||||
Kind_PatternPropertyList,
|
Kind_PatternPropertyList,
|
||||||
|
Kind_Type,
|
||||||
|
Kind_TypeArgumentList,
|
||||||
|
Kind_TypeAnnotation,
|
||||||
|
|
||||||
Kind_UiArrayBinding,
|
Kind_UiArrayBinding,
|
||||||
Kind_UiImport,
|
Kind_UiImport,
|
||||||
@@ -236,7 +238,8 @@ public:
|
|||||||
Kind_UiSourceElement,
|
Kind_UiSourceElement,
|
||||||
Kind_UiHeaderItemList,
|
Kind_UiHeaderItemList,
|
||||||
Kind_UiEnumDeclaration,
|
Kind_UiEnumDeclaration,
|
||||||
Kind_UiEnumMemberList
|
Kind_UiEnumMemberList,
|
||||||
|
Kind_UiVersionSpecifier
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Node() {}
|
inline Node() {}
|
||||||
@@ -256,11 +259,35 @@ public:
|
|||||||
virtual FunctionExpression *asFunctionDefinition();
|
virtual FunctionExpression *asFunctionDefinition();
|
||||||
virtual ClassExpression *asClassDefinition();
|
virtual ClassExpression *asClassDefinition();
|
||||||
|
|
||||||
void accept(Visitor *visitor);
|
bool ignoreRecursionDepth() const;
|
||||||
static void accept(Node *node, Visitor *visitor);
|
|
||||||
|
|
||||||
|
inline void accept(Visitor *visitor)
|
||||||
|
{
|
||||||
|
Visitor::RecursionDepthCheck recursionCheck(visitor);
|
||||||
|
|
||||||
|
// Stack overflow is uncommon, ignoreRecursionDepth() only returns true if
|
||||||
|
// QV4_CRASH_ON_STACKOVERFLOW is set, and ignoreRecursionDepth() needs to be out of line.
|
||||||
|
// Therefore, check for ignoreRecursionDepth() _after_ calling the inline recursionCheck().
|
||||||
|
if (recursionCheck() || ignoreRecursionDepth()) {
|
||||||
|
if (visitor->preVisit(this))
|
||||||
|
accept0(visitor);
|
||||||
|
visitor->postVisit(this);
|
||||||
|
} else {
|
||||||
|
visitor->throwRecursionDepthError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void accept(Node *node, Visitor *visitor)
|
||||||
|
{
|
||||||
|
if (node)
|
||||||
|
node->accept(visitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ### Remove when we can. This is part of the qmldevtools library, though.
|
||||||
inline static void acceptChild(Node *node, Visitor *visitor)
|
inline static void acceptChild(Node *node, Visitor *visitor)
|
||||||
{ return accept(node, visitor); } // ### remove
|
{
|
||||||
|
return accept(node, visitor);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void accept0(Visitor *visitor) = 0;
|
virtual void accept0(Visitor *visitor) = 0;
|
||||||
virtual SourceLocation firstSourceLocation() const = 0;
|
virtual SourceLocation firstSourceLocation() const = 0;
|
||||||
@@ -270,6 +297,139 @@ public:
|
|||||||
int kind = Kind_Undefined;
|
int kind = Kind_Undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T lastListElement(T head)
|
||||||
|
{
|
||||||
|
auto current = head;
|
||||||
|
while (current->next)
|
||||||
|
current = current->next;
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
class QML_PARSER_EXPORT UiQualifiedId: public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMLJS_DECLARE_AST_NODE(UiQualifiedId)
|
||||||
|
|
||||||
|
UiQualifiedId(const QStringRef &name)
|
||||||
|
: next(this), name(name)
|
||||||
|
{ kind = K; }
|
||||||
|
|
||||||
|
UiQualifiedId(UiQualifiedId *previous, const QStringRef &name)
|
||||||
|
: name(name)
|
||||||
|
{
|
||||||
|
kind = K;
|
||||||
|
next = previous->next;
|
||||||
|
previous->next = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
UiQualifiedId *finish()
|
||||||
|
{
|
||||||
|
UiQualifiedId *head = next;
|
||||||
|
next = nullptr;
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
void accept0(Visitor *visitor) override;
|
||||||
|
|
||||||
|
SourceLocation firstSourceLocation() const override
|
||||||
|
{ return identifierToken; }
|
||||||
|
|
||||||
|
SourceLocation lastSourceLocation() const override
|
||||||
|
{ return lastListElement(this)->identifierToken; }
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
UiQualifiedId *next;
|
||||||
|
QStringRef name;
|
||||||
|
SourceLocation identifierToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QML_PARSER_EXPORT Type: public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMLJS_DECLARE_AST_NODE(Type)
|
||||||
|
|
||||||
|
Type(UiQualifiedId *typeId, Node *typeArguments = nullptr)
|
||||||
|
: typeId(typeId)
|
||||||
|
, typeArguments(typeArguments)
|
||||||
|
{ kind = K; }
|
||||||
|
|
||||||
|
void accept0(Visitor *visitor) override;
|
||||||
|
|
||||||
|
SourceLocation firstSourceLocation() const override
|
||||||
|
{ return typeId->firstSourceLocation(); }
|
||||||
|
|
||||||
|
SourceLocation lastSourceLocation() const override
|
||||||
|
{ return typeArguments ? typeArguments->lastSourceLocation() : typeId->lastSourceLocation(); }
|
||||||
|
|
||||||
|
QString toString() const;
|
||||||
|
void toString(QString *out) const;
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
UiQualifiedId *typeId;
|
||||||
|
Node *typeArguments; // TypeArgumentList
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class QML_PARSER_EXPORT TypeArgumentList: public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMLJS_DECLARE_AST_NODE(TypeArgumentList)
|
||||||
|
|
||||||
|
TypeArgumentList(Type *typeId)
|
||||||
|
: typeId(typeId)
|
||||||
|
, next(nullptr)
|
||||||
|
{ kind = K; }
|
||||||
|
|
||||||
|
TypeArgumentList(TypeArgumentList *previous, Type *typeId)
|
||||||
|
: typeId(typeId)
|
||||||
|
{
|
||||||
|
kind = K;
|
||||||
|
next = previous->next;
|
||||||
|
previous->next = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void accept0(Visitor *visitor) override;
|
||||||
|
|
||||||
|
SourceLocation firstSourceLocation() const override
|
||||||
|
{ return typeId->firstSourceLocation(); }
|
||||||
|
|
||||||
|
SourceLocation lastSourceLocation() const override
|
||||||
|
{ return lastListElement(this)->typeId->lastSourceLocation(); }
|
||||||
|
|
||||||
|
inline TypeArgumentList *finish()
|
||||||
|
{
|
||||||
|
TypeArgumentList *front = next;
|
||||||
|
next = nullptr;
|
||||||
|
return front;
|
||||||
|
}
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
Type *typeId;
|
||||||
|
TypeArgumentList *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QML_PARSER_EXPORT TypeAnnotation: public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMLJS_DECLARE_AST_NODE(TypeAnnotation)
|
||||||
|
|
||||||
|
TypeAnnotation(Type *type)
|
||||||
|
: type(type)
|
||||||
|
{ kind = K; }
|
||||||
|
|
||||||
|
void accept0(Visitor *visitor) override;
|
||||||
|
|
||||||
|
SourceLocation firstSourceLocation() const override
|
||||||
|
{ return colonToken; }
|
||||||
|
|
||||||
|
SourceLocation lastSourceLocation() const override
|
||||||
|
{ return type->lastSourceLocation(); }
|
||||||
|
|
||||||
|
// attributes
|
||||||
|
Type *type;
|
||||||
|
SourceLocation colonToken;
|
||||||
|
};
|
||||||
class QML_PARSER_EXPORT ExpressionNode: public Node
|
class QML_PARSER_EXPORT ExpressionNode: public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -459,7 +619,30 @@ public:
|
|||||||
SourceLocation literalToken;
|
SourceLocation literalToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QML_PARSER_EXPORT StringLiteral: public LeftHandSideExpression
|
class QML_PARSER_EXPORT UiVersionSpecifier : public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMLJS_DECLARE_AST_NODE(UiVersionSpecifier)
|
||||||
|
|
||||||
|
UiVersionSpecifier(int majorum, int minorum) : majorVersion(majorum), minorVersion(minorum) { kind = K; }
|
||||||
|
|
||||||
|
void accept0(Visitor *visitor) override;
|
||||||
|
|
||||||
|
SourceLocation firstSourceLocation() const override { return majorToken; }
|
||||||
|
|
||||||
|
SourceLocation lastSourceLocation() const override
|
||||||
|
{
|
||||||
|
return minorToken.isValid() ? minorToken : majorToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
// attributes:
|
||||||
|
int majorVersion;
|
||||||
|
int minorVersion;
|
||||||
|
SourceLocation majorToken;
|
||||||
|
SourceLocation minorToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QML_PARSER_EXPORT StringLiteral : public LeftHandSideExpression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QMLJS_DECLARE_AST_NODE(StringLiteral)
|
QMLJS_DECLARE_AST_NODE(StringLiteral)
|
||||||
@@ -485,19 +668,23 @@ class QML_PARSER_EXPORT TemplateLiteral : public LeftHandSideExpression
|
|||||||
public:
|
public:
|
||||||
QMLJS_DECLARE_AST_NODE(TemplateLiteral)
|
QMLJS_DECLARE_AST_NODE(TemplateLiteral)
|
||||||
|
|
||||||
TemplateLiteral(const QStringRef &str, ExpressionNode *e)
|
TemplateLiteral(const QStringRef &str, const QStringRef &raw, ExpressionNode *e)
|
||||||
: value(str), expression(e), next(nullptr)
|
: value(str), rawValue(raw), expression(e), next(nullptr)
|
||||||
{ kind = K; }
|
{ kind = K; }
|
||||||
|
|
||||||
SourceLocation firstSourceLocation() const override
|
SourceLocation firstSourceLocation() const override
|
||||||
{ return literalToken; }
|
{ return literalToken; }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : (expression ? expression->lastSourceLocation() : literalToken); }
|
{
|
||||||
|
auto last = lastListElement(this);
|
||||||
|
return (last->expression ? last->expression->lastSourceLocation() : last->literalToken);
|
||||||
|
}
|
||||||
|
|
||||||
void accept0(Visitor *visitor) override;
|
void accept0(Visitor *visitor) override;
|
||||||
|
|
||||||
QStringRef value;
|
QStringRef value;
|
||||||
|
QStringRef rawValue;
|
||||||
ExpressionNode *expression;
|
ExpressionNode *expression;
|
||||||
TemplateLiteral *next;
|
TemplateLiteral *next;
|
||||||
SourceLocation literalToken;
|
SourceLocation literalToken;
|
||||||
@@ -614,7 +801,7 @@ public:
|
|||||||
{ return commaToken; }
|
{ return commaToken; }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : commaToken; }
|
{ return lastListElement(this)->commaToken; }
|
||||||
|
|
||||||
inline Elision *finish ()
|
inline Elision *finish ()
|
||||||
{
|
{
|
||||||
@@ -647,6 +834,34 @@ public:
|
|||||||
SourceLocation propertyNameToken;
|
SourceLocation propertyNameToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct QML_PARSER_EXPORT BoundName
|
||||||
|
{
|
||||||
|
QString id;
|
||||||
|
TypeAnnotation *typeAnnotation = nullptr;
|
||||||
|
BoundName(const QString &id, TypeAnnotation *typeAnnotation)
|
||||||
|
: id(id), typeAnnotation(typeAnnotation)
|
||||||
|
{}
|
||||||
|
BoundName() = default;
|
||||||
|
QString typeName() const { return typeAnnotation ? typeAnnotation->type->toString() : QString(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoundNames : public QVector<BoundName>
|
||||||
|
{
|
||||||
|
int indexOf(const QString &name, int from = 0) const
|
||||||
|
{
|
||||||
|
auto found = std::find_if(constBegin() + from, constEnd(),
|
||||||
|
[name](const BoundName &it) { return it.id == name; });
|
||||||
|
if (found == constEnd())
|
||||||
|
return -1;
|
||||||
|
return found - constBegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool contains(const QString &name) const
|
||||||
|
{
|
||||||
|
return indexOf(name) != -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class QML_PARSER_EXPORT PatternElement : public Node
|
class QML_PARSER_EXPORT PatternElement : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -655,6 +870,7 @@ public:
|
|||||||
enum Type {
|
enum Type {
|
||||||
// object literal types
|
// object literal types
|
||||||
Literal,
|
Literal,
|
||||||
|
Method,
|
||||||
Getter,
|
Getter,
|
||||||
Setter,
|
Setter,
|
||||||
|
|
||||||
@@ -670,8 +886,9 @@ public:
|
|||||||
: initializer(i), type(t)
|
: initializer(i), type(t)
|
||||||
{ kind = K; }
|
{ kind = K; }
|
||||||
|
|
||||||
PatternElement(const QStringRef &n, ExpressionNode *i = nullptr, Type t = Binding)
|
PatternElement(const QStringRef &n, TypeAnnotation *typeAnnotation = nullptr, ExpressionNode *i = nullptr, Type t = Binding)
|
||||||
: bindingIdentifier(n), initializer(i), type(t)
|
: bindingIdentifier(n), initializer(i), type(t)
|
||||||
|
, typeAnnotation(typeAnnotation)
|
||||||
{
|
{
|
||||||
Q_ASSERT(t >= RestElement);
|
Q_ASSERT(t >= RestElement);
|
||||||
kind = K;
|
kind = K;
|
||||||
@@ -691,7 +908,7 @@ public:
|
|||||||
{ return identifierToken.isValid() ? identifierToken : (bindingTarget ? bindingTarget->firstSourceLocation() : initializer->firstSourceLocation()); }
|
{ return identifierToken.isValid() ? identifierToken : (bindingTarget ? bindingTarget->firstSourceLocation() : initializer->firstSourceLocation()); }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return initializer ? initializer->lastSourceLocation() : (bindingTarget ? bindingTarget->lastSourceLocation() : identifierToken); }
|
{ return initializer ? initializer->lastSourceLocation() : (bindingTarget ? bindingTarget->lastSourceLocation() : (typeAnnotation ? typeAnnotation->lastSourceLocation() : identifierToken)); }
|
||||||
|
|
||||||
ExpressionNode *destructuringTarget() const { return bindingTarget; }
|
ExpressionNode *destructuringTarget() const { return bindingTarget; }
|
||||||
Pattern *destructuringPattern() const { return bindingTarget ? bindingTarget->patternCast() : nullptr; }
|
Pattern *destructuringPattern() const { return bindingTarget ? bindingTarget->patternCast() : nullptr; }
|
||||||
@@ -701,7 +918,7 @@ public:
|
|||||||
bool isVariableDeclaration() const { return scope != VariableScope::NoScope; }
|
bool isVariableDeclaration() const { return scope != VariableScope::NoScope; }
|
||||||
bool isLexicallyScoped() const { return scope == VariableScope::Let || scope == VariableScope::Const; }
|
bool isLexicallyScoped() const { return scope == VariableScope::Let || scope == VariableScope::Const; }
|
||||||
|
|
||||||
virtual void boundNames(QStringList *names);
|
virtual void boundNames(BoundNames *names);
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
SourceLocation identifierToken;
|
SourceLocation identifierToken;
|
||||||
@@ -709,6 +926,7 @@ public:
|
|||||||
ExpressionNode *bindingTarget = nullptr;
|
ExpressionNode *bindingTarget = nullptr;
|
||||||
ExpressionNode *initializer = nullptr;
|
ExpressionNode *initializer = nullptr;
|
||||||
Type type = Literal;
|
Type type = Literal;
|
||||||
|
TypeAnnotation *typeAnnotation = nullptr;
|
||||||
// when used in a VariableDeclarationList
|
// when used in a VariableDeclarationList
|
||||||
VariableScope scope = VariableScope::NoScope;
|
VariableScope scope = VariableScope::NoScope;
|
||||||
bool isForDeclaration = false;
|
bool isForDeclaration = false;
|
||||||
@@ -738,13 +956,16 @@ public:
|
|||||||
|
|
||||||
void accept0(Visitor *visitor) override;
|
void accept0(Visitor *visitor) override;
|
||||||
|
|
||||||
void boundNames(QStringList *names);
|
void boundNames(BoundNames *names);
|
||||||
|
|
||||||
SourceLocation firstSourceLocation() const override
|
SourceLocation firstSourceLocation() const override
|
||||||
{ return elision ? elision->firstSourceLocation() : element->firstSourceLocation(); }
|
{ return elision ? elision->firstSourceLocation() : element->firstSourceLocation(); }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : (element ? element->lastSourceLocation() : elision->lastSourceLocation()); }
|
{
|
||||||
|
auto last = lastListElement(this);
|
||||||
|
return last->element ? last->element->lastSourceLocation() : last->elision->lastSourceLocation();
|
||||||
|
}
|
||||||
|
|
||||||
Elision *elision = nullptr;
|
Elision *elision = nullptr;
|
||||||
PatternElement *element = nullptr;
|
PatternElement *element = nullptr;
|
||||||
@@ -761,7 +982,7 @@ public:
|
|||||||
{ kind = K; }
|
{ kind = K; }
|
||||||
|
|
||||||
PatternProperty(PropertyName *name, const QStringRef &n, ExpressionNode *i = nullptr)
|
PatternProperty(PropertyName *name, const QStringRef &n, ExpressionNode *i = nullptr)
|
||||||
: PatternElement(n, i), name(name)
|
: PatternElement(n, /*type annotation*/nullptr, i), name(name)
|
||||||
{ kind = K; }
|
{ kind = K; }
|
||||||
|
|
||||||
PatternProperty(PropertyName *name, Pattern *pattern, ExpressionNode *i = nullptr)
|
PatternProperty(PropertyName *name, Pattern *pattern, ExpressionNode *i = nullptr)
|
||||||
@@ -778,7 +999,7 @@ public:
|
|||||||
return loc.isValid() ? loc : name->lastSourceLocation();
|
return loc.isValid() ? loc : name->lastSourceLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void boundNames(QStringList *names) override;
|
void boundNames(BoundNames *names) override;
|
||||||
bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) override;
|
bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) override;
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
@@ -806,7 +1027,7 @@ public:
|
|||||||
|
|
||||||
void accept0(Visitor *visitor) override;
|
void accept0(Visitor *visitor) override;
|
||||||
|
|
||||||
void boundNames(QStringList *names);
|
void boundNames(BoundNames *names);
|
||||||
|
|
||||||
inline PatternPropertyList *finish ()
|
inline PatternPropertyList *finish ()
|
||||||
{
|
{
|
||||||
@@ -819,7 +1040,7 @@ public:
|
|||||||
{ return property->firstSourceLocation(); }
|
{ return property->firstSourceLocation(); }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : property->lastSourceLocation(); }
|
{ return lastListElement(this)->property->lastSourceLocation(); }
|
||||||
|
|
||||||
PatternProperty *property;
|
PatternProperty *property;
|
||||||
PatternPropertyList *next;
|
PatternPropertyList *next;
|
||||||
@@ -1428,7 +1649,9 @@ public:
|
|||||||
{ return statement->firstSourceLocation(); }
|
{ return statement->firstSourceLocation(); }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : statement->lastSourceLocation(); }
|
{
|
||||||
|
return lastListElement(this)->statement->lastSourceLocation();
|
||||||
|
}
|
||||||
|
|
||||||
inline StatementList *finish ()
|
inline StatementList *finish ()
|
||||||
{
|
{
|
||||||
@@ -1543,7 +1766,7 @@ public:
|
|||||||
{ return expression->firstSourceLocation(); }
|
{ return expression->firstSourceLocation(); }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return semicolonToken.isValid() ? semicolonToken : expression->lastSourceLocation(); }
|
{ return expression->lastSourceLocation(); }
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
ExpressionNode *expression;
|
ExpressionNode *expression;
|
||||||
@@ -1921,7 +2144,9 @@ public:
|
|||||||
{ return clause->firstSourceLocation(); }
|
{ return clause->firstSourceLocation(); }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : clause->lastSourceLocation(); }
|
{
|
||||||
|
return lastListElement(this)->clause->lastSourceLocation();
|
||||||
|
}
|
||||||
|
|
||||||
inline CaseClauses *finish ()
|
inline CaseClauses *finish ()
|
||||||
{
|
{
|
||||||
@@ -2096,8 +2321,9 @@ class QML_PARSER_EXPORT FunctionExpression: public ExpressionNode
|
|||||||
public:
|
public:
|
||||||
QMLJS_DECLARE_AST_NODE(FunctionExpression)
|
QMLJS_DECLARE_AST_NODE(FunctionExpression)
|
||||||
|
|
||||||
FunctionExpression(const QStringRef &n, FormalParameterList *f, StatementList *b):
|
FunctionExpression(const QStringRef &n, FormalParameterList *f, StatementList *b, TypeAnnotation *typeAnnotation = nullptr):
|
||||||
name (n), formals (f), body (b)
|
name (n), formals (f), body (b),
|
||||||
|
typeAnnotation(typeAnnotation)
|
||||||
{ kind = K; }
|
{ kind = K; }
|
||||||
|
|
||||||
void accept0(Visitor *visitor) override;
|
void accept0(Visitor *visitor) override;
|
||||||
@@ -2116,6 +2342,7 @@ public:
|
|||||||
bool isGenerator = false;
|
bool isGenerator = false;
|
||||||
FormalParameterList *formals;
|
FormalParameterList *formals;
|
||||||
StatementList *body;
|
StatementList *body;
|
||||||
|
TypeAnnotation *typeAnnotation;
|
||||||
SourceLocation functionToken;
|
SourceLocation functionToken;
|
||||||
SourceLocation identifierToken;
|
SourceLocation identifierToken;
|
||||||
SourceLocation lparenToken;
|
SourceLocation lparenToken;
|
||||||
@@ -2129,8 +2356,8 @@ class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression
|
|||||||
public:
|
public:
|
||||||
QMLJS_DECLARE_AST_NODE(FunctionDeclaration)
|
QMLJS_DECLARE_AST_NODE(FunctionDeclaration)
|
||||||
|
|
||||||
FunctionDeclaration(const QStringRef &n, FormalParameterList *f, StatementList *b):
|
FunctionDeclaration(const QStringRef &n, FormalParameterList *f, StatementList *b, TypeAnnotation *typeAnnotation = nullptr):
|
||||||
FunctionExpression(n, f, b)
|
FunctionExpression(n, f, b, typeAnnotation)
|
||||||
{ kind = K; }
|
{ kind = K; }
|
||||||
|
|
||||||
void accept0(Visitor *visitor) override;
|
void accept0(Visitor *visitor) override;
|
||||||
@@ -2200,9 +2427,9 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList formals() const;
|
BoundNames formals() const;
|
||||||
|
|
||||||
QStringList boundNames() const;
|
BoundNames boundNames() const;
|
||||||
|
|
||||||
void accept0(Visitor *visitor) override;
|
void accept0(Visitor *visitor) override;
|
||||||
|
|
||||||
@@ -2210,7 +2437,9 @@ public:
|
|||||||
{ return element->firstSourceLocation(); }
|
{ return element->firstSourceLocation(); }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : element->lastSourceLocation(); }
|
{
|
||||||
|
return lastListElement(this)->element->lastSourceLocation();
|
||||||
|
}
|
||||||
|
|
||||||
FormalParameterList *finish(MemoryPool *pool);
|
FormalParameterList *finish(MemoryPool *pool);
|
||||||
|
|
||||||
@@ -2387,7 +2616,9 @@ public:
|
|||||||
{ return importSpecifierToken; }
|
{ return importSpecifierToken; }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : importSpecifierToken; }
|
{
|
||||||
|
return lastListElement(this)->importSpecifierToken;
|
||||||
|
}
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
SourceLocation importSpecifierToken;
|
SourceLocation importSpecifierToken;
|
||||||
@@ -2624,7 +2855,7 @@ public:
|
|||||||
SourceLocation firstSourceLocation() const override
|
SourceLocation firstSourceLocation() const override
|
||||||
{ return exportSpecifier->firstSourceLocation(); }
|
{ return exportSpecifier->firstSourceLocation(); }
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : exportSpecifier->lastSourceLocation(); }
|
{ return lastListElement(this)->exportSpecifier->lastSourceLocation(); }
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
ExportSpecifier *exportSpecifier;
|
ExportSpecifier *exportSpecifier;
|
||||||
@@ -2751,44 +2982,6 @@ public:
|
|||||||
SourceLocation semicolonToken;
|
SourceLocation semicolonToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QML_PARSER_EXPORT UiQualifiedId: public Node
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QMLJS_DECLARE_AST_NODE(UiQualifiedId)
|
|
||||||
|
|
||||||
UiQualifiedId(const QStringRef &name)
|
|
||||||
: next(this), name(name)
|
|
||||||
{ kind = K; }
|
|
||||||
|
|
||||||
UiQualifiedId(UiQualifiedId *previous, const QStringRef &name)
|
|
||||||
: name(name)
|
|
||||||
{
|
|
||||||
kind = K;
|
|
||||||
next = previous->next;
|
|
||||||
previous->next = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
UiQualifiedId *finish()
|
|
||||||
{
|
|
||||||
UiQualifiedId *head = next;
|
|
||||||
next = nullptr;
|
|
||||||
return head;
|
|
||||||
}
|
|
||||||
|
|
||||||
void accept0(Visitor *visitor) override;
|
|
||||||
|
|
||||||
SourceLocation firstSourceLocation() const override
|
|
||||||
{ return identifierToken; }
|
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
|
||||||
{ return next ? next->lastSourceLocation() : identifierToken; }
|
|
||||||
|
|
||||||
// attributes
|
|
||||||
UiQualifiedId *next;
|
|
||||||
QStringRef name;
|
|
||||||
SourceLocation identifierToken;
|
|
||||||
};
|
|
||||||
|
|
||||||
class QML_PARSER_EXPORT UiImport: public Node
|
class QML_PARSER_EXPORT UiImport: public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -2820,6 +3013,7 @@ public:
|
|||||||
SourceLocation asToken;
|
SourceLocation asToken;
|
||||||
SourceLocation importIdToken;
|
SourceLocation importIdToken;
|
||||||
SourceLocation semicolonToken;
|
SourceLocation semicolonToken;
|
||||||
|
UiVersionSpecifier *version = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QML_PARSER_EXPORT UiObjectMember: public Node
|
class QML_PARSER_EXPORT UiObjectMember: public Node
|
||||||
@@ -2854,7 +3048,7 @@ public:
|
|||||||
{ return member->firstSourceLocation(); }
|
{ return member->firstSourceLocation(); }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : member->lastSourceLocation(); }
|
{ return lastListElement(this)->member->lastSourceLocation(); }
|
||||||
|
|
||||||
UiObjectMemberList *finish()
|
UiObjectMemberList *finish()
|
||||||
{
|
{
|
||||||
@@ -2933,7 +3127,7 @@ public:
|
|||||||
{ return headerItem->firstSourceLocation(); }
|
{ return headerItem->firstSourceLocation(); }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : headerItem->lastSourceLocation(); }
|
{ return lastListElement(this)->headerItem->lastSourceLocation(); }
|
||||||
|
|
||||||
// attributes
|
// attributes
|
||||||
Node *headerItem;
|
Node *headerItem;
|
||||||
@@ -2997,7 +3191,7 @@ public:
|
|||||||
{ return member->firstSourceLocation(); }
|
{ return member->firstSourceLocation(); }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : member->lastSourceLocation(); }
|
{ return lastListElement(this)->member->lastSourceLocation(); }
|
||||||
|
|
||||||
UiArrayMemberList *finish()
|
UiArrayMemberList *finish()
|
||||||
{
|
{
|
||||||
@@ -3055,10 +3249,13 @@ public:
|
|||||||
void accept0(Visitor *) override;
|
void accept0(Visitor *) override;
|
||||||
|
|
||||||
SourceLocation firstSourceLocation() const override
|
SourceLocation firstSourceLocation() const override
|
||||||
{ return propertyTypeToken; }
|
{ return colonToken.isValid() ? identifierToken : propertyTypeToken; }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() : identifierToken; }
|
{
|
||||||
|
auto last = lastListElement(this);
|
||||||
|
return (last->colonToken.isValid() ? last->propertyTypeToken : last->identifierToken);
|
||||||
|
}
|
||||||
|
|
||||||
inline UiParameterList *finish ()
|
inline UiParameterList *finish ()
|
||||||
{
|
{
|
||||||
@@ -3074,6 +3271,7 @@ public:
|
|||||||
SourceLocation commaToken;
|
SourceLocation commaToken;
|
||||||
SourceLocation propertyTypeToken;
|
SourceLocation propertyTypeToken;
|
||||||
SourceLocation identifierToken;
|
SourceLocation identifierToken;
|
||||||
|
SourceLocation colonToken;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QML_PARSER_EXPORT UiPublicMember: public UiObjectMember
|
class QML_PARSER_EXPORT UiPublicMember: public UiObjectMember
|
||||||
@@ -3100,6 +3298,8 @@ public:
|
|||||||
return defaultToken;
|
return defaultToken;
|
||||||
else if (readonlyToken.isValid())
|
else if (readonlyToken.isValid())
|
||||||
return readonlyToken;
|
return readonlyToken;
|
||||||
|
else if (requiredToken.isValid())
|
||||||
|
return requiredToken;
|
||||||
|
|
||||||
return propertyToken;
|
return propertyToken;
|
||||||
}
|
}
|
||||||
@@ -3123,10 +3323,13 @@ public:
|
|||||||
UiObjectMember *binding; // initialized with a QML object or array.
|
UiObjectMember *binding; // initialized with a QML object or array.
|
||||||
bool isDefaultMember;
|
bool isDefaultMember;
|
||||||
bool isReadonlyMember;
|
bool isReadonlyMember;
|
||||||
|
bool isRequired = false;
|
||||||
UiParameterList *parameters;
|
UiParameterList *parameters;
|
||||||
|
// TODO: merge source locations
|
||||||
SourceLocation defaultToken;
|
SourceLocation defaultToken;
|
||||||
SourceLocation readonlyToken;
|
SourceLocation readonlyToken;
|
||||||
SourceLocation propertyToken;
|
SourceLocation propertyToken;
|
||||||
|
SourceLocation requiredToken;
|
||||||
SourceLocation typeModifierToken;
|
SourceLocation typeModifierToken;
|
||||||
SourceLocation typeToken;
|
SourceLocation typeToken;
|
||||||
SourceLocation identifierToken;
|
SourceLocation identifierToken;
|
||||||
@@ -3168,7 +3371,7 @@ public:
|
|||||||
|
|
||||||
SourceLocation firstSourceLocation() const override
|
SourceLocation firstSourceLocation() const override
|
||||||
{
|
{
|
||||||
if (FunctionDeclaration *funDecl = cast<FunctionDeclaration *>(sourceElement))
|
if (FunctionExpression *funDecl = sourceElement->asFunctionDefinition())
|
||||||
return funDecl->firstSourceLocation();
|
return funDecl->firstSourceLocation();
|
||||||
else if (VariableStatement *varStmt = cast<VariableStatement *>(sourceElement))
|
else if (VariableStatement *varStmt = cast<VariableStatement *>(sourceElement))
|
||||||
return varStmt->firstSourceLocation();
|
return varStmt->firstSourceLocation();
|
||||||
@@ -3178,7 +3381,7 @@ public:
|
|||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{
|
{
|
||||||
if (FunctionDeclaration *funDecl = cast<FunctionDeclaration *>(sourceElement))
|
if (FunctionExpression *funDecl = sourceElement->asFunctionDefinition())
|
||||||
return funDecl->lastSourceLocation();
|
return funDecl->lastSourceLocation();
|
||||||
else if (VariableStatement *varStmt = cast<VariableStatement *>(sourceElement))
|
else if (VariableStatement *varStmt = cast<VariableStatement *>(sourceElement))
|
||||||
return varStmt->lastSourceLocation();
|
return varStmt->lastSourceLocation();
|
||||||
@@ -3310,8 +3513,10 @@ public:
|
|||||||
{ return memberToken; }
|
{ return memberToken; }
|
||||||
|
|
||||||
SourceLocation lastSourceLocation() const override
|
SourceLocation lastSourceLocation() const override
|
||||||
{ return next ? next->lastSourceLocation() :
|
{
|
||||||
valueToken.isValid() ? valueToken : memberToken; }
|
auto last = lastListElement(this);
|
||||||
|
return last->valueToken.isValid() ? last->valueToken : last->memberToken;
|
||||||
|
}
|
||||||
|
|
||||||
void accept0(Visitor *visitor) override;
|
void accept0(Visitor *visitor) override;
|
||||||
|
|
||||||
|
@@ -163,6 +163,9 @@ class NestedExpression;
|
|||||||
class ClassExpression;
|
class ClassExpression;
|
||||||
class ClassDeclaration;
|
class ClassDeclaration;
|
||||||
class ClassElementList;
|
class ClassElementList;
|
||||||
|
class TypeArgumentList;
|
||||||
|
class Type;
|
||||||
|
class TypeAnnotation;
|
||||||
|
|
||||||
// ui elements
|
// ui elements
|
||||||
class UiProgram;
|
class UiProgram;
|
||||||
@@ -183,6 +186,7 @@ class UiQualifiedId;
|
|||||||
class UiHeaderItemList;
|
class UiHeaderItemList;
|
||||||
class UiEnumDeclaration;
|
class UiEnumDeclaration;
|
||||||
class UiEnumMemberList;
|
class UiEnumMemberList;
|
||||||
|
class UiVersionSpecifier;
|
||||||
|
|
||||||
} } // namespace AST
|
} } // namespace AST
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@ QT_QML_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
namespace QmlJS { namespace AST {
|
namespace QmlJS { namespace AST {
|
||||||
|
|
||||||
Visitor::Visitor()
|
Visitor::Visitor(quint16 parentRecursionDepth) : m_recursionDepth(parentRecursionDepth)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,7 +46,33 @@ namespace QmlJS { namespace AST {
|
|||||||
class QML_PARSER_EXPORT Visitor
|
class QML_PARSER_EXPORT Visitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Visitor();
|
class RecursionDepthCheck
|
||||||
|
{
|
||||||
|
Q_DISABLE_COPY(RecursionDepthCheck)
|
||||||
|
public:
|
||||||
|
RecursionDepthCheck(RecursionDepthCheck &&) = delete;
|
||||||
|
RecursionDepthCheck &operator=(RecursionDepthCheck &&) = delete;
|
||||||
|
|
||||||
|
RecursionDepthCheck(Visitor *visitor) : m_visitor(visitor)
|
||||||
|
{
|
||||||
|
++(m_visitor->m_recursionDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
~RecursionDepthCheck()
|
||||||
|
{
|
||||||
|
--(m_visitor->m_recursionDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()() const {
|
||||||
|
return m_visitor->m_recursionDepth < s_recursionLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const quint16 s_recursionLimit = 4096;
|
||||||
|
Visitor *m_visitor;
|
||||||
|
};
|
||||||
|
|
||||||
|
Visitor(quint16 parentRecursionDepth = 0);
|
||||||
virtual ~Visitor();
|
virtual ~Visitor();
|
||||||
|
|
||||||
virtual bool preVisit(Node *) { return true; }
|
virtual bool preVisit(Node *) { return true; }
|
||||||
@@ -70,6 +96,7 @@ public:
|
|||||||
virtual bool visit(UiQualifiedId *) { return true; }
|
virtual bool visit(UiQualifiedId *) { return true; }
|
||||||
virtual bool visit(UiEnumDeclaration *) { return true; }
|
virtual bool visit(UiEnumDeclaration *) { return true; }
|
||||||
virtual bool visit(UiEnumMemberList *) { return true; }
|
virtual bool visit(UiEnumMemberList *) { return true; }
|
||||||
|
virtual bool visit(UiVersionSpecifier *) { return true; }
|
||||||
|
|
||||||
virtual void endVisit(UiProgram *) {}
|
virtual void endVisit(UiProgram *) {}
|
||||||
virtual void endVisit(UiImport *) {}
|
virtual void endVisit(UiImport *) {}
|
||||||
@@ -88,6 +115,7 @@ public:
|
|||||||
virtual void endVisit(UiQualifiedId *) {}
|
virtual void endVisit(UiQualifiedId *) {}
|
||||||
virtual void endVisit(UiEnumDeclaration *) {}
|
virtual void endVisit(UiEnumDeclaration *) {}
|
||||||
virtual void endVisit(UiEnumMemberList *) { }
|
virtual void endVisit(UiEnumMemberList *) { }
|
||||||
|
virtual void endVisit(UiVersionSpecifier *) {}
|
||||||
|
|
||||||
// QmlJS
|
// QmlJS
|
||||||
virtual bool visit(ThisExpression *) { return true; }
|
virtual bool visit(ThisExpression *) { return true; }
|
||||||
@@ -359,6 +387,23 @@ public:
|
|||||||
|
|
||||||
virtual bool visit(DebuggerStatement *) { return true; }
|
virtual bool visit(DebuggerStatement *) { return true; }
|
||||||
virtual void endVisit(DebuggerStatement *) {}
|
virtual void endVisit(DebuggerStatement *) {}
|
||||||
|
|
||||||
|
virtual bool visit(Type *) { return true; }
|
||||||
|
virtual void endVisit(Type *) {}
|
||||||
|
|
||||||
|
virtual bool visit(TypeArgumentList *) { return true; }
|
||||||
|
virtual void endVisit(TypeArgumentList *) {}
|
||||||
|
|
||||||
|
virtual bool visit(TypeAnnotation *) { return true; }
|
||||||
|
virtual void endVisit(TypeAnnotation *) {}
|
||||||
|
|
||||||
|
virtual void throwRecursionDepthError() {}
|
||||||
|
|
||||||
|
quint16 recursionDepth() const { return m_recursionDepth; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
quint16 m_recursionDepth = 0;
|
||||||
|
friend class RecursionDepthCheck;
|
||||||
};
|
};
|
||||||
|
|
||||||
} } // namespace AST
|
} } // namespace AST
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -50,152 +50,150 @@ class QML_PARSER_EXPORT QmlJSGrammar
|
|||||||
public:
|
public:
|
||||||
enum VariousConstants {
|
enum VariousConstants {
|
||||||
EOF_SYMBOL = 0,
|
EOF_SYMBOL = 0,
|
||||||
REDUCE_HERE = 125,
|
REDUCE_HERE = 128,
|
||||||
T_AND = 1,
|
T_AND = 1,
|
||||||
T_AND_AND = 2,
|
T_AND_AND = 2,
|
||||||
T_AND_EQ = 3,
|
T_AND_EQ = 3,
|
||||||
T_ARROW = 93,
|
T_ARROW = 95,
|
||||||
T_AS = 110,
|
T_AS = 113,
|
||||||
T_AUTOMATIC_SEMICOLON = 62,
|
T_AUTOMATIC_SEMICOLON = 64,
|
||||||
T_BREAK = 4,
|
T_BREAK = 4,
|
||||||
T_CASE = 5,
|
T_CASE = 5,
|
||||||
T_CATCH = 6,
|
T_CATCH = 6,
|
||||||
T_CLASS = 98,
|
T_CLASS = 100,
|
||||||
T_COLON = 7,
|
T_COLON = 7,
|
||||||
T_COMMA = 8,
|
T_COMMA = 8,
|
||||||
T_COMMENT = 91,
|
T_COMMENT = 93,
|
||||||
T_COMPATIBILITY_SEMICOLON = 92,
|
T_COMPATIBILITY_SEMICOLON = 94,
|
||||||
T_CONST = 86,
|
T_CONST = 88,
|
||||||
T_CONTINUE = 9,
|
T_CONTINUE = 9,
|
||||||
T_DEBUGGER = 88,
|
T_DEBUGGER = 90,
|
||||||
T_DEFAULT = 10,
|
T_DEFAULT = 10,
|
||||||
T_DELETE = 11,
|
T_DELETE = 11,
|
||||||
T_DIVIDE_ = 12,
|
T_DIVIDE_ = 12,
|
||||||
T_DIVIDE_EQ = 13,
|
T_DIVIDE_EQ = 13,
|
||||||
T_DO = 14,
|
T_DO = 14,
|
||||||
T_DOT = 15,
|
T_DOT = 15,
|
||||||
T_ELLIPSIS = 95,
|
T_ELLIPSIS = 97,
|
||||||
T_ELSE = 16,
|
T_ELSE = 16,
|
||||||
T_ENUM = 94,
|
T_ENUM = 96,
|
||||||
T_EQ = 17,
|
T_EQ = 17,
|
||||||
T_EQ_EQ = 18,
|
T_EQ_EQ = 18,
|
||||||
T_EQ_EQ_EQ = 19,
|
T_EQ_EQ_EQ = 19,
|
||||||
T_ERROR = 114,
|
T_ERROR = 117,
|
||||||
T_EXPORT = 101,
|
T_EXPORT = 103,
|
||||||
T_EXTENDS = 99,
|
T_EXTENDS = 101,
|
||||||
T_FALSE = 85,
|
T_FALSE = 87,
|
||||||
T_FEED_JS_EXPRESSION = 118,
|
T_FEED_JS_EXPRESSION = 121,
|
||||||
T_FEED_JS_MODULE = 120,
|
T_FEED_JS_MODULE = 123,
|
||||||
T_FEED_JS_SCRIPT = 119,
|
T_FEED_JS_SCRIPT = 122,
|
||||||
T_FEED_JS_STATEMENT = 117,
|
T_FEED_JS_STATEMENT = 120,
|
||||||
T_FEED_UI_OBJECT_MEMBER = 116,
|
T_FEED_UI_OBJECT_MEMBER = 119,
|
||||||
T_FEED_UI_PROGRAM = 115,
|
T_FEED_UI_PROGRAM = 118,
|
||||||
T_FINALLY = 20,
|
T_FINALLY = 20,
|
||||||
T_FOR = 21,
|
T_FOR = 21,
|
||||||
T_FORCE_BLOCK = 122,
|
T_FORCE_BLOCK = 125,
|
||||||
T_FORCE_DECLARATION = 121,
|
T_FORCE_DECLARATION = 124,
|
||||||
T_FOR_LOOKAHEAD_OK = 123,
|
T_FOR_LOOKAHEAD_OK = 126,
|
||||||
T_FROM = 102,
|
T_FROM = 104,
|
||||||
T_FUNCTION = 22,
|
T_FUNCTION = 23,
|
||||||
T_GE = 23,
|
T_FUNCTION_STAR = 22,
|
||||||
T_GET = 112,
|
T_GE = 24,
|
||||||
T_GT = 24,
|
T_GET = 115,
|
||||||
T_GT_GT = 25,
|
T_GT = 25,
|
||||||
T_GT_GT_EQ = 26,
|
T_GT_GT = 26,
|
||||||
T_GT_GT_GT = 27,
|
T_GT_GT_EQ = 27,
|
||||||
T_GT_GT_GT_EQ = 28,
|
T_GT_GT_GT = 28,
|
||||||
T_IDENTIFIER = 29,
|
T_GT_GT_GT_EQ = 29,
|
||||||
T_IF = 30,
|
T_IDENTIFIER = 30,
|
||||||
T_IMPORT = 108,
|
T_IF = 31,
|
||||||
T_IN = 31,
|
T_IMPORT = 111,
|
||||||
T_INSTANCEOF = 32,
|
T_IN = 32,
|
||||||
T_LBRACE = 33,
|
T_INSTANCEOF = 33,
|
||||||
T_LBRACKET = 34,
|
T_LBRACE = 34,
|
||||||
T_LE = 35,
|
T_LBRACKET = 35,
|
||||||
T_LET = 87,
|
T_LE = 36,
|
||||||
T_LPAREN = 36,
|
T_LET = 89,
|
||||||
T_LT = 37,
|
T_LPAREN = 37,
|
||||||
T_LT_LT = 38,
|
T_LT = 38,
|
||||||
T_LT_LT_EQ = 39,
|
T_LT_LT = 39,
|
||||||
T_MINUS = 40,
|
T_LT_LT_EQ = 40,
|
||||||
T_MINUS_EQ = 41,
|
T_MINUS = 41,
|
||||||
T_MINUS_MINUS = 42,
|
T_MINUS_EQ = 42,
|
||||||
T_MULTILINE_STRING_LITERAL = 90,
|
T_MINUS_MINUS = 43,
|
||||||
T_NEW = 43,
|
T_MULTILINE_STRING_LITERAL = 92,
|
||||||
T_NOT = 44,
|
T_NEW = 44,
|
||||||
T_NOT_EQ = 45,
|
T_NOT = 45,
|
||||||
T_NOT_EQ_EQ = 46,
|
T_NOT_EQ = 46,
|
||||||
T_NO_SUBSTITUTION_TEMPLATE = 103,
|
T_NOT_EQ_EQ = 47,
|
||||||
T_NULL = 83,
|
T_NO_SUBSTITUTION_TEMPLATE = 106,
|
||||||
T_NUMERIC_LITERAL = 47,
|
T_NULL = 85,
|
||||||
T_OF = 111,
|
T_NUMERIC_LITERAL = 48,
|
||||||
T_ON = 124,
|
T_OF = 114,
|
||||||
T_OR = 48,
|
T_ON = 127,
|
||||||
T_OR_EQ = 49,
|
T_OR = 49,
|
||||||
T_OR_OR = 50,
|
T_OR_EQ = 51,
|
||||||
T_PLUS = 51,
|
T_OR_OR = 52,
|
||||||
T_PLUS_EQ = 52,
|
T_PLUS = 53,
|
||||||
T_PLUS_PLUS = 53,
|
T_PLUS_EQ = 54,
|
||||||
T_PRAGMA = 109,
|
T_PLUS_PLUS = 55,
|
||||||
T_PROPERTY = 68,
|
T_PRAGMA = 112,
|
||||||
T_PUBLIC = 107,
|
T_PROPERTY = 70,
|
||||||
T_QUESTION = 54,
|
T_PUBLIC = 110,
|
||||||
T_RBRACE = 55,
|
T_QUESTION = 56,
|
||||||
T_RBRACKET = 56,
|
T_RBRACE = 57,
|
||||||
T_READONLY = 70,
|
T_RBRACKET = 58,
|
||||||
T_REMAINDER = 57,
|
T_READONLY = 72,
|
||||||
T_REMAINDER_EQ = 58,
|
T_REMAINDER = 59,
|
||||||
T_RESERVED_WORD = 89,
|
T_REMAINDER_EQ = 60,
|
||||||
T_RETURN = 59,
|
T_REQUIRED = 105,
|
||||||
T_RPAREN = 60,
|
T_RESERVED_WORD = 91,
|
||||||
T_SEMICOLON = 61,
|
T_RETURN = 61,
|
||||||
T_SET = 113,
|
T_RPAREN = 62,
|
||||||
T_SIGNAL = 69,
|
T_SEMICOLON = 63,
|
||||||
T_STAR = 63,
|
T_SET = 116,
|
||||||
T_STAR_EQ = 66,
|
T_SIGNAL = 71,
|
||||||
T_STAR_STAR = 64,
|
T_STAR = 65,
|
||||||
T_STAR_STAR_EQ = 65,
|
T_STAR_EQ = 68,
|
||||||
T_STATIC = 100,
|
T_STAR_STAR = 66,
|
||||||
T_STRING_LITERAL = 67,
|
T_STAR_STAR_EQ = 67,
|
||||||
T_SUPER = 97,
|
T_STATIC = 102,
|
||||||
T_SWITCH = 71,
|
T_STRING_LITERAL = 69,
|
||||||
T_TEMPLATE_HEAD = 104,
|
T_SUPER = 99,
|
||||||
T_TEMPLATE_MIDDLE = 105,
|
T_SWITCH = 73,
|
||||||
T_TEMPLATE_TAIL = 106,
|
T_TEMPLATE_HEAD = 107,
|
||||||
T_THIS = 72,
|
T_TEMPLATE_MIDDLE = 108,
|
||||||
T_THROW = 73,
|
T_TEMPLATE_TAIL = 109,
|
||||||
T_TILDE = 74,
|
T_THEN = 129,
|
||||||
T_TRUE = 84,
|
T_THIS = 74,
|
||||||
T_TRY = 75,
|
T_THROW = 75,
|
||||||
T_TYPEOF = 76,
|
T_TILDE = 76,
|
||||||
T_VAR = 77,
|
T_TRUE = 86,
|
||||||
T_VOID = 78,
|
T_TRY = 77,
|
||||||
T_WHILE = 79,
|
T_TYPEOF = 78,
|
||||||
T_WITH = 80,
|
T_VAR = 79,
|
||||||
T_XOR = 81,
|
T_VERSION_NUMBER = 50,
|
||||||
T_XOR_EQ = 82,
|
T_VOID = 80,
|
||||||
T_YIELD = 96,
|
T_WHILE = 81,
|
||||||
|
T_WITH = 82,
|
||||||
|
T_XOR = 83,
|
||||||
|
T_XOR_EQ = 84,
|
||||||
|
T_YIELD = 98,
|
||||||
|
|
||||||
ACCEPT_STATE = 1008,
|
ACCEPT_STATE = 1055,
|
||||||
RULE_COUNT = 586,
|
RULE_COUNT = 591,
|
||||||
STATE_COUNT = 1009,
|
STATE_COUNT = 1056,
|
||||||
TERMINAL_COUNT = 126,
|
TERMINAL_COUNT = 130,
|
||||||
NON_TERMINAL_COUNT = 213,
|
NON_TERMINAL_COUNT = 227,
|
||||||
|
|
||||||
GOTO_INDEX_OFFSET = 1009,
|
GOTO_INDEX_OFFSET = 1056,
|
||||||
GOTO_INFO_OFFSET = 5937,
|
GOTO_INFO_OFFSET = 6757,
|
||||||
GOTO_CHECK_OFFSET = 5937
|
GOTO_CHECK_OFFSET = 6757
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const spell[];
|
static const char *const spell[];
|
||||||
static const short lhs[];
|
static const short lhs[];
|
||||||
static const short rhs[];
|
static const short rhs[];
|
||||||
|
|
||||||
#ifndef QLALR_NO_QMLJSGRAMMAR_DEBUG_INFO
|
|
||||||
static const int rule_index[];
|
|
||||||
static const int rule_info[];
|
|
||||||
#endif // QLALR_NO_QMLJSGRAMMAR_DEBUG_INFO
|
|
||||||
|
|
||||||
static const short goto_default[];
|
static const short goto_default[];
|
||||||
static const short action_default[];
|
static const short action_default[];
|
||||||
static const short action_index[];
|
static const short action_index[];
|
||||||
|
@@ -728,6 +728,18 @@ static inline int classify8(const QChar *s, int parseModeFlags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (s[2].unicode() == 'q') {
|
||||||
|
if (s[3].unicode() == 'u') {
|
||||||
|
if (s[4].unicode() == 'i') {
|
||||||
|
if (s[5].unicode() == 'r') {
|
||||||
|
if (s[6].unicode() == 'e') {
|
||||||
|
if (s[7].unicode() == 'd') {
|
||||||
|
return Lexer::T_REQUIRED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
#include <QtCore/qcoreapplication.h>
|
#include <QtCore/qcoreapplication.h>
|
||||||
#include <QtCore/qvarlengtharray.h>
|
#include <QtCore/qvarlengtharray.h>
|
||||||
#include <QtCore/qdebug.h>
|
#include <QtCore/qdebug.h>
|
||||||
|
#include <QtCore/QScopedValueRollback>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
|
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
|
||||||
@@ -255,16 +256,29 @@ int Lexer::lex()
|
|||||||
++_bracesCount;
|
++_bracesCount;
|
||||||
Q_FALLTHROUGH();
|
Q_FALLTHROUGH();
|
||||||
case T_SEMICOLON:
|
case T_SEMICOLON:
|
||||||
|
_importState = ImportState::NoQmlImport;
|
||||||
|
Q_FALLTHROUGH();
|
||||||
case T_QUESTION:
|
case T_QUESTION:
|
||||||
case T_COLON:
|
case T_COLON:
|
||||||
case T_TILDE:
|
case T_TILDE:
|
||||||
_delimited = true;
|
_delimited = true;
|
||||||
break;
|
break;
|
||||||
|
case T_AUTOMATIC_SEMICOLON:
|
||||||
|
case T_AS:
|
||||||
|
_importState = ImportState::NoQmlImport;
|
||||||
|
Q_FALLTHROUGH();
|
||||||
default:
|
default:
|
||||||
if (isBinop(_tokenKind))
|
if (isBinop(_tokenKind))
|
||||||
_delimited = true;
|
_delimited = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_IMPORT:
|
||||||
|
if (qmlMode() || (_handlingDirectives && previousTokenKind == T_DOT))
|
||||||
|
_importState = ImportState::SawImport;
|
||||||
|
if (isBinop(_tokenKind))
|
||||||
|
_delimited = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case T_IF:
|
case T_IF:
|
||||||
case T_FOR:
|
case T_FOR:
|
||||||
case T_WHILE:
|
case T_WHILE:
|
||||||
@@ -462,6 +476,42 @@ int Lexer::scanToken()
|
|||||||
again:
|
again:
|
||||||
_validTokenText = false;
|
_validTokenText = false;
|
||||||
|
|
||||||
|
// handle comment can be called after a '/' has been read
|
||||||
|
// and returns true if it actually encountered a comment
|
||||||
|
auto handleComment = [this](){
|
||||||
|
if (_char == QLatin1Char('*')) {
|
||||||
|
scanChar();
|
||||||
|
while (_codePtr <= _endPtr) {
|
||||||
|
if (_char == QLatin1Char('*')) {
|
||||||
|
scanChar();
|
||||||
|
if (_char == QLatin1Char('/')) {
|
||||||
|
scanChar();
|
||||||
|
|
||||||
|
if (_engine) {
|
||||||
|
_engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 4,
|
||||||
|
tokenStartLine(), tokenStartColumn() + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scanChar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (_char == QLatin1Char('/')) {
|
||||||
|
while (_codePtr <= _endPtr && !isLineTerminator()) {
|
||||||
|
scanChar();
|
||||||
|
}
|
||||||
|
if (_engine) {
|
||||||
|
_engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 2,
|
||||||
|
tokenStartLine(), tokenStartColumn() + 2);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
while (_char.isSpace()) {
|
while (_char.isSpace()) {
|
||||||
if (isLineTerminator()) {
|
if (isLineTerminator()) {
|
||||||
if (_restrictedKeyword) {
|
if (_restrictedKeyword) {
|
||||||
@@ -569,41 +619,17 @@ again:
|
|||||||
case ':': return T_COLON;
|
case ':': return T_COLON;
|
||||||
|
|
||||||
case '/':
|
case '/':
|
||||||
if (_char == QLatin1Char('*')) {
|
if (handleComment())
|
||||||
scanChar();
|
|
||||||
while (_codePtr <= _endPtr) {
|
|
||||||
if (_char == QLatin1Char('*')) {
|
|
||||||
scanChar();
|
|
||||||
if (_char == QLatin1Char('/')) {
|
|
||||||
scanChar();
|
|
||||||
|
|
||||||
if (_engine) {
|
|
||||||
_engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 4,
|
|
||||||
tokenStartLine(), tokenStartColumn() + 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
scanChar();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (_char == QLatin1Char('/')) {
|
|
||||||
while (_codePtr <= _endPtr && !isLineTerminator()) {
|
|
||||||
scanChar();
|
|
||||||
}
|
|
||||||
if (_engine) {
|
|
||||||
_engine->addComment(tokenOffset() + 2, _codePtr - _tokenStartPtr - 1 - 2,
|
|
||||||
tokenStartLine(), tokenStartColumn() + 2);
|
|
||||||
}
|
|
||||||
goto again;
|
goto again;
|
||||||
} if (_char == QLatin1Char('=')) {
|
else if (_char == QLatin1Char('=')) {
|
||||||
scanChar();
|
scanChar();
|
||||||
return T_DIVIDE_EQ;
|
return T_DIVIDE_EQ;
|
||||||
}
|
}
|
||||||
return T_DIVIDE_;
|
return T_DIVIDE_;
|
||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
|
if (_importState == ImportState::SawImport)
|
||||||
|
return T_DOT;
|
||||||
if (isDecimalDigit(_char.unicode()))
|
if (isDecimalDigit(_char.unicode()))
|
||||||
return scanNumber(ch);
|
return scanNumber(ch);
|
||||||
if (_char == QLatin1Char('.')) {
|
if (_char == QLatin1Char('.')) {
|
||||||
@@ -714,7 +740,10 @@ again:
|
|||||||
case '7':
|
case '7':
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
return scanNumber(ch);
|
if (_importState == ImportState::SawImport)
|
||||||
|
return scanVersionNumber(ch);
|
||||||
|
else
|
||||||
|
return scanNumber(ch);
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
uint c = ch.unicode();
|
uint c = ch.unicode();
|
||||||
@@ -794,6 +823,21 @@ again:
|
|||||||
if (!identifierWithEscapeChars)
|
if (!identifierWithEscapeChars)
|
||||||
kind = classify(_tokenStartPtr, _tokenLength, parseModeFlags());
|
kind = classify(_tokenStartPtr, _tokenLength, parseModeFlags());
|
||||||
|
|
||||||
|
if (kind == T_FUNCTION) {
|
||||||
|
continue_skipping:
|
||||||
|
while (_codePtr < _endPtr && _char.isSpace())
|
||||||
|
scanChar();
|
||||||
|
if (_char == QLatin1Char('*')) {
|
||||||
|
_tokenLength = _codePtr - _tokenStartPtr - 1;
|
||||||
|
kind = T_FUNCTION_STAR;
|
||||||
|
scanChar();
|
||||||
|
} else if (_char == QLatin1Char('/')) {
|
||||||
|
scanChar();
|
||||||
|
if (handleComment())
|
||||||
|
goto continue_skipping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_engine) {
|
if (_engine) {
|
||||||
if (kind == T_IDENTIFIER && identifierWithEscapeChars)
|
if (kind == T_IDENTIFIER && identifierWithEscapeChars)
|
||||||
_tokenSpell = _engine->newStringRef(_tokenText);
|
_tokenSpell = _engine->newStringRef(_tokenText);
|
||||||
@@ -1132,6 +1176,26 @@ int Lexer::scanNumber(QChar ch)
|
|||||||
return T_NUMERIC_LITERAL;
|
return T_NUMERIC_LITERAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Lexer::scanVersionNumber(QChar ch)
|
||||||
|
{
|
||||||
|
if (ch == QLatin1Char('0')) {
|
||||||
|
_tokenValue = 0;
|
||||||
|
return T_VERSION_NUMBER;
|
||||||
|
}
|
||||||
|
|
||||||
|
int acc = 0;
|
||||||
|
acc += ch.digitValue();
|
||||||
|
|
||||||
|
while (_char.isDigit()) {
|
||||||
|
acc *= 10;
|
||||||
|
acc += _char.digitValue();
|
||||||
|
scanChar(); // consume the digit
|
||||||
|
}
|
||||||
|
|
||||||
|
_tokenValue = acc;
|
||||||
|
return T_VERSION_NUMBER;
|
||||||
|
}
|
||||||
|
|
||||||
bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
|
bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
|
||||||
{
|
{
|
||||||
_tokenText.resize(0);
|
_tokenText.resize(0);
|
||||||
@@ -1352,6 +1416,7 @@ static const int uriTokens[] = {
|
|||||||
QmlJSGrammar::T_FINALLY,
|
QmlJSGrammar::T_FINALLY,
|
||||||
QmlJSGrammar::T_FOR,
|
QmlJSGrammar::T_FOR,
|
||||||
QmlJSGrammar::T_FUNCTION,
|
QmlJSGrammar::T_FUNCTION,
|
||||||
|
QmlJSGrammar::T_FUNCTION_STAR,
|
||||||
QmlJSGrammar::T_IF,
|
QmlJSGrammar::T_IF,
|
||||||
QmlJSGrammar::T_IN,
|
QmlJSGrammar::T_IN,
|
||||||
QmlJSGrammar::T_OF,
|
QmlJSGrammar::T_OF,
|
||||||
@@ -1388,6 +1453,13 @@ static inline bool isUriToken(int token)
|
|||||||
|
|
||||||
bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
||||||
{
|
{
|
||||||
|
auto setError = [error, this](QString message) {
|
||||||
|
error->message = std::move(message);
|
||||||
|
error->loc.startLine = tokenStartLine();
|
||||||
|
error->loc.startColumn = tokenStartColumn();
|
||||||
|
};
|
||||||
|
|
||||||
|
QScopedValueRollback<bool> directivesGuard(_handlingDirectives, true);
|
||||||
Q_ASSERT(!_qmlMode);
|
Q_ASSERT(!_qmlMode);
|
||||||
|
|
||||||
lex(); // fetch the first token
|
lex(); // fetch the first token
|
||||||
@@ -1408,9 +1480,7 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
|||||||
|
|
||||||
if (! (directiveName == QLatin1String("pragma") ||
|
if (! (directiveName == QLatin1String("pragma") ||
|
||||||
directiveName == QLatin1String("import"))) {
|
directiveName == QLatin1String("import"))) {
|
||||||
error->message = QCoreApplication::translate("QmlParser", "Syntax error");
|
setError(QCoreApplication::translate("QmlParser", "Syntax error"));
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
return false; // not a valid directive name
|
return false; // not a valid directive name
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1418,9 +1488,7 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
|||||||
if (directiveName == QLatin1String("pragma")) {
|
if (directiveName == QLatin1String("pragma")) {
|
||||||
// .pragma library
|
// .pragma library
|
||||||
if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("library"))) {
|
if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("library"))) {
|
||||||
error->message = QCoreApplication::translate("QmlParser", "Syntax error");
|
setError(QCoreApplication::translate("QmlParser", "Syntax error"));
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
return false; // expected `library
|
return false; // expected `library
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1442,20 +1510,15 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
|||||||
pathOrUri = tokenText();
|
pathOrUri = tokenText();
|
||||||
|
|
||||||
if (!pathOrUri.endsWith(QLatin1String("js"))) {
|
if (!pathOrUri.endsWith(QLatin1String("js"))) {
|
||||||
error->message = QCoreApplication::translate("QmlParser","Imported file must be a script");
|
setError(QCoreApplication::translate("QmlParser","Imported file must be a script"));
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (_tokenKind == T_IDENTIFIER) {
|
} else if (_tokenKind == T_IDENTIFIER) {
|
||||||
// .import T_IDENTIFIER (. T_IDENTIFIER)* T_NUMERIC_LITERAL as T_IDENTIFIER
|
// .import T_IDENTIFIER (. T_IDENTIFIER)* T_VERSION_NUMBER . T_VERSION_NUMBER as T_IDENTIFIER
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!isUriToken(_tokenKind)) {
|
if (!isUriToken(_tokenKind)) {
|
||||||
error->message = QCoreApplication::translate("QmlParser","Invalid module URI");
|
setError(QCoreApplication::translate("QmlParser","Invalid module URI"));
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1463,9 +1526,7 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
|||||||
|
|
||||||
lex();
|
lex();
|
||||||
if (tokenStartLine() != lineNumber) {
|
if (tokenStartLine() != lineNumber) {
|
||||||
error->message = QCoreApplication::translate("QmlParser","Invalid module URI");
|
setError(QCoreApplication::translate("QmlParser","Invalid module URI"));
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_tokenKind != QmlJSGrammar::T_DOT)
|
if (_tokenKind != QmlJSGrammar::T_DOT)
|
||||||
@@ -1475,21 +1536,30 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
|||||||
|
|
||||||
lex();
|
lex();
|
||||||
if (tokenStartLine() != lineNumber) {
|
if (tokenStartLine() != lineNumber) {
|
||||||
error->message = QCoreApplication::translate("QmlParser","Invalid module URI");
|
setError(QCoreApplication::translate("QmlParser","Invalid module URI"));
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_tokenKind != T_NUMERIC_LITERAL) {
|
if (_tokenKind != T_VERSION_NUMBER) {
|
||||||
error->message = QCoreApplication::translate("QmlParser","Module import requires a version");
|
setError(QCoreApplication::translate("QmlParser","Module import requires a version"));
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
return false; // expected the module version number
|
return false; // expected the module version number
|
||||||
}
|
}
|
||||||
|
|
||||||
version = tokenText();
|
version = tokenText();
|
||||||
|
lex();
|
||||||
|
if (_tokenKind != T_DOT) {
|
||||||
|
setError(QCoreApplication::translate( "QmlParser", "Module import requires a minor version (missing dot)"));
|
||||||
|
return false; // expected the module version number
|
||||||
|
}
|
||||||
|
version += QLatin1Char('.');
|
||||||
|
|
||||||
|
lex();
|
||||||
|
if (_tokenKind != T_VERSION_NUMBER) {
|
||||||
|
setError(QCoreApplication::translate( "QmlParser", "Module import requires a minor version (missing number)"));
|
||||||
|
return false; // expected the module version number
|
||||||
|
}
|
||||||
|
version += tokenText();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -1497,34 +1567,27 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
|||||||
//
|
//
|
||||||
if (! (lex() == T_AS && tokenStartLine() == lineNumber)) {
|
if (! (lex() == T_AS && tokenStartLine() == lineNumber)) {
|
||||||
if (fileImport)
|
if (fileImport)
|
||||||
error->message = QCoreApplication::translate("QmlParser", "File import requires a qualifier");
|
setError(QCoreApplication::translate("QmlParser", "File import requires a qualifier"));
|
||||||
else
|
else
|
||||||
error->message = QCoreApplication::translate("QmlParser", "Module import requires a qualifier");
|
setError(QCoreApplication::translate("QmlParser", "Module import requires a qualifier"));
|
||||||
if (tokenStartLine() != lineNumber) {
|
if (tokenStartLine() != lineNumber) {
|
||||||
error->loc.startLine = lineNumber;
|
error->loc.startLine = lineNumber;
|
||||||
error->loc.startColumn = column;
|
error->loc.startColumn = column;
|
||||||
} else {
|
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
}
|
}
|
||||||
return false; // expected `as'
|
return false; // expected `as'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lex() != T_IDENTIFIER || tokenStartLine() != lineNumber) {
|
if (lex() != T_IDENTIFIER || tokenStartLine() != lineNumber) {
|
||||||
if (fileImport)
|
if (fileImport)
|
||||||
error->message = QCoreApplication::translate("QmlParser", "File import requires a qualifier");
|
setError(QCoreApplication::translate("QmlParser", "File import requires a qualifier"));
|
||||||
else
|
else
|
||||||
error->message = QCoreApplication::translate("QmlParser", "Module import requires a qualifier");
|
setError(QCoreApplication::translate("QmlParser", "Module import requires a qualifier"));
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
return false; // expected module name
|
return false; // expected module name
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString module = tokenText();
|
const QString module = tokenText();
|
||||||
if (!module.at(0).isUpper()) {
|
if (!module.at(0).isUpper()) {
|
||||||
error->message = QCoreApplication::translate("QmlParser","Invalid import qualifier");
|
setError(QCoreApplication::translate("QmlParser","Invalid import qualifier"));
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1535,9 +1598,7 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tokenStartLine() != lineNumber) {
|
if (tokenStartLine() != lineNumber) {
|
||||||
error->message = QCoreApplication::translate("QmlParser", "Syntax error");
|
setError(QCoreApplication::translate("QmlParser", "Syntax error"));
|
||||||
error->loc.startLine = tokenStartLine();
|
|
||||||
error->loc.startColumn = tokenStartColumn();
|
|
||||||
return false; // the directives cannot span over multiple lines
|
return false; // the directives cannot span over multiple lines
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -109,6 +109,11 @@ public:
|
|||||||
StaticIsKeyword = 0x4
|
StaticIsKeyword = 0x4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ImportState {
|
||||||
|
SawImport,
|
||||||
|
NoQmlImport
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Lexer(Engine *engine);
|
Lexer(Engine *engine);
|
||||||
|
|
||||||
@@ -173,6 +178,7 @@ private:
|
|||||||
inline void scanChar();
|
inline void scanChar();
|
||||||
int scanToken();
|
int scanToken();
|
||||||
int scanNumber(QChar ch);
|
int scanNumber(QChar ch);
|
||||||
|
int scanVersionNumber(QChar ch);
|
||||||
enum ScanStringMode {
|
enum ScanStringMode {
|
||||||
SingleQuote = '\'',
|
SingleQuote = '\'',
|
||||||
DoubleQuote = '"',
|
DoubleQuote = '"',
|
||||||
@@ -227,6 +233,7 @@ private:
|
|||||||
int _tokenLength;
|
int _tokenLength;
|
||||||
int _tokenLine;
|
int _tokenLine;
|
||||||
int _tokenColumn;
|
int _tokenColumn;
|
||||||
|
ImportState _importState = ImportState::NoQmlImport;
|
||||||
|
|
||||||
bool _validTokenText;
|
bool _validTokenText;
|
||||||
bool _prohibitAutomaticSemicolon;
|
bool _prohibitAutomaticSemicolon;
|
||||||
@@ -238,6 +245,7 @@ private:
|
|||||||
bool _skipLinefeed = false;
|
bool _skipLinefeed = false;
|
||||||
int _generatorLevel = 0;
|
int _generatorLevel = 0;
|
||||||
bool _staticIsKeyword = false;
|
bool _staticIsKeyword = false;
|
||||||
|
bool _handlingDirectives = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace QmlJS
|
} // end of namespace QmlJS
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 178 "qmljs.g"
|
#line 182 "qmljs.g"
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2016 The Qt Company Ltd.
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
@@ -122,6 +122,9 @@ public:
|
|||||||
AST::ExportsList *ExportsList;
|
AST::ExportsList *ExportsList;
|
||||||
AST::ExportClause *ExportClause;
|
AST::ExportClause *ExportClause;
|
||||||
AST::ExportDeclaration *ExportDeclaration;
|
AST::ExportDeclaration *ExportDeclaration;
|
||||||
|
AST::TypeAnnotation *TypeAnnotation;
|
||||||
|
AST::TypeArgumentList *TypeArgumentList;
|
||||||
|
AST::Type *Type;
|
||||||
|
|
||||||
AST::UiProgram *UiProgram;
|
AST::UiProgram *UiProgram;
|
||||||
AST::UiHeaderItemList *UiHeaderItemList;
|
AST::UiHeaderItemList *UiHeaderItemList;
|
||||||
@@ -139,6 +142,7 @@ public:
|
|||||||
AST::UiArrayMemberList *UiArrayMemberList;
|
AST::UiArrayMemberList *UiArrayMemberList;
|
||||||
AST::UiQualifiedId *UiQualifiedId;
|
AST::UiQualifiedId *UiQualifiedId;
|
||||||
AST::UiEnumMemberList *UiEnumMemberList;
|
AST::UiEnumMemberList *UiEnumMemberList;
|
||||||
|
AST::UiVersionSpecifier *UiVersionSpecifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -217,6 +221,9 @@ protected:
|
|||||||
inline QStringRef &stringRef(int index)
|
inline QStringRef &stringRef(int index)
|
||||||
{ return string_stack [tos + index - 1]; }
|
{ return string_stack [tos + index - 1]; }
|
||||||
|
|
||||||
|
inline QStringRef &rawStringRef(int index)
|
||||||
|
{ return rawString_stack [tos + index - 1]; }
|
||||||
|
|
||||||
inline AST::SourceLocation &loc(int index)
|
inline AST::SourceLocation &loc(int index)
|
||||||
{ return location_stack [tos + index - 1]; }
|
{ return location_stack [tos + index - 1]; }
|
||||||
|
|
||||||
@@ -225,13 +232,25 @@ protected:
|
|||||||
void pushToken(int token);
|
void pushToken(int token);
|
||||||
int lookaheadToken(Lexer *lexer);
|
int lookaheadToken(Lexer *lexer);
|
||||||
|
|
||||||
|
static DiagnosticMessage compileError(const AST::SourceLocation &location,
|
||||||
|
const QString &message, Severity::Enum kind = Severity::Error)
|
||||||
|
{
|
||||||
|
DiagnosticMessage error;
|
||||||
|
error.loc = location;
|
||||||
|
error.message = message;
|
||||||
|
error.kind = kind;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
void syntaxError(const AST::SourceLocation &location, const char *message) {
|
void syntaxError(const AST::SourceLocation &location, const char *message) {
|
||||||
diagnostic_messages.append(DiagnosticMessage(Severity::Error, location, QLatin1String(message)));
|
diagnostic_messages.append(compileError(location, QLatin1String(message)));
|
||||||
}
|
}
|
||||||
void syntaxError(const AST::SourceLocation &location, const QString &message) {
|
void syntaxError(const AST::SourceLocation &location, const QString &message) {
|
||||||
diagnostic_messages.append(DiagnosticMessage(Severity::Error, location, message));
|
diagnostic_messages.append(compileError(location, message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ensureNoFunctionTypeAnnotations(AST::TypeAnnotation *returnTypeAnnotation, AST::FormalParameterList *formals);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Engine *driver;
|
Engine *driver;
|
||||||
MemoryPool *pool;
|
MemoryPool *pool;
|
||||||
@@ -241,6 +260,7 @@ protected:
|
|||||||
int *state_stack = nullptr;
|
int *state_stack = nullptr;
|
||||||
AST::SourceLocation *location_stack = nullptr;
|
AST::SourceLocation *location_stack = nullptr;
|
||||||
QVector<QStringRef> string_stack;
|
QVector<QStringRef> string_stack;
|
||||||
|
QVector<QStringRef> rawString_stack;
|
||||||
|
|
||||||
AST::Node *program = nullptr;
|
AST::Node *program = nullptr;
|
||||||
|
|
||||||
@@ -252,11 +272,13 @@ protected:
|
|||||||
double dval;
|
double dval;
|
||||||
AST::SourceLocation loc;
|
AST::SourceLocation loc;
|
||||||
QStringRef spell;
|
QStringRef spell;
|
||||||
|
QStringRef raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
int yytoken = -1;
|
int yytoken = -1;
|
||||||
double yylval = 0.;
|
double yylval = 0.;
|
||||||
QStringRef yytokenspell;
|
QStringRef yytokenspell;
|
||||||
|
QStringRef yytokenraw;
|
||||||
AST::SourceLocation yylloc;
|
AST::SourceLocation yylloc;
|
||||||
AST::SourceLocation yyprevlloc;
|
AST::SourceLocation yyprevlloc;
|
||||||
|
|
||||||
@@ -281,27 +303,27 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#line 1511 "qmljs.g"
|
#line 1686 "qmljs.g"
|
||||||
|
|
||||||
#define J_SCRIPT_REGEXPLITERAL_RULE1 128
|
#define J_SCRIPT_REGEXPLITERAL_RULE1 144
|
||||||
|
|
||||||
#line 1523 "qmljs.g"
|
#line 1698 "qmljs.g"
|
||||||
|
|
||||||
#define J_SCRIPT_REGEXPLITERAL_RULE2 129
|
#define J_SCRIPT_REGEXPLITERAL_RULE2 145
|
||||||
|
|
||||||
#line 3022 "qmljs.g"
|
#line 3198 "qmljs.g"
|
||||||
|
|
||||||
#define J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE 421
|
#define J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE 435
|
||||||
|
|
||||||
#line 3653 "qmljs.g"
|
#line 3850 "qmljs.g"
|
||||||
|
|
||||||
#define J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE 499
|
#define J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE 505
|
||||||
|
|
||||||
#line 4181 "qmljs.g"
|
#line 4389 "qmljs.g"
|
||||||
|
|
||||||
#define J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE 569
|
#define J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE 574
|
||||||
|
|
||||||
#line 4469 "qmljs.g"
|
#line 4673 "qmljs.g"
|
||||||
|
|
||||||
QT_QML_END_NAMESPACE
|
QT_QML_END_NAMESPACE
|
||||||
|
|
||||||
|
@@ -66,7 +66,7 @@ public:
|
|||||||
return _message;
|
return _message;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMessage(Type type)
|
void setMessage(StaticAnalysis::Type type)
|
||||||
{
|
{
|
||||||
_message = Message(type, _location);
|
_message = Message(type, _location);
|
||||||
}
|
}
|
||||||
@@ -511,7 +511,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addMessage(Type type, const SourceLocation &loc, const QString &arg1 = QString())
|
void addMessage(StaticAnalysis::Type type, const SourceLocation &loc, const QString &arg1 = QString())
|
||||||
{
|
{
|
||||||
_messages.append(Message(type, loc, arg1));
|
_messages.append(Message(type, loc, arg1));
|
||||||
}
|
}
|
||||||
@@ -695,12 +695,12 @@ QList<Message> Check::operator()()
|
|||||||
return _messages;
|
return _messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Check::enableMessage(Type type)
|
void Check::enableMessage(StaticAnalysis::Type type)
|
||||||
{
|
{
|
||||||
_enabledMessages.insert(type);
|
_enabledMessages.insert(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Check::disableMessage(Type type)
|
void Check::disableMessage(StaticAnalysis::Type type)
|
||||||
{
|
{
|
||||||
_enabledMessages.remove(type);
|
_enabledMessages.remove(type);
|
||||||
}
|
}
|
||||||
@@ -1267,7 +1267,7 @@ bool Check::visit(BinaryExpression *ast)
|
|||||||
const QLatin1Char newline('\n');
|
const QLatin1Char newline('\n');
|
||||||
if (ast->op == QSOperator::Add || ast->op == QSOperator::Sub) {
|
if (ast->op == QSOperator::Add || ast->op == QSOperator::Sub) {
|
||||||
QChar match;
|
QChar match;
|
||||||
Type msg;
|
StaticAnalysis::Type msg;
|
||||||
if (ast->op == QSOperator::Add) {
|
if (ast->op == QSOperator::Add) {
|
||||||
match = '+';
|
match = '+';
|
||||||
msg = WarnConfusingPluses;
|
msg = WarnConfusingPluses;
|
||||||
@@ -1522,7 +1522,7 @@ void Check::addMessage(const Message &message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Check::addMessage(Type type, const SourceLocation &location, const QString &arg1, const QString &arg2)
|
void Check::addMessage(StaticAnalysis::Type type, const SourceLocation &location, const QString &arg1, const QString &arg2)
|
||||||
{
|
{
|
||||||
addMessage(Message(type, location, arg1, arg2));
|
addMessage(Message(type, location, arg1, arg2));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user