forked from qt-creator/qt-creator
qmljs: update parser
Update the qtcreator qmljs parser to the one of Qt 5.12. It supports EcmaScript 7. Task-number: QTCREATORBUG-20341 Change-Id: I0d1cff71402ba17e22cde6b46c65614e162280de Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
This commit is contained in:
@@ -84,7 +84,7 @@ void JsonCheck::postVisit(Node *)
|
||||
analysis()->m_ranking += previous.m_ranking;
|
||||
}
|
||||
|
||||
bool JsonCheck::visit(ObjectLiteral *ast)
|
||||
bool JsonCheck::visit(ObjectPattern *ast)
|
||||
{
|
||||
if (!proceedCheck(JsonValue::Object, ast->lbraceToken))
|
||||
return false;
|
||||
@@ -96,8 +96,8 @@ bool JsonCheck::visit(ObjectLiteral *ast)
|
||||
return false;
|
||||
|
||||
QSet<QString> propertiesFound;
|
||||
for (PropertyAssignmentList *it = ast->properties; it; it = it->next) {
|
||||
PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(it->assignment);
|
||||
for (PatternPropertyList *it = ast->properties; it; it = it->next) {
|
||||
PatternProperty *assignment = AST::cast<AST::PatternProperty *>(it->property);
|
||||
StringLiteralPropertyName *literalName = cast<StringLiteralPropertyName *>(assignment->name);
|
||||
if (literalName) {
|
||||
const QString &propertyName = literalName->id.toString();
|
||||
@@ -106,7 +106,7 @@ bool JsonCheck::visit(ObjectLiteral *ast)
|
||||
propertiesFound.insert(propertyName);
|
||||
// Sec. 5.2: "... each property definition's value MUST be a schema..."
|
||||
m_schema->enterNestedPropertySchema(propertyName);
|
||||
processSchema(assignment->value);
|
||||
processSchema(assignment->initializer);
|
||||
m_schema->leaveNestedSchema();
|
||||
} else {
|
||||
analysis()->m_messages.append(Message(ErrInvalidPropertyName,
|
||||
@@ -144,7 +144,7 @@ bool JsonCheck::visit(ObjectLiteral *ast)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JsonCheck::visit(ArrayLiteral *ast)
|
||||
bool JsonCheck::visit(ArrayPattern *ast)
|
||||
{
|
||||
if (!proceedCheck(JsonValue::Array, ast->firstSourceLocation()))
|
||||
return false;
|
||||
@@ -155,21 +155,21 @@ bool JsonCheck::visit(ArrayLiteral *ast)
|
||||
// Sec. 5.5: "When this attribute value is a schema... all the items in the array MUST
|
||||
// be valid according to the schema."
|
||||
m_schema->enterNestedItemSchema();
|
||||
for (ElementList *element = ast->elements; element; element = element->next)
|
||||
processSchema(element->expression);
|
||||
for (PatternElementList *element = ast->elements; element; element = element->next)
|
||||
processSchema(element->element->initializer);
|
||||
m_schema->leaveNestedSchema();
|
||||
} else if (m_schema->hasItemArraySchema()) {
|
||||
// Sec. 5.5: "When this attribute value is an array of schemas... each position in the
|
||||
// instance array MUST conform to the schema in the corresponding position for this array."
|
||||
int current = 0;
|
||||
const int arraySize = m_schema->itemArraySchemaSize();
|
||||
for (ElementList *element = ast->elements; element; element = element->next, ++current) {
|
||||
for (PatternElementList *element = ast->elements; element; element = element->next, ++current) {
|
||||
if (current < arraySize) {
|
||||
if (m_schema->maybeEnterNestedArraySchema(current)) {
|
||||
processSchema(element->expression);
|
||||
processSchema(element->element->initializer);
|
||||
m_schema->leaveNestedSchema();
|
||||
} else {
|
||||
Node::accept(element->expression, this);
|
||||
Node::accept(element->element->initializer, this);
|
||||
}
|
||||
} else {
|
||||
// TODO: Handle additionalItems.
|
||||
|
@@ -51,8 +51,8 @@ private:
|
||||
bool preVisit(AST::Node *) override;
|
||||
void postVisit(AST::Node *) override;
|
||||
|
||||
bool visit(AST::ObjectLiteral *ast) override;
|
||||
bool visit(AST::ArrayLiteral *ast) override;
|
||||
bool visit(AST::ObjectPattern *ast) override;
|
||||
bool visit(AST::ArrayPattern *ast) override;
|
||||
bool visit(AST::NullExpression *ast) override;
|
||||
bool visit(AST::TrueLiteral *ast) override;
|
||||
bool visit(AST::FalseLiteral *ast) override;
|
||||
|
@@ -10,7 +10,7 @@ HEADERS += \
|
||||
$$PWD/qmljsglobal_p.h \
|
||||
$$PWD/qmldirparser_p.h \
|
||||
$$PWD/qmlerror.h \
|
||||
$$PWD/qmljskeywords_p.h \
|
||||
$$PWD/qmljskeywords_p.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qmljsast.cpp \
|
||||
@@ -20,7 +20,13 @@ SOURCES += \
|
||||
$$PWD/qmljslexer.cpp \
|
||||
$$PWD/qmljsparser.cpp \
|
||||
$$PWD/qmldirparser.cpp \
|
||||
$$PWD/qmlerror.cpp \
|
||||
$$PWD/qmlerror.cpp
|
||||
|
||||
DISTFILES += \
|
||||
$$PWD/qmljs.g
|
||||
#CONFIG += qlalr
|
||||
QLALRSOURCES = $$PWD/qmljs.g
|
||||
#QMAKE_QLALRFLAGS = --no-debug --qt
|
||||
|
||||
DISTFILES += $$QLALRSOURCES
|
||||
|
||||
# make sure we install the headers generated by qlalr
|
||||
#private_headers.CONFIG += no_check_exist
|
||||
|
@@ -93,6 +93,7 @@ bool QmlDirParser::parse(const QString &source)
|
||||
_components.clear();
|
||||
_scripts.clear();
|
||||
_designerSupported = false;
|
||||
_className.clear();
|
||||
|
||||
quint16 lineNumber = 0;
|
||||
bool firstLine = true;
|
||||
@@ -182,7 +183,8 @@ bool QmlDirParser::parse(const QString &source)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore these. qmlimportscanner uses them.
|
||||
_className = sections[1];
|
||||
|
||||
} else if (sections[0] == QLatin1String("internal")) {
|
||||
if (sectionCount != 3) {
|
||||
reportError(lineNumber, 0,
|
||||
@@ -256,7 +258,7 @@ bool QmlDirParser::parse(const QString &source)
|
||||
if (parseVersion(sections[1], &major, &minor)) {
|
||||
const QString &fileName = sections[2];
|
||||
|
||||
if (fileName.endsWith(QLatin1String(".js"))) {
|
||||
if (fileName.endsWith(QLatin1String(".js")) || fileName.endsWith(QLatin1String(".mjs"))) {
|
||||
// A 'js' extension indicates a namespaced script import
|
||||
const Script entry(sections[0], fileName, major, minor);
|
||||
_scripts.append(entry);
|
||||
@@ -363,6 +365,11 @@ bool QmlDirParser::designerSupported() const
|
||||
return _designerSupported;
|
||||
}
|
||||
|
||||
QString QmlDirParser::className() const
|
||||
{
|
||||
return _className;
|
||||
}
|
||||
|
||||
QDebug &operator<< (QDebug &debug, const QmlDirParser::Component &component)
|
||||
{
|
||||
const QString output = QStringLiteral("{%1 %2.%3}").
|
||||
|
@@ -39,8 +39,8 @@
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include "qmljsengine_p.h"
|
||||
#include "qmljsglobal_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@@ -48,8 +48,6 @@ class QmlError;
|
||||
class QmlEngine;
|
||||
class QML_PARSER_EXPORT QmlDirParser
|
||||
{
|
||||
Q_DISABLE_COPY(QmlDirParser)
|
||||
|
||||
public:
|
||||
QmlDirParser();
|
||||
~QmlDirParser();
|
||||
@@ -76,8 +74,7 @@ public:
|
||||
|
||||
struct Component
|
||||
{
|
||||
Component()
|
||||
: majorVersion(0), minorVersion(0), internal(false), singleton(false) {}
|
||||
Component() {}
|
||||
|
||||
Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
|
||||
: typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
|
||||
@@ -85,24 +82,23 @@ public:
|
||||
|
||||
QString typeName;
|
||||
QString fileName;
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
bool internal;
|
||||
bool singleton;
|
||||
int majorVersion = 0;
|
||||
int minorVersion = 0;
|
||||
bool internal = false;
|
||||
bool singleton = false;
|
||||
};
|
||||
|
||||
struct Script
|
||||
{
|
||||
Script()
|
||||
: majorVersion(0), minorVersion(0) {}
|
||||
Script() {}
|
||||
|
||||
Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion)
|
||||
: nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) {}
|
||||
|
||||
QString nameSpace;
|
||||
QString fileName;
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
int majorVersion = 0;
|
||||
int minorVersion = 0;
|
||||
};
|
||||
|
||||
QHash<QString,Component> components() const;
|
||||
@@ -124,6 +120,8 @@ public:
|
||||
QList<TypeInfo> typeInfos() const;
|
||||
#endif
|
||||
|
||||
QString className() const;
|
||||
|
||||
private:
|
||||
bool maybeAddComponent(const QString &typeName, const QString &fileName, const QString &version, QHash<QString,Component> &hash, int lineNumber = -1, bool multi = true);
|
||||
void reportError(quint16 line, quint16 column, const QString &message);
|
||||
@@ -139,6 +137,7 @@ private:
|
||||
#ifdef QT_CREATOR
|
||||
QList<TypeInfo> _typeInfos;
|
||||
#endif
|
||||
QString _className;
|
||||
};
|
||||
|
||||
typedef QHash<QString,QmlDirParser::Component> QmlDirComponents;
|
||||
|
@@ -91,7 +91,7 @@ QmlErrorPrivate::QmlErrorPrivate()
|
||||
Creates an empty error object.
|
||||
*/
|
||||
QmlError::QmlError()
|
||||
: d(0)
|
||||
: d(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ QmlError::QmlError()
|
||||
Creates a copy of \a other.
|
||||
*/
|
||||
QmlError::QmlError(const QmlError &other)
|
||||
: d(0)
|
||||
: d(nullptr)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
@@ -111,7 +111,7 @@ QmlError &QmlError::operator=(const QmlError &other)
|
||||
{
|
||||
if (!other.d) {
|
||||
delete d;
|
||||
d = 0;
|
||||
d = nullptr;
|
||||
} else {
|
||||
if (!d)
|
||||
d = new QmlErrorPrivate;
|
||||
@@ -130,7 +130,7 @@ QmlError &QmlError::operator=(const QmlError &other)
|
||||
*/
|
||||
QmlError::~QmlError()
|
||||
{
|
||||
delete d; d = 0;
|
||||
delete d; d = nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -138,7 +138,7 @@ QmlError::~QmlError()
|
||||
*/
|
||||
bool QmlError::isValid() const
|
||||
{
|
||||
return d != 0;
|
||||
return d != nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -231,7 +231,7 @@ QObject *QmlError::object() const
|
||||
{
|
||||
if (d)
|
||||
return d->object;
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -260,7 +260,7 @@ QtMsgType QmlError::messageType() const
|
||||
\since 5.9
|
||||
|
||||
Sets the \a messageType for this message. The message type determines which
|
||||
QDebug handlers are responsible for recieving the message.
|
||||
QDebug handlers are responsible for receiving the message.
|
||||
*/
|
||||
void QmlError::setMessageType(QtMsgType messageType)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,27 @@ QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
namespace QmlJS { namespace AST {
|
||||
|
||||
FunctionExpression *asAnonymousFunctionDefinition(Node *n)
|
||||
{
|
||||
if (!n)
|
||||
return nullptr;
|
||||
FunctionExpression *f = n->asFunctionDefinition();
|
||||
if (!f || !f->name.isNull())
|
||||
return nullptr;
|
||||
return f;
|
||||
}
|
||||
|
||||
ClassExpression *asAnonymousClassDefinition(Node *n)
|
||||
{
|
||||
if (!n)
|
||||
return nullptr;
|
||||
ClassExpression *c = n->asClassDefinition();
|
||||
if (!c || !c->name.isNull())
|
||||
return nullptr;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void Node::accept(Visitor *visitor)
|
||||
{
|
||||
if (visitor->preVisit(this)) {
|
||||
@@ -47,22 +68,42 @@ void Node::accept(Node *node, Visitor *visitor)
|
||||
|
||||
ExpressionNode *Node::expressionCast()
|
||||
{
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BinaryExpression *Node::binaryExpressionCast()
|
||||
{
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Statement *Node::statementCast()
|
||||
{
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UiObjectMember *Node::uiObjectMemberCast()
|
||||
{
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LeftHandSideExpression *Node::leftHandSideExpressionCast()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Pattern *Node::patternCast()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FunctionExpression *Node::asFunctionDefinition()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ClassExpression *Node::asClassDefinition()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ExpressionNode *ExpressionNode::expressionCast()
|
||||
@@ -70,6 +111,42 @@ ExpressionNode *ExpressionNode::expressionCast()
|
||||
return this;
|
||||
}
|
||||
|
||||
FormalParameterList *ExpressionNode::reparseAsFormalParameterList(MemoryPool *pool)
|
||||
{
|
||||
AST::ExpressionNode *expr = this;
|
||||
AST::FormalParameterList *f = nullptr;
|
||||
if (AST::Expression *commaExpr = AST::cast<AST::Expression *>(expr)) {
|
||||
f = commaExpr->left->reparseAsFormalParameterList(pool);
|
||||
if (!f)
|
||||
return nullptr;
|
||||
|
||||
expr = commaExpr->right;
|
||||
}
|
||||
|
||||
AST::ExpressionNode *rhs = nullptr;
|
||||
if (AST::BinaryExpression *assign = AST::cast<AST::BinaryExpression *>(expr)) {
|
||||
if (assign->op != QSOperator::Assign)
|
||||
return nullptr;
|
||||
expr = assign->left;
|
||||
rhs = assign->right;
|
||||
}
|
||||
AST::PatternElement *binding = nullptr;
|
||||
if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(expr)) {
|
||||
binding = new (pool) AST::PatternElement(idExpr->name, rhs);
|
||||
binding->identifierToken = idExpr->identifierToken;
|
||||
} else if (AST::Pattern *p = expr->patternCast()) {
|
||||
SourceLocation loc;
|
||||
QString s;
|
||||
if (!p->convertLiteralToAssignmentPattern(pool, &loc, &s))
|
||||
return nullptr;
|
||||
binding = new (pool) AST::PatternElement(p, rhs);
|
||||
binding->identifierToken = p->firstSourceLocation();
|
||||
}
|
||||
if (!binding)
|
||||
return nullptr;
|
||||
return new (pool) AST::FormalParameterList(f, binding);
|
||||
}
|
||||
|
||||
BinaryExpression *BinaryExpression::binaryExpressionCast()
|
||||
{
|
||||
return this;
|
||||
@@ -93,6 +170,16 @@ void NestedExpression::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
FunctionExpression *NestedExpression::asFunctionDefinition()
|
||||
{
|
||||
return expression->asFunctionDefinition();
|
||||
}
|
||||
|
||||
ClassExpression *NestedExpression::asClassDefinition()
|
||||
{
|
||||
return expression->asClassDefinition();
|
||||
}
|
||||
|
||||
void ThisExpression::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
@@ -133,6 +220,15 @@ void FalseLiteral::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void SuperLiteral::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
|
||||
void StringLiteral::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
@@ -141,6 +237,16 @@ void StringLiteral::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void TemplateLiteral::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
if (next)
|
||||
accept(next, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void NumericLiteral::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
@@ -157,17 +263,27 @@ void RegExpLiteral::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ArrayLiteral::accept0(Visitor *visitor)
|
||||
void ArrayPattern::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
if (visitor->visit(this))
|
||||
accept(elements, visitor);
|
||||
accept(elision, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ObjectLiteral::accept0(Visitor *visitor)
|
||||
bool ArrayPattern::isValidArrayLiteral(SourceLocation *errorLocation) const {
|
||||
for (PatternElementList *it = elements; it != nullptr; it = it->next) {
|
||||
PatternElement *e = it->element;
|
||||
if (e && e->bindingTarget != nullptr) {
|
||||
if (errorLocation)
|
||||
*errorLocation = e->firstSourceLocation();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ObjectPattern::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(properties, visitor);
|
||||
@@ -176,18 +292,170 @@ void ObjectLiteral::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ElementList::accept0(Visitor *visitor)
|
||||
/*
|
||||
This is the grammar for AssignmentPattern that we need to convert the literal to:
|
||||
|
||||
AssignmentPattern:
|
||||
ObjectAssignmentPattern
|
||||
ArrayAssignmentPattern
|
||||
ArrayAssignmentPattern:
|
||||
[ ElisionOpt AssignmentRestElementOpt ]
|
||||
[ AssignmentElementList ]
|
||||
[ AssignmentElementList , ElisionOpt AssignmentRestElementOpt ]
|
||||
AssignmentElementList:
|
||||
AssignmentElisionElement
|
||||
AssignmentElementList , AssignmentElisionElement
|
||||
AssignmentElisionElement:
|
||||
ElisionOpt AssignmentElement
|
||||
AssignmentRestElement:
|
||||
... DestructuringAssignmentTarget
|
||||
|
||||
ObjectAssignmentPattern:
|
||||
{}
|
||||
{ AssignmentPropertyList }
|
||||
{ AssignmentPropertyList, }
|
||||
AssignmentPropertyList:
|
||||
AssignmentProperty
|
||||
AssignmentPropertyList , AssignmentProperty
|
||||
AssignmentProperty:
|
||||
IdentifierReference InitializerOpt_In
|
||||
PropertyName:
|
||||
AssignmentElement
|
||||
|
||||
AssignmentElement:
|
||||
DestructuringAssignmentTarget InitializerOpt_In
|
||||
DestructuringAssignmentTarget:
|
||||
LeftHandSideExpression
|
||||
|
||||
It was originally parsed with the following grammar:
|
||||
|
||||
ArrayLiteral:
|
||||
[ ElisionOpt ]
|
||||
[ ElementList ]
|
||||
[ ElementList , ElisionOpt ]
|
||||
ElementList:
|
||||
ElisionOpt AssignmentExpression_In
|
||||
ElisionOpt SpreadElement
|
||||
ElementList , ElisionOpt AssignmentExpression_In
|
||||
ElementList , Elisionopt SpreadElement
|
||||
SpreadElement:
|
||||
... AssignmentExpression_In
|
||||
ObjectLiteral:
|
||||
{}
|
||||
{ PropertyDefinitionList }
|
||||
{ PropertyDefinitionList , }
|
||||
PropertyDefinitionList:
|
||||
PropertyDefinition
|
||||
PropertyDefinitionList , PropertyDefinition
|
||||
PropertyDefinition:
|
||||
IdentifierReference
|
||||
CoverInitializedName
|
||||
PropertyName : AssignmentExpression_In
|
||||
MethodDefinition
|
||||
PropertyName:
|
||||
LiteralPropertyName
|
||||
ComputedPropertyName
|
||||
|
||||
*/
|
||||
bool ArrayPattern::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
for (ElementList *it = this; it; it = it->next) {
|
||||
accept(it->elision, visitor);
|
||||
accept(it->expression, visitor);
|
||||
if (parseMode == Binding)
|
||||
return true;
|
||||
for (auto *it = elements; it; it = it->next) {
|
||||
if (!it->element)
|
||||
continue;
|
||||
if (it->element->type == PatternElement::SpreadElement && it->next) {
|
||||
*errorLocation = it->element->firstSourceLocation();
|
||||
*errorMessage = QString::fromLatin1("'...' can only appear as last element in a destructuring list.");
|
||||
return false;
|
||||
}
|
||||
if (!it->element->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage))
|
||||
return false;
|
||||
}
|
||||
parseMode = Binding;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectPattern::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage)
|
||||
{
|
||||
if (parseMode == Binding)
|
||||
return true;
|
||||
for (auto *it = properties; it; it = it->next) {
|
||||
if (!it->property->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage))
|
||||
return false;
|
||||
}
|
||||
parseMode = Binding;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PatternElement::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage)
|
||||
{
|
||||
Q_ASSERT(type == Literal || type == SpreadElement);
|
||||
Q_ASSERT(bindingIdentifier.isNull());
|
||||
Q_ASSERT(bindingTarget == nullptr);
|
||||
Q_ASSERT(bindingTarget == nullptr);
|
||||
Q_ASSERT(initializer);
|
||||
ExpressionNode *init = initializer;
|
||||
|
||||
initializer = nullptr;
|
||||
LeftHandSideExpression *lhs = init->leftHandSideExpressionCast();
|
||||
if (type == SpreadElement) {
|
||||
if (!lhs) {
|
||||
*errorLocation = init->firstSourceLocation();
|
||||
*errorMessage = QString::fromLatin1("Invalid lhs expression after '...' in destructuring expression.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
type = PatternElement::Binding;
|
||||
|
||||
if (BinaryExpression *b = init->binaryExpressionCast()) {
|
||||
if (b->op != QSOperator::Assign) {
|
||||
*errorLocation = b->operatorToken;
|
||||
*errorMessage = QString::fromLatin1("Invalid assignment operation in destructuring expression");
|
||||
return false;
|
||||
}
|
||||
lhs = b->left->leftHandSideExpressionCast();
|
||||
initializer = b->right;
|
||||
Q_ASSERT(lhs);
|
||||
} else {
|
||||
lhs = init->leftHandSideExpressionCast();
|
||||
}
|
||||
if (!lhs) {
|
||||
*errorLocation = init->firstSourceLocation();
|
||||
*errorMessage = QString::fromLatin1("Destructuring target is not a left hand side expression.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
if (auto *i = cast<IdentifierExpression *>(lhs)) {
|
||||
bindingIdentifier = i->name;
|
||||
identifierToken = i->identifierToken;
|
||||
return true;
|
||||
}
|
||||
|
||||
bindingTarget = lhs;
|
||||
if (auto *p = lhs->patternCast()) {
|
||||
if (!p->convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PatternProperty::convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage)
|
||||
{
|
||||
Q_ASSERT(type != SpreadElement);
|
||||
if (type == Binding)
|
||||
return true;
|
||||
if (type == Getter || type == Setter) {
|
||||
*errorLocation = firstSourceLocation();
|
||||
*errorMessage = QString::fromLatin1("Invalid getter/setter in destructuring expression.");
|
||||
return false;
|
||||
}
|
||||
Q_ASSERT(type == Literal);
|
||||
return PatternElement::convertLiteralToAssignmentPattern(pool, errorLocation, errorMessage);
|
||||
}
|
||||
|
||||
|
||||
void Elision::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
@@ -197,38 +465,6 @@ void Elision::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PropertyNameAndValue::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(name, visitor);
|
||||
accept(value, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PropertyGetterSetter::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(name, visitor);
|
||||
accept(formals, visitor);
|
||||
accept(functionBody, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PropertyAssignmentList::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
for (PropertyAssignmentList *it = this; it; it = it->next) {
|
||||
accept(it->assignment, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void IdentifierPropertyName::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
@@ -253,6 +489,28 @@ void NumericLiteralPropertyName::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct LocaleWithoutZeroPadding : public QLocale
|
||||
{
|
||||
LocaleWithoutZeroPadding()
|
||||
: QLocale(QLocale::C)
|
||||
{
|
||||
setNumberOptions(QLocale::OmitLeadingZeroInExponent | QLocale::OmitGroupSeparator);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
QString NumericLiteralPropertyName::asString()const
|
||||
{
|
||||
// Can't use QString::number here anymore as it does zero padding by default now.
|
||||
|
||||
// In C++11 this initialization is thread-safe (6.7 [stmt.dcl] p4)
|
||||
static LocaleWithoutZeroPadding locale;
|
||||
// Because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562 we can't use thread_local
|
||||
// for the locale variable and therefore rely on toString(double) to be thread-safe.
|
||||
return locale.toString(id, 'g', 16);
|
||||
}
|
||||
|
||||
void ArrayMemberExpression::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
@@ -482,15 +740,6 @@ void VariableDeclarationList::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void VariableDeclaration::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(expression, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void EmptyStatement::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
@@ -543,17 +792,6 @@ void ForStatement::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(initialiser, visitor);
|
||||
accept(condition, visitor);
|
||||
accept(expression, visitor);
|
||||
accept(statement, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void LocalForStatement::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(declarations, visitor);
|
||||
accept(condition, visitor);
|
||||
accept(expression, visitor);
|
||||
@@ -566,18 +804,7 @@ void LocalForStatement::accept0(Visitor *visitor)
|
||||
void ForEachStatement::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(initialiser, visitor);
|
||||
accept(expression, visitor);
|
||||
accept(statement, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void LocalForEachStatement::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(declaration, visitor);
|
||||
accept(lhs, visitor);
|
||||
accept(expression, visitor);
|
||||
accept(statement, visitor);
|
||||
}
|
||||
@@ -610,6 +837,16 @@ void ReturnStatement::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void YieldExpression::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(expression, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
|
||||
void WithStatement::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
@@ -703,6 +940,7 @@ void TryStatement::accept0(Visitor *visitor)
|
||||
void Catch::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(patternElement, visitor);
|
||||
accept(statement, visitor);
|
||||
}
|
||||
|
||||
@@ -738,57 +976,182 @@ void FunctionExpression::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
FunctionExpression *FunctionExpression::asFunctionDefinition()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
QStringList FormalParameterList::formals() const
|
||||
{
|
||||
QStringList formals;
|
||||
int i = 0;
|
||||
for (const FormalParameterList *it = this; it; it = it->next) {
|
||||
if (it->element) {
|
||||
QString name = it->element->bindingIdentifier.toString();
|
||||
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 += name;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return formals;
|
||||
}
|
||||
|
||||
QStringList FormalParameterList::boundNames() const
|
||||
{
|
||||
QStringList names;
|
||||
for (const FormalParameterList *it = this; it; it = it->next) {
|
||||
if (it->element)
|
||||
it->element->boundNames(&names);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
void FormalParameterList::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
// ###
|
||||
accept(element, visitor);
|
||||
if (next)
|
||||
accept(next, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void FunctionBody::accept0(Visitor *visitor)
|
||||
FormalParameterList *FormalParameterList::finish(QmlJS::MemoryPool *pool)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(elements, visitor);
|
||||
}
|
||||
FormalParameterList *front = next;
|
||||
next = nullptr;
|
||||
|
||||
visitor->endVisit(this);
|
||||
int i = 0;
|
||||
for (const FormalParameterList *it = this; it; it = it->next) {
|
||||
if (it->element && it->element->bindingIdentifier.isEmpty())
|
||||
it->element->bindingIdentifier = pool->newString(QLatin1String("arg#") + QString::number(i));
|
||||
++i;
|
||||
}
|
||||
return front;
|
||||
}
|
||||
|
||||
void Program::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(elements, visitor);
|
||||
accept(statements, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void SourceElements::accept0(Visitor *visitor)
|
||||
void ImportSpecifier::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
for (SourceElements *it = this; it; it = it->next) {
|
||||
accept(it->element, visitor);
|
||||
|
||||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ImportsList::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
for (ImportsList *it = this; it; it = it->next) {
|
||||
accept(it->importSpecifier, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void FunctionSourceElement::accept0(Visitor *visitor)
|
||||
void NamedImports::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(declaration, visitor);
|
||||
accept(importsList, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void StatementSourceElement::accept0(Visitor *visitor)
|
||||
void FromClause::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(statement, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void NameSpaceImport::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ImportClause::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(nameSpaceImport, visitor);
|
||||
accept(namedImports, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ImportDeclaration::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(importClause, visitor);
|
||||
accept(fromClause, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ExportSpecifier::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ExportsList::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
for (ExportsList *it = this; it; it = it->next) {
|
||||
accept(it->exportSpecifier, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ExportClause::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(exportsList, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ExportDeclaration::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(fromClause, visitor);
|
||||
accept(exportClause, visitor);
|
||||
accept(variableStatementOrDeclaration, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ESModule::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(body, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
@@ -916,18 +1279,9 @@ void UiImport::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void UiQualifiedPragmaId::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void UiPragma::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(pragmaType, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
@@ -970,6 +1324,153 @@ void UiEnumMemberList::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void TaggedTemplate::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(base, visitor);
|
||||
accept(templateLiteral, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PatternElement::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(bindingTarget, visitor);
|
||||
accept(initializer, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PatternElement::boundNames(QStringList *names)
|
||||
{
|
||||
if (bindingTarget) {
|
||||
if (PatternElementList *e = elementList())
|
||||
e->boundNames(names);
|
||||
else if (PatternPropertyList *p = propertyList())
|
||||
p->boundNames(names);
|
||||
} else {
|
||||
names->append(bindingIdentifier.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void PatternElementList::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(elision, visitor);
|
||||
accept(element, visitor);
|
||||
if (next)
|
||||
accept(next, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PatternElementList::boundNames(QStringList *names)
|
||||
{
|
||||
for (PatternElementList *it = this; it; it = it->next) {
|
||||
if (it->element)
|
||||
it->element->boundNames(names);
|
||||
}
|
||||
}
|
||||
|
||||
void PatternProperty::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(name, visitor);
|
||||
accept(bindingTarget, visitor);
|
||||
accept(initializer, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PatternProperty::boundNames(QStringList *names)
|
||||
{
|
||||
PatternElement::boundNames(names);
|
||||
}
|
||||
|
||||
void PatternPropertyList::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(property, visitor);
|
||||
if (next)
|
||||
accept(next, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PatternPropertyList::boundNames(QStringList *names)
|
||||
{
|
||||
for (PatternPropertyList *it = this; it; it = it->next)
|
||||
it->property->boundNames(names);
|
||||
}
|
||||
|
||||
void ComputedPropertyName::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(expression, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ClassExpression::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(heritage, visitor);
|
||||
accept(elements, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
ClassExpression *ClassExpression::asClassDefinition()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void ClassDeclaration::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(heritage, visitor);
|
||||
accept(elements, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void ClassElementList::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(property, visitor);
|
||||
if (next)
|
||||
accept(next, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
ClassElementList *ClassElementList::finish()
|
||||
{
|
||||
ClassElementList *front = next;
|
||||
next = nullptr;
|
||||
return front;
|
||||
}
|
||||
|
||||
Pattern *Pattern::patternCast()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
LeftHandSideExpression *LeftHandSideExpression::leftHandSideExpressionCast()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
} } // namespace QmlJS::AST
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -74,22 +74,27 @@ class IdentifierExpression;
|
||||
class NullExpression;
|
||||
class TrueLiteral;
|
||||
class FalseLiteral;
|
||||
class SuperLiteral;
|
||||
class NumericLiteral;
|
||||
class StringLiteral;
|
||||
class TemplateLiteral;
|
||||
class RegExpLiteral;
|
||||
class ArrayLiteral;
|
||||
class ObjectLiteral;
|
||||
class ElementList;
|
||||
class Pattern;
|
||||
class ArrayPattern;
|
||||
class ObjectPattern;
|
||||
class PatternElement;
|
||||
class PatternElementList;
|
||||
class PatternProperty;
|
||||
class PatternPropertyList;
|
||||
class Elision;
|
||||
class PropertyAssignmentList;
|
||||
class PropertyGetterSetter;
|
||||
class PropertyNameAndValue;
|
||||
class PropertyName;
|
||||
class IdentifierPropertyName;
|
||||
class StringLiteralPropertyName;
|
||||
class NumericLiteralPropertyName;
|
||||
class ComputedPropertyName;
|
||||
class ArrayMemberExpression;
|
||||
class FieldMemberExpression;
|
||||
class TaggedTemplate;
|
||||
class NewMemberExpression;
|
||||
class NewExpression;
|
||||
class CallExpression;
|
||||
@@ -108,20 +113,19 @@ class NotExpression;
|
||||
class BinaryExpression;
|
||||
class ConditionalExpression;
|
||||
class Expression; // ### rename
|
||||
class YieldExpression;
|
||||
class Block;
|
||||
class LeftHandSideExpression;
|
||||
class StatementList;
|
||||
class VariableStatement;
|
||||
class VariableDeclarationList;
|
||||
class VariableDeclaration;
|
||||
class EmptyStatement;
|
||||
class ExpressionStatement;
|
||||
class IfStatement;
|
||||
class DoWhileStatement;
|
||||
class WhileStatement;
|
||||
class ForStatement;
|
||||
class LocalForStatement;
|
||||
class ForEachStatement;
|
||||
class LocalForEachStatement;
|
||||
class ContinueStatement;
|
||||
class BreakStatement;
|
||||
class ReturnStatement;
|
||||
@@ -139,14 +143,26 @@ class Finally;
|
||||
class FunctionDeclaration;
|
||||
class FunctionExpression;
|
||||
class FormalParameterList;
|
||||
class FunctionBody;
|
||||
class ExportSpecifier;
|
||||
class ExportsList;
|
||||
class ExportClause;
|
||||
class ExportDeclaration;
|
||||
class Program;
|
||||
class SourceElements;
|
||||
class SourceElement;
|
||||
class FunctionSourceElement;
|
||||
class StatementSourceElement;
|
||||
class ImportSpecifier;
|
||||
class ImportsList;
|
||||
class NamedImports;
|
||||
class NameSpaceImport;
|
||||
class NamedImport;
|
||||
class ImportClause;
|
||||
class FromClause;
|
||||
class ImportDeclaration;
|
||||
class ModuleItem;
|
||||
class ESModule;
|
||||
class DebuggerStatement;
|
||||
class NestedExpression;
|
||||
class ClassExpression;
|
||||
class ClassDeclaration;
|
||||
class ClassElementList;
|
||||
|
||||
// ui elements
|
||||
class UiProgram;
|
||||
@@ -164,7 +180,6 @@ class UiObjectMember;
|
||||
class UiObjectMemberList;
|
||||
class UiArrayMemberList;
|
||||
class UiQualifiedId;
|
||||
class UiQualifiedPragmaId;
|
||||
class UiHeaderItemList;
|
||||
class UiEnumDeclaration;
|
||||
class UiEnumMemberList;
|
||||
|
@@ -68,7 +68,6 @@ public:
|
||||
virtual bool visit(UiObjectMemberList *) { return true; }
|
||||
virtual bool visit(UiArrayMemberList *) { return true; }
|
||||
virtual bool visit(UiQualifiedId *) { return true; }
|
||||
virtual bool visit(UiQualifiedPragmaId *) { return true; }
|
||||
virtual bool visit(UiEnumDeclaration *) { return true; }
|
||||
virtual bool visit(UiEnumMemberList *) { return true; }
|
||||
|
||||
@@ -87,7 +86,6 @@ public:
|
||||
virtual void endVisit(UiObjectMemberList *) {}
|
||||
virtual void endVisit(UiArrayMemberList *) {}
|
||||
virtual void endVisit(UiQualifiedId *) {}
|
||||
virtual void endVisit(UiQualifiedPragmaId *) {}
|
||||
virtual void endVisit(UiEnumDeclaration *) {}
|
||||
virtual void endVisit(UiEnumMemberList *) { }
|
||||
|
||||
@@ -107,36 +105,42 @@ public:
|
||||
virtual bool visit(FalseLiteral *) { return true; }
|
||||
virtual void endVisit(FalseLiteral *) {}
|
||||
|
||||
virtual bool visit(SuperLiteral *) { return true; }
|
||||
virtual void endVisit(SuperLiteral *) {}
|
||||
|
||||
virtual bool visit(StringLiteral *) { return true; }
|
||||
virtual void endVisit(StringLiteral *) {}
|
||||
|
||||
virtual bool visit(TemplateLiteral *) { return true; }
|
||||
virtual void endVisit(TemplateLiteral *) {}
|
||||
|
||||
virtual bool visit(NumericLiteral *) { return true; }
|
||||
virtual void endVisit(NumericLiteral *) {}
|
||||
|
||||
virtual bool visit(RegExpLiteral *) { return true; }
|
||||
virtual void endVisit(RegExpLiteral *) {}
|
||||
|
||||
virtual bool visit(ArrayLiteral *) { return true; }
|
||||
virtual void endVisit(ArrayLiteral *) {}
|
||||
virtual bool visit(ArrayPattern *) { return true; }
|
||||
virtual void endVisit(ArrayPattern *) {}
|
||||
|
||||
virtual bool visit(ObjectLiteral *) { return true; }
|
||||
virtual void endVisit(ObjectLiteral *) {}
|
||||
virtual bool visit(ObjectPattern *) { return true; }
|
||||
virtual void endVisit(ObjectPattern *) {}
|
||||
|
||||
virtual bool visit(ElementList *) { return true; }
|
||||
virtual void endVisit(ElementList *) {}
|
||||
virtual bool visit(PatternElementList *) { return true; }
|
||||
virtual void endVisit(PatternElementList *) {}
|
||||
|
||||
virtual bool visit(PatternPropertyList *) { return true; }
|
||||
virtual void endVisit(PatternPropertyList *) {}
|
||||
|
||||
virtual bool visit(PatternElement *) { return true; }
|
||||
virtual void endVisit(PatternElement *) {}
|
||||
|
||||
virtual bool visit(PatternProperty *) { return true; }
|
||||
virtual void endVisit(PatternProperty *) {}
|
||||
|
||||
virtual bool visit(Elision *) { return true; }
|
||||
virtual void endVisit(Elision *) {}
|
||||
|
||||
virtual bool visit(PropertyAssignmentList *) { return true; }
|
||||
virtual void endVisit(PropertyAssignmentList *) {}
|
||||
|
||||
virtual bool visit(PropertyNameAndValue *) { return true; }
|
||||
virtual void endVisit(PropertyNameAndValue *) {}
|
||||
|
||||
virtual bool visit(PropertyGetterSetter *) { return true; }
|
||||
virtual void endVisit(PropertyGetterSetter *) {}
|
||||
|
||||
virtual bool visit(NestedExpression *) { return true; }
|
||||
virtual void endVisit(NestedExpression *) {}
|
||||
|
||||
@@ -149,12 +153,18 @@ public:
|
||||
virtual bool visit(NumericLiteralPropertyName *) { return true; }
|
||||
virtual void endVisit(NumericLiteralPropertyName *) {}
|
||||
|
||||
virtual bool visit(ComputedPropertyName *) { return true; }
|
||||
virtual void endVisit(ComputedPropertyName *) {}
|
||||
|
||||
virtual bool visit(ArrayMemberExpression *) { return true; }
|
||||
virtual void endVisit(ArrayMemberExpression *) {}
|
||||
|
||||
virtual bool visit(FieldMemberExpression *) { return true; }
|
||||
virtual void endVisit(FieldMemberExpression *) {}
|
||||
|
||||
virtual bool visit(TaggedTemplate *) { return true; }
|
||||
virtual void endVisit(TaggedTemplate *) {}
|
||||
|
||||
virtual bool visit(NewMemberExpression *) { return true; }
|
||||
virtual void endVisit(NewMemberExpression *) {}
|
||||
|
||||
@@ -221,9 +231,6 @@ public:
|
||||
virtual bool visit(VariableDeclarationList *) { return true; }
|
||||
virtual void endVisit(VariableDeclarationList *) {}
|
||||
|
||||
virtual bool visit(VariableDeclaration *) { return true; }
|
||||
virtual void endVisit(VariableDeclaration *) {}
|
||||
|
||||
virtual bool visit(EmptyStatement *) { return true; }
|
||||
virtual void endVisit(EmptyStatement *) {}
|
||||
|
||||
@@ -242,15 +249,9 @@ public:
|
||||
virtual bool visit(ForStatement *) { return true; }
|
||||
virtual void endVisit(ForStatement *) {}
|
||||
|
||||
virtual bool visit(LocalForStatement *) { return true; }
|
||||
virtual void endVisit(LocalForStatement *) {}
|
||||
|
||||
virtual bool visit(ForEachStatement *) { return true; }
|
||||
virtual void endVisit(ForEachStatement *) {}
|
||||
|
||||
virtual bool visit(LocalForEachStatement *) { return true; }
|
||||
virtual void endVisit(LocalForEachStatement *) {}
|
||||
|
||||
virtual bool visit(ContinueStatement *) { return true; }
|
||||
virtual void endVisit(ContinueStatement *) {}
|
||||
|
||||
@@ -260,6 +261,9 @@ public:
|
||||
virtual bool visit(ReturnStatement *) { return true; }
|
||||
virtual void endVisit(ReturnStatement *) {}
|
||||
|
||||
virtual bool visit(YieldExpression *) { return true; }
|
||||
virtual void endVisit(YieldExpression *) {}
|
||||
|
||||
virtual bool visit(WithStatement *) { return true; }
|
||||
virtual void endVisit(WithStatement *) {}
|
||||
|
||||
@@ -302,20 +306,56 @@ public:
|
||||
virtual bool visit(FormalParameterList *) { return true; }
|
||||
virtual void endVisit(FormalParameterList *) {}
|
||||
|
||||
virtual bool visit(FunctionBody *) { return true; }
|
||||
virtual void endVisit(FunctionBody *) {}
|
||||
virtual bool visit(ClassExpression *) { return true; }
|
||||
virtual void endVisit(ClassExpression *) {}
|
||||
|
||||
virtual bool visit(ClassDeclaration *) { return true; }
|
||||
virtual void endVisit(ClassDeclaration *) {}
|
||||
|
||||
virtual bool visit(ClassElementList *) { return true; }
|
||||
virtual void endVisit(ClassElementList *) {}
|
||||
|
||||
virtual bool visit(Program *) { return true; }
|
||||
virtual void endVisit(Program *) {}
|
||||
|
||||
virtual bool visit(SourceElements *) { return true; }
|
||||
virtual void endVisit(SourceElements *) {}
|
||||
virtual bool visit(NameSpaceImport *) { return true; }
|
||||
virtual void endVisit(NameSpaceImport *) {}
|
||||
|
||||
virtual bool visit(FunctionSourceElement *) { return true; }
|
||||
virtual void endVisit(FunctionSourceElement *) {}
|
||||
virtual bool visit(ImportSpecifier *) { return true; }
|
||||
virtual void endVisit(ImportSpecifier *) {}
|
||||
|
||||
virtual bool visit(StatementSourceElement *) { return true; }
|
||||
virtual void endVisit(StatementSourceElement *) {}
|
||||
virtual bool visit(ImportsList *) { return true; }
|
||||
virtual void endVisit(ImportsList *) {}
|
||||
|
||||
virtual bool visit(NamedImports *) { return true; }
|
||||
virtual void endVisit(NamedImports *) {}
|
||||
|
||||
virtual bool visit(FromClause *) { return true; }
|
||||
virtual void endVisit(FromClause *) {}
|
||||
|
||||
virtual bool visit(ImportClause *) { return true; }
|
||||
virtual void endVisit(ImportClause *) {}
|
||||
|
||||
virtual bool visit(ImportDeclaration *) { return true; }
|
||||
virtual void endVisit(ImportDeclaration *) {}
|
||||
|
||||
virtual bool visit(ExportSpecifier *) { return true; }
|
||||
virtual void endVisit(ExportSpecifier *) {}
|
||||
|
||||
virtual bool visit(ExportsList *) { return true; }
|
||||
virtual void endVisit(ExportsList *) {}
|
||||
|
||||
virtual bool visit(ExportClause *) { return true; }
|
||||
virtual void endVisit(ExportClause *) {}
|
||||
|
||||
virtual bool visit(ExportDeclaration *) { return true; }
|
||||
virtual void endVisit(ExportDeclaration *) {}
|
||||
|
||||
virtual bool visit(ModuleItem *) { return true; }
|
||||
virtual void endVisit(ModuleItem *) {}
|
||||
|
||||
virtual bool visit(ESModule *) { return true; }
|
||||
virtual void endVisit(ESModule *) {}
|
||||
|
||||
virtual bool visit(DebuggerStatement *) { return true; }
|
||||
virtual void endVisit(DebuggerStatement *) {}
|
||||
|
@@ -98,15 +98,8 @@ double integerFromString(const char *buf, int size, int radix)
|
||||
return result;
|
||||
}
|
||||
|
||||
double integerFromString(const QString &str, int radix)
|
||||
{
|
||||
QByteArray ba = QStringRef(&str).trimmed().toLatin1();
|
||||
return integerFromString(ba.constData(), ba.size(), radix);
|
||||
}
|
||||
|
||||
|
||||
Engine::Engine()
|
||||
: _lexer(0), _directives(0)
|
||||
: _lexer(nullptr), _directives(nullptr)
|
||||
{ }
|
||||
|
||||
Engine::~Engine()
|
||||
|
@@ -49,14 +49,40 @@ QT_QML_BEGIN_NAMESPACE
|
||||
namespace QmlJS {
|
||||
|
||||
class Lexer;
|
||||
class Directives;
|
||||
class MemoryPool;
|
||||
|
||||
class QML_PARSER_EXPORT Directives {
|
||||
public:
|
||||
virtual ~Directives() {}
|
||||
|
||||
virtual void pragmaLibrary()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void importFile(const QString &jsfile, const QString &module, int line, int column)
|
||||
{
|
||||
Q_UNUSED(jsfile);
|
||||
Q_UNUSED(module);
|
||||
Q_UNUSED(line);
|
||||
Q_UNUSED(column);
|
||||
}
|
||||
|
||||
virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column)
|
||||
{
|
||||
Q_UNUSED(uri);
|
||||
Q_UNUSED(version);
|
||||
Q_UNUSED(module);
|
||||
Q_UNUSED(line);
|
||||
Q_UNUSED(column);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class QML_PARSER_EXPORT DiagnosticMessage
|
||||
{
|
||||
public:
|
||||
DiagnosticMessage()
|
||||
: kind(Severity::Error) {}
|
||||
|
||||
DiagnosticMessage() {}
|
||||
|
||||
DiagnosticMessage(Severity::Enum kind, const AST::SourceLocation &loc, const QString &message)
|
||||
: kind(kind), loc(loc), message(message) {}
|
||||
@@ -67,7 +93,7 @@ public:
|
||||
bool isError() const
|
||||
{ return kind == Severity::Error; }
|
||||
|
||||
Severity::Enum kind;
|
||||
Severity::Enum kind = Severity::Error;
|
||||
AST::SourceLocation loc;
|
||||
QString message;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -3,8 +3,9 @@
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
** This file is part of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
@@ -21,6 +22,8 @@
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//
|
||||
@@ -39,7 +42,6 @@
|
||||
#define QMLJSGRAMMAR_P_H
|
||||
|
||||
#include "qmljsglobal_p.h"
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@@ -48,47 +50,55 @@ class QML_PARSER_EXPORT QmlJSGrammar
|
||||
public:
|
||||
enum VariousConstants {
|
||||
EOF_SYMBOL = 0,
|
||||
REDUCE_HERE = 107,
|
||||
SHIFT_THERE = 106,
|
||||
REDUCE_HERE = 125,
|
||||
T_AND = 1,
|
||||
T_AND_AND = 2,
|
||||
T_AND_EQ = 3,
|
||||
T_AS = 95,
|
||||
T_ARROW = 93,
|
||||
T_AS = 110,
|
||||
T_AUTOMATIC_SEMICOLON = 62,
|
||||
T_BREAK = 4,
|
||||
T_CASE = 5,
|
||||
T_CATCH = 6,
|
||||
T_CLASS = 98,
|
||||
T_COLON = 7,
|
||||
T_COMMA = 8,
|
||||
T_COMMENT = 89,
|
||||
T_COMPATIBILITY_SEMICOLON = 90,
|
||||
T_CONST = 84,
|
||||
T_COMMENT = 91,
|
||||
T_COMPATIBILITY_SEMICOLON = 92,
|
||||
T_CONST = 86,
|
||||
T_CONTINUE = 9,
|
||||
T_DEBUGGER = 86,
|
||||
T_DEBUGGER = 88,
|
||||
T_DEFAULT = 10,
|
||||
T_DELETE = 11,
|
||||
T_DIVIDE_ = 12,
|
||||
T_DIVIDE_EQ = 13,
|
||||
T_DO = 14,
|
||||
T_DOT = 15,
|
||||
T_ELLIPSIS = 95,
|
||||
T_ELSE = 16,
|
||||
T_ENUM = 91,
|
||||
T_ENUM = 94,
|
||||
T_EQ = 17,
|
||||
T_EQ_EQ = 18,
|
||||
T_EQ_EQ_EQ = 19,
|
||||
T_ERROR = 99,
|
||||
T_FALSE = 83,
|
||||
T_FEED_JS_EXPRESSION = 103,
|
||||
T_FEED_JS_PROGRAM = 105,
|
||||
T_FEED_JS_SOURCE_ELEMENT = 104,
|
||||
T_FEED_JS_STATEMENT = 102,
|
||||
T_FEED_UI_OBJECT_MEMBER = 101,
|
||||
T_FEED_UI_PROGRAM = 100,
|
||||
T_ERROR = 114,
|
||||
T_EXPORT = 101,
|
||||
T_EXTENDS = 99,
|
||||
T_FALSE = 85,
|
||||
T_FEED_JS_EXPRESSION = 118,
|
||||
T_FEED_JS_MODULE = 120,
|
||||
T_FEED_JS_SCRIPT = 119,
|
||||
T_FEED_JS_STATEMENT = 117,
|
||||
T_FEED_UI_OBJECT_MEMBER = 116,
|
||||
T_FEED_UI_PROGRAM = 115,
|
||||
T_FINALLY = 20,
|
||||
T_FOR = 21,
|
||||
T_FORCE_BLOCK = 122,
|
||||
T_FORCE_DECLARATION = 121,
|
||||
T_FOR_LOOKAHEAD_OK = 123,
|
||||
T_FROM = 102,
|
||||
T_FUNCTION = 22,
|
||||
T_GE = 23,
|
||||
T_GET = 97,
|
||||
T_GET = 112,
|
||||
T_GT = 24,
|
||||
T_GT_GT = 25,
|
||||
T_GT_GT_EQ = 26,
|
||||
@@ -96,13 +106,13 @@ public:
|
||||
T_GT_GT_GT_EQ = 28,
|
||||
T_IDENTIFIER = 29,
|
||||
T_IF = 30,
|
||||
T_IMPORT = 93,
|
||||
T_IMPORT = 108,
|
||||
T_IN = 31,
|
||||
T_INSTANCEOF = 32,
|
||||
T_LBRACE = 33,
|
||||
T_LBRACKET = 34,
|
||||
T_LE = 35,
|
||||
T_LET = 85,
|
||||
T_LET = 87,
|
||||
T_LPAREN = 36,
|
||||
T_LT = 37,
|
||||
T_LT_LT = 38,
|
||||
@@ -110,66 +120,82 @@ public:
|
||||
T_MINUS = 40,
|
||||
T_MINUS_EQ = 41,
|
||||
T_MINUS_MINUS = 42,
|
||||
T_MULTILINE_STRING_LITERAL = 88,
|
||||
T_MULTILINE_STRING_LITERAL = 90,
|
||||
T_NEW = 43,
|
||||
T_NOT = 44,
|
||||
T_NOT_EQ = 45,
|
||||
T_NOT_EQ_EQ = 46,
|
||||
T_NULL = 81,
|
||||
T_NO_SUBSTITUTION_TEMPLATE = 103,
|
||||
T_NULL = 83,
|
||||
T_NUMERIC_LITERAL = 47,
|
||||
T_ON = 96,
|
||||
T_OF = 111,
|
||||
T_ON = 124,
|
||||
T_OR = 48,
|
||||
T_OR_EQ = 49,
|
||||
T_OR_OR = 50,
|
||||
T_PLUS = 51,
|
||||
T_PLUS_EQ = 52,
|
||||
T_PLUS_PLUS = 53,
|
||||
T_PRAGMA = 94,
|
||||
T_PROPERTY = 66,
|
||||
T_PUBLIC = 92,
|
||||
T_PRAGMA = 109,
|
||||
T_PROPERTY = 68,
|
||||
T_PUBLIC = 107,
|
||||
T_QUESTION = 54,
|
||||
T_RBRACE = 55,
|
||||
T_RBRACKET = 56,
|
||||
T_READONLY = 68,
|
||||
T_READONLY = 70,
|
||||
T_REMAINDER = 57,
|
||||
T_REMAINDER_EQ = 58,
|
||||
T_RESERVED_WORD = 87,
|
||||
T_RESERVED_WORD = 89,
|
||||
T_RETURN = 59,
|
||||
T_RPAREN = 60,
|
||||
T_SEMICOLON = 61,
|
||||
T_SET = 98,
|
||||
T_SIGNAL = 67,
|
||||
T_SET = 113,
|
||||
T_SIGNAL = 69,
|
||||
T_STAR = 63,
|
||||
T_STAR_EQ = 64,
|
||||
T_STRING_LITERAL = 65,
|
||||
T_SWITCH = 69,
|
||||
T_THIS = 70,
|
||||
T_THROW = 71,
|
||||
T_TILDE = 72,
|
||||
T_TRUE = 82,
|
||||
T_TRY = 73,
|
||||
T_TYPEOF = 74,
|
||||
T_VAR = 75,
|
||||
T_VOID = 76,
|
||||
T_WHILE = 77,
|
||||
T_WITH = 78,
|
||||
T_XOR = 79,
|
||||
T_XOR_EQ = 80,
|
||||
T_STAR_EQ = 66,
|
||||
T_STAR_STAR = 64,
|
||||
T_STAR_STAR_EQ = 65,
|
||||
T_STATIC = 100,
|
||||
T_STRING_LITERAL = 67,
|
||||
T_SUPER = 97,
|
||||
T_SWITCH = 71,
|
||||
T_TEMPLATE_HEAD = 104,
|
||||
T_TEMPLATE_MIDDLE = 105,
|
||||
T_TEMPLATE_TAIL = 106,
|
||||
T_THIS = 72,
|
||||
T_THROW = 73,
|
||||
T_TILDE = 74,
|
||||
T_TRUE = 84,
|
||||
T_TRY = 75,
|
||||
T_TYPEOF = 76,
|
||||
T_VAR = 77,
|
||||
T_VOID = 78,
|
||||
T_WHILE = 79,
|
||||
T_WITH = 80,
|
||||
T_XOR = 81,
|
||||
T_XOR_EQ = 82,
|
||||
T_YIELD = 96,
|
||||
|
||||
ACCEPT_STATE = 691,
|
||||
RULE_COUNT = 369,
|
||||
STATE_COUNT = 692,
|
||||
TERMINAL_COUNT = 108,
|
||||
NON_TERMINAL_COUNT = 112,
|
||||
ACCEPT_STATE = 1008,
|
||||
RULE_COUNT = 586,
|
||||
STATE_COUNT = 1009,
|
||||
TERMINAL_COUNT = 126,
|
||||
NON_TERMINAL_COUNT = 213,
|
||||
|
||||
GOTO_INDEX_OFFSET = 692,
|
||||
GOTO_INFO_OFFSET = 3357,
|
||||
GOTO_CHECK_OFFSET = 3357
|
||||
GOTO_INDEX_OFFSET = 1009,
|
||||
GOTO_INFO_OFFSET = 5937,
|
||||
GOTO_CHECK_OFFSET = 5937
|
||||
};
|
||||
|
||||
static const char *const spell[];
|
||||
static const short lhs[];
|
||||
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 action_default[];
|
||||
static const short action_index[];
|
||||
|
@@ -42,10 +42,10 @@ QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
namespace QmlJS {
|
||||
|
||||
static inline int classify2(const QChar *s, bool qmlMode) {
|
||||
static inline int classify2(const QChar *s, int parseModeFlags) {
|
||||
if (s[0].unicode() == 'a') {
|
||||
if (s[1].unicode() == 's') {
|
||||
return qmlMode ? Lexer::T_AS : Lexer::T_IDENTIFIER;
|
||||
return Lexer::T_AS;
|
||||
}
|
||||
}
|
||||
else if (s[0].unicode() == 'd') {
|
||||
@@ -61,15 +61,18 @@ static inline int classify2(const QChar *s, bool qmlMode) {
|
||||
return Lexer::T_IN;
|
||||
}
|
||||
}
|
||||
else if (qmlMode && s[0].unicode() == 'o') {
|
||||
else if (s[0].unicode() == 'o') {
|
||||
if (s[1].unicode() == 'n') {
|
||||
return qmlMode ? Lexer::T_ON : Lexer::T_IDENTIFIER;
|
||||
return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_ON : Lexer::T_IDENTIFIER;
|
||||
}
|
||||
else if (s[1].unicode() == 'f') {
|
||||
return Lexer::T_OF;
|
||||
}
|
||||
}
|
||||
return Lexer::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
static inline int classify3(const QChar *s, bool qmlMode) {
|
||||
static inline int classify3(const QChar *s, int parseModeFlags) {
|
||||
if (s[0].unicode() == 'f') {
|
||||
if (s[1].unicode() == 'o') {
|
||||
if (s[2].unicode() == 'r') {
|
||||
@@ -87,7 +90,7 @@ static inline int classify3(const QChar *s, bool qmlMode) {
|
||||
else if (s[0].unicode() == 'i') {
|
||||
if (s[1].unicode() == 'n') {
|
||||
if (s[2].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_INT) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_INT) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,12 +132,12 @@ static inline int classify3(const QChar *s, bool qmlMode) {
|
||||
return Lexer::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
static inline int classify4(const QChar *s, bool qmlMode) {
|
||||
static inline int classify4(const QChar *s, int parseModeFlags) {
|
||||
if (s[0].unicode() == 'b') {
|
||||
if (s[1].unicode() == 'y') {
|
||||
if (s[2].unicode() == 't') {
|
||||
if (s[3].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_BYTE) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_BYTE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,7 +153,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
|
||||
else if (s[1].unicode() == 'h') {
|
||||
if (s[2].unicode() == 'a') {
|
||||
if (s[3].unicode() == 'r') {
|
||||
return qmlMode ? int(Lexer::T_CHAR) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_CHAR) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,7 +169,16 @@ static inline int classify4(const QChar *s, bool qmlMode) {
|
||||
else if (s[1].unicode() == 'n') {
|
||||
if (s[2].unicode() == 'u') {
|
||||
if (s[3].unicode() == 'm') {
|
||||
return qmlMode ? int(Lexer::T_ENUM) : int(Lexer::T_RESERVED_WORD);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_ENUM) : int(Lexer::T_RESERVED_WORD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s[0].unicode() == 'f') {
|
||||
if (s[1].unicode() == 'r') {
|
||||
if (s[2].unicode() == 'o') {
|
||||
if (s[3].unicode() == 'm') {
|
||||
return int(Lexer::T_FROM);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,7 +187,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
|
||||
if (s[1].unicode() == 'o') {
|
||||
if (s[2].unicode() == 't') {
|
||||
if (s[3].unicode() == 'o') {
|
||||
return qmlMode ? int(Lexer::T_GOTO) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_GOTO) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,7 +196,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
|
||||
if (s[1].unicode() == 'o') {
|
||||
if (s[2].unicode() == 'n') {
|
||||
if (s[3].unicode() == 'g') {
|
||||
return qmlMode ? int(Lexer::T_LONG) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_LONG) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +247,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
|
||||
return Lexer::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
static inline int classify5(const QChar *s, int parseModeFlags) {
|
||||
if (s[0].unicode() == 'b') {
|
||||
if (s[1].unicode() == 'r') {
|
||||
if (s[2].unicode() == 'e') {
|
||||
@@ -290,7 +302,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
if (s[2].unicode() == 'n') {
|
||||
if (s[3].unicode() == 'a') {
|
||||
if (s[4].unicode() == 'l') {
|
||||
return qmlMode ? int(Lexer::T_FINAL) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_FINAL) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,7 +311,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
if (s[2].unicode() == 'o') {
|
||||
if (s[3].unicode() == 'a') {
|
||||
if (s[4].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_FLOAT) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_FLOAT) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,7 +322,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
if (s[2].unicode() == 'o') {
|
||||
if (s[3].unicode() == 'r') {
|
||||
if (s[4].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_SHORT) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_SHORT) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,7 +331,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
if (s[2].unicode() == 'p') {
|
||||
if (s[3].unicode() == 'e') {
|
||||
if (s[4].unicode() == 'r') {
|
||||
return qmlMode ? int(Lexer::T_SUPER) : int(Lexer::T_RESERVED_WORD);
|
||||
return int(Lexer::T_SUPER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -347,10 +359,21 @@ static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s[0].unicode() == 'y') {
|
||||
if (s[1].unicode() == 'i') {
|
||||
if (s[2].unicode() == 'e') {
|
||||
if (s[3].unicode() == 'l') {
|
||||
if (s[4].unicode() == 'd') {
|
||||
return (parseModeFlags & Lexer::YieldIsKeyword) ? Lexer::T_YIELD : Lexer::T_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Lexer::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
static inline int classify6(const QChar *s, int parseModeFlags) {
|
||||
if (s[0].unicode() == 'd') {
|
||||
if (s[1].unicode() == 'e') {
|
||||
if (s[2].unicode() == 'l') {
|
||||
@@ -368,7 +391,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 'b') {
|
||||
if (s[4].unicode() == 'l') {
|
||||
if (s[5].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_DOUBLE) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_DOUBLE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -394,7 +417,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 'o') {
|
||||
if (s[4].unicode() == 'r') {
|
||||
if (s[5].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_IMPORT) : int(Lexer::T_RESERVED_WORD);
|
||||
return Lexer::T_IMPORT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -407,7 +430,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 'i') {
|
||||
if (s[4].unicode() == 'v') {
|
||||
if (s[5].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_NATIVE) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_NATIVE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -420,7 +443,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 'l') {
|
||||
if (s[4].unicode() == 'i') {
|
||||
if (s[5].unicode() == 'c') {
|
||||
return qmlMode ? Lexer::T_PUBLIC : Lexer::T_IDENTIFIER;
|
||||
return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_PUBLIC : Lexer::T_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -431,7 +454,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 'g') {
|
||||
if (s[4].unicode() == 'm') {
|
||||
if (s[5].unicode() == 'a') {
|
||||
return qmlMode ? Lexer::T_PRAGMA : Lexer::T_IDENTIFIER;
|
||||
return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_PRAGMA : Lexer::T_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,7 +475,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
}
|
||||
}
|
||||
else if (s[0].unicode() == 's') {
|
||||
if (qmlMode && s[1].unicode() == 'i') {
|
||||
if ((parseModeFlags & Lexer::QmlMode) && s[1].unicode() == 'i') {
|
||||
if (s[2].unicode() == 'g') {
|
||||
if (s[3].unicode() == 'n') {
|
||||
if (s[4].unicode() == 'a') {
|
||||
@@ -468,7 +491,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 't') {
|
||||
if (s[4].unicode() == 'i') {
|
||||
if (s[5].unicode() == 'c') {
|
||||
return qmlMode ? int(Lexer::T_STATIC) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::StaticIsKeyword) ? int(Lexer::T_STATIC) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -492,7 +515,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 'o') {
|
||||
if (s[4].unicode() == 'w') {
|
||||
if (s[5].unicode() == 's') {
|
||||
return qmlMode ? int(Lexer::T_THROWS) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_THROWS) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -513,7 +536,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
return Lexer::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
static inline int classify7(const QChar *s, bool qmlMode) {
|
||||
static inline int classify7(const QChar *s, int parseModeFlags) {
|
||||
if (s[0].unicode() == 'b') {
|
||||
if (s[1].unicode() == 'o') {
|
||||
if (s[2].unicode() == 'o') {
|
||||
@@ -521,7 +544,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
|
||||
if (s[4].unicode() == 'e') {
|
||||
if (s[5].unicode() == 'a') {
|
||||
if (s[6].unicode() == 'n') {
|
||||
return qmlMode ? int(Lexer::T_BOOLEAN) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_BOOLEAN) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -581,7 +604,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
|
||||
if (s[4].unicode() == 'a') {
|
||||
if (s[5].unicode() == 'g') {
|
||||
if (s[6].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_PACKAGE) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_PACKAGE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -594,7 +617,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
|
||||
if (s[4].unicode() == 'a') {
|
||||
if (s[5].unicode() == 't') {
|
||||
if (s[6].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_PRIVATE) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_PRIVATE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -605,7 +628,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
|
||||
return Lexer::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
static inline int classify8(const QChar *s, bool qmlMode) {
|
||||
static inline int classify8(const QChar *s, int parseModeFlags) {
|
||||
if (s[0].unicode() == 'a') {
|
||||
if (s[1].unicode() == 'b') {
|
||||
if (s[2].unicode() == 's') {
|
||||
@@ -614,7 +637,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
|
||||
if (s[5].unicode() == 'a') {
|
||||
if (s[6].unicode() == 'c') {
|
||||
if (s[7].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_ABSTRACT) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_ABSTRACT) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -674,7 +697,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (qmlMode && s[0].unicode() == 'p') {
|
||||
else if ((parseModeFlags & Lexer::QmlMode) && s[0].unicode() == 'p') {
|
||||
if (s[1].unicode() == 'r') {
|
||||
if (s[2].unicode() == 'o') {
|
||||
if (s[3].unicode() == 'p') {
|
||||
@@ -691,7 +714,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (qmlMode && s[0].unicode() == 'r') {
|
||||
else if ((parseModeFlags & Lexer::QmlMode) && s[0].unicode() == 'r') {
|
||||
if (s[1].unicode() == 'e') {
|
||||
if (s[2].unicode() == 'a') {
|
||||
if (s[3].unicode() == 'd') {
|
||||
@@ -716,7 +739,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
|
||||
if (s[5].unicode() == 'i') {
|
||||
if (s[6].unicode() == 'l') {
|
||||
if (s[7].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_VOLATILE) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_VOLATILE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -728,7 +751,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
|
||||
return Lexer::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
static inline int classify9(const QChar *s, bool qmlMode) {
|
||||
static inline int classify9(const QChar *s, int parseModeFlags) {
|
||||
if (s[0].unicode() == 'i') {
|
||||
if (s[1].unicode() == 'n') {
|
||||
if (s[2].unicode() == 't') {
|
||||
@@ -738,7 +761,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
|
||||
if (s[6].unicode() == 'a') {
|
||||
if (s[7].unicode() == 'c') {
|
||||
if (s[8].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_INTERFACE) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_INTERFACE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -757,7 +780,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
|
||||
if (s[6].unicode() == 't') {
|
||||
if (s[7].unicode() == 'e') {
|
||||
if (s[8].unicode() == 'd') {
|
||||
return qmlMode ? int(Lexer::T_PROTECTED) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_PROTECTED) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -776,7 +799,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
|
||||
if (s[6].unicode() == 'e') {
|
||||
if (s[7].unicode() == 'n') {
|
||||
if (s[8].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_TRANSIENT) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_TRANSIENT) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -789,7 +812,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
|
||||
return Lexer::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
static inline int classify10(const QChar *s, bool qmlMode) {
|
||||
static inline int classify10(const QChar *s, int parseModeFlags) {
|
||||
if (s[0].unicode() == 'i') {
|
||||
if (s[1].unicode() == 'm') {
|
||||
if (s[2].unicode() == 'p') {
|
||||
@@ -800,7 +823,7 @@ static inline int classify10(const QChar *s, bool qmlMode) {
|
||||
if (s[7].unicode() == 'n') {
|
||||
if (s[8].unicode() == 't') {
|
||||
if (s[9].unicode() == 's') {
|
||||
return qmlMode ? int(Lexer::T_IMPLEMENTS) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_IMPLEMENTS) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -833,7 +856,7 @@ static inline int classify10(const QChar *s, bool qmlMode) {
|
||||
return Lexer::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
static inline int classify12(const QChar *s, bool qmlMode) {
|
||||
static inline int classify12(const QChar *s, int parseModeFlags) {
|
||||
if (s[0].unicode() == 's') {
|
||||
if (s[1].unicode() == 'y') {
|
||||
if (s[2].unicode() == 'n') {
|
||||
@@ -846,7 +869,7 @@ static inline int classify12(const QChar *s, bool qmlMode) {
|
||||
if (s[9].unicode() == 'z') {
|
||||
if (s[10].unicode() == 'e') {
|
||||
if (s[11].unicode() == 'd') {
|
||||
return qmlMode ? int(Lexer::T_SYNCHRONIZED) : int(Lexer::T_IDENTIFIER);
|
||||
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_SYNCHRONIZED) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -862,18 +885,18 @@ static inline int classify12(const QChar *s, bool qmlMode) {
|
||||
return Lexer::T_IDENTIFIER;
|
||||
}
|
||||
|
||||
int Lexer::classify(const QChar *s, int n, bool qmlMode) {
|
||||
int Lexer::classify(const QChar *s, int n, int parseModeFlags) {
|
||||
switch (n) {
|
||||
case 2: return classify2(s, qmlMode);
|
||||
case 3: return classify3(s, qmlMode);
|
||||
case 4: return classify4(s, qmlMode);
|
||||
case 5: return classify5(s, qmlMode);
|
||||
case 6: return classify6(s, qmlMode);
|
||||
case 7: return classify7(s, qmlMode);
|
||||
case 8: return classify8(s, qmlMode);
|
||||
case 9: return classify9(s, qmlMode);
|
||||
case 10: return classify10(s, qmlMode);
|
||||
case 12: return classify12(s, qmlMode);
|
||||
case 2: return classify2(s, parseModeFlags);
|
||||
case 3: return classify3(s, parseModeFlags);
|
||||
case 4: return classify4(s, parseModeFlags);
|
||||
case 5: return classify5(s, parseModeFlags);
|
||||
case 6: return classify6(s, parseModeFlags);
|
||||
case 7: return classify7(s, parseModeFlags);
|
||||
case 8: return classify8(s, parseModeFlags);
|
||||
case 9: return classify9(s, parseModeFlags);
|
||||
case 10: return classify10(s, parseModeFlags);
|
||||
case 12: return classify12(s, parseModeFlags);
|
||||
default: return Lexer::T_IDENTIFIER;
|
||||
} // switch
|
||||
}
|
||||
|
@@ -44,6 +44,8 @@ static inline int regExpFlagFromChar(const QChar &ch)
|
||||
case 'g': return Lexer::RegExp_Global;
|
||||
case 'i': return Lexer::RegExp_IgnoreCase;
|
||||
case 'm': return Lexer::RegExp_Multiline;
|
||||
case 'u': return Lexer::RegExp_Unicode;
|
||||
case 'y': return Lexer::RegExp_Sticky;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -63,22 +65,15 @@ static inline QChar convertHex(QChar c1, QChar c2)
|
||||
return QChar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
|
||||
}
|
||||
|
||||
static inline QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
|
||||
{
|
||||
return QChar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode()),
|
||||
(convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
|
||||
}
|
||||
|
||||
Lexer::Lexer(Engine *engine)
|
||||
: _engine(engine)
|
||||
, _codePtr(0)
|
||||
, _endPtr(0)
|
||||
, _lastLinePtr(0)
|
||||
, _tokenLinePtr(0)
|
||||
, _tokenStartPtr(0)
|
||||
, _codePtr(nullptr)
|
||||
, _endPtr(nullptr)
|
||||
, _tokenStartPtr(nullptr)
|
||||
, _char(QLatin1Char('\n'))
|
||||
, _errorCode(NoError)
|
||||
, _currentLineNumber(0)
|
||||
, _currentColumnNumber(0)
|
||||
, _tokenValue(0)
|
||||
, _parenthesesState(IgnoreParentheses)
|
||||
, _parenthesesCount(0)
|
||||
@@ -87,6 +82,7 @@ Lexer::Lexer(Engine *engine)
|
||||
, _tokenKind(0)
|
||||
, _tokenLength(0)
|
||||
, _tokenLine(0)
|
||||
, _tokenColumn(0)
|
||||
, _validTokenText(false)
|
||||
, _prohibitAutomaticSemicolon(false)
|
||||
, _restrictedKeyword(false)
|
||||
@@ -123,14 +119,13 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
|
||||
|
||||
_codePtr = code.unicode();
|
||||
_endPtr = _codePtr + code.length();
|
||||
_lastLinePtr = _codePtr;
|
||||
_tokenLinePtr = _codePtr;
|
||||
_tokenStartPtr = _codePtr;
|
||||
|
||||
_char = QLatin1Char('\n');
|
||||
_errorCode = NoError;
|
||||
|
||||
_currentLineNumber = lineno;
|
||||
_currentColumnNumber = 0;
|
||||
_tokenValue = 0;
|
||||
|
||||
// parentheses state
|
||||
@@ -142,6 +137,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
|
||||
_patternFlags = 0;
|
||||
_tokenLength = 0;
|
||||
_tokenLine = lineno;
|
||||
_tokenColumn = 0;
|
||||
|
||||
_validTokenText = false;
|
||||
_prohibitAutomaticSemicolon = false;
|
||||
@@ -158,9 +154,10 @@ void Lexer::scanChar()
|
||||
if (sequenceLength == 2)
|
||||
_char = *_codePtr++;
|
||||
|
||||
if (unsigned sequenceLength = isLineTerminatorSequence()) {
|
||||
_lastLinePtr = _codePtr + sequenceLength - 1; // points to the first character after the newline
|
||||
++_currentColumnNumber;
|
||||
if (isLineTerminator()) {
|
||||
++_currentLineNumber;
|
||||
_currentColumnNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,12 +205,32 @@ inline bool isBinop(int tok)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int hexDigit(QChar c)
|
||||
{
|
||||
if (c >= QLatin1Char('0') && c <= QLatin1Char('9'))
|
||||
return c.unicode() - '0';
|
||||
if (c >= QLatin1Char('a') && c <= QLatin1Char('f'))
|
||||
return c.unicode() - 'a' + 10;
|
||||
if (c >= QLatin1Char('A') && c <= QLatin1Char('F'))
|
||||
return c.unicode() - 'A' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int octalDigit(QChar c)
|
||||
{
|
||||
if (c >= QLatin1Char('0') && c <= QLatin1Char('7'))
|
||||
return c.unicode() - '0';
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int Lexer::lex()
|
||||
{
|
||||
const int previousTokenKind = _tokenKind;
|
||||
|
||||
again:
|
||||
_tokenSpell = QStringRef();
|
||||
_tokenKind = scanToken();
|
||||
_tokenLength = _codePtr - _tokenStartPtr - 1;
|
||||
@@ -225,6 +242,9 @@ int Lexer::lex()
|
||||
// update the flags
|
||||
switch (_tokenKind) {
|
||||
case T_LBRACE:
|
||||
if (_bracesCount > 0)
|
||||
++_bracesCount;
|
||||
Q_FALLTHROUGH();
|
||||
case T_SEMICOLON:
|
||||
case T_QUESTION:
|
||||
case T_COLON:
|
||||
@@ -252,9 +272,15 @@ int Lexer::lex()
|
||||
case T_CONTINUE:
|
||||
case T_BREAK:
|
||||
case T_RETURN:
|
||||
case T_YIELD:
|
||||
case T_THROW:
|
||||
_restrictedKeyword = true;
|
||||
break;
|
||||
case T_RBRACE:
|
||||
if (_bracesCount > 0)
|
||||
--_bracesCount;
|
||||
if (_bracesCount == 0)
|
||||
goto again;
|
||||
} // switch
|
||||
|
||||
// update the parentheses state
|
||||
@@ -281,39 +307,57 @@ int Lexer::lex()
|
||||
return _tokenKind;
|
||||
}
|
||||
|
||||
bool Lexer::isUnicodeEscapeSequence(const QChar *chars)
|
||||
uint Lexer::decodeUnicodeEscapeCharacter(bool *ok)
|
||||
{
|
||||
if (isHexDigit(chars[0]) && isHexDigit(chars[1]) && isHexDigit(chars[2]) && isHexDigit(chars[3]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QChar Lexer::decodeUnicodeEscapeCharacter(bool *ok)
|
||||
{
|
||||
if (_char == QLatin1Char('u') && isUnicodeEscapeSequence(&_codePtr[0])) {
|
||||
Q_ASSERT(_char == QLatin1Char('u'));
|
||||
scanChar(); // skip u
|
||||
|
||||
const QChar c1 = _char;
|
||||
if (_codePtr + 4 <= _endPtr && isHexDigit(_char)) {
|
||||
uint codePoint = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int digit = hexDigit(_char);
|
||||
if (digit < 0)
|
||||
goto error;
|
||||
codePoint *= 16;
|
||||
codePoint += digit;
|
||||
scanChar();
|
||||
|
||||
const QChar c2 = _char;
|
||||
scanChar();
|
||||
|
||||
const QChar c3 = _char;
|
||||
scanChar();
|
||||
|
||||
const QChar c4 = _char;
|
||||
scanChar();
|
||||
|
||||
if (ok)
|
||||
*ok = true;
|
||||
|
||||
return convertUnicode(c1, c2, c3, c4);
|
||||
}
|
||||
|
||||
*ok = true;
|
||||
return codePoint;
|
||||
} else if (_codePtr < _endPtr && _char == QLatin1Char('{')) {
|
||||
scanChar(); // skip '{'
|
||||
uint codePoint = 0;
|
||||
if (!isHexDigit(_char))
|
||||
// need at least one hex digit
|
||||
goto error;
|
||||
|
||||
while (_codePtr <= _endPtr) {
|
||||
int digit = hexDigit(_char);
|
||||
if (digit < 0)
|
||||
break;
|
||||
codePoint *= 16;
|
||||
codePoint += digit;
|
||||
if (codePoint > 0x10ffff)
|
||||
goto error;
|
||||
scanChar();
|
||||
}
|
||||
|
||||
if (_char != QLatin1Char('}'))
|
||||
goto error;
|
||||
|
||||
scanChar(); // skip '}'
|
||||
|
||||
|
||||
*ok = true;
|
||||
return codePoint;
|
||||
}
|
||||
|
||||
error:
|
||||
_errorCode = IllegalUnicodeEscapeSequence;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
|
||||
|
||||
*ok = false;
|
||||
return QChar();
|
||||
return 0;
|
||||
}
|
||||
|
||||
QChar Lexer::decodeHexEscapeCharacter(bool *ok)
|
||||
@@ -337,15 +381,15 @@ QChar Lexer::decodeHexEscapeCharacter(bool *ok)
|
||||
return QChar();
|
||||
}
|
||||
|
||||
static inline bool isIdentifierStart(QChar ch)
|
||||
static inline bool isIdentifierStart(uint ch)
|
||||
{
|
||||
// fast path for ascii
|
||||
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
|
||||
(ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
|
||||
if ((ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
ch == '$' || ch == '_')
|
||||
return true;
|
||||
|
||||
switch (ch.category()) {
|
||||
switch (QChar::category(ch)) {
|
||||
case QChar::Number_Letter:
|
||||
case QChar::Letter_Uppercase:
|
||||
case QChar::Letter_Lowercase:
|
||||
@@ -359,17 +403,17 @@ static inline bool isIdentifierStart(QChar ch)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isIdentifierPart(QChar ch)
|
||||
static bool isIdentifierPart(uint ch)
|
||||
{
|
||||
// fast path for ascii
|
||||
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
|
||||
(ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
|
||||
(ch.unicode() >= '0' && ch.unicode() <= '9') ||
|
||||
if ((ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
ch == '$' || ch == '_' ||
|
||||
ch.unicode() == 0x200c /* ZWNJ */ || ch.unicode() == 0x200d /* ZWJ */)
|
||||
ch == 0x200c /* ZWNJ */ || ch == 0x200d /* ZWJ */)
|
||||
return true;
|
||||
|
||||
switch (ch.category()) {
|
||||
switch (QChar::category(ch)) {
|
||||
case QChar::Mark_NonSpacing:
|
||||
case QChar::Mark_SpacingCombining:
|
||||
|
||||
@@ -398,19 +442,23 @@ int Lexer::scanToken()
|
||||
return tk;
|
||||
}
|
||||
|
||||
if (_bracesCount == 0) {
|
||||
// we're inside a Template string
|
||||
return scanString(TemplateContinuation);
|
||||
}
|
||||
|
||||
|
||||
_terminator = false;
|
||||
|
||||
again:
|
||||
_validTokenText = false;
|
||||
_tokenLinePtr = _lastLinePtr;
|
||||
|
||||
while (_char.isSpace()) {
|
||||
if (unsigned sequenceLength = isLineTerminatorSequence()) {
|
||||
_tokenLinePtr = _codePtr + sequenceLength - 1;
|
||||
|
||||
if (isLineTerminator()) {
|
||||
if (_restrictedKeyword) {
|
||||
// automatic semicolon insertion
|
||||
_tokenLine = _currentLineNumber;
|
||||
_tokenColumn = _currentColumnNumber;
|
||||
_tokenStartPtr = _codePtr - 1;
|
||||
return T_SEMICOLON;
|
||||
} else {
|
||||
@@ -424,6 +472,7 @@ again:
|
||||
|
||||
_tokenStartPtr = _codePtr - 1;
|
||||
_tokenLine = _currentLineNumber;
|
||||
_tokenColumn = _currentColumnNumber;
|
||||
|
||||
if (_codePtr > _endPtr)
|
||||
return EOF_SYMBOL;
|
||||
@@ -487,6 +536,9 @@ again:
|
||||
return T_EQ_EQ_EQ;
|
||||
}
|
||||
return T_EQ_EQ;
|
||||
} else if (_char == QLatin1Char('>')) {
|
||||
scanChar();
|
||||
return T_ARROW;
|
||||
}
|
||||
return T_EQ;
|
||||
|
||||
@@ -543,50 +595,18 @@ again:
|
||||
return T_DIVIDE_;
|
||||
|
||||
case '.':
|
||||
if (_char.isDigit()) {
|
||||
QVarLengthArray<char,32> chars;
|
||||
|
||||
chars.append(ch.unicode()); // append the `.'
|
||||
|
||||
while (_char.isDigit()) {
|
||||
chars.append(_char.unicode());
|
||||
if (isDecimalDigit(_char.unicode()))
|
||||
return scanNumber(ch);
|
||||
if (_char == QLatin1Char('.')) {
|
||||
scanChar();
|
||||
}
|
||||
|
||||
if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
|
||||
if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
|
||||
_codePtr[1].isDigit())) {
|
||||
|
||||
chars.append(_char.unicode());
|
||||
scanChar(); // consume `e'
|
||||
|
||||
if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
|
||||
chars.append(_char.unicode());
|
||||
scanChar(); // consume the sign
|
||||
}
|
||||
|
||||
while (_char.isDigit()) {
|
||||
chars.append(_char.unicode());
|
||||
if (_char == QLatin1Char('.')) {
|
||||
scanChar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chars.append('\0');
|
||||
|
||||
const char *begin = chars.constData();
|
||||
const char *end = 0;
|
||||
bool ok = false;
|
||||
|
||||
_tokenValue = qstrtod(begin, &end, &ok);
|
||||
|
||||
if (end - begin != chars.size() - 1) {
|
||||
_errorCode = IllegalExponentIndicator;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Illegal syntax for exponential number");
|
||||
return T_ELLIPSIS;
|
||||
} else {
|
||||
_errorCode = IllegalCharacter;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Unexpected token '.'");
|
||||
return T_ERROR;
|
||||
}
|
||||
|
||||
return T_NUMERIC_LITERAL;
|
||||
}
|
||||
return T_DOT;
|
||||
|
||||
@@ -597,7 +617,7 @@ again:
|
||||
} else if (_char == QLatin1Char('-')) {
|
||||
scanChar();
|
||||
|
||||
if (_terminator && !_delimited && !_prohibitAutomaticSemicolon) {
|
||||
if (_terminator && !_delimited && !_prohibitAutomaticSemicolon && _tokenKind != T_LPAREN) {
|
||||
_stackToken = T_MINUS_MINUS;
|
||||
return T_SEMICOLON;
|
||||
}
|
||||
@@ -615,7 +635,7 @@ again:
|
||||
} else if (_char == QLatin1Char('+')) {
|
||||
scanChar();
|
||||
|
||||
if (_terminator && !_delimited && !_prohibitAutomaticSemicolon) {
|
||||
if (_terminator && !_delimited && !_prohibitAutomaticSemicolon && _tokenKind != T_LPAREN) {
|
||||
_stackToken = T_PLUS_PLUS;
|
||||
return T_SEMICOLON;
|
||||
}
|
||||
@@ -628,6 +648,13 @@ again:
|
||||
if (_char == QLatin1Char('=')) {
|
||||
scanChar();
|
||||
return T_STAR_EQ;
|
||||
} else if (_char == QLatin1Char('*')) {
|
||||
scanChar();
|
||||
if (_char == QLatin1Char('=')) {
|
||||
scanChar();
|
||||
return T_STAR_STAR_EQ;
|
||||
}
|
||||
return T_STAR_STAR;
|
||||
}
|
||||
return T_STAR;
|
||||
|
||||
@@ -662,16 +689,129 @@ again:
|
||||
}
|
||||
return T_NOT;
|
||||
|
||||
case '`':
|
||||
_outerTemplateBraceCount.push(_bracesCount);
|
||||
Q_FALLTHROUGH();
|
||||
case '\'':
|
||||
case '"': {
|
||||
const QChar quote = ch;
|
||||
case '"':
|
||||
return scanString(ScanStringMode(ch.unicode()));
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
return scanNumber(ch);
|
||||
|
||||
default: {
|
||||
uint c = ch.unicode();
|
||||
bool identifierWithEscapeChars = false;
|
||||
if (QChar::isHighSurrogate(c) && QChar::isLowSurrogate(_char.unicode())) {
|
||||
c = QChar::surrogateToUcs4(ushort(c), _char.unicode());
|
||||
scanChar();
|
||||
} else if (c == '\\' && _char == QLatin1Char('u')) {
|
||||
identifierWithEscapeChars = true;
|
||||
bool ok = false;
|
||||
c = decodeUnicodeEscapeCharacter(&ok);
|
||||
if (!ok)
|
||||
return T_ERROR;
|
||||
}
|
||||
if (isIdentifierStart(c)) {
|
||||
if (identifierWithEscapeChars) {
|
||||
_tokenText.resize(0);
|
||||
if (QChar::requiresSurrogates(c)) {
|
||||
_tokenText += QChar(QChar::highSurrogate(c));
|
||||
_tokenText += QChar(QChar::lowSurrogate(c));
|
||||
} else {
|
||||
_tokenText += QChar(c);
|
||||
}
|
||||
_validTokenText = true;
|
||||
}
|
||||
while (_codePtr <= _endPtr) {
|
||||
c = _char.unicode();
|
||||
if (QChar::isHighSurrogate(c) && QChar::isLowSurrogate(_codePtr->unicode())) {
|
||||
scanChar();
|
||||
c = QChar::surrogateToUcs4(ushort(c), _char.unicode());
|
||||
} else if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
|
||||
if (!identifierWithEscapeChars) {
|
||||
identifierWithEscapeChars = true;
|
||||
_tokenText.resize(0);
|
||||
_tokenText.insert(0, _tokenStartPtr, _codePtr - _tokenStartPtr - 1);
|
||||
_validTokenText = true;
|
||||
}
|
||||
|
||||
scanChar(); // skip '\\'
|
||||
bool ok = false;
|
||||
c = decodeUnicodeEscapeCharacter(&ok);
|
||||
if (!ok)
|
||||
return T_ERROR;
|
||||
|
||||
if (!isIdentifierPart(c))
|
||||
break;
|
||||
|
||||
if (identifierWithEscapeChars) {
|
||||
if (QChar::requiresSurrogates(c)) {
|
||||
_tokenText += QChar(QChar::highSurrogate(c));
|
||||
_tokenText += QChar(QChar::lowSurrogate(c));
|
||||
} else {
|
||||
_tokenText += QChar(c);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isIdentifierPart(c))
|
||||
break;
|
||||
|
||||
if (identifierWithEscapeChars) {
|
||||
if (QChar::requiresSurrogates(c)) {
|
||||
_tokenText += QChar(QChar::highSurrogate(c));
|
||||
_tokenText += QChar(QChar::lowSurrogate(c));
|
||||
} else {
|
||||
_tokenText += QChar(c);
|
||||
}
|
||||
}
|
||||
scanChar();
|
||||
}
|
||||
|
||||
_tokenLength = _codePtr - _tokenStartPtr - 1;
|
||||
|
||||
int kind = T_IDENTIFIER;
|
||||
|
||||
if (!identifierWithEscapeChars)
|
||||
kind = classify(_tokenStartPtr, _tokenLength, parseModeFlags());
|
||||
|
||||
if (_engine) {
|
||||
if (kind == T_IDENTIFIER && identifierWithEscapeChars)
|
||||
_tokenSpell = _engine->newStringRef(_tokenText);
|
||||
else
|
||||
_tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
|
||||
}
|
||||
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return T_ERROR;
|
||||
}
|
||||
|
||||
int Lexer::scanString(ScanStringMode mode)
|
||||
{
|
||||
QChar quote = (mode == TemplateContinuation) ? QChar(TemplateHead) : QChar(mode);
|
||||
bool multilineStringLiteral = false;
|
||||
|
||||
const QChar *startCode = _codePtr;
|
||||
|
||||
if (_engine) {
|
||||
while (_codePtr <= _endPtr) {
|
||||
if (isLineTerminator()) {
|
||||
if (isLineTerminator() && quote != QLatin1Char('`')) {
|
||||
if (qmlMode())
|
||||
break;
|
||||
_errorCode = IllegalCharacter;
|
||||
@@ -679,10 +819,20 @@ again:
|
||||
return T_ERROR;
|
||||
} else if (_char == QLatin1Char('\\')) {
|
||||
break;
|
||||
} else if (_char == '$' && quote == QLatin1Char('`')) {
|
||||
break;
|
||||
} else if (_char == quote) {
|
||||
_tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode);
|
||||
scanChar();
|
||||
|
||||
if (quote == QLatin1Char('`'))
|
||||
_bracesCount = _outerTemplateBraceCount.pop();
|
||||
|
||||
if (mode == TemplateHead)
|
||||
return T_NO_SUBSTITUTION_TEMPLATE;
|
||||
else if (mode == TemplateContinuation)
|
||||
return T_TEMPLATE_TAIL;
|
||||
else
|
||||
return T_STRING_LITERAL;
|
||||
}
|
||||
scanChar();
|
||||
@@ -702,13 +852,29 @@ again:
|
||||
if (sequenceLength == 2)
|
||||
_tokenText += *_codePtr;
|
||||
scanChar();
|
||||
} else if (_char == quote) {
|
||||
} else if (_char == mode) {
|
||||
scanChar();
|
||||
|
||||
if (_engine)
|
||||
_tokenSpell = _engine->newStringRef(_tokenText);
|
||||
|
||||
if (quote == QLatin1Char('`'))
|
||||
_bracesCount = _outerTemplateBraceCount.pop();
|
||||
|
||||
if (mode == TemplateContinuation)
|
||||
return T_TEMPLATE_TAIL;
|
||||
else if (mode == TemplateHead)
|
||||
return T_NO_SUBSTITUTION_TEMPLATE;
|
||||
|
||||
return multilineStringLiteral ? T_MULTILINE_STRING_LITERAL : T_STRING_LITERAL;
|
||||
} else if (quote == QLatin1Char('`') && _char == QLatin1Char('$') && *_codePtr == '{') {
|
||||
scanChar();
|
||||
scanChar();
|
||||
_bracesCount = 1;
|
||||
if (_engine)
|
||||
_tokenSpell = _engine->newStringRef(_tokenText);
|
||||
|
||||
return (mode == TemplateHead ? T_TEMPLATE_HEAD : T_TEMPLATE_MIDDLE);
|
||||
} else if (_char == QLatin1Char('\\')) {
|
||||
scanChar();
|
||||
if (_codePtr > _endPtr) {
|
||||
@@ -723,11 +889,15 @@ again:
|
||||
// unicode escape sequence
|
||||
case 'u': {
|
||||
bool ok = false;
|
||||
u = decodeUnicodeEscapeCharacter(&ok);
|
||||
if (! ok) {
|
||||
_errorCode = IllegalUnicodeEscapeSequence;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
|
||||
uint codePoint = decodeUnicodeEscapeCharacter(&ok);
|
||||
if (!ok)
|
||||
return T_ERROR;
|
||||
if (QChar::requiresSurrogates(codePoint)) {
|
||||
// need to use a surrogate pair
|
||||
_tokenText += QChar(QChar::highSurrogate(codePoint));
|
||||
u = QChar::lowSurrogate(codePoint);
|
||||
} else {
|
||||
u = codePoint;
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -759,7 +929,7 @@ again:
|
||||
u = QLatin1Char('\0');
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
Q_FALLTHROUGH();
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
@@ -797,145 +967,96 @@ again:
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Unclosed string at end of line");
|
||||
return T_ERROR;
|
||||
}
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
return scanNumber(ch);
|
||||
|
||||
default: {
|
||||
QChar c = ch;
|
||||
bool identifierWithEscapeChars = false;
|
||||
if (c == QLatin1Char('\\') && _char == QLatin1Char('u')) {
|
||||
identifierWithEscapeChars = true;
|
||||
bool ok = false;
|
||||
c = decodeUnicodeEscapeCharacter(&ok);
|
||||
if (! ok) {
|
||||
_errorCode = IllegalUnicodeEscapeSequence;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
|
||||
return T_ERROR;
|
||||
}
|
||||
}
|
||||
if (isIdentifierStart(c)) {
|
||||
if (identifierWithEscapeChars) {
|
||||
_tokenText.resize(0);
|
||||
_tokenText += c;
|
||||
_validTokenText = true;
|
||||
}
|
||||
while (true) {
|
||||
c = _char;
|
||||
if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
|
||||
if (! identifierWithEscapeChars) {
|
||||
identifierWithEscapeChars = true;
|
||||
_tokenText.resize(0);
|
||||
_tokenText.insert(0, _tokenStartPtr, _codePtr - _tokenStartPtr - 1);
|
||||
_validTokenText = true;
|
||||
}
|
||||
|
||||
scanChar(); // skip '\\'
|
||||
bool ok = false;
|
||||
c = decodeUnicodeEscapeCharacter(&ok);
|
||||
if (! ok) {
|
||||
_errorCode = IllegalUnicodeEscapeSequence;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
|
||||
return T_ERROR;
|
||||
}
|
||||
if (isIdentifierPart(c))
|
||||
_tokenText += c;
|
||||
continue;
|
||||
} else if (isIdentifierPart(c)) {
|
||||
if (identifierWithEscapeChars)
|
||||
_tokenText += c;
|
||||
|
||||
scanChar();
|
||||
continue;
|
||||
}
|
||||
|
||||
_tokenLength = _codePtr - _tokenStartPtr - 1;
|
||||
|
||||
int kind = T_IDENTIFIER;
|
||||
|
||||
if (! identifierWithEscapeChars)
|
||||
kind = classify(_tokenStartPtr, _tokenLength, _qmlMode);
|
||||
|
||||
if (_engine) {
|
||||
if (kind == T_IDENTIFIER && identifierWithEscapeChars)
|
||||
_tokenSpell = _engine->newStringRef(_tokenText);
|
||||
else
|
||||
_tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
|
||||
}
|
||||
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return T_ERROR;
|
||||
}
|
||||
|
||||
int Lexer::scanNumber(QChar ch)
|
||||
{
|
||||
if (ch != QLatin1Char('0')) {
|
||||
QVarLengthArray<char, 64> buf;
|
||||
buf += ch.toLatin1();
|
||||
if (ch == QLatin1Char('0')) {
|
||||
if (_char == QLatin1Char('x') || _char == QLatin1Char('X')) {
|
||||
ch = _char; // remember the x or X to use it in the error message below.
|
||||
|
||||
QChar n = _char;
|
||||
const QChar *code = _codePtr;
|
||||
while (n.isDigit()) {
|
||||
buf += n.toLatin1();
|
||||
n = *code++;
|
||||
// parse hex integer literal
|
||||
scanChar(); // consume 'x'
|
||||
|
||||
if (!isHexDigit(_char)) {
|
||||
_errorCode = IllegalNumber;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "At least one hexadecimal digit is required after '0%1'").arg(ch);
|
||||
return T_ERROR;
|
||||
}
|
||||
|
||||
if (n != QLatin1Char('.') && n != QLatin1Char('e') && n != QLatin1Char('E')) {
|
||||
if (code != _codePtr) {
|
||||
_codePtr = code - 1;
|
||||
double d = 0.;
|
||||
while (1) {
|
||||
int digit = ::hexDigit(_char);
|
||||
if (digit < 0)
|
||||
break;
|
||||
d *= 16;
|
||||
d += digit;
|
||||
scanChar();
|
||||
}
|
||||
buf.append('\0');
|
||||
_tokenValue = strtod(buf.constData(), 0);
|
||||
|
||||
_tokenValue = d;
|
||||
return T_NUMERIC_LITERAL;
|
||||
} else if (_char == QLatin1Char('o') || _char == QLatin1Char('O')) {
|
||||
ch = _char; // remember the o or O to use it in the error message below.
|
||||
|
||||
// parse octal integer literal
|
||||
scanChar(); // consume 'o'
|
||||
|
||||
if (!isOctalDigit(_char.unicode())) {
|
||||
_errorCode = IllegalNumber;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "At least one octal digit is required after '0%1'").arg(ch);
|
||||
return T_ERROR;
|
||||
}
|
||||
|
||||
double d = 0.;
|
||||
while (1) {
|
||||
int digit = ::octalDigit(_char);
|
||||
if (digit < 0)
|
||||
break;
|
||||
d *= 8;
|
||||
d += digit;
|
||||
scanChar();
|
||||
}
|
||||
|
||||
_tokenValue = d;
|
||||
return T_NUMERIC_LITERAL;
|
||||
} else if (_char == QLatin1Char('b') || _char == QLatin1Char('B')) {
|
||||
ch = _char; // remember the b or B to use it in the error message below.
|
||||
|
||||
// parse binary integer literal
|
||||
scanChar(); // consume 'b'
|
||||
|
||||
if (_char.unicode() != '0' && _char.unicode() != '1') {
|
||||
_errorCode = IllegalNumber;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "At least one binary digit is required after '0%1'").arg(ch);
|
||||
return T_ERROR;
|
||||
}
|
||||
|
||||
double d = 0.;
|
||||
while (1) {
|
||||
int digit = 0;
|
||||
if (_char.unicode() == '1')
|
||||
digit = 1;
|
||||
else if (_char.unicode() != '0')
|
||||
break;
|
||||
d *= 2;
|
||||
d += digit;
|
||||
scanChar();
|
||||
}
|
||||
|
||||
_tokenValue = d;
|
||||
return T_NUMERIC_LITERAL;
|
||||
} else if (_char.isDigit() && !qmlMode()) {
|
||||
_errorCode = IllegalCharacter;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Decimal numbers can't start with '0'");
|
||||
return T_ERROR;
|
||||
}
|
||||
|
||||
QVarLengthArray<char,32> chars;
|
||||
chars.append(ch.unicode());
|
||||
|
||||
if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) {
|
||||
ch = _char; // remember the x or X to use it in the error message below.
|
||||
|
||||
// parse hex integer literal
|
||||
chars.append(_char.unicode());
|
||||
scanChar(); // consume `x'
|
||||
|
||||
while (isHexDigit(_char)) {
|
||||
chars.append(_char.unicode());
|
||||
scanChar();
|
||||
}
|
||||
|
||||
if (chars.size() < 3) {
|
||||
_errorCode = IllegalHexNumber;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "At least one hexadecimal digit is required after '0%1'").arg(ch);
|
||||
return T_ERROR;
|
||||
}
|
||||
|
||||
_tokenValue = integerFromString(chars.constData(), chars.size(), 16);
|
||||
return T_NUMERIC_LITERAL;
|
||||
}
|
||||
|
||||
// decimal integer literal
|
||||
QVarLengthArray<char,32> chars;
|
||||
chars.append(ch.unicode());
|
||||
|
||||
if (ch != QLatin1Char('.')) {
|
||||
while (_char.isDigit()) {
|
||||
chars.append(_char.unicode());
|
||||
scanChar(); // consume the digit
|
||||
@@ -944,6 +1065,8 @@ int Lexer::scanNumber(QChar ch)
|
||||
if (_char == QLatin1Char('.')) {
|
||||
chars.append(_char.unicode());
|
||||
scanChar(); // consume `.'
|
||||
}
|
||||
}
|
||||
|
||||
while (_char.isDigit()) {
|
||||
chars.append(_char.unicode());
|
||||
@@ -968,35 +1091,11 @@ int Lexer::scanNumber(QChar ch)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
|
||||
if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
|
||||
_codePtr[1].isDigit())) {
|
||||
|
||||
chars.append(_char.unicode());
|
||||
scanChar(); // consume `e'
|
||||
|
||||
if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
|
||||
chars.append(_char.unicode());
|
||||
scanChar(); // consume the sign
|
||||
}
|
||||
|
||||
while (_char.isDigit()) {
|
||||
chars.append(_char.unicode());
|
||||
scanChar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chars.size() == 1) {
|
||||
// if we ended up with a single digit, then it was a '0'
|
||||
_tokenValue = 0;
|
||||
return T_NUMERIC_LITERAL;
|
||||
}
|
||||
|
||||
chars.append('\0');
|
||||
|
||||
const char *begin = chars.constData();
|
||||
const char *end = 0;
|
||||
const char *end = nullptr;
|
||||
bool ok = false;
|
||||
|
||||
_tokenValue = qstrtod(begin, &end, &ok);
|
||||
@@ -1160,16 +1259,6 @@ bool Lexer::isOctalDigit(ushort c)
|
||||
return (c >= '0' && c <= '7');
|
||||
}
|
||||
|
||||
int Lexer::tokenEndLine() const
|
||||
{
|
||||
return _currentLineNumber;
|
||||
}
|
||||
|
||||
int Lexer::tokenEndColumn() const
|
||||
{
|
||||
return _codePtr - _lastLinePtr;
|
||||
}
|
||||
|
||||
QString Lexer::tokenText() const
|
||||
{
|
||||
if (_validTokenText)
|
||||
@@ -1242,6 +1331,7 @@ static const int uriTokens[] = {
|
||||
QmlJSGrammar::T_FUNCTION,
|
||||
QmlJSGrammar::T_IF,
|
||||
QmlJSGrammar::T_IN,
|
||||
QmlJSGrammar::T_OF,
|
||||
QmlJSGrammar::T_INSTANCEOF,
|
||||
QmlJSGrammar::T_NEW,
|
||||
QmlJSGrammar::T_NULL,
|
||||
@@ -1288,7 +1378,7 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
||||
|
||||
lex(); // skip T_DOT
|
||||
|
||||
if (! (_tokenKind == T_IDENTIFIER || _tokenKind == T_RESERVED_WORD))
|
||||
if (! (_tokenKind == T_IDENTIFIER || _tokenKind == T_IMPORT))
|
||||
return true; // expected a valid QML/JS directive
|
||||
|
||||
const QString directiveName = tokenText();
|
||||
@@ -1312,7 +1402,7 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
||||
}
|
||||
|
||||
// we found a .pragma library directive
|
||||
directives->pragmaLibrary(lineNumber, column);
|
||||
directives->pragmaLibrary();
|
||||
|
||||
} else {
|
||||
Q_ASSERT(directiveName == QLatin1String("import"));
|
||||
@@ -1382,7 +1472,7 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
||||
//
|
||||
// recognize the mandatory `as' followed by the module name
|
||||
//
|
||||
if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("as") && tokenStartLine() == lineNumber)) {
|
||||
if (! (lex() == T_AS && tokenStartLine() == lineNumber)) {
|
||||
if (fileImport)
|
||||
error->message = QCoreApplication::translate("QmlParser", "File import requires a qualifier");
|
||||
else
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include "qmljsgrammar_p.h"
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qstack.h>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
@@ -47,35 +48,7 @@ namespace QmlJS {
|
||||
|
||||
class Engine;
|
||||
class DiagnosticMessage;
|
||||
|
||||
class QML_PARSER_EXPORT Directives {
|
||||
|
||||
public:
|
||||
virtual ~Directives() {}
|
||||
|
||||
virtual void pragmaLibrary(int line, int column)
|
||||
{
|
||||
Q_UNUSED(line);
|
||||
Q_UNUSED(column);
|
||||
}
|
||||
|
||||
virtual void importFile(const QString &jsfile, const QString &module, int line, int column)
|
||||
{
|
||||
Q_UNUSED(jsfile);
|
||||
Q_UNUSED(module);
|
||||
Q_UNUSED(line);
|
||||
Q_UNUSED(column);
|
||||
}
|
||||
|
||||
virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column)
|
||||
{
|
||||
Q_UNUSED(uri);
|
||||
Q_UNUSED(version);
|
||||
Q_UNUSED(module);
|
||||
Q_UNUSED(line);
|
||||
Q_UNUSED(column);
|
||||
}
|
||||
};
|
||||
class Directives;
|
||||
|
||||
class QML_PARSER_EXPORT Lexer: public QmlJSGrammar
|
||||
{
|
||||
@@ -85,10 +58,7 @@ public:
|
||||
T_BOOLEAN = T_RESERVED_WORD,
|
||||
T_BYTE = T_RESERVED_WORD,
|
||||
T_CHAR = T_RESERVED_WORD,
|
||||
T_CLASS = T_RESERVED_WORD,
|
||||
T_DOUBLE = T_RESERVED_WORD,
|
||||
T_EXPORT = T_RESERVED_WORD,
|
||||
T_EXTENDS = T_RESERVED_WORD,
|
||||
T_FINAL = T_RESERVED_WORD,
|
||||
T_FLOAT = T_RESERVED_WORD,
|
||||
T_GOTO = T_RESERVED_WORD,
|
||||
@@ -101,8 +71,6 @@ public:
|
||||
T_PRIVATE = T_RESERVED_WORD,
|
||||
T_PROTECTED = T_RESERVED_WORD,
|
||||
T_SHORT = T_RESERVED_WORD,
|
||||
T_STATIC = T_RESERVED_WORD,
|
||||
T_SUPER = T_RESERVED_WORD,
|
||||
T_SYNCHRONIZED = T_RESERVED_WORD,
|
||||
T_THROWS = T_RESERVED_WORD,
|
||||
T_TRANSIENT = T_RESERVED_WORD,
|
||||
@@ -112,7 +80,7 @@ public:
|
||||
enum Error {
|
||||
NoError,
|
||||
IllegalCharacter,
|
||||
IllegalHexNumber,
|
||||
IllegalNumber,
|
||||
UnclosedStringLiteral,
|
||||
IllegalEscapeSequence,
|
||||
IllegalUnicodeEscapeSequence,
|
||||
@@ -130,13 +98,34 @@ public:
|
||||
enum RegExpFlag {
|
||||
RegExp_Global = 0x01,
|
||||
RegExp_IgnoreCase = 0x02,
|
||||
RegExp_Multiline = 0x04
|
||||
RegExp_Multiline = 0x04,
|
||||
RegExp_Unicode = 0x08,
|
||||
RegExp_Sticky = 0x10
|
||||
};
|
||||
|
||||
enum ParseModeFlags {
|
||||
QmlMode = 0x1,
|
||||
YieldIsKeyword = 0x2,
|
||||
StaticIsKeyword = 0x4
|
||||
};
|
||||
|
||||
public:
|
||||
Lexer(Engine *engine);
|
||||
|
||||
int parseModeFlags() const {
|
||||
int flags = 0;
|
||||
if (qmlMode())
|
||||
flags |= QmlMode|StaticIsKeyword;
|
||||
if (yieldIsKeyWord())
|
||||
flags |= YieldIsKeyword;
|
||||
if (_staticIsKeyword)
|
||||
flags |= StaticIsKeyword;
|
||||
return flags;
|
||||
}
|
||||
|
||||
bool qmlMode() const;
|
||||
bool yieldIsKeyWord() const { return _generatorLevel != 0; }
|
||||
void setStaticIsKeyword(bool b) { _staticIsKeyword = b; }
|
||||
|
||||
QString code() const;
|
||||
void setCode(const QString &code, int lineno, bool qmlMode = true);
|
||||
@@ -154,10 +143,7 @@ public:
|
||||
int tokenLength() const { return _tokenLength; }
|
||||
|
||||
int tokenStartLine() const { return _tokenLine; }
|
||||
int tokenStartColumn() const { return _tokenStartPtr - _tokenLinePtr + 1; }
|
||||
|
||||
int tokenEndLine() const;
|
||||
int tokenEndColumn() const;
|
||||
int tokenStartColumn() const { return _tokenColumn; }
|
||||
|
||||
inline QStringRef tokenSpell() const { return _tokenSpell; }
|
||||
double tokenValue() const { return _tokenValue; }
|
||||
@@ -176,13 +162,23 @@ public:
|
||||
BalancedParentheses
|
||||
};
|
||||
|
||||
void enterGeneratorBody() { ++_generatorLevel; }
|
||||
void leaveGeneratorBody() { --_generatorLevel; }
|
||||
|
||||
protected:
|
||||
int classify(const QChar *s, int n, bool qmlMode);
|
||||
static int classify(const QChar *s, int n, int parseModeFlags);
|
||||
|
||||
private:
|
||||
inline void scanChar();
|
||||
int scanToken();
|
||||
int scanNumber(QChar ch);
|
||||
enum ScanStringMode {
|
||||
SingleQuote = '\'',
|
||||
DoubleQuote = '"',
|
||||
TemplateHead = '`',
|
||||
TemplateContinuation = 0
|
||||
};
|
||||
int scanString(ScanStringMode mode);
|
||||
|
||||
bool isLineTerminator() const;
|
||||
unsigned isLineTerminatorSequence() const;
|
||||
@@ -190,10 +186,9 @@ private:
|
||||
static bool isDecimalDigit(ushort c);
|
||||
static bool isHexDigit(QChar c);
|
||||
static bool isOctalDigit(ushort c);
|
||||
static bool isUnicodeEscapeSequence(const QChar *chars);
|
||||
|
||||
void syncProhibitAutomaticSemicolon();
|
||||
QChar decodeUnicodeEscapeCharacter(bool *ok);
|
||||
uint decodeUnicodeEscapeCharacter(bool *ok);
|
||||
QChar decodeHexEscapeCharacter(bool *ok);
|
||||
|
||||
private:
|
||||
@@ -206,26 +201,30 @@ private:
|
||||
|
||||
const QChar *_codePtr;
|
||||
const QChar *_endPtr;
|
||||
const QChar *_lastLinePtr;
|
||||
const QChar *_tokenLinePtr;
|
||||
const QChar *_tokenStartPtr;
|
||||
|
||||
QChar _char;
|
||||
Error _errorCode;
|
||||
|
||||
int _currentLineNumber;
|
||||
int _currentColumnNumber;
|
||||
double _tokenValue;
|
||||
|
||||
// parentheses state
|
||||
ParenthesesState _parenthesesState;
|
||||
int _parenthesesCount;
|
||||
|
||||
// template string stack
|
||||
QStack<int> _outerTemplateBraceCount;
|
||||
int _bracesCount = -1;
|
||||
|
||||
int _stackToken;
|
||||
|
||||
int _patternFlags;
|
||||
int _tokenKind;
|
||||
int _tokenLength;
|
||||
int _tokenLine;
|
||||
int _tokenColumn;
|
||||
|
||||
bool _validTokenText;
|
||||
bool _prohibitAutomaticSemicolon;
|
||||
@@ -234,6 +233,8 @@ private:
|
||||
bool _followsClosingBrace;
|
||||
bool _delimited;
|
||||
bool _qmlMode;
|
||||
int _generatorLevel = 0;
|
||||
bool _staticIsKeyword = false;
|
||||
};
|
||||
|
||||
} // end of namespace QmlJS
|
||||
|
@@ -56,13 +56,7 @@ class QML_PARSER_EXPORT MemoryPool : public QSharedData
|
||||
void operator =(const MemoryPool &other);
|
||||
|
||||
public:
|
||||
MemoryPool()
|
||||
: _blocks(0),
|
||||
_allocatedBlocks(0),
|
||||
_blockCount(-1),
|
||||
_ptr(0),
|
||||
_end(0)
|
||||
{ }
|
||||
MemoryPool() {}
|
||||
|
||||
~MemoryPool()
|
||||
{
|
||||
@@ -74,6 +68,7 @@ public:
|
||||
|
||||
free(_blocks);
|
||||
}
|
||||
qDeleteAll(strings);
|
||||
}
|
||||
|
||||
inline void *allocate(size_t size)
|
||||
@@ -90,11 +85,16 @@ public:
|
||||
void reset()
|
||||
{
|
||||
_blockCount = -1;
|
||||
_ptr = _end = 0;
|
||||
_ptr = _end = nullptr;
|
||||
}
|
||||
|
||||
template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); }
|
||||
|
||||
QStringRef newString(const QString &string) {
|
||||
strings.append(new QString(string));
|
||||
return QStringRef(strings.last());
|
||||
}
|
||||
|
||||
private:
|
||||
Q_NEVER_INLINE void *allocate_helper(size_t size)
|
||||
{
|
||||
@@ -110,7 +110,7 @@ private:
|
||||
Q_CHECK_PTR(_blocks);
|
||||
|
||||
for (int index = _blockCount; index < _allocatedBlocks; ++index)
|
||||
_blocks[index] = 0;
|
||||
_blocks[index] = nullptr;
|
||||
}
|
||||
|
||||
char *&block = _blocks[_blockCount];
|
||||
@@ -129,11 +129,12 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
char **_blocks;
|
||||
int _allocatedBlocks;
|
||||
int _blockCount;
|
||||
char *_ptr;
|
||||
char *_end;
|
||||
char **_blocks = nullptr;
|
||||
int _allocatedBlocks = 0;
|
||||
int _blockCount = -1;
|
||||
char *_ptr = nullptr;
|
||||
char *_end = nullptr;
|
||||
QVector<QString*> strings;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -144,12 +145,10 @@ private:
|
||||
|
||||
class QML_PARSER_EXPORT Managed
|
||||
{
|
||||
Managed(const Managed &other);
|
||||
void operator = (const Managed &other);
|
||||
|
||||
Q_DISABLE_COPY(Managed)
|
||||
public:
|
||||
Managed() {}
|
||||
~Managed() {}
|
||||
Managed() = default;
|
||||
~Managed() = default;
|
||||
|
||||
void *operator new(size_t size, MemoryPool *pool) { return pool->allocate(size); }
|
||||
void operator delete(void *) {}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,13 @@
|
||||
|
||||
#line 178 "qmljs.g"
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
** This file is part of the QtQml module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
@@ -13,13 +16,26 @@
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
@@ -70,30 +86,42 @@ public:
|
||||
union Value {
|
||||
int ival;
|
||||
double dval;
|
||||
AST::VariableScope scope;
|
||||
AST::ForEachType forEachType;
|
||||
AST::ArgumentList *ArgumentList;
|
||||
AST::CaseBlock *CaseBlock;
|
||||
AST::CaseClause *CaseClause;
|
||||
AST::CaseClauses *CaseClauses;
|
||||
AST::Catch *Catch;
|
||||
AST::DefaultClause *DefaultClause;
|
||||
AST::ElementList *ElementList;
|
||||
AST::Elision *Elision;
|
||||
AST::ExpressionNode *Expression;
|
||||
AST::TemplateLiteral *Template;
|
||||
AST::Finally *Finally;
|
||||
AST::FormalParameterList *FormalParameterList;
|
||||
AST::FunctionBody *FunctionBody;
|
||||
AST::FunctionDeclaration *FunctionDeclaration;
|
||||
AST::Node *Node;
|
||||
AST::PropertyName *PropertyName;
|
||||
AST::PropertyAssignment *PropertyAssignment;
|
||||
AST::PropertyAssignmentList *PropertyAssignmentList;
|
||||
AST::SourceElement *SourceElement;
|
||||
AST::SourceElements *SourceElements;
|
||||
AST::Statement *Statement;
|
||||
AST::StatementList *StatementList;
|
||||
AST::Block *Block;
|
||||
AST::VariableDeclaration *VariableDeclaration;
|
||||
AST::VariableDeclarationList *VariableDeclarationList;
|
||||
AST::Pattern *Pattern;
|
||||
AST::PatternElement *PatternElement;
|
||||
AST::PatternElementList *PatternElementList;
|
||||
AST::PatternProperty *PatternProperty;
|
||||
AST::PatternPropertyList *PatternPropertyList;
|
||||
AST::ClassElementList *ClassElementList;
|
||||
AST::ImportClause *ImportClause;
|
||||
AST::FromClause *FromClause;
|
||||
AST::NameSpaceImport *NameSpaceImport;
|
||||
AST::ImportsList *ImportsList;
|
||||
AST::NamedImports *NamedImports;
|
||||
AST::ImportSpecifier *ImportSpecifier;
|
||||
AST::ExportSpecifier *ExportSpecifier;
|
||||
AST::ExportsList *ExportsList;
|
||||
AST::ExportClause *ExportClause;
|
||||
AST::ExportDeclaration *ExportDeclaration;
|
||||
|
||||
AST::UiProgram *UiProgram;
|
||||
AST::UiHeaderItemList *UiHeaderItemList;
|
||||
@@ -110,7 +138,6 @@ public:
|
||||
AST::UiObjectMemberList *UiObjectMemberList;
|
||||
AST::UiArrayMemberList *UiArrayMemberList;
|
||||
AST::UiQualifiedId *UiQualifiedId;
|
||||
AST::UiQualifiedPragmaId *UiQualifiedPragmaId;
|
||||
AST::UiEnumMemberList *UiEnumMemberList;
|
||||
};
|
||||
|
||||
@@ -119,12 +146,13 @@ public:
|
||||
~Parser();
|
||||
|
||||
// parse a UI program
|
||||
bool parse() { return parse(T_FEED_UI_PROGRAM); }
|
||||
bool parse() { ++functionNestingLevel; bool r = parse(T_FEED_UI_PROGRAM); --functionNestingLevel; return r; }
|
||||
bool parseStatement() { return parse(T_FEED_JS_STATEMENT); }
|
||||
bool parseExpression() { return parse(T_FEED_JS_EXPRESSION); }
|
||||
bool parseSourceElement() { return parse(T_FEED_JS_SOURCE_ELEMENT); }
|
||||
bool parseUiObjectMember() { return parse(T_FEED_UI_OBJECT_MEMBER); }
|
||||
bool parseProgram() { return parse(T_FEED_JS_PROGRAM); }
|
||||
bool parseUiObjectMember() { ++functionNestingLevel; bool r = parse(T_FEED_UI_OBJECT_MEMBER); --functionNestingLevel; return r; }
|
||||
bool parseProgram() { return parse(T_FEED_JS_SCRIPT); }
|
||||
bool parseScript() { return parse(T_FEED_JS_SCRIPT); }
|
||||
bool parseModule() { return parse(T_FEED_JS_MODULE); }
|
||||
|
||||
AST::UiProgram *ast() const
|
||||
{ return AST::cast<AST::UiProgram *>(program); }
|
||||
@@ -193,22 +221,31 @@ protected:
|
||||
{ return location_stack [tos + index - 1]; }
|
||||
|
||||
AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr);
|
||||
AST::UiQualifiedPragmaId *reparseAsQualifiedPragmaId(AST::ExpressionNode *expr);
|
||||
|
||||
void pushToken(int token);
|
||||
int lookaheadToken(Lexer *lexer);
|
||||
|
||||
void syntaxError(const AST::SourceLocation &location, const char *message) {
|
||||
diagnostic_messages.append(DiagnosticMessage(Severity::Error, location, QLatin1String(message)));
|
||||
}
|
||||
void syntaxError(const AST::SourceLocation &location, const QString &message) {
|
||||
diagnostic_messages.append(DiagnosticMessage(Severity::Error, location, message));
|
||||
}
|
||||
|
||||
protected:
|
||||
Engine *driver;
|
||||
MemoryPool *pool;
|
||||
int tos;
|
||||
int stack_size;
|
||||
Value *sym_stack;
|
||||
int *state_stack;
|
||||
AST::SourceLocation *location_stack;
|
||||
QStringRef *string_stack;
|
||||
int tos = 0;
|
||||
int stack_size = 0;
|
||||
Value *sym_stack = nullptr;
|
||||
int *state_stack = nullptr;
|
||||
AST::SourceLocation *location_stack = nullptr;
|
||||
QVector<QStringRef> string_stack;
|
||||
|
||||
AST::Node *program;
|
||||
AST::Node *program = nullptr;
|
||||
|
||||
// error recovery
|
||||
enum { TOKEN_BUFFER_SIZE = 3 };
|
||||
// error recovery and lookahead handling
|
||||
enum { TOKEN_BUFFER_SIZE = 5 };
|
||||
|
||||
struct SavedToken {
|
||||
int token;
|
||||
@@ -217,14 +254,25 @@ protected:
|
||||
QStringRef spell;
|
||||
};
|
||||
|
||||
double yylval;
|
||||
int yytoken = -1;
|
||||
double yylval = 0.;
|
||||
QStringRef yytokenspell;
|
||||
AST::SourceLocation yylloc;
|
||||
AST::SourceLocation yyprevlloc;
|
||||
|
||||
SavedToken token_buffer[TOKEN_BUFFER_SIZE];
|
||||
SavedToken *first_token;
|
||||
SavedToken *last_token;
|
||||
SavedToken *first_token = nullptr;
|
||||
SavedToken *last_token = nullptr;
|
||||
|
||||
int functionNestingLevel = 0;
|
||||
|
||||
enum CoverExpressionType {
|
||||
CE_Invalid,
|
||||
CE_ParenthesizedExpression,
|
||||
CE_FormalParameterList
|
||||
};
|
||||
AST::SourceLocation coverExpressionErrorLocation;
|
||||
CoverExpressionType coverExpressionType = CE_Invalid;
|
||||
|
||||
QList<DiagnosticMessage> diagnostic_messages;
|
||||
};
|
||||
@@ -233,9 +281,27 @@ protected:
|
||||
|
||||
|
||||
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE1 96
|
||||
#line 1511 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE2 97
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE1 128
|
||||
|
||||
#line 1523 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE2 129
|
||||
|
||||
#line 3022 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE 421
|
||||
|
||||
#line 3653 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE 499
|
||||
|
||||
#line 4181 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE 569
|
||||
|
||||
#line 4469 "qmljs.g"
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
|
||||
|
@@ -306,14 +306,14 @@ bool Bind::visit(UiArrayBinding *)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Bind::visit(VariableDeclaration *ast)
|
||||
bool Bind::visit(PatternElement *ast)
|
||||
{
|
||||
if (ast->name.isEmpty())
|
||||
if (ast->bindingIdentifier.isEmpty() || !ast->isVariableDeclaration())
|
||||
return false;
|
||||
|
||||
ASTVariableReference *ref = new ASTVariableReference(ast, _doc, &_valueOwner);
|
||||
if (_currentObjectValue)
|
||||
_currentObjectValue->setMember(ast->name.toString(), ref);
|
||||
_currentObjectValue->setMember(ast->bindingIdentifier, ref);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -337,8 +337,8 @@ bool Bind::visit(FunctionExpression *ast)
|
||||
|
||||
// 1. Function formal arguments
|
||||
for (FormalParameterList *it = ast->formals; it; it = it->next) {
|
||||
if (!it->name.isEmpty())
|
||||
functionScope->setMember(it->name.toString(), _valueOwner.unknownValue());
|
||||
if (!it->element->bindingIdentifier.isEmpty())
|
||||
functionScope->setMember(it->element->bindingIdentifier, _valueOwner.unknownValue());
|
||||
}
|
||||
|
||||
// 2. Functions defined inside the function body
|
||||
|
@@ -79,7 +79,7 @@ protected:
|
||||
// QML/JS
|
||||
bool visit(AST::FunctionDeclaration *ast) override;
|
||||
bool visit(AST::FunctionExpression *ast) override;
|
||||
bool visit(AST::VariableDeclaration *ast) override;
|
||||
bool visit(AST::PatternElement *ast) override;
|
||||
|
||||
ObjectValue *switchObjectValue(ObjectValue *newObjectValue);
|
||||
ObjectValue *bindObject(AST::UiQualifiedId *qualifiedTypeNameId, AST::UiObjectInitializer *initializer);
|
||||
|
@@ -197,10 +197,6 @@ protected:
|
||||
return true;
|
||||
if (Statement *stmt = ast->statementCast())
|
||||
onUnreachable(stmt);
|
||||
if (FunctionSourceElement *fun = cast<FunctionSourceElement *>(ast))
|
||||
onUnreachable(fun->declaration);
|
||||
if (StatementSourceElement *stmt = cast<StatementSourceElement *>(ast))
|
||||
onUnreachable(stmt->statement);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -306,8 +302,6 @@ protected:
|
||||
bool visit(WhileStatement *ast) override { return preconditionLoopStatement(ast, ast->statement); }
|
||||
bool visit(ForStatement *ast) override { return preconditionLoopStatement(ast, ast->statement); }
|
||||
bool visit(ForEachStatement *ast) override { return preconditionLoopStatement(ast, ast->statement); }
|
||||
bool visit(LocalForStatement *ast) override { return preconditionLoopStatement(ast, ast->statement); }
|
||||
bool visit(LocalForEachStatement *ast) override { return preconditionLoopStatement(ast, ast->statement); }
|
||||
|
||||
bool visit(DoWhileStatement *ast) override
|
||||
{
|
||||
@@ -367,8 +361,8 @@ public:
|
||||
{
|
||||
clear();
|
||||
for (FormalParameterList *plist = function->formals; plist; plist = plist->next) {
|
||||
if (!plist->name.isEmpty())
|
||||
_formalParameterNames += plist->name.toString();
|
||||
if (!plist->element->bindingIdentifier.isEmpty())
|
||||
_formalParameterNames += plist->element->bindingIdentifier.toString();
|
||||
}
|
||||
|
||||
Node::accept(function->body, this);
|
||||
@@ -418,11 +412,11 @@ protected:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool visit(VariableDeclaration *ast)
|
||||
bool visit(PatternElement *ast)
|
||||
{
|
||||
if (ast->name.isEmpty())
|
||||
if (ast->bindingIdentifier.isEmpty() || !ast->isVariableDeclaration())
|
||||
return true;
|
||||
const QString &name = ast->name.toString();
|
||||
const QString &name = ast->bindingIdentifier.toString();
|
||||
|
||||
if (_formalParameterNames.contains(name))
|
||||
addMessage(WarnAlreadyFormalParameter, ast->identifierToken, name);
|
||||
@@ -484,7 +478,7 @@ private:
|
||||
|
||||
QList<Message> _messages;
|
||||
QStringList _formalParameterNames;
|
||||
QHash<QString, VariableDeclaration *> _declaredVariables;
|
||||
QHash<QString, PatternElement *> _declaredVariables;
|
||||
QHash<QString, FunctionDeclaration *> _declaredFunctions;
|
||||
QHash<QString, QList<SourceLocation> > _possiblyUndeclaredUses;
|
||||
bool _seenNonDeclarationStatement;
|
||||
@@ -1039,8 +1033,8 @@ bool Check::visit(UiArrayBinding *ast)
|
||||
bool Check::visit(UiPublicMember *ast)
|
||||
{
|
||||
if (ast->type == UiPublicMember::Property) {
|
||||
if (ast->isValid()) {
|
||||
const QStringRef typeName = ast->memberTypeName();
|
||||
if (ast->defaultToken.isValid() || ast->readonlyToken.isValid()) {
|
||||
const QStringRef typeName = ast->memberType->name;
|
||||
if (!typeName.isEmpty() && typeName.at(0).isLower()) {
|
||||
const QString typeNameS = typeName.toString();
|
||||
if (!isValidBuiltinPropertyType(typeNameS))
|
||||
@@ -1277,8 +1271,6 @@ bool Check::visit(Block *ast)
|
||||
&& !cast<Finally *>(p)
|
||||
&& !cast<ForStatement *>(p)
|
||||
&& !cast<ForEachStatement *>(p)
|
||||
&& !cast<LocalForStatement *>(p)
|
||||
&& !cast<LocalForEachStatement *>(p)
|
||||
&& !cast<DoWhileStatement *>(p)
|
||||
&& !cast<WhileStatement *>(p)
|
||||
&& !cast<IfStatement *>(p)
|
||||
@@ -1311,8 +1303,7 @@ bool Check::visit(Expression *ast)
|
||||
{
|
||||
if (ast->left && ast->right) {
|
||||
Node *p = parent();
|
||||
if (!cast<ForStatement *>(p)
|
||||
&& !cast<LocalForStatement *>(p)) {
|
||||
if (!cast<ForStatement *>(p)) {
|
||||
addMessage(WarnComma, ast->commaToken);
|
||||
}
|
||||
}
|
||||
@@ -1372,13 +1363,6 @@ bool Check::visit(ForStatement *ast)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Check::visit(LocalForStatement *ast)
|
||||
{
|
||||
if (ast->condition)
|
||||
checkAssignInCondition(ast->condition);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Check::visit(WhileStatement *ast)
|
||||
{
|
||||
if (ast->expression)
|
||||
|
@@ -84,7 +84,6 @@ protected:
|
||||
bool visit(AST::ExpressionStatement *ast) override;
|
||||
bool visit(AST::IfStatement *ast) override;
|
||||
bool visit(AST::ForStatement *ast) override;
|
||||
bool visit(AST::LocalForStatement *ast) override;
|
||||
bool visit(AST::WhileStatement *ast) override;
|
||||
bool visit(AST::DoWhileStatement *ast) override;
|
||||
bool visit(AST::CaseBlock *ast) override;
|
||||
|
@@ -366,11 +366,11 @@ void DescribeValueVisitor::visit(const Reference *value)
|
||||
}
|
||||
} else if (const ASTVariableReference *v = value->asAstVariableReference()) {
|
||||
basicDump("ASTVariableReference", v, printDetail);
|
||||
const AST::VariableDeclaration *var = v->ast();
|
||||
if (printDetail && var) {
|
||||
const AST::PatternElement *var = v->ast();
|
||||
if (printDetail && var && var->isVariableDeclaration()) {
|
||||
dumpNewline();
|
||||
dump("variable:");
|
||||
dump(var->name.toString());
|
||||
dump(var->bindingIdentifier.toString());
|
||||
}
|
||||
} else if (const QmlPrototypeReference *v = value->asQmlPrototypeReference()) {
|
||||
basicDump("QmlPrototypeReference", v, printDetail);
|
||||
|
@@ -248,7 +248,7 @@ public:
|
||||
|
||||
{}
|
||||
|
||||
void pragmaLibrary(int line, int column) override
|
||||
void pragmaLibrary(int line, int column)
|
||||
{
|
||||
isLibrary = true;
|
||||
addLocation(line, column);
|
||||
@@ -305,12 +305,14 @@ bool Document::parse_helper(int startToken)
|
||||
case QmlJSGrammar::T_FEED_UI_PROGRAM:
|
||||
_parsedCorrectly = parser.parse();
|
||||
break;
|
||||
case QmlJSGrammar::T_FEED_JS_PROGRAM:
|
||||
case QmlJSGrammar::T_FEED_JS_SCRIPT:
|
||||
case QmlJSGrammar::T_FEED_JS_MODULE:
|
||||
_parsedCorrectly = parser.parseProgram();
|
||||
for (const auto &d: directives.locations()) {
|
||||
_jsdirectives << d;
|
||||
}
|
||||
break;
|
||||
|
||||
case QmlJSGrammar::T_FEED_JS_EXPRESSION:
|
||||
_parsedCorrectly = parser.parseExpression();
|
||||
break;
|
||||
@@ -341,7 +343,7 @@ bool Document::parseQml()
|
||||
|
||||
bool Document::parseJavaScript()
|
||||
{
|
||||
return parse_helper(QmlJSGrammar::T_FEED_JS_PROGRAM);
|
||||
return parse_helper(QmlJSGrammar::T_FEED_JS_SCRIPT);
|
||||
}
|
||||
|
||||
bool Document::parseExpression()
|
||||
|
@@ -126,11 +126,6 @@ bool Evaluate::visit(AST::UiHeaderItemList *)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::UiQualifiedPragmaId *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::UiPragma *)
|
||||
{
|
||||
return false;
|
||||
@@ -264,20 +259,20 @@ bool Evaluate::visit(AST::RegExpLiteral *)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::ArrayLiteral *)
|
||||
bool Evaluate::visit(AST::ArrayPattern *)
|
||||
{
|
||||
_result = _valueOwner->arrayCtor()->returnValue();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::ObjectLiteral *)
|
||||
bool Evaluate::visit(AST::ObjectPattern *)
|
||||
{
|
||||
// ### properties
|
||||
_result = _valueOwner->newObject();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::ElementList *)
|
||||
bool Evaluate::visit(AST::PatternElementList *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -287,17 +282,12 @@ bool Evaluate::visit(AST::Elision *)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::PropertyAssignmentList *)
|
||||
bool Evaluate::visit(AST::PatternPropertyList *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::PropertyGetterSetter *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::PropertyNameAndValue *)
|
||||
bool Evaluate::visit(AST::PatternProperty *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -529,11 +519,6 @@ bool Evaluate::visit(AST::Block *)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::StatementList *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::VariableStatement *)
|
||||
{
|
||||
return false;
|
||||
@@ -544,7 +529,7 @@ bool Evaluate::visit(AST::VariableDeclarationList *)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::VariableDeclaration *)
|
||||
bool Evaluate::visit(AST::PatternElement *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -579,21 +564,11 @@ bool Evaluate::visit(AST::ForStatement *)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::LocalForStatement *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::ForEachStatement *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::LocalForEachStatement *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::ContinueStatement *)
|
||||
{
|
||||
return false;
|
||||
@@ -679,27 +654,12 @@ bool Evaluate::visit(AST::FormalParameterList *)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::FunctionBody *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::Program *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::SourceElements *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::FunctionSourceElement *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::StatementSourceElement *)
|
||||
bool Evaluate::visit(AST::StatementList *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@@ -61,7 +61,6 @@ protected:
|
||||
// Ui
|
||||
bool visit(AST::UiProgram *ast) override;
|
||||
bool visit(AST::UiHeaderItemList *ast) override;
|
||||
bool visit(AST::UiQualifiedPragmaId *ast) override;
|
||||
bool visit(AST::UiPragma *ast) override;
|
||||
bool visit(AST::UiImport *ast) override;
|
||||
bool visit(AST::UiPublicMember *ast) override;
|
||||
@@ -84,13 +83,12 @@ protected:
|
||||
bool visit(AST::StringLiteral *ast) override;
|
||||
bool visit(AST::NumericLiteral *ast) override;
|
||||
bool visit(AST::RegExpLiteral *ast) override;
|
||||
bool visit(AST::ArrayLiteral *ast) override;
|
||||
bool visit(AST::ObjectLiteral *ast) override;
|
||||
bool visit(AST::ElementList *ast) override;
|
||||
bool visit(AST::ArrayPattern *ast) override;
|
||||
bool visit(AST::ObjectPattern *ast) override;
|
||||
bool visit(AST::Elision *ast) override;
|
||||
bool visit(AST::PropertyAssignmentList *ast) override;
|
||||
bool visit(AST::PropertyGetterSetter *ast) override;
|
||||
bool visit(AST::PropertyNameAndValue *ast) override;
|
||||
bool visit(AST::PatternElementList *ast) override;
|
||||
bool visit(AST::PatternPropertyList *ast) override;
|
||||
bool visit(AST::PatternProperty *ast) override;
|
||||
bool visit(AST::NestedExpression *ast) override;
|
||||
bool visit(AST::IdentifierPropertyName *ast) override;
|
||||
bool visit(AST::StringLiteralPropertyName *ast) override;
|
||||
@@ -116,19 +114,16 @@ protected:
|
||||
bool visit(AST::ConditionalExpression *ast) override;
|
||||
bool visit(AST::Expression *ast) override;
|
||||
bool visit(AST::Block *ast) override;
|
||||
bool visit(AST::StatementList *ast) override;
|
||||
bool visit(AST::VariableStatement *ast) override;
|
||||
bool visit(AST::VariableDeclarationList *ast) override;
|
||||
bool visit(AST::VariableDeclaration *ast) override;
|
||||
bool visit(AST::PatternElement *ast) override;
|
||||
bool visit(AST::EmptyStatement *ast) override;
|
||||
bool visit(AST::ExpressionStatement *ast) override;
|
||||
bool visit(AST::IfStatement *ast) override;
|
||||
bool visit(AST::DoWhileStatement *ast) override;
|
||||
bool visit(AST::WhileStatement *ast) override;
|
||||
bool visit(AST::ForStatement *ast) override;
|
||||
bool visit(AST::LocalForStatement *ast) override;
|
||||
bool visit(AST::ForEachStatement *ast) override;
|
||||
bool visit(AST::LocalForEachStatement *ast) override;
|
||||
bool visit(AST::ContinueStatement *ast) override;
|
||||
bool visit(AST::BreakStatement *ast) override;
|
||||
bool visit(AST::ReturnStatement *ast) override;
|
||||
@@ -146,11 +141,8 @@ protected:
|
||||
bool visit(AST::FunctionDeclaration *ast) override;
|
||||
bool visit(AST::FunctionExpression *ast) override;
|
||||
bool visit(AST::FormalParameterList *ast) override;
|
||||
bool visit(AST::FunctionBody *ast) override;
|
||||
bool visit(AST::Program *ast) override;
|
||||
bool visit(AST::SourceElements *ast) override;
|
||||
bool visit(AST::FunctionSourceElement *ast) override;
|
||||
bool visit(AST::StatementSourceElement *ast) override;
|
||||
bool visit(AST::StatementList *ast) override;
|
||||
bool visit(AST::DebuggerStatement *ast) override;
|
||||
|
||||
private:
|
||||
|
@@ -1052,6 +1052,11 @@ void ObjectValue::setMember(const QString &name, const Value *value)
|
||||
m_members[name].value = value;
|
||||
}
|
||||
|
||||
void ObjectValue::setMember(const QStringRef &name, const Value *value)
|
||||
{
|
||||
m_members[name.toString()].value = value;
|
||||
}
|
||||
|
||||
void ObjectValue::setPropertyInfo(const QString &name, const PropertyInfo &propertyInfo)
|
||||
{
|
||||
m_members[name].propertyInfo = propertyInfo;
|
||||
@@ -1856,7 +1861,7 @@ ASTObjectValue::ASTObjectValue(UiQualifiedId *typeName,
|
||||
for (UiObjectMemberList *it = m_initializer->members; it; it = it->next) {
|
||||
UiObjectMember *member = it->member;
|
||||
if (UiPublicMember *def = cast<UiPublicMember *>(member)) {
|
||||
if (def->type == UiPublicMember::Property && !def->name.isEmpty() && def->isValid()) {
|
||||
if (def->type == UiPublicMember::Property && !def->name.isEmpty()) {
|
||||
ASTPropertyReference *ref = new ASTPropertyReference(def, m_doc, valueOwner);
|
||||
m_properties.append(ref);
|
||||
if (def->defaultToken.isValid())
|
||||
@@ -1931,7 +1936,7 @@ const Document *ASTObjectValue::document() const
|
||||
return m_doc;
|
||||
}
|
||||
|
||||
ASTVariableReference::ASTVariableReference(VariableDeclaration *ast, const Document *doc, ValueOwner *valueOwner)
|
||||
ASTVariableReference::ASTVariableReference(PatternElement *ast, const Document *doc, ValueOwner *valueOwner)
|
||||
: Reference(valueOwner)
|
||||
, m_ast(ast)
|
||||
, m_doc(doc)
|
||||
@@ -1947,7 +1952,7 @@ const ASTVariableReference *ASTVariableReference::asAstVariableReference() const
|
||||
return this;
|
||||
}
|
||||
|
||||
const VariableDeclaration *ASTVariableReference::ast() const
|
||||
const PatternElement *ASTVariableReference::ast() const
|
||||
{
|
||||
return m_ast;
|
||||
}
|
||||
@@ -1955,16 +1960,16 @@ const VariableDeclaration *ASTVariableReference::ast() const
|
||||
const Value *ASTVariableReference::value(ReferenceContext *referenceContext) const
|
||||
{
|
||||
// may be assigned to later
|
||||
if (!m_ast->expression)
|
||||
if (!m_ast->expressionCast())
|
||||
return valueOwner()->unknownValue();
|
||||
|
||||
Document::Ptr doc = m_doc->ptr();
|
||||
ScopeChain scopeChain(doc, referenceContext->context());
|
||||
ScopeBuilder builder(&scopeChain);
|
||||
builder.push(ScopeAstPath(doc)(m_ast->expression->firstSourceLocation().begin()));
|
||||
builder.push(ScopeAstPath(doc)(m_ast->expressionCast()->firstSourceLocation().begin()));
|
||||
|
||||
Evaluate evaluator(&scopeChain, referenceContext);
|
||||
return evaluator(m_ast->expression);
|
||||
return evaluator(m_ast->expressionCast());
|
||||
}
|
||||
|
||||
bool ASTVariableReference::getSourceLocation(QString *fileName, int *line, int *column) const
|
||||
@@ -1981,12 +1986,12 @@ class UsesArgumentsArray : protected Visitor
|
||||
bool m_usesArgumentsArray;
|
||||
|
||||
public:
|
||||
bool operator()(FunctionBody *ast)
|
||||
bool operator()(StatementList *ast)
|
||||
{
|
||||
if (!ast || !ast->elements)
|
||||
if (!ast)
|
||||
return false;
|
||||
m_usesArgumentsArray = false;
|
||||
Node::accept(ast->elements, this);
|
||||
Node::accept(ast, this);
|
||||
return m_usesArgumentsArray;
|
||||
}
|
||||
|
||||
@@ -2001,7 +2006,8 @@ protected:
|
||||
}
|
||||
|
||||
// don't go into nested functions
|
||||
bool visit(FunctionBody *) { return false; }
|
||||
bool visit(Program *) { return false; }
|
||||
bool visit(StatementList *) { return false; }
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
@@ -2013,7 +2019,7 @@ ASTFunctionValue::ASTFunctionValue(FunctionExpression *ast, const Document *doc,
|
||||
setPrototype(valueOwner->functionPrototype());
|
||||
|
||||
for (FormalParameterList *it = ast->formals; it; it = it->next)
|
||||
m_argumentNames.append(it->name.toString());
|
||||
m_argumentNames.append(it->element->bindingIdentifier.toString());
|
||||
|
||||
m_isVariadic = UsesArgumentsArray()(ast->body);
|
||||
}
|
||||
@@ -2121,10 +2127,9 @@ bool ASTPropertyReference::getSourceLocation(QString *fileName, int *line, int *
|
||||
const Value *ASTPropertyReference::value(ReferenceContext *referenceContext) const
|
||||
{
|
||||
if (m_ast->statement
|
||||
&& (!m_ast->isValid()
|
||||
|| m_ast->memberTypeName() == QLatin1String("variant")
|
||||
|| m_ast->memberTypeName() == QLatin1String("var")
|
||||
|| m_ast->memberTypeName() == QLatin1String("alias"))) {
|
||||
&& (m_ast->memberType->name == QLatin1String("variant")
|
||||
|| m_ast->memberType->name == QLatin1String("var")
|
||||
|| m_ast->memberType->name == QLatin1String("alias"))) {
|
||||
|
||||
// Adjust the context for the current location - expensive!
|
||||
// ### Improve efficiency by caching the 'use chain' constructed in ScopeBuilder.
|
||||
@@ -2140,7 +2145,7 @@ const Value *ASTPropertyReference::value(ReferenceContext *referenceContext) con
|
||||
return evaluator(m_ast->statement);
|
||||
}
|
||||
|
||||
const QString memberType = m_ast->memberTypeName().toString();
|
||||
const QString memberType = m_ast->memberType->name.toString();
|
||||
|
||||
const Value *builtin = valueOwner()->defaultValueForBuiltinType(memberType);
|
||||
if (!builtin->asUndefinedValue())
|
||||
|
@@ -508,6 +508,7 @@ public:
|
||||
virtual void processMembers(MemberProcessor *processor) const;
|
||||
|
||||
virtual void setMember(const QString &name, const Value *value);
|
||||
virtual void setMember(const QStringRef &name, const Value *value);
|
||||
virtual void setPropertyInfo(const QString &name, const PropertyInfo &propertyInfo);
|
||||
virtual void removeMember(const QString &name);
|
||||
|
||||
@@ -884,14 +885,14 @@ private:
|
||||
|
||||
class QMLJS_EXPORT ASTVariableReference: public Reference
|
||||
{
|
||||
AST::VariableDeclaration *m_ast;
|
||||
AST::PatternElement *m_ast;
|
||||
const Document *m_doc;
|
||||
|
||||
public:
|
||||
ASTVariableReference(AST::VariableDeclaration *ast, const Document *doc, ValueOwner *valueOwner);
|
||||
ASTVariableReference(AST::PatternElement *ast, const Document *doc, ValueOwner *valueOwner);
|
||||
~ASTVariableReference();
|
||||
const ASTVariableReference *asAstVariableReference() const override;
|
||||
const AST::VariableDeclaration *ast() const;
|
||||
const AST::PatternElement *ast() const;
|
||||
private:
|
||||
const Value *value(ReferenceContext *referenceContext) const override;
|
||||
bool getSourceLocation(QString *fileName, int *line, int *column) const override;
|
||||
|
@@ -531,7 +531,6 @@ protected:
|
||||
bool visit(UiPragma *ast) override
|
||||
{
|
||||
out("pragma ", ast->pragmaToken);
|
||||
accept(ast->pragmaType);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -666,20 +665,16 @@ protected:
|
||||
bool visit(NumericLiteral *ast) override { out(ast->literalToken); return true; }
|
||||
bool visit(RegExpLiteral *ast) override { out(ast->literalToken); return true; }
|
||||
|
||||
bool visit(ArrayLiteral *ast) override
|
||||
bool visit(ArrayPattern *ast) override
|
||||
{
|
||||
out(ast->lbracketToken);
|
||||
if (ast->elements)
|
||||
accept(ast->elements);
|
||||
if (ast->elements && ast->elision)
|
||||
out(", ", ast->commaToken);
|
||||
if (ast->elision)
|
||||
accept(ast->elision);
|
||||
out(ast->rbracketToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(ObjectLiteral *ast) override
|
||||
bool visit(ObjectPattern *ast) override
|
||||
{
|
||||
out(ast->lbraceToken);
|
||||
lnAcceptIndented(ast->properties);
|
||||
@@ -688,55 +683,57 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(ElementList *ast) override
|
||||
bool visit(PatternElementList *ast) override
|
||||
{
|
||||
for (ElementList *it = ast; it; it = it->next) {
|
||||
for (PatternElementList *it = ast; it; it = it->next) {
|
||||
if (it->elision)
|
||||
accept(it->elision);
|
||||
if (it->elision && it->expression)
|
||||
if (it->elision && it->element)
|
||||
out(", ");
|
||||
if (it->expression)
|
||||
accept(it->expression);
|
||||
if (it->element)
|
||||
accept(it->element);
|
||||
if (it->next)
|
||||
out(", ", ast->commaToken);
|
||||
out(", ");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(PropertyAssignmentList *ast) override
|
||||
bool visit(PatternPropertyList *ast) override
|
||||
{
|
||||
for (PropertyAssignmentList *it = ast; it; it = it->next) {
|
||||
PropertyNameAndValue *assignment = AST::cast<PropertyNameAndValue *>(it->assignment);
|
||||
for (PatternPropertyList *it = ast; it; it = it->next) {
|
||||
PatternProperty *assignment = AST::cast<PatternProperty *>(it->property);
|
||||
if (assignment) {
|
||||
out("\"");
|
||||
accept(assignment->name);
|
||||
out("\"");
|
||||
out(": ", assignment->colonToken);
|
||||
accept(assignment->value);
|
||||
accept(assignment->initializer);
|
||||
if (it->next) {
|
||||
out(",", ast->commaToken); // always invalid?
|
||||
out(","); // always invalid?
|
||||
newLine();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
PropertyGetterSetter *getterSetter = AST::cast<PropertyGetterSetter *>(it->assignment);
|
||||
if (getterSetter) {
|
||||
switch (getterSetter->type) {
|
||||
case PropertyGetterSetter::Getter:
|
||||
PatternPropertyList *getterSetter = AST::cast<PatternPropertyList *>(it->next);
|
||||
if (getterSetter->property) {
|
||||
switch (getterSetter->property->type) {
|
||||
case PatternElement::Getter:
|
||||
out("get");
|
||||
break;
|
||||
case PropertyGetterSetter::Setter:
|
||||
case PatternElement::Setter:
|
||||
out("set");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
accept(getterSetter->name);
|
||||
out("(", getterSetter->lparenToken);
|
||||
accept(getterSetter->formals);
|
||||
out("(", getterSetter->rparenToken);
|
||||
out(" {", getterSetter->lbraceToken);
|
||||
accept(getterSetter->functionBody);
|
||||
out(" }", getterSetter->rbraceToken);
|
||||
accept(getterSetter->property->name);
|
||||
out("(");
|
||||
//accept(getterSetter->formals); // TODO
|
||||
out(")");
|
||||
out(" {");
|
||||
//accept(getterSetter->functionBody); // TODO
|
||||
out(" }");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -922,12 +919,15 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(VariableDeclaration *ast) override
|
||||
bool visit(PatternElement *ast) override
|
||||
{
|
||||
if (!ast->isVariableDeclaration())
|
||||
return false;
|
||||
|
||||
out(ast->identifierToken);
|
||||
if (ast->expression) {
|
||||
if (ast->initializer) {
|
||||
out(" = ");
|
||||
accept(ast->expression);
|
||||
accept(ast->initializer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -996,45 +996,13 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(LocalForStatement *ast) override
|
||||
{
|
||||
out(ast->forToken);
|
||||
out(" ");
|
||||
out(ast->lparenToken);
|
||||
out(ast->varToken);
|
||||
out(" ");
|
||||
accept(ast->declarations);
|
||||
out("; ", ast->firstSemicolonToken);
|
||||
accept(ast->condition);
|
||||
out("; ", ast->secondSemicolonToken);
|
||||
accept(ast->expression);
|
||||
out(")", ast->rparenToken);
|
||||
acceptBlockOrIndented(ast->statement);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(ForEachStatement *ast) override
|
||||
{
|
||||
out(ast->forToken);
|
||||
out(" ");
|
||||
out(ast->lparenToken);
|
||||
accept(ast->initialiser);
|
||||
out(" in ", ast->inToken);
|
||||
accept(ast->expression);
|
||||
out(ast->rparenToken);
|
||||
acceptBlockOrIndented(ast->statement);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(LocalForEachStatement *ast) override
|
||||
{
|
||||
out(ast->forToken);
|
||||
out(" ");
|
||||
out(ast->lparenToken);
|
||||
out(ast->varToken);
|
||||
out(" ");
|
||||
accept(ast->declaration);
|
||||
out(" in ", ast->inToken);
|
||||
accept(ast->lhs);
|
||||
out(" in ");
|
||||
accept(ast->expression);
|
||||
out(ast->rparenToken);
|
||||
acceptBlockOrIndented(ast->statement);
|
||||
@@ -1245,12 +1213,6 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(UiQualifiedPragmaId *ast) override
|
||||
{
|
||||
out(ast->identifierToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(Elision *ast) override
|
||||
{
|
||||
for (Elision *it = ast; it; it = it->next) {
|
||||
@@ -1288,16 +1250,6 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(SourceElements *ast) override
|
||||
{
|
||||
for (SourceElements *it = ast; it; it = it->next) {
|
||||
accept(it->element);
|
||||
if (it->next)
|
||||
newLine();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(VariableDeclarationList *ast) override
|
||||
{
|
||||
for (VariableDeclarationList *it = ast; it; it = it->next) {
|
||||
@@ -1321,9 +1273,7 @@ protected:
|
||||
bool visit(FormalParameterList *ast) override
|
||||
{
|
||||
for (FormalParameterList *it = ast; it; it = it->next) {
|
||||
if (it->commaToken.isValid())
|
||||
out(", ", it->commaToken);
|
||||
out(it->identifierToken);
|
||||
out(it->element->bindingIdentifier.toString()); // TODO
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@@ -250,12 +250,12 @@ QVariant SimpleAbstractStreamReader::parsePropertyExpression(AST::ExpressionNode
|
||||
{
|
||||
Q_ASSERT(expressionNode);
|
||||
|
||||
AST::ArrayLiteral *arrayLiteral = AST::cast<AST::ArrayLiteral *>(expressionNode);
|
||||
AST::ArrayPattern *arrayLiteral = AST::cast<AST::ArrayPattern *>(expressionNode);
|
||||
|
||||
if (arrayLiteral) {
|
||||
QList<QVariant> variantList;
|
||||
for (AST::ElementList *it = arrayLiteral->elements; it; it = it->next)
|
||||
variantList << parsePropertyExpression(it->expression);
|
||||
for (AST::PatternElementList *it = arrayLiteral->elements; it; it = it->next)
|
||||
variantList << parsePropertyExpression(it->element->initializer);
|
||||
return variantList;
|
||||
}
|
||||
|
||||
|
@@ -189,13 +189,14 @@ void TypeDescriptionReader::readDependencies(UiScriptBinding *ast)
|
||||
addError(ast->statement->firstSourceLocation(), tr("Expected dependency definitions"));
|
||||
return;
|
||||
}
|
||||
ArrayLiteral *exp = AST::cast<ArrayLiteral *>(stmt->expression);
|
||||
ArrayPattern *exp = AST::cast<ArrayPattern *>(stmt->expression);
|
||||
if (!exp) {
|
||||
addError(stmt->expression->firstSourceLocation(), tr("Expected dependency definitions"));
|
||||
return;
|
||||
}
|
||||
for (ElementList *l = exp->elements; l; l = l->next) {
|
||||
StringLiteral *str = AST::cast<StringLiteral *>(l->expression);
|
||||
for (PatternElementList *l = exp->elements; l; l = l->next) {
|
||||
//StringLiteral *str = AST::cast<StringLiteral *>(l->element->initializer);
|
||||
StringLiteral *str = AST::cast<StringLiteral *>(l->element->initializer);
|
||||
*_dependencies << str->value.toString();
|
||||
}
|
||||
}
|
||||
@@ -231,7 +232,7 @@ void TypeDescriptionReader::readComponent(UiObjectDefinition *ast)
|
||||
} else if (name == QLatin1String("exports")) {
|
||||
readExports(script, fmo);
|
||||
} else if (name == QLatin1String("exportMetaObjectRevisions")) {
|
||||
readMetaObjectRevisions(script, fmo);
|
||||
//readMetaObjectRevisions(script, fmo);
|
||||
} else if (name == QLatin1String("attachedType")) {
|
||||
fmo->setAttachedTypeName(readStringBinding(script));
|
||||
} else if (name == QLatin1String("isSingleton")) {
|
||||
@@ -562,14 +563,14 @@ void TypeDescriptionReader::readExports(UiScriptBinding *ast, FakeMetaObject::Pt
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayLiteral *arrayLit = AST::cast<ArrayLiteral *>(expStmt->expression);
|
||||
ArrayPattern *arrayLit = AST::cast<ArrayPattern *>(expStmt->expression);
|
||||
if (!arrayLit) {
|
||||
addError(expStmt->firstSourceLocation(), tr("Expected array of strings after colon."));
|
||||
return;
|
||||
}
|
||||
|
||||
for (ElementList *it = arrayLit->elements; it; it = it->next) {
|
||||
StringLiteral *stringLit = AST::cast<StringLiteral *>(it->expression);
|
||||
for (PatternElementList *it = arrayLit->elements; it; it = it->next) {
|
||||
StringLiteral *stringLit = AST::cast<StringLiteral *>(it->element->initializer);
|
||||
if (!stringLit) {
|
||||
addError(arrayLit->firstSourceLocation(), tr("Expected array literal with only string literal members."));
|
||||
return;
|
||||
@@ -608,7 +609,7 @@ void TypeDescriptionReader::readMetaObjectRevisions(UiScriptBinding *ast, FakeMe
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayLiteral *arrayLit = AST::cast<ArrayLiteral *>(expStmt->expression);
|
||||
ArrayPattern *arrayLit = AST::cast<ArrayPattern *>(expStmt->expression);
|
||||
if (!arrayLit) {
|
||||
addError(expStmt->firstSourceLocation(), tr("Expected array of numbers after colon."));
|
||||
return;
|
||||
@@ -616,8 +617,8 @@ void TypeDescriptionReader::readMetaObjectRevisions(UiScriptBinding *ast, FakeMe
|
||||
|
||||
int exportIndex = 0;
|
||||
const int exportCount = fmo->exports().size();
|
||||
for (ElementList *it = arrayLit->elements; it; it = it->next, ++exportIndex) {
|
||||
NumericLiteral *numberLit = cast<NumericLiteral *>(it->expression);
|
||||
for (PatternElementList *it = arrayLit->elements; it; it = it->next, ++exportIndex) {
|
||||
NumericLiteral *numberLit = cast<NumericLiteral *>(it->element->initializer);
|
||||
if (!numberLit) {
|
||||
addError(arrayLit->firstSourceLocation(), tr("Expected array literal with only number literal members."));
|
||||
return;
|
||||
@@ -654,18 +655,18 @@ void TypeDescriptionReader::readEnumValues(AST::UiScriptBinding *ast, LanguageUt
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectLiteral *objectLit = AST::cast<ObjectLiteral *>(expStmt->expression);
|
||||
ObjectPattern *objectLit = AST::cast<ObjectPattern *>(expStmt->expression);
|
||||
if (!objectLit) {
|
||||
addError(expStmt->firstSourceLocation(), tr("Expected object literal after colon."));
|
||||
return;
|
||||
}
|
||||
|
||||
for (PropertyAssignmentList *it = objectLit->properties; it; it = it->next) {
|
||||
PropertyNameAndValue *assignement = AST::cast<PropertyNameAndValue *>(it->assignment);
|
||||
for (PatternPropertyList *it = objectLit->properties; it; it = it->next) {
|
||||
PatternProperty *assignement = AST::cast<PatternProperty *>(it->property);
|
||||
if (assignement) {
|
||||
StringLiteralPropertyName *propName = AST::cast<StringLiteralPropertyName *>(assignement->name);
|
||||
NumericLiteral *value = AST::cast<NumericLiteral *>(assignement->value);
|
||||
UnaryMinusExpression *minus = AST::cast<UnaryMinusExpression *>(assignement->value);
|
||||
NumericLiteral *value = AST::cast<NumericLiteral *>(assignement->initializer);
|
||||
UnaryMinusExpression *minus = AST::cast<UnaryMinusExpression *>(assignement->initializer);
|
||||
if (minus)
|
||||
value = AST::cast<NumericLiteral *>(minus->expression);
|
||||
if (!propName || !value) {
|
||||
@@ -679,7 +680,7 @@ void TypeDescriptionReader::readEnumValues(AST::UiScriptBinding *ast, LanguageUt
|
||||
fme->addKey(propName->id.toString(), v);
|
||||
continue;
|
||||
}
|
||||
PropertyGetterSetter *getterSetter = AST::cast<PropertyGetterSetter *>(it->assignment);
|
||||
PatternPropertyList *getterSetter = AST::cast<PatternPropertyList *>(it->next);
|
||||
if (getterSetter)
|
||||
addError(objectLit->firstSourceLocation(), tr("Enum should not contain getter and setters, but only 'string: number' elements."));
|
||||
}
|
||||
|
@@ -35,7 +35,8 @@ bool InteractiveInterpreter::canEvaluate()
|
||||
int yytos = -1;
|
||||
|
||||
setCode(m_code, 1);
|
||||
m_tokens.append(T_FEED_JS_PROGRAM);
|
||||
m_tokens.append(T_FEED_JS_SCRIPT);
|
||||
m_tokens.append(T_FEED_JS_MODULE);
|
||||
|
||||
do {
|
||||
if (++yytos == m_stateStack.size())
|
||||
|
@@ -160,15 +160,12 @@ public:
|
||||
|
||||
bool visit(VariableStatement *ast) override { test(ast); return true; }
|
||||
bool visit(VariableDeclarationList *ast) override { test(ast); return true; }
|
||||
bool visit(VariableDeclaration *ast) override { test(ast); return true; }
|
||||
bool visit(ExpressionStatement *ast) override { test(ast); return true; }
|
||||
bool visit(IfStatement *ast) override { test(ast); return true; }
|
||||
bool visit(DoWhileStatement *ast) override { test(ast); return true; }
|
||||
bool visit(WhileStatement *ast) override { test(ast); return true; }
|
||||
bool visit(ForStatement *ast) override { test(ast); return true; }
|
||||
bool visit(LocalForStatement *ast) override { test(ast); return true; }
|
||||
bool visit(ForEachStatement *ast) override { test(ast); return true; }
|
||||
bool visit(LocalForEachStatement *ast) override { test(ast); return true; }
|
||||
bool visit(ContinueStatement *ast) override { test(ast); return true; }
|
||||
bool visit(BreakStatement *ast) override { test(ast); return true; }
|
||||
bool visit(ReturnStatement *ast) override { test(ast); return true; }
|
||||
|
@@ -84,7 +84,7 @@ protected:
|
||||
|
||||
bool visit(AST::UiPublicMember *node) override
|
||||
{
|
||||
if (node->memberTypeName() == m_typeName){
|
||||
if (node->memberType->name == m_typeName){
|
||||
const ObjectValue * objectValue = m_context->lookupType(m_document.data(), QStringList(m_typeName));
|
||||
if (objectValue == m_typeValue)
|
||||
m_implemenations.append(node->typeToken);
|
||||
@@ -187,9 +187,10 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(AST::VariableDeclaration *node) override
|
||||
bool visit(AST::PatternElement *node) override
|
||||
{
|
||||
AST::Node::accept(node->expression, this);
|
||||
if (node->isVariableDeclaration())
|
||||
AST::Node::accept(node->initializer, this);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -81,6 +81,7 @@ void AddPropertyVisitor::addInMembers(QmlJS::AST::UiObjectInitializer *initializ
|
||||
QmlJS::AST::UiObjectMemberList *insertAfter = searchMemberToInsertAfter(initializer->members, m_name, m_propertyOrder);
|
||||
QmlJS::AST::SourceLocation endOfPreviousMember;
|
||||
QmlJS::AST::SourceLocation startOfNextMember;
|
||||
bool previousMemberSemicolon = false;
|
||||
unsigned depth;
|
||||
|
||||
if (insertAfter == nullptr || insertAfter->member == nullptr) {
|
||||
@@ -96,6 +97,16 @@ void AddPropertyVisitor::addInMembers(QmlJS::AST::UiObjectInitializer *initializ
|
||||
} else {
|
||||
endOfPreviousMember = insertAfter->member->lastSourceLocation();
|
||||
|
||||
// Find out if the previous members ends with semicolon.
|
||||
if (auto member = QmlJS::AST::cast<QmlJS::AST::UiScriptBinding*>(insertAfter->member)) {
|
||||
if (auto stmt = QmlJS::AST::cast<QmlJS::AST::ExpressionStatement*>(member->statement))
|
||||
previousMemberSemicolon = stmt->semicolonToken.isValid();
|
||||
else
|
||||
previousMemberSemicolon = endOfPreviousMember.isValid();
|
||||
} else {
|
||||
previousMemberSemicolon = endOfPreviousMember.isValid();
|
||||
}
|
||||
|
||||
if (insertAfter->next && insertAfter->next->member)
|
||||
startOfNextMember = insertAfter->next->member->firstSourceLocation();
|
||||
else
|
||||
@@ -113,7 +124,7 @@ void AddPropertyVisitor::addInMembers(QmlJS::AST::UiObjectInitializer *initializ
|
||||
needsTrailingSemicolon = m_propertyType == QmlRefactoring::ScriptBinding;
|
||||
}
|
||||
} else { // we're inserting after a member, not after the lbrace
|
||||
if (endOfPreviousMember.isValid()) { // there already is a semicolon after the previous member
|
||||
if (previousMemberSemicolon) {
|
||||
if (insertAfter->next && insertAfter->next->member) { // and the after us there is a member, not an rbrace, so:
|
||||
needsTrailingSemicolon = m_propertyType == QmlRefactoring::ScriptBinding;
|
||||
}
|
||||
|
@@ -85,8 +85,8 @@ static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPt
|
||||
{
|
||||
TypeName type = "unknown";
|
||||
|
||||
if (ref->ast()->isValid()) {
|
||||
type = ref->ast()->memberTypeName().toUtf8();
|
||||
if (ref->ast()->defaultToken.isValid()) {
|
||||
type = ref->ast()->memberType->name.toUtf8();
|
||||
|
||||
if (type == "alias") {
|
||||
const Value *value = context->lookupReference(ref);
|
||||
|
@@ -1178,9 +1178,6 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
|
||||
if (property->type == AST::UiPublicMember::Signal)
|
||||
continue; // QML designer doesn't support this yet.
|
||||
|
||||
if (property->name.isEmpty() || !property->isValid())
|
||||
continue; // better safe than sorry.
|
||||
|
||||
const QStringRef astName = property->name;
|
||||
QString astValue;
|
||||
if (property->statement)
|
||||
@@ -1193,7 +1190,7 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
|
||||
astValue = astValue.left(astValue.length() - 1);
|
||||
astValue = astValue.trimmed();
|
||||
|
||||
const TypeName &astType = property->memberTypeName().toUtf8();
|
||||
const TypeName &astType = property->memberType->name.toUtf8();
|
||||
AbstractProperty modelProperty = modelNode.property(astName.toUtf8());
|
||||
|
||||
if (property->binding) {
|
||||
@@ -1250,12 +1247,12 @@ static QVariant parsePropertyExpression(AST::ExpressionNode *expressionNode)
|
||||
{
|
||||
Q_ASSERT(expressionNode);
|
||||
|
||||
auto arrayLiteral = AST::cast<AST::ArrayLiteral *>(expressionNode);
|
||||
auto arrayLiteral = AST::cast<AST::ArrayPattern *>(expressionNode);
|
||||
|
||||
if (arrayLiteral) {
|
||||
QList<QVariant> variantList;
|
||||
for (AST::ElementList *it = arrayLiteral->elements; it; it = it->next)
|
||||
variantList << parsePropertyExpression(it->expression);
|
||||
for (AST::PatternElementList *it = arrayLiteral->elements; it; it = it->next)
|
||||
variantList << parsePropertyExpression(it->element->initializer);
|
||||
return variantList;
|
||||
}
|
||||
|
||||
|
@@ -295,8 +295,8 @@ protected:
|
||||
|
||||
decl.text += QLatin1Char('(');
|
||||
for (FormalParameterList *it = ast->formals; it; it = it->next) {
|
||||
if (!it->name.isEmpty())
|
||||
decl.text += it->name;
|
||||
if (!it->element->bindingIdentifier.isEmpty())
|
||||
decl.text += it->element->bindingIdentifier;
|
||||
|
||||
if (it->next)
|
||||
decl.text += QLatin1String(", ");
|
||||
@@ -309,14 +309,14 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(AST::VariableDeclaration *ast) override
|
||||
bool visit(AST::PatternElement *ast) override
|
||||
{
|
||||
if (ast->name.isEmpty())
|
||||
if (!ast->isVariableDeclaration() || ast->bindingIdentifier.isEmpty())
|
||||
return false;
|
||||
|
||||
Declaration decl;
|
||||
decl.text.fill(QLatin1Char(' '), _depth);
|
||||
decl.text += ast->name;
|
||||
decl.text += ast->bindingIdentifier;
|
||||
|
||||
const SourceLocation first = ast->identifierToken;
|
||||
decl.startLine = first.startLine;
|
||||
@@ -343,8 +343,8 @@ protected:
|
||||
|
||||
decl.text += QLatin1Char('(');
|
||||
for (FormalParameterList *it = funcExpr->formals; it; it = it->next) {
|
||||
if (!it->name.isEmpty())
|
||||
decl.text += it->name;
|
||||
if (!it->element->bindingIdentifier.isEmpty())
|
||||
decl.text += it->element->bindingIdentifier;
|
||||
|
||||
if (it->next)
|
||||
decl.text += QLatin1String(", ");
|
||||
|
@@ -227,9 +227,9 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(AST::VariableDeclaration *node) override
|
||||
bool visit(AST::PatternElement *node) override
|
||||
{
|
||||
if (node->name == _name) {
|
||||
if (node->isVariableDeclaration() && node->bindingIdentifier == _name) {
|
||||
if (checkLookup())
|
||||
_usages.append(node->identifierToken);
|
||||
}
|
||||
@@ -322,7 +322,7 @@ protected:
|
||||
|
||||
bool visit(AST::UiPublicMember *node) override
|
||||
{
|
||||
if (node->memberTypeName() == _name){
|
||||
if (node->memberType->name == _name){
|
||||
const ObjectValue * tVal = _context->lookupType(_doc.data(), QStringList(_name));
|
||||
if (tVal == _typeValue)
|
||||
_usages.append(node->typeToken);
|
||||
@@ -406,9 +406,10 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(AST::VariableDeclaration *node) override
|
||||
bool visit(AST::PatternElement *node) override
|
||||
{
|
||||
Node::accept(node->expression, this);
|
||||
if (node->isVariableDeclaration())
|
||||
Node::accept(node->initializer, this);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -583,8 +584,8 @@ protected:
|
||||
bool visit(UiPublicMember *node) override
|
||||
{
|
||||
if (containsOffset(node->typeToken)){
|
||||
if (node->isValid()) {
|
||||
_name = node->memberTypeName().toString();
|
||||
if (node->defaultToken.isValid()) {
|
||||
_name = node->memberType->name.toString();
|
||||
_targetValue = _scopeChain->context()->lookupType(_doc.data(), QStringList(_name));
|
||||
_scope = 0;
|
||||
_typeKind = TypeKind;
|
||||
@@ -612,10 +613,10 @@ protected:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool visit(VariableDeclaration *node) override
|
||||
bool visit(PatternElement *node) override
|
||||
{
|
||||
if (containsOffset(node->identifierToken)) {
|
||||
_name = node->name.toString();
|
||||
if (node->isVariableDeclaration() && containsOffset(node->identifierToken)) {
|
||||
_name = node->bindingIdentifier.toString();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@@ -323,8 +323,8 @@ protected:
|
||||
|
||||
bool visit(UiPublicMember *ast)
|
||||
{
|
||||
if (ast->typeToken.isValid() && ast->isValid()) {
|
||||
if (m_scopeChain.context()->lookupType(m_scopeChain.document().data(), QStringList(ast->memberTypeName().toString())))
|
||||
if (ast->typeToken.isValid()) { // TODO: ast->isValid() ?
|
||||
if (m_scopeChain.context()->lookupType(m_scopeChain.document().data(), QStringList(ast->memberType->name.toString())))
|
||||
addUse(ast->typeToken, SemanticHighlighter::QmlTypeType);
|
||||
}
|
||||
if (ast->identifierToken.isValid())
|
||||
@@ -350,9 +350,10 @@ protected:
|
||||
return visit(static_cast<FunctionExpression *>(ast));
|
||||
}
|
||||
|
||||
bool visit(VariableDeclaration *ast)
|
||||
bool visit(PatternElement *ast)
|
||||
{
|
||||
processName(ast->name, ast->identifierToken);
|
||||
if (ast->isVariableDeclaration())
|
||||
processName(ast->bindingIdentifier, ast->identifierToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -263,14 +263,14 @@ private:
|
||||
bool visit(AST::BinaryExpression *binExp)
|
||||
{
|
||||
AST::IdentifierExpression *lhsIdent = AST::cast<AST::IdentifierExpression *>(binExp->left);
|
||||
AST::ObjectLiteral *rhsObjLit = AST::cast<AST::ObjectLiteral *>(binExp->right);
|
||||
AST::ObjectPattern *rhsObjLit = AST::cast<AST::ObjectPattern *>(binExp->right);
|
||||
|
||||
if (lhsIdent && rhsObjLit && (lhsIdent->name == QLatin1String("testcase"))
|
||||
&& (binExp->op == QSOperator::Assign)) {
|
||||
QModelIndex index = m_model->enterTestCase(rhsObjLit);
|
||||
m_nodeToIndex.insert(rhsObjLit, index);
|
||||
|
||||
if (AST::PropertyAssignmentList *properties = rhsObjLit->properties)
|
||||
if (AST::PatternPropertyList *properties = rhsObjLit->properties)
|
||||
visitProperties(properties);
|
||||
|
||||
m_model->leaveTestCase();
|
||||
@@ -290,13 +290,13 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
void visitProperties(AST::PropertyAssignmentList *properties)
|
||||
void visitProperties(AST::PatternPropertyList *properties)
|
||||
{
|
||||
while (properties) {
|
||||
QModelIndex index = m_model->enterTestCaseProperties(properties);
|
||||
m_nodeToIndex.insert(properties, index);
|
||||
if (AST::PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(properties->assignment))
|
||||
if (AST::ObjectLiteral *objLiteral = AST::cast<AST::ObjectLiteral *>(assignment->value))
|
||||
if (AST::PatternProperty *assignment = AST::cast<AST::PatternProperty *>(properties->property))
|
||||
if (AST::ObjectPattern *objLiteral = AST::cast<AST::ObjectPattern *>(assignment->initializer))
|
||||
visitProperties(objLiteral->properties);
|
||||
|
||||
m_model->leaveTestCaseProperties();
|
||||
@@ -592,7 +592,7 @@ static QString functionDisplayName(QStringRef name, AST::FormalParameterList *fo
|
||||
if (!name.isEmpty())
|
||||
display += name.toString() + QLatin1Char('(');
|
||||
for (AST::FormalParameterList *param = formals; param; param = param->next) {
|
||||
display += param->name.toString();
|
||||
display += param->element->bindingIdentifier.toString();
|
||||
if (param->next)
|
||||
display += QLatin1String(", ");
|
||||
}
|
||||
@@ -650,7 +650,7 @@ void QmlOutlineModel::leaveFieldMemberExpression()
|
||||
leaveNode();
|
||||
}
|
||||
|
||||
QModelIndex QmlOutlineModel::enterTestCase(AST::ObjectLiteral *objectLiteral)
|
||||
QModelIndex QmlOutlineModel::enterTestCase(AST::ObjectPattern *objectLiteral)
|
||||
{
|
||||
QMap<int, QVariant> objectData;
|
||||
|
||||
@@ -667,18 +667,18 @@ void QmlOutlineModel::leaveTestCase()
|
||||
leaveNode();
|
||||
}
|
||||
|
||||
QModelIndex QmlOutlineModel::enterTestCaseProperties(AST::PropertyAssignmentList *propertyAssignmentList)
|
||||
QModelIndex QmlOutlineModel::enterTestCaseProperties(AST::PatternPropertyList *propertyAssignmentList)
|
||||
{
|
||||
QMap<int, QVariant> objectData;
|
||||
if (AST::PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(
|
||||
propertyAssignmentList->assignment)) {
|
||||
if (AST::PatternProperty *assignment = AST::cast<AST::PatternProperty *>(
|
||||
propertyAssignmentList->property)) {
|
||||
if (AST::IdentifierPropertyName *propertyName = AST::cast<AST::IdentifierPropertyName *>(assignment->name)) {
|
||||
objectData.insert(Qt::DisplayRole, propertyName->id.toString());
|
||||
objectData.insert(ItemTypeRole, ElementBindingType);
|
||||
QmlOutlineItem *item;
|
||||
if (assignment->value->kind == AST::Node::Kind_FunctionExpression)
|
||||
if (assignment->initializer->kind == AST::Node::Kind_FunctionExpression)
|
||||
item = enterNode(objectData, assignment, 0, Icons::functionDeclarationIcon());
|
||||
else if (assignment->value->kind == AST::Node::Kind_ObjectLiteral)
|
||||
else if (assignment->initializer->kind == AST::Node::Kind_ObjectPattern)
|
||||
item = enterNode(objectData, assignment, 0, Icons::objectDefinitionIcon());
|
||||
else
|
||||
item = enterNode(objectData, assignment, 0, Icons::scriptBindingIcon());
|
||||
@@ -686,8 +686,8 @@ QModelIndex QmlOutlineModel::enterTestCaseProperties(AST::PropertyAssignmentList
|
||||
return item->index();
|
||||
}
|
||||
}
|
||||
if (AST::PropertyGetterSetter *getterSetter = AST::cast<AST::PropertyGetterSetter *>(
|
||||
propertyAssignmentList->assignment)) {
|
||||
if (AST::PatternProperty *getterSetter = AST::cast<AST::PatternProperty *>(
|
||||
propertyAssignmentList->property)) {
|
||||
if (AST::IdentifierPropertyName *propertyName = AST::cast<AST::IdentifierPropertyName *>(getterSetter->name)) {
|
||||
objectData.insert(Qt::DisplayRole, propertyName->id.toString());
|
||||
objectData.insert(ItemTypeRole, ElementBindingType);
|
||||
@@ -728,7 +728,7 @@ AST::SourceLocation QmlOutlineModel::sourceLocation(const QModelIndex &index) co
|
||||
location = getLocation(member);
|
||||
else if (AST::ExpressionNode *expression = node->expressionCast())
|
||||
location = getLocation(expression);
|
||||
else if (AST::PropertyAssignmentList *propertyAssignmentList = AST::cast<AST::PropertyAssignmentList *>(node))
|
||||
else if (AST::PatternPropertyList *propertyAssignmentList = AST::cast<AST::PatternPropertyList *>(node))
|
||||
location = getLocation(propertyAssignmentList);
|
||||
}
|
||||
return location;
|
||||
@@ -999,26 +999,16 @@ AST::SourceLocation QmlOutlineModel::getLocation(AST::ExpressionNode *exprNode)
|
||||
return location;
|
||||
}
|
||||
|
||||
AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyAssignmentList *propertyNode) {
|
||||
if (AST::PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(propertyNode->assignment))
|
||||
AST::SourceLocation QmlOutlineModel::getLocation(AST::PatternPropertyList *propertyNode) {
|
||||
if (AST::PatternProperty *assignment = AST::cast<AST::PatternProperty *>(propertyNode->property))
|
||||
return getLocation(assignment);
|
||||
if (AST::PropertyGetterSetter *getterSetter = AST::cast<AST::PropertyGetterSetter *>(propertyNode->assignment))
|
||||
return getLocation(getterSetter);
|
||||
return propertyNode->commaToken; // should never happen
|
||||
return propertyNode->firstSourceLocation(); // should never happen
|
||||
}
|
||||
|
||||
AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyNameAndValue *propertyNode) {
|
||||
AST::SourceLocation QmlOutlineModel::getLocation(AST::PatternProperty *propertyNode) {
|
||||
AST::SourceLocation location;
|
||||
location = propertyNode->name->propertyNameToken;
|
||||
location.length = propertyNode->value->lastSourceLocation().end() - location.offset;
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyGetterSetter *propertyNode) {
|
||||
AST::SourceLocation location;
|
||||
location = propertyNode->name->propertyNameToken;
|
||||
location.length = propertyNode->rbraceToken.end() - location.offset;
|
||||
location.length = propertyNode->initializer->lastSourceLocation().end() - location.offset;
|
||||
|
||||
return location;
|
||||
}
|
||||
|
@@ -120,10 +120,10 @@ private:
|
||||
QmlJS::AST::FunctionExpression *functionExpression);
|
||||
void leaveFieldMemberExpression();
|
||||
|
||||
QModelIndex enterTestCase(QmlJS::AST::ObjectLiteral *objectLiteral);
|
||||
QModelIndex enterTestCase(QmlJS::AST::ObjectPattern *objectLiteral);
|
||||
void leaveTestCase();
|
||||
|
||||
QModelIndex enterTestCaseProperties(QmlJS::AST::PropertyAssignmentList *propertyAssignmentList);
|
||||
QModelIndex enterTestCaseProperties(QmlJS::AST::PatternPropertyList *propertyAssignmentList);
|
||||
void leaveTestCaseProperties();
|
||||
|
||||
private:
|
||||
@@ -140,9 +140,8 @@ private:
|
||||
static QString asString(QmlJS::AST::UiQualifiedId *id);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::UiObjectMember *objMember);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::ExpressionNode *exprNode);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyAssignmentList *propertyNode);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyNameAndValue *propertyNode);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyGetterSetter *propertyNode);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PatternProperty *propertyNode);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PatternPropertyList *propertyNode);
|
||||
QIcon getIcon(QmlJS::AST::UiQualifiedId *objDef);
|
||||
|
||||
QString getAnnotation(QmlJS::AST::UiObjectInitializer *objInitializer);
|
||||
|
@@ -134,8 +134,8 @@ protected:
|
||||
for (FormalParameterList *it = ast->formals; it; it = it->next) {
|
||||
if (it != ast->formals)
|
||||
entry.displayName += QLatin1String(", ");
|
||||
if (!it->name.isEmpty())
|
||||
entry.displayName += it->name.toString();
|
||||
if (!it->element->bindingIdentifier.isEmpty())
|
||||
entry.displayName += it->element->bindingIdentifier.toString();
|
||||
}
|
||||
entry.displayName += QLatin1Char(')');
|
||||
entry.symbolName = entry.displayName;
|
||||
@@ -214,8 +214,8 @@ protected:
|
||||
for (FormalParameterList *it = funcExpr->formals; it; it = it->next) {
|
||||
if (it != funcExpr->formals)
|
||||
entry.displayName += QLatin1String(", ");
|
||||
if (!it->name.isEmpty())
|
||||
entry.displayName += it->name.toString();
|
||||
if (!it->element->bindingIdentifier.isEmpty())
|
||||
entry.displayName += it->element->bindingIdentifier.toString();
|
||||
}
|
||||
entry.displayName += QLatin1Char(')');
|
||||
entry.symbolName = entry.displayName;
|
||||
|
Reference in New Issue
Block a user