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:
Marco Benelli
2018-10-16 15:32:58 +02:00
parent fe8a372773
commit 4646acad0d
46 changed files with 10604 additions and 5872 deletions

View File

@@ -84,7 +84,7 @@ void JsonCheck::postVisit(Node *)
analysis()->m_ranking += previous.m_ranking; analysis()->m_ranking += previous.m_ranking;
} }
bool JsonCheck::visit(ObjectLiteral *ast) bool JsonCheck::visit(ObjectPattern *ast)
{ {
if (!proceedCheck(JsonValue::Object, ast->lbraceToken)) if (!proceedCheck(JsonValue::Object, ast->lbraceToken))
return false; return false;
@@ -96,8 +96,8 @@ bool JsonCheck::visit(ObjectLiteral *ast)
return false; return false;
QSet<QString> propertiesFound; QSet<QString> propertiesFound;
for (PropertyAssignmentList *it = ast->properties; it; it = it->next) { for (PatternPropertyList *it = ast->properties; it; it = it->next) {
PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(it->assignment); PatternProperty *assignment = AST::cast<AST::PatternProperty *>(it->property);
StringLiteralPropertyName *literalName = cast<StringLiteralPropertyName *>(assignment->name); StringLiteralPropertyName *literalName = cast<StringLiteralPropertyName *>(assignment->name);
if (literalName) { if (literalName) {
const QString &propertyName = literalName->id.toString(); const QString &propertyName = literalName->id.toString();
@@ -106,7 +106,7 @@ bool JsonCheck::visit(ObjectLiteral *ast)
propertiesFound.insert(propertyName); propertiesFound.insert(propertyName);
// Sec. 5.2: "... each property definition's value MUST be a schema..." // Sec. 5.2: "... each property definition's value MUST be a schema..."
m_schema->enterNestedPropertySchema(propertyName); m_schema->enterNestedPropertySchema(propertyName);
processSchema(assignment->value); processSchema(assignment->initializer);
m_schema->leaveNestedSchema(); m_schema->leaveNestedSchema();
} else { } else {
analysis()->m_messages.append(Message(ErrInvalidPropertyName, analysis()->m_messages.append(Message(ErrInvalidPropertyName,
@@ -144,7 +144,7 @@ bool JsonCheck::visit(ObjectLiteral *ast)
return false; return false;
} }
bool JsonCheck::visit(ArrayLiteral *ast) bool JsonCheck::visit(ArrayPattern *ast)
{ {
if (!proceedCheck(JsonValue::Array, ast->firstSourceLocation())) if (!proceedCheck(JsonValue::Array, ast->firstSourceLocation()))
return false; 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 // Sec. 5.5: "When this attribute value is a schema... all the items in the array MUST
// be valid according to the schema." // be valid according to the schema."
m_schema->enterNestedItemSchema(); m_schema->enterNestedItemSchema();
for (ElementList *element = ast->elements; element; element = element->next) for (PatternElementList *element = ast->elements; element; element = element->next)
processSchema(element->expression); processSchema(element->element->initializer);
m_schema->leaveNestedSchema(); m_schema->leaveNestedSchema();
} else if (m_schema->hasItemArraySchema()) { } else if (m_schema->hasItemArraySchema()) {
// Sec. 5.5: "When this attribute value is an array of schemas... each position in the // 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." // instance array MUST conform to the schema in the corresponding position for this array."
int current = 0; int current = 0;
const int arraySize = m_schema->itemArraySchemaSize(); 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 (current < arraySize) {
if (m_schema->maybeEnterNestedArraySchema(current)) { if (m_schema->maybeEnterNestedArraySchema(current)) {
processSchema(element->expression); processSchema(element->element->initializer);
m_schema->leaveNestedSchema(); m_schema->leaveNestedSchema();
} else { } else {
Node::accept(element->expression, this); Node::accept(element->element->initializer, this);
} }
} else { } else {
// TODO: Handle additionalItems. // TODO: Handle additionalItems.

View File

@@ -51,8 +51,8 @@ private:
bool preVisit(AST::Node *) override; bool preVisit(AST::Node *) override;
void postVisit(AST::Node *) override; void postVisit(AST::Node *) override;
bool visit(AST::ObjectLiteral *ast) override; bool visit(AST::ObjectPattern *ast) override;
bool visit(AST::ArrayLiteral *ast) override; bool visit(AST::ArrayPattern *ast) override;
bool visit(AST::NullExpression *ast) override; bool visit(AST::NullExpression *ast) override;
bool visit(AST::TrueLiteral *ast) override; bool visit(AST::TrueLiteral *ast) override;
bool visit(AST::FalseLiteral *ast) override; bool visit(AST::FalseLiteral *ast) override;

View File

@@ -10,7 +10,7 @@ HEADERS += \
$$PWD/qmljsglobal_p.h \ $$PWD/qmljsglobal_p.h \
$$PWD/qmldirparser_p.h \ $$PWD/qmldirparser_p.h \
$$PWD/qmlerror.h \ $$PWD/qmlerror.h \
$$PWD/qmljskeywords_p.h \ $$PWD/qmljskeywords_p.h
SOURCES += \ SOURCES += \
$$PWD/qmljsast.cpp \ $$PWD/qmljsast.cpp \
@@ -20,7 +20,13 @@ SOURCES += \
$$PWD/qmljslexer.cpp \ $$PWD/qmljslexer.cpp \
$$PWD/qmljsparser.cpp \ $$PWD/qmljsparser.cpp \
$$PWD/qmldirparser.cpp \ $$PWD/qmldirparser.cpp \
$$PWD/qmlerror.cpp \ $$PWD/qmlerror.cpp
DISTFILES += \ #CONFIG += qlalr
$$PWD/qmljs.g 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

View File

@@ -93,6 +93,7 @@ bool QmlDirParser::parse(const QString &source)
_components.clear(); _components.clear();
_scripts.clear(); _scripts.clear();
_designerSupported = false; _designerSupported = false;
_className.clear();
quint16 lineNumber = 0; quint16 lineNumber = 0;
bool firstLine = true; bool firstLine = true;
@@ -182,7 +183,8 @@ bool QmlDirParser::parse(const QString &source)
continue; continue;
} }
// Ignore these. qmlimportscanner uses them. _className = sections[1];
} else if (sections[0] == QLatin1String("internal")) { } else if (sections[0] == QLatin1String("internal")) {
if (sectionCount != 3) { if (sectionCount != 3) {
reportError(lineNumber, 0, reportError(lineNumber, 0,
@@ -256,7 +258,7 @@ bool QmlDirParser::parse(const QString &source)
if (parseVersion(sections[1], &major, &minor)) { if (parseVersion(sections[1], &major, &minor)) {
const QString &fileName = sections[2]; 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 // A 'js' extension indicates a namespaced script import
const Script entry(sections[0], fileName, major, minor); const Script entry(sections[0], fileName, major, minor);
_scripts.append(entry); _scripts.append(entry);
@@ -363,6 +365,11 @@ bool QmlDirParser::designerSupported() const
return _designerSupported; return _designerSupported;
} }
QString QmlDirParser::className() const
{
return _className;
}
QDebug &operator<< (QDebug &debug, const QmlDirParser::Component &component) QDebug &operator<< (QDebug &debug, const QmlDirParser::Component &component)
{ {
const QString output = QStringLiteral("{%1 %2.%3}"). const QString output = QStringLiteral("{%1 %2.%3}").

View File

@@ -39,8 +39,8 @@
#include <QtCore/QUrl> #include <QtCore/QUrl>
#include <QtCore/QHash> #include <QtCore/QHash>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include "qmljsengine_p.h" #include "qmljsengine_p.h"
#include "qmljsglobal_p.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -48,8 +48,6 @@ class QmlError;
class QmlEngine; class QmlEngine;
class QML_PARSER_EXPORT QmlDirParser class QML_PARSER_EXPORT QmlDirParser
{ {
Q_DISABLE_COPY(QmlDirParser)
public: public:
QmlDirParser(); QmlDirParser();
~QmlDirParser(); ~QmlDirParser();
@@ -76,8 +74,7 @@ public:
struct Component struct Component
{ {
Component() Component() {}
: majorVersion(0), minorVersion(0), internal(false), singleton(false) {}
Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion) Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
: typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion), : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
@@ -85,24 +82,23 @@ public:
QString typeName; QString typeName;
QString fileName; QString fileName;
int majorVersion; int majorVersion = 0;
int minorVersion; int minorVersion = 0;
bool internal; bool internal = false;
bool singleton; bool singleton = false;
}; };
struct Script struct Script
{ {
Script() Script() {}
: majorVersion(0), minorVersion(0) {}
Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion) Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion)
: nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) {} : nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) {}
QString nameSpace; QString nameSpace;
QString fileName; QString fileName;
int majorVersion; int majorVersion = 0;
int minorVersion; int minorVersion = 0;
}; };
QHash<QString,Component> components() const; QHash<QString,Component> components() const;
@@ -124,6 +120,8 @@ public:
QList<TypeInfo> typeInfos() const; QList<TypeInfo> typeInfos() const;
#endif #endif
QString className() const;
private: private:
bool maybeAddComponent(const QString &typeName, const QString &fileName, const QString &version, QHash<QString,Component> &hash, int lineNumber = -1, bool multi = true); 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); void reportError(quint16 line, quint16 column, const QString &message);
@@ -139,6 +137,7 @@ private:
#ifdef QT_CREATOR #ifdef QT_CREATOR
QList<TypeInfo> _typeInfos; QList<TypeInfo> _typeInfos;
#endif #endif
QString _className;
}; };
typedef QHash<QString,QmlDirParser::Component> QmlDirComponents; typedef QHash<QString,QmlDirParser::Component> QmlDirComponents;

View File

@@ -91,7 +91,7 @@ QmlErrorPrivate::QmlErrorPrivate()
Creates an empty error object. Creates an empty error object.
*/ */
QmlError::QmlError() QmlError::QmlError()
: d(0) : d(nullptr)
{ {
} }
@@ -99,7 +99,7 @@ QmlError::QmlError()
Creates a copy of \a other. Creates a copy of \a other.
*/ */
QmlError::QmlError(const QmlError &other) QmlError::QmlError(const QmlError &other)
: d(0) : d(nullptr)
{ {
*this = other; *this = other;
} }
@@ -111,7 +111,7 @@ QmlError &QmlError::operator=(const QmlError &other)
{ {
if (!other.d) { if (!other.d) {
delete d; delete d;
d = 0; d = nullptr;
} else { } else {
if (!d) if (!d)
d = new QmlErrorPrivate; d = new QmlErrorPrivate;
@@ -130,7 +130,7 @@ QmlError &QmlError::operator=(const QmlError &other)
*/ */
QmlError::~QmlError() QmlError::~QmlError()
{ {
delete d; d = 0; delete d; d = nullptr;
} }
/*! /*!
@@ -138,7 +138,7 @@ QmlError::~QmlError()
*/ */
bool QmlError::isValid() const bool QmlError::isValid() const
{ {
return d != 0; return d != nullptr;
} }
/*! /*!
@@ -231,7 +231,7 @@ QObject *QmlError::object() const
{ {
if (d) if (d)
return d->object; return d->object;
return 0; return nullptr;
} }
/*! /*!
@@ -260,7 +260,7 @@ QtMsgType QmlError::messageType() const
\since 5.9 \since 5.9
Sets the \a messageType for this message. The message type determines which 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) void QmlError::setMessageType(QtMsgType messageType)
{ {

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,27 @@ QT_QML_BEGIN_NAMESPACE
namespace QmlJS { namespace AST { 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) void Node::accept(Visitor *visitor)
{ {
if (visitor->preVisit(this)) { if (visitor->preVisit(this)) {
@@ -47,22 +68,42 @@ void Node::accept(Node *node, Visitor *visitor)
ExpressionNode *Node::expressionCast() ExpressionNode *Node::expressionCast()
{ {
return 0; return nullptr;
} }
BinaryExpression *Node::binaryExpressionCast() BinaryExpression *Node::binaryExpressionCast()
{ {
return 0; return nullptr;
} }
Statement *Node::statementCast() Statement *Node::statementCast()
{ {
return 0; return nullptr;
} }
UiObjectMember *Node::uiObjectMemberCast() 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() ExpressionNode *ExpressionNode::expressionCast()
@@ -70,6 +111,42 @@ ExpressionNode *ExpressionNode::expressionCast()
return this; 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() BinaryExpression *BinaryExpression::binaryExpressionCast()
{ {
return this; return this;
@@ -93,6 +170,16 @@ void NestedExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
FunctionExpression *NestedExpression::asFunctionDefinition()
{
return expression->asFunctionDefinition();
}
ClassExpression *NestedExpression::asClassDefinition()
{
return expression->asClassDefinition();
}
void ThisExpression::accept0(Visitor *visitor) void ThisExpression::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
@@ -133,6 +220,15 @@ void FalseLiteral::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void SuperLiteral::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
}
visitor->endVisit(this);
}
void StringLiteral::accept0(Visitor *visitor) void StringLiteral::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
@@ -141,6 +237,16 @@ void StringLiteral::accept0(Visitor *visitor)
visitor->endVisit(this); 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) void NumericLiteral::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
@@ -157,17 +263,27 @@ void RegExpLiteral::accept0(Visitor *visitor)
visitor->endVisit(this); 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(elements, visitor);
accept(elision, visitor);
}
visitor->endVisit(this); 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)) { if (visitor->visit(this)) {
accept(properties, visitor); accept(properties, visitor);
@@ -176,18 +292,170 @@ void ObjectLiteral::accept0(Visitor *visitor)
visitor->endVisit(this); 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)) { if (parseMode == Binding)
for (ElementList *it = this; it; it = it->next) { return true;
accept(it->elision, visitor); for (auto *it = elements; it; it = it->next) {
accept(it->expression, visitor); 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) void Elision::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
@@ -197,38 +465,6 @@ void Elision::accept0(Visitor *visitor)
visitor->endVisit(this); 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) void IdentifierPropertyName::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
@@ -253,6 +489,28 @@ void NumericLiteralPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this); 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) void ArrayMemberExpression::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
@@ -482,15 +740,6 @@ void VariableDeclarationList::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void VariableDeclaration::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
}
visitor->endVisit(this);
}
void EmptyStatement::accept0(Visitor *visitor) void EmptyStatement::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
@@ -543,17 +792,6 @@ void ForStatement::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(initialiser, visitor); 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(declarations, visitor);
accept(condition, visitor); accept(condition, visitor);
accept(expression, visitor); accept(expression, visitor);
@@ -566,18 +804,7 @@ void LocalForStatement::accept0(Visitor *visitor)
void ForEachStatement::accept0(Visitor *visitor) void ForEachStatement::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(initialiser, visitor); accept(lhs, visitor);
accept(expression, visitor);
accept(statement, visitor);
}
visitor->endVisit(this);
}
void LocalForEachStatement::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(declaration, visitor);
accept(expression, visitor); accept(expression, visitor);
accept(statement, visitor); accept(statement, visitor);
} }
@@ -610,6 +837,16 @@ void ReturnStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void YieldExpression::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
}
visitor->endVisit(this);
}
void WithStatement::accept0(Visitor *visitor) void WithStatement::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
@@ -703,6 +940,7 @@ void TryStatement::accept0(Visitor *visitor)
void Catch::accept0(Visitor *visitor) void Catch::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(patternElement, visitor);
accept(statement, visitor); accept(statement, visitor);
} }
@@ -738,57 +976,182 @@ void FunctionExpression::accept0(Visitor *visitor)
visitor->endVisit(this); 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) void FormalParameterList::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// ### accept(element, visitor);
if (next)
accept(next, visitor);
} }
visitor->endVisit(this); visitor->endVisit(this);
} }
void FunctionBody::accept0(Visitor *visitor) FormalParameterList *FormalParameterList::finish(QmlJS::MemoryPool *pool)
{ {
if (visitor->visit(this)) { FormalParameterList *front = next;
accept(elements, visitor); 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) void Program::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(elements, visitor); accept(statements, visitor);
} }
visitor->endVisit(this); visitor->endVisit(this);
} }
void SourceElements::accept0(Visitor *visitor) void ImportSpecifier::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { 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); visitor->endVisit(this);
} }
void FunctionSourceElement::accept0(Visitor *visitor) void NamedImports::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(declaration, visitor); accept(importsList, visitor);
} }
visitor->endVisit(this); visitor->endVisit(this);
} }
void StatementSourceElement::accept0(Visitor *visitor) void FromClause::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { 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); visitor->endVisit(this);
@@ -916,18 +1279,9 @@ void UiImport::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiQualifiedPragmaId::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
}
visitor->endVisit(this);
}
void UiPragma::accept0(Visitor *visitor) void UiPragma::accept0(Visitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(pragmaType, visitor);
} }
visitor->endVisit(this); visitor->endVisit(this);
@@ -970,6 +1324,153 @@ void UiEnumMemberList::accept0(Visitor *visitor)
visitor->endVisit(this); 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 } } // namespace QmlJS::AST
QT_QML_END_NAMESPACE QT_QML_END_NAMESPACE

File diff suppressed because it is too large Load Diff

View File

@@ -74,22 +74,27 @@ class IdentifierExpression;
class NullExpression; class NullExpression;
class TrueLiteral; class TrueLiteral;
class FalseLiteral; class FalseLiteral;
class SuperLiteral;
class NumericLiteral; class NumericLiteral;
class StringLiteral; class StringLiteral;
class TemplateLiteral;
class RegExpLiteral; class RegExpLiteral;
class ArrayLiteral; class Pattern;
class ObjectLiteral; class ArrayPattern;
class ElementList; class ObjectPattern;
class PatternElement;
class PatternElementList;
class PatternProperty;
class PatternPropertyList;
class Elision; class Elision;
class PropertyAssignmentList;
class PropertyGetterSetter;
class PropertyNameAndValue;
class PropertyName; class PropertyName;
class IdentifierPropertyName; class IdentifierPropertyName;
class StringLiteralPropertyName; class StringLiteralPropertyName;
class NumericLiteralPropertyName; class NumericLiteralPropertyName;
class ComputedPropertyName;
class ArrayMemberExpression; class ArrayMemberExpression;
class FieldMemberExpression; class FieldMemberExpression;
class TaggedTemplate;
class NewMemberExpression; class NewMemberExpression;
class NewExpression; class NewExpression;
class CallExpression; class CallExpression;
@@ -108,20 +113,19 @@ class NotExpression;
class BinaryExpression; class BinaryExpression;
class ConditionalExpression; class ConditionalExpression;
class Expression; // ### rename class Expression; // ### rename
class YieldExpression;
class Block; class Block;
class LeftHandSideExpression;
class StatementList; class StatementList;
class VariableStatement; class VariableStatement;
class VariableDeclarationList; class VariableDeclarationList;
class VariableDeclaration;
class EmptyStatement; class EmptyStatement;
class ExpressionStatement; class ExpressionStatement;
class IfStatement; class IfStatement;
class DoWhileStatement; class DoWhileStatement;
class WhileStatement; class WhileStatement;
class ForStatement; class ForStatement;
class LocalForStatement;
class ForEachStatement; class ForEachStatement;
class LocalForEachStatement;
class ContinueStatement; class ContinueStatement;
class BreakStatement; class BreakStatement;
class ReturnStatement; class ReturnStatement;
@@ -139,14 +143,26 @@ class Finally;
class FunctionDeclaration; class FunctionDeclaration;
class FunctionExpression; class FunctionExpression;
class FormalParameterList; class FormalParameterList;
class FunctionBody; class ExportSpecifier;
class ExportsList;
class ExportClause;
class ExportDeclaration;
class Program; class Program;
class SourceElements; class ImportSpecifier;
class SourceElement; class ImportsList;
class FunctionSourceElement; class NamedImports;
class StatementSourceElement; class NameSpaceImport;
class NamedImport;
class ImportClause;
class FromClause;
class ImportDeclaration;
class ModuleItem;
class ESModule;
class DebuggerStatement; class DebuggerStatement;
class NestedExpression; class NestedExpression;
class ClassExpression;
class ClassDeclaration;
class ClassElementList;
// ui elements // ui elements
class UiProgram; class UiProgram;
@@ -164,7 +180,6 @@ class UiObjectMember;
class UiObjectMemberList; class UiObjectMemberList;
class UiArrayMemberList; class UiArrayMemberList;
class UiQualifiedId; class UiQualifiedId;
class UiQualifiedPragmaId;
class UiHeaderItemList; class UiHeaderItemList;
class UiEnumDeclaration; class UiEnumDeclaration;
class UiEnumMemberList; class UiEnumMemberList;

View File

@@ -68,7 +68,6 @@ public:
virtual bool visit(UiObjectMemberList *) { return true; } virtual bool visit(UiObjectMemberList *) { return true; }
virtual bool visit(UiArrayMemberList *) { return true; } virtual bool visit(UiArrayMemberList *) { return true; }
virtual bool visit(UiQualifiedId *) { return true; } virtual bool visit(UiQualifiedId *) { return true; }
virtual bool visit(UiQualifiedPragmaId *) { return true; }
virtual bool visit(UiEnumDeclaration *) { return true; } virtual bool visit(UiEnumDeclaration *) { return true; }
virtual bool visit(UiEnumMemberList *) { return true; } virtual bool visit(UiEnumMemberList *) { return true; }
@@ -87,7 +86,6 @@ public:
virtual void endVisit(UiObjectMemberList *) {} virtual void endVisit(UiObjectMemberList *) {}
virtual void endVisit(UiArrayMemberList *) {} virtual void endVisit(UiArrayMemberList *) {}
virtual void endVisit(UiQualifiedId *) {} virtual void endVisit(UiQualifiedId *) {}
virtual void endVisit(UiQualifiedPragmaId *) {}
virtual void endVisit(UiEnumDeclaration *) {} virtual void endVisit(UiEnumDeclaration *) {}
virtual void endVisit(UiEnumMemberList *) { } virtual void endVisit(UiEnumMemberList *) { }
@@ -107,36 +105,42 @@ public:
virtual bool visit(FalseLiteral *) { return true; } virtual bool visit(FalseLiteral *) { return true; }
virtual void endVisit(FalseLiteral *) {} virtual void endVisit(FalseLiteral *) {}
virtual bool visit(SuperLiteral *) { return true; }
virtual void endVisit(SuperLiteral *) {}
virtual bool visit(StringLiteral *) { return true; } virtual bool visit(StringLiteral *) { return true; }
virtual void endVisit(StringLiteral *) {} virtual void endVisit(StringLiteral *) {}
virtual bool visit(TemplateLiteral *) { return true; }
virtual void endVisit(TemplateLiteral *) {}
virtual bool visit(NumericLiteral *) { return true; } virtual bool visit(NumericLiteral *) { return true; }
virtual void endVisit(NumericLiteral *) {} virtual void endVisit(NumericLiteral *) {}
virtual bool visit(RegExpLiteral *) { return true; } virtual bool visit(RegExpLiteral *) { return true; }
virtual void endVisit(RegExpLiteral *) {} virtual void endVisit(RegExpLiteral *) {}
virtual bool visit(ArrayLiteral *) { return true; } virtual bool visit(ArrayPattern *) { return true; }
virtual void endVisit(ArrayLiteral *) {} virtual void endVisit(ArrayPattern *) {}
virtual bool visit(ObjectLiteral *) { return true; } virtual bool visit(ObjectPattern *) { return true; }
virtual void endVisit(ObjectLiteral *) {} virtual void endVisit(ObjectPattern *) {}
virtual bool visit(ElementList *) { return true; } virtual bool visit(PatternElementList *) { return true; }
virtual void endVisit(ElementList *) {} 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 bool visit(Elision *) { return true; }
virtual void endVisit(Elision *) {} 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 bool visit(NestedExpression *) { return true; }
virtual void endVisit(NestedExpression *) {} virtual void endVisit(NestedExpression *) {}
@@ -149,12 +153,18 @@ public:
virtual bool visit(NumericLiteralPropertyName *) { return true; } virtual bool visit(NumericLiteralPropertyName *) { return true; }
virtual void endVisit(NumericLiteralPropertyName *) {} virtual void endVisit(NumericLiteralPropertyName *) {}
virtual bool visit(ComputedPropertyName *) { return true; }
virtual void endVisit(ComputedPropertyName *) {}
virtual bool visit(ArrayMemberExpression *) { return true; } virtual bool visit(ArrayMemberExpression *) { return true; }
virtual void endVisit(ArrayMemberExpression *) {} virtual void endVisit(ArrayMemberExpression *) {}
virtual bool visit(FieldMemberExpression *) { return true; } virtual bool visit(FieldMemberExpression *) { return true; }
virtual void endVisit(FieldMemberExpression *) {} virtual void endVisit(FieldMemberExpression *) {}
virtual bool visit(TaggedTemplate *) { return true; }
virtual void endVisit(TaggedTemplate *) {}
virtual bool visit(NewMemberExpression *) { return true; } virtual bool visit(NewMemberExpression *) { return true; }
virtual void endVisit(NewMemberExpression *) {} virtual void endVisit(NewMemberExpression *) {}
@@ -221,9 +231,6 @@ public:
virtual bool visit(VariableDeclarationList *) { return true; } virtual bool visit(VariableDeclarationList *) { return true; }
virtual void endVisit(VariableDeclarationList *) {} virtual void endVisit(VariableDeclarationList *) {}
virtual bool visit(VariableDeclaration *) { return true; }
virtual void endVisit(VariableDeclaration *) {}
virtual bool visit(EmptyStatement *) { return true; } virtual bool visit(EmptyStatement *) { return true; }
virtual void endVisit(EmptyStatement *) {} virtual void endVisit(EmptyStatement *) {}
@@ -242,15 +249,9 @@ public:
virtual bool visit(ForStatement *) { return true; } virtual bool visit(ForStatement *) { return true; }
virtual void endVisit(ForStatement *) {} virtual void endVisit(ForStatement *) {}
virtual bool visit(LocalForStatement *) { return true; }
virtual void endVisit(LocalForStatement *) {}
virtual bool visit(ForEachStatement *) { return true; } virtual bool visit(ForEachStatement *) { return true; }
virtual void endVisit(ForEachStatement *) {} virtual void endVisit(ForEachStatement *) {}
virtual bool visit(LocalForEachStatement *) { return true; }
virtual void endVisit(LocalForEachStatement *) {}
virtual bool visit(ContinueStatement *) { return true; } virtual bool visit(ContinueStatement *) { return true; }
virtual void endVisit(ContinueStatement *) {} virtual void endVisit(ContinueStatement *) {}
@@ -260,6 +261,9 @@ public:
virtual bool visit(ReturnStatement *) { return true; } virtual bool visit(ReturnStatement *) { return true; }
virtual void endVisit(ReturnStatement *) {} virtual void endVisit(ReturnStatement *) {}
virtual bool visit(YieldExpression *) { return true; }
virtual void endVisit(YieldExpression *) {}
virtual bool visit(WithStatement *) { return true; } virtual bool visit(WithStatement *) { return true; }
virtual void endVisit(WithStatement *) {} virtual void endVisit(WithStatement *) {}
@@ -302,20 +306,56 @@ public:
virtual bool visit(FormalParameterList *) { return true; } virtual bool visit(FormalParameterList *) { return true; }
virtual void endVisit(FormalParameterList *) {} virtual void endVisit(FormalParameterList *) {}
virtual bool visit(FunctionBody *) { return true; } virtual bool visit(ClassExpression *) { return true; }
virtual void endVisit(FunctionBody *) {} 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 bool visit(Program *) { return true; }
virtual void endVisit(Program *) {} virtual void endVisit(Program *) {}
virtual bool visit(SourceElements *) { return true; } virtual bool visit(NameSpaceImport *) { return true; }
virtual void endVisit(SourceElements *) {} virtual void endVisit(NameSpaceImport *) {}
virtual bool visit(FunctionSourceElement *) { return true; } virtual bool visit(ImportSpecifier *) { return true; }
virtual void endVisit(FunctionSourceElement *) {} virtual void endVisit(ImportSpecifier *) {}
virtual bool visit(StatementSourceElement *) { return true; } virtual bool visit(ImportsList *) { return true; }
virtual void endVisit(StatementSourceElement *) {} 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 bool visit(DebuggerStatement *) { return true; }
virtual void endVisit(DebuggerStatement *) {} virtual void endVisit(DebuggerStatement *) {}

View File

@@ -98,15 +98,8 @@ double integerFromString(const char *buf, int size, int radix)
return result; return result;
} }
double integerFromString(const QString &str, int radix)
{
QByteArray ba = QStringRef(&str).trimmed().toLatin1();
return integerFromString(ba.constData(), ba.size(), radix);
}
Engine::Engine() Engine::Engine()
: _lexer(0), _directives(0) : _lexer(nullptr), _directives(nullptr)
{ } { }
Engine::~Engine() Engine::~Engine()

View File

@@ -49,14 +49,40 @@ QT_QML_BEGIN_NAMESPACE
namespace QmlJS { namespace QmlJS {
class Lexer; class Lexer;
class Directives;
class MemoryPool; 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 class QML_PARSER_EXPORT DiagnosticMessage
{ {
public: public:
DiagnosticMessage()
: kind(Severity::Error) {} DiagnosticMessage() {}
DiagnosticMessage(Severity::Enum kind, const AST::SourceLocation &loc, const QString &message) DiagnosticMessage(Severity::Enum kind, const AST::SourceLocation &loc, const QString &message)
: kind(kind), loc(loc), message(message) {} : kind(kind), loc(loc), message(message) {}
@@ -67,7 +93,7 @@ public:
bool isError() const bool isError() const
{ return kind == Severity::Error; } { return kind == Severity::Error; }
Severity::Enum kind; Severity::Enum kind = Severity::Error;
AST::SourceLocation loc; AST::SourceLocation loc;
QString message; QString message;
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -3,8 +3,9 @@
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** 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 ** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in ** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the ** accordance with the commercial license agreement provided with the
@@ -21,6 +22,8 @@
** information to ensure the GNU General Public License requirements will ** 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-3.0.html.
** **
** $QT_END_LICENSE$
**
****************************************************************************/ ****************************************************************************/
// //
@@ -39,7 +42,6 @@
#define QMLJSGRAMMAR_P_H #define QMLJSGRAMMAR_P_H
#include "qmljsglobal_p.h" #include "qmljsglobal_p.h"
#include <QtCore/qglobal.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@@ -48,47 +50,55 @@ class QML_PARSER_EXPORT QmlJSGrammar
public: public:
enum VariousConstants { enum VariousConstants {
EOF_SYMBOL = 0, EOF_SYMBOL = 0,
REDUCE_HERE = 107, REDUCE_HERE = 125,
SHIFT_THERE = 106,
T_AND = 1, T_AND = 1,
T_AND_AND = 2, T_AND_AND = 2,
T_AND_EQ = 3, T_AND_EQ = 3,
T_AS = 95, T_ARROW = 93,
T_AS = 110,
T_AUTOMATIC_SEMICOLON = 62, T_AUTOMATIC_SEMICOLON = 62,
T_BREAK = 4, T_BREAK = 4,
T_CASE = 5, T_CASE = 5,
T_CATCH = 6, T_CATCH = 6,
T_CLASS = 98,
T_COLON = 7, T_COLON = 7,
T_COMMA = 8, T_COMMA = 8,
T_COMMENT = 89, T_COMMENT = 91,
T_COMPATIBILITY_SEMICOLON = 90, T_COMPATIBILITY_SEMICOLON = 92,
T_CONST = 84, T_CONST = 86,
T_CONTINUE = 9, T_CONTINUE = 9,
T_DEBUGGER = 86, T_DEBUGGER = 88,
T_DEFAULT = 10, T_DEFAULT = 10,
T_DELETE = 11, T_DELETE = 11,
T_DIVIDE_ = 12, T_DIVIDE_ = 12,
T_DIVIDE_EQ = 13, T_DIVIDE_EQ = 13,
T_DO = 14, T_DO = 14,
T_DOT = 15, T_DOT = 15,
T_ELLIPSIS = 95,
T_ELSE = 16, T_ELSE = 16,
T_ENUM = 91, T_ENUM = 94,
T_EQ = 17, T_EQ = 17,
T_EQ_EQ = 18, T_EQ_EQ = 18,
T_EQ_EQ_EQ = 19, T_EQ_EQ_EQ = 19,
T_ERROR = 99, T_ERROR = 114,
T_FALSE = 83, T_EXPORT = 101,
T_FEED_JS_EXPRESSION = 103, T_EXTENDS = 99,
T_FEED_JS_PROGRAM = 105, T_FALSE = 85,
T_FEED_JS_SOURCE_ELEMENT = 104, T_FEED_JS_EXPRESSION = 118,
T_FEED_JS_STATEMENT = 102, T_FEED_JS_MODULE = 120,
T_FEED_UI_OBJECT_MEMBER = 101, T_FEED_JS_SCRIPT = 119,
T_FEED_UI_PROGRAM = 100, T_FEED_JS_STATEMENT = 117,
T_FEED_UI_OBJECT_MEMBER = 116,
T_FEED_UI_PROGRAM = 115,
T_FINALLY = 20, T_FINALLY = 20,
T_FOR = 21, T_FOR = 21,
T_FORCE_BLOCK = 122,
T_FORCE_DECLARATION = 121,
T_FOR_LOOKAHEAD_OK = 123,
T_FROM = 102,
T_FUNCTION = 22, T_FUNCTION = 22,
T_GE = 23, T_GE = 23,
T_GET = 97, T_GET = 112,
T_GT = 24, T_GT = 24,
T_GT_GT = 25, T_GT_GT = 25,
T_GT_GT_EQ = 26, T_GT_GT_EQ = 26,
@@ -96,13 +106,13 @@ public:
T_GT_GT_GT_EQ = 28, T_GT_GT_GT_EQ = 28,
T_IDENTIFIER = 29, T_IDENTIFIER = 29,
T_IF = 30, T_IF = 30,
T_IMPORT = 93, T_IMPORT = 108,
T_IN = 31, T_IN = 31,
T_INSTANCEOF = 32, T_INSTANCEOF = 32,
T_LBRACE = 33, T_LBRACE = 33,
T_LBRACKET = 34, T_LBRACKET = 34,
T_LE = 35, T_LE = 35,
T_LET = 85, T_LET = 87,
T_LPAREN = 36, T_LPAREN = 36,
T_LT = 37, T_LT = 37,
T_LT_LT = 38, T_LT_LT = 38,
@@ -110,66 +120,82 @@ public:
T_MINUS = 40, T_MINUS = 40,
T_MINUS_EQ = 41, T_MINUS_EQ = 41,
T_MINUS_MINUS = 42, T_MINUS_MINUS = 42,
T_MULTILINE_STRING_LITERAL = 88, T_MULTILINE_STRING_LITERAL = 90,
T_NEW = 43, T_NEW = 43,
T_NOT = 44, T_NOT = 44,
T_NOT_EQ = 45, T_NOT_EQ = 45,
T_NOT_EQ_EQ = 46, T_NOT_EQ_EQ = 46,
T_NULL = 81, T_NO_SUBSTITUTION_TEMPLATE = 103,
T_NULL = 83,
T_NUMERIC_LITERAL = 47, T_NUMERIC_LITERAL = 47,
T_ON = 96, T_OF = 111,
T_ON = 124,
T_OR = 48, T_OR = 48,
T_OR_EQ = 49, T_OR_EQ = 49,
T_OR_OR = 50, T_OR_OR = 50,
T_PLUS = 51, T_PLUS = 51,
T_PLUS_EQ = 52, T_PLUS_EQ = 52,
T_PLUS_PLUS = 53, T_PLUS_PLUS = 53,
T_PRAGMA = 94, T_PRAGMA = 109,
T_PROPERTY = 66, T_PROPERTY = 68,
T_PUBLIC = 92, T_PUBLIC = 107,
T_QUESTION = 54, T_QUESTION = 54,
T_RBRACE = 55, T_RBRACE = 55,
T_RBRACKET = 56, T_RBRACKET = 56,
T_READONLY = 68, T_READONLY = 70,
T_REMAINDER = 57, T_REMAINDER = 57,
T_REMAINDER_EQ = 58, T_REMAINDER_EQ = 58,
T_RESERVED_WORD = 87, T_RESERVED_WORD = 89,
T_RETURN = 59, T_RETURN = 59,
T_RPAREN = 60, T_RPAREN = 60,
T_SEMICOLON = 61, T_SEMICOLON = 61,
T_SET = 98, T_SET = 113,
T_SIGNAL = 67, T_SIGNAL = 69,
T_STAR = 63, T_STAR = 63,
T_STAR_EQ = 64, T_STAR_EQ = 66,
T_STRING_LITERAL = 65, T_STAR_STAR = 64,
T_SWITCH = 69, T_STAR_STAR_EQ = 65,
T_THIS = 70, T_STATIC = 100,
T_THROW = 71, T_STRING_LITERAL = 67,
T_TILDE = 72, T_SUPER = 97,
T_TRUE = 82, T_SWITCH = 71,
T_TRY = 73, T_TEMPLATE_HEAD = 104,
T_TYPEOF = 74, T_TEMPLATE_MIDDLE = 105,
T_VAR = 75, T_TEMPLATE_TAIL = 106,
T_VOID = 76, T_THIS = 72,
T_WHILE = 77, T_THROW = 73,
T_WITH = 78, T_TILDE = 74,
T_XOR = 79, T_TRUE = 84,
T_XOR_EQ = 80, 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, ACCEPT_STATE = 1008,
RULE_COUNT = 369, RULE_COUNT = 586,
STATE_COUNT = 692, STATE_COUNT = 1009,
TERMINAL_COUNT = 108, TERMINAL_COUNT = 126,
NON_TERMINAL_COUNT = 112, NON_TERMINAL_COUNT = 213,
GOTO_INDEX_OFFSET = 692, GOTO_INDEX_OFFSET = 1009,
GOTO_INFO_OFFSET = 3357, GOTO_INFO_OFFSET = 5937,
GOTO_CHECK_OFFSET = 3357 GOTO_CHECK_OFFSET = 5937
}; };
static const char *const spell[]; static const char *const spell[];
static const short lhs[]; static const short lhs[];
static const short rhs[]; static const short rhs[];
#ifndef QLALR_NO_QMLJSGRAMMAR_DEBUG_INFO
static const int rule_index[];
static const int rule_info[];
#endif // QLALR_NO_QMLJSGRAMMAR_DEBUG_INFO
static const short goto_default[]; static const short goto_default[];
static const short action_default[]; static const short action_default[];
static const short action_index[]; static const short action_index[];

View File

@@ -42,10 +42,10 @@ QT_QML_BEGIN_NAMESPACE
namespace QmlJS { 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[0].unicode() == 'a') {
if (s[1].unicode() == 's') { if (s[1].unicode() == 's') {
return qmlMode ? Lexer::T_AS : Lexer::T_IDENTIFIER; return Lexer::T_AS;
} }
} }
else if (s[0].unicode() == 'd') { else if (s[0].unicode() == 'd') {
@@ -61,15 +61,18 @@ static inline int classify2(const QChar *s, bool qmlMode) {
return Lexer::T_IN; return Lexer::T_IN;
} }
} }
else if (qmlMode && s[0].unicode() == 'o') { else if (s[0].unicode() == 'o') {
if (s[1].unicode() == 'n') { 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; 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[0].unicode() == 'f') {
if (s[1].unicode() == 'o') { if (s[1].unicode() == 'o') {
if (s[2].unicode() == 'r') { if (s[2].unicode() == 'r') {
@@ -87,7 +90,7 @@ static inline int classify3(const QChar *s, bool qmlMode) {
else if (s[0].unicode() == 'i') { else if (s[0].unicode() == 'i') {
if (s[1].unicode() == 'n') { if (s[1].unicode() == 'n') {
if (s[2].unicode() == 't') { 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; 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[0].unicode() == 'b') {
if (s[1].unicode() == 'y') { if (s[1].unicode() == 'y') {
if (s[2].unicode() == 't') { if (s[2].unicode() == 't') {
if (s[3].unicode() == 'e') { 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') { else if (s[1].unicode() == 'h') {
if (s[2].unicode() == 'a') { if (s[2].unicode() == 'a') {
if (s[3].unicode() == 'r') { 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') { else if (s[1].unicode() == 'n') {
if (s[2].unicode() == 'u') { if (s[2].unicode() == 'u') {
if (s[3].unicode() == 'm') { 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[1].unicode() == 'o') {
if (s[2].unicode() == 't') { if (s[2].unicode() == 't') {
if (s[3].unicode() == 'o') { 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[1].unicode() == 'o') {
if (s[2].unicode() == 'n') { if (s[2].unicode() == 'n') {
if (s[3].unicode() == 'g') { 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; 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[0].unicode() == 'b') {
if (s[1].unicode() == 'r') { if (s[1].unicode() == 'r') {
if (s[2].unicode() == 'e') { 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[2].unicode() == 'n') {
if (s[3].unicode() == 'a') { if (s[3].unicode() == 'a') {
if (s[4].unicode() == 'l') { 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[2].unicode() == 'o') {
if (s[3].unicode() == 'a') { if (s[3].unicode() == 'a') {
if (s[4].unicode() == 't') { 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[2].unicode() == 'o') {
if (s[3].unicode() == 'r') { if (s[3].unicode() == 'r') {
if (s[4].unicode() == 't') { 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[2].unicode() == 'p') {
if (s[3].unicode() == 'e') { if (s[3].unicode() == 'e') {
if (s[4].unicode() == 'r') { 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; 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[0].unicode() == 'd') {
if (s[1].unicode() == 'e') { if (s[1].unicode() == 'e') {
if (s[2].unicode() == 'l') { 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[3].unicode() == 'b') {
if (s[4].unicode() == 'l') { if (s[4].unicode() == 'l') {
if (s[5].unicode() == 'e') { 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[3].unicode() == 'o') {
if (s[4].unicode() == 'r') { if (s[4].unicode() == 'r') {
if (s[5].unicode() == 't') { 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[3].unicode() == 'i') {
if (s[4].unicode() == 'v') { if (s[4].unicode() == 'v') {
if (s[5].unicode() == 'e') { 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[3].unicode() == 'l') {
if (s[4].unicode() == 'i') { if (s[4].unicode() == 'i') {
if (s[5].unicode() == 'c') { 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[3].unicode() == 'g') {
if (s[4].unicode() == 'm') { if (s[4].unicode() == 'm') {
if (s[5].unicode() == 'a') { 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') { 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[2].unicode() == 'g') {
if (s[3].unicode() == 'n') { if (s[3].unicode() == 'n') {
if (s[4].unicode() == 'a') { 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[3].unicode() == 't') {
if (s[4].unicode() == 'i') { if (s[4].unicode() == 'i') {
if (s[5].unicode() == 'c') { 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[3].unicode() == 'o') {
if (s[4].unicode() == 'w') { if (s[4].unicode() == 'w') {
if (s[5].unicode() == 's') { 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; 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[0].unicode() == 'b') {
if (s[1].unicode() == 'o') { if (s[1].unicode() == 'o') {
if (s[2].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[4].unicode() == 'e') {
if (s[5].unicode() == 'a') { if (s[5].unicode() == 'a') {
if (s[6].unicode() == 'n') { 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[4].unicode() == 'a') {
if (s[5].unicode() == 'g') { if (s[5].unicode() == 'g') {
if (s[6].unicode() == 'e') { 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[4].unicode() == 'a') {
if (s[5].unicode() == 't') { if (s[5].unicode() == 't') {
if (s[6].unicode() == 'e') { 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; 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[0].unicode() == 'a') {
if (s[1].unicode() == 'b') { if (s[1].unicode() == 'b') {
if (s[2].unicode() == 's') { 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[5].unicode() == 'a') {
if (s[6].unicode() == 'c') { if (s[6].unicode() == 'c') {
if (s[7].unicode() == 't') { 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[1].unicode() == 'r') {
if (s[2].unicode() == 'o') { if (s[2].unicode() == 'o') {
if (s[3].unicode() == 'p') { 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[1].unicode() == 'e') {
if (s[2].unicode() == 'a') { if (s[2].unicode() == 'a') {
if (s[3].unicode() == 'd') { 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[5].unicode() == 'i') {
if (s[6].unicode() == 'l') { if (s[6].unicode() == 'l') {
if (s[7].unicode() == 'e') { 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; 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[0].unicode() == 'i') {
if (s[1].unicode() == 'n') { if (s[1].unicode() == 'n') {
if (s[2].unicode() == 't') { 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[6].unicode() == 'a') {
if (s[7].unicode() == 'c') { if (s[7].unicode() == 'c') {
if (s[8].unicode() == 'e') { 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[6].unicode() == 't') {
if (s[7].unicode() == 'e') { if (s[7].unicode() == 'e') {
if (s[8].unicode() == 'd') { 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[6].unicode() == 'e') {
if (s[7].unicode() == 'n') { if (s[7].unicode() == 'n') {
if (s[8].unicode() == 't') { 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; 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[0].unicode() == 'i') {
if (s[1].unicode() == 'm') { if (s[1].unicode() == 'm') {
if (s[2].unicode() == 'p') { 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[7].unicode() == 'n') {
if (s[8].unicode() == 't') { if (s[8].unicode() == 't') {
if (s[9].unicode() == 's') { 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; 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[0].unicode() == 's') {
if (s[1].unicode() == 'y') { if (s[1].unicode() == 'y') {
if (s[2].unicode() == 'n') { 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[9].unicode() == 'z') {
if (s[10].unicode() == 'e') { if (s[10].unicode() == 'e') {
if (s[11].unicode() == 'd') { 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; 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) { switch (n) {
case 2: return classify2(s, qmlMode); case 2: return classify2(s, parseModeFlags);
case 3: return classify3(s, qmlMode); case 3: return classify3(s, parseModeFlags);
case 4: return classify4(s, qmlMode); case 4: return classify4(s, parseModeFlags);
case 5: return classify5(s, qmlMode); case 5: return classify5(s, parseModeFlags);
case 6: return classify6(s, qmlMode); case 6: return classify6(s, parseModeFlags);
case 7: return classify7(s, qmlMode); case 7: return classify7(s, parseModeFlags);
case 8: return classify8(s, qmlMode); case 8: return classify8(s, parseModeFlags);
case 9: return classify9(s, qmlMode); case 9: return classify9(s, parseModeFlags);
case 10: return classify10(s, qmlMode); case 10: return classify10(s, parseModeFlags);
case 12: return classify12(s, qmlMode); case 12: return classify12(s, parseModeFlags);
default: return Lexer::T_IDENTIFIER; default: return Lexer::T_IDENTIFIER;
} // switch } // switch
} }

File diff suppressed because it is too large Load Diff

View File

@@ -40,6 +40,7 @@
#include "qmljsgrammar_p.h" #include "qmljsgrammar_p.h"
#include <QtCore/qstring.h> #include <QtCore/qstring.h>
#include <QtCore/qstack.h>
QT_QML_BEGIN_NAMESPACE QT_QML_BEGIN_NAMESPACE
@@ -47,35 +48,7 @@ namespace QmlJS {
class Engine; class Engine;
class DiagnosticMessage; class DiagnosticMessage;
class Directives;
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 QML_PARSER_EXPORT Lexer: public QmlJSGrammar class QML_PARSER_EXPORT Lexer: public QmlJSGrammar
{ {
@@ -85,10 +58,7 @@ public:
T_BOOLEAN = T_RESERVED_WORD, T_BOOLEAN = T_RESERVED_WORD,
T_BYTE = T_RESERVED_WORD, T_BYTE = T_RESERVED_WORD,
T_CHAR = T_RESERVED_WORD, T_CHAR = T_RESERVED_WORD,
T_CLASS = T_RESERVED_WORD,
T_DOUBLE = T_RESERVED_WORD, T_DOUBLE = T_RESERVED_WORD,
T_EXPORT = T_RESERVED_WORD,
T_EXTENDS = T_RESERVED_WORD,
T_FINAL = T_RESERVED_WORD, T_FINAL = T_RESERVED_WORD,
T_FLOAT = T_RESERVED_WORD, T_FLOAT = T_RESERVED_WORD,
T_GOTO = T_RESERVED_WORD, T_GOTO = T_RESERVED_WORD,
@@ -101,8 +71,6 @@ public:
T_PRIVATE = T_RESERVED_WORD, T_PRIVATE = T_RESERVED_WORD,
T_PROTECTED = T_RESERVED_WORD, T_PROTECTED = T_RESERVED_WORD,
T_SHORT = T_RESERVED_WORD, T_SHORT = T_RESERVED_WORD,
T_STATIC = T_RESERVED_WORD,
T_SUPER = T_RESERVED_WORD,
T_SYNCHRONIZED = T_RESERVED_WORD, T_SYNCHRONIZED = T_RESERVED_WORD,
T_THROWS = T_RESERVED_WORD, T_THROWS = T_RESERVED_WORD,
T_TRANSIENT = T_RESERVED_WORD, T_TRANSIENT = T_RESERVED_WORD,
@@ -112,7 +80,7 @@ public:
enum Error { enum Error {
NoError, NoError,
IllegalCharacter, IllegalCharacter,
IllegalHexNumber, IllegalNumber,
UnclosedStringLiteral, UnclosedStringLiteral,
IllegalEscapeSequence, IllegalEscapeSequence,
IllegalUnicodeEscapeSequence, IllegalUnicodeEscapeSequence,
@@ -130,13 +98,34 @@ public:
enum RegExpFlag { enum RegExpFlag {
RegExp_Global = 0x01, RegExp_Global = 0x01,
RegExp_IgnoreCase = 0x02, RegExp_IgnoreCase = 0x02,
RegExp_Multiline = 0x04 RegExp_Multiline = 0x04,
RegExp_Unicode = 0x08,
RegExp_Sticky = 0x10
};
enum ParseModeFlags {
QmlMode = 0x1,
YieldIsKeyword = 0x2,
StaticIsKeyword = 0x4
}; };
public: public:
Lexer(Engine *engine); 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 qmlMode() const;
bool yieldIsKeyWord() const { return _generatorLevel != 0; }
void setStaticIsKeyword(bool b) { _staticIsKeyword = b; }
QString code() const; QString code() const;
void setCode(const QString &code, int lineno, bool qmlMode = true); void setCode(const QString &code, int lineno, bool qmlMode = true);
@@ -154,10 +143,7 @@ public:
int tokenLength() const { return _tokenLength; } int tokenLength() const { return _tokenLength; }
int tokenStartLine() const { return _tokenLine; } int tokenStartLine() const { return _tokenLine; }
int tokenStartColumn() const { return _tokenStartPtr - _tokenLinePtr + 1; } int tokenStartColumn() const { return _tokenColumn; }
int tokenEndLine() const;
int tokenEndColumn() const;
inline QStringRef tokenSpell() const { return _tokenSpell; } inline QStringRef tokenSpell() const { return _tokenSpell; }
double tokenValue() const { return _tokenValue; } double tokenValue() const { return _tokenValue; }
@@ -176,13 +162,23 @@ public:
BalancedParentheses BalancedParentheses
}; };
void enterGeneratorBody() { ++_generatorLevel; }
void leaveGeneratorBody() { --_generatorLevel; }
protected: protected:
int classify(const QChar *s, int n, bool qmlMode); static int classify(const QChar *s, int n, int parseModeFlags);
private: private:
inline void scanChar(); inline void scanChar();
int scanToken(); int scanToken();
int scanNumber(QChar ch); int scanNumber(QChar ch);
enum ScanStringMode {
SingleQuote = '\'',
DoubleQuote = '"',
TemplateHead = '`',
TemplateContinuation = 0
};
int scanString(ScanStringMode mode);
bool isLineTerminator() const; bool isLineTerminator() const;
unsigned isLineTerminatorSequence() const; unsigned isLineTerminatorSequence() const;
@@ -190,10 +186,9 @@ private:
static bool isDecimalDigit(ushort c); static bool isDecimalDigit(ushort c);
static bool isHexDigit(QChar c); static bool isHexDigit(QChar c);
static bool isOctalDigit(ushort c); static bool isOctalDigit(ushort c);
static bool isUnicodeEscapeSequence(const QChar *chars);
void syncProhibitAutomaticSemicolon(); void syncProhibitAutomaticSemicolon();
QChar decodeUnicodeEscapeCharacter(bool *ok); uint decodeUnicodeEscapeCharacter(bool *ok);
QChar decodeHexEscapeCharacter(bool *ok); QChar decodeHexEscapeCharacter(bool *ok);
private: private:
@@ -206,26 +201,30 @@ private:
const QChar *_codePtr; const QChar *_codePtr;
const QChar *_endPtr; const QChar *_endPtr;
const QChar *_lastLinePtr;
const QChar *_tokenLinePtr;
const QChar *_tokenStartPtr; const QChar *_tokenStartPtr;
QChar _char; QChar _char;
Error _errorCode; Error _errorCode;
int _currentLineNumber; int _currentLineNumber;
int _currentColumnNumber;
double _tokenValue; double _tokenValue;
// parentheses state // parentheses state
ParenthesesState _parenthesesState; ParenthesesState _parenthesesState;
int _parenthesesCount; int _parenthesesCount;
// template string stack
QStack<int> _outerTemplateBraceCount;
int _bracesCount = -1;
int _stackToken; int _stackToken;
int _patternFlags; int _patternFlags;
int _tokenKind; int _tokenKind;
int _tokenLength; int _tokenLength;
int _tokenLine; int _tokenLine;
int _tokenColumn;
bool _validTokenText; bool _validTokenText;
bool _prohibitAutomaticSemicolon; bool _prohibitAutomaticSemicolon;
@@ -234,6 +233,8 @@ private:
bool _followsClosingBrace; bool _followsClosingBrace;
bool _delimited; bool _delimited;
bool _qmlMode; bool _qmlMode;
int _generatorLevel = 0;
bool _staticIsKeyword = false;
}; };
} // end of namespace QmlJS } // end of namespace QmlJS

View File

@@ -56,13 +56,7 @@ class QML_PARSER_EXPORT MemoryPool : public QSharedData
void operator =(const MemoryPool &other); void operator =(const MemoryPool &other);
public: public:
MemoryPool() MemoryPool() {}
: _blocks(0),
_allocatedBlocks(0),
_blockCount(-1),
_ptr(0),
_end(0)
{ }
~MemoryPool() ~MemoryPool()
{ {
@@ -74,6 +68,7 @@ public:
free(_blocks); free(_blocks);
} }
qDeleteAll(strings);
} }
inline void *allocate(size_t size) inline void *allocate(size_t size)
@@ -90,11 +85,16 @@ public:
void reset() void reset()
{ {
_blockCount = -1; _blockCount = -1;
_ptr = _end = 0; _ptr = _end = nullptr;
} }
template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); } 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: private:
Q_NEVER_INLINE void *allocate_helper(size_t size) Q_NEVER_INLINE void *allocate_helper(size_t size)
{ {
@@ -110,7 +110,7 @@ private:
Q_CHECK_PTR(_blocks); Q_CHECK_PTR(_blocks);
for (int index = _blockCount; index < _allocatedBlocks; ++index) for (int index = _blockCount; index < _allocatedBlocks; ++index)
_blocks[index] = 0; _blocks[index] = nullptr;
} }
char *&block = _blocks[_blockCount]; char *&block = _blocks[_blockCount];
@@ -129,11 +129,12 @@ private:
} }
private: private:
char **_blocks; char **_blocks = nullptr;
int _allocatedBlocks; int _allocatedBlocks = 0;
int _blockCount; int _blockCount = -1;
char *_ptr; char *_ptr = nullptr;
char *_end; char *_end = nullptr;
QVector<QString*> strings;
enum enum
{ {
@@ -144,12 +145,10 @@ private:
class QML_PARSER_EXPORT Managed class QML_PARSER_EXPORT Managed
{ {
Managed(const Managed &other); Q_DISABLE_COPY(Managed)
void operator = (const Managed &other);
public: public:
Managed() {} Managed() = default;
~Managed() {} ~Managed() = default;
void *operator new(size_t size, MemoryPool *pool) { return pool->allocate(size); } void *operator new(size_t size, MemoryPool *pool) { return pool->allocate(size); }
void operator delete(void *) {} void operator delete(void *) {}

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,13 @@
#line 178 "qmljs.g"
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** 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 ** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in ** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the ** accordance with the commercial license agreement provided with the
@@ -13,13 +16,26 @@
** and conditions see https://www.qt.io/terms-conditions. For further ** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us. ** 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 ** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU ** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software ** General Public License version 2.0 or (at your option) the GNU General
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** 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 ** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will ** 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 { union Value {
int ival; int ival;
double dval; double dval;
AST::VariableScope scope;
AST::ForEachType forEachType;
AST::ArgumentList *ArgumentList; AST::ArgumentList *ArgumentList;
AST::CaseBlock *CaseBlock; AST::CaseBlock *CaseBlock;
AST::CaseClause *CaseClause; AST::CaseClause *CaseClause;
AST::CaseClauses *CaseClauses; AST::CaseClauses *CaseClauses;
AST::Catch *Catch; AST::Catch *Catch;
AST::DefaultClause *DefaultClause; AST::DefaultClause *DefaultClause;
AST::ElementList *ElementList;
AST::Elision *Elision; AST::Elision *Elision;
AST::ExpressionNode *Expression; AST::ExpressionNode *Expression;
AST::TemplateLiteral *Template;
AST::Finally *Finally; AST::Finally *Finally;
AST::FormalParameterList *FormalParameterList; AST::FormalParameterList *FormalParameterList;
AST::FunctionBody *FunctionBody;
AST::FunctionDeclaration *FunctionDeclaration; AST::FunctionDeclaration *FunctionDeclaration;
AST::Node *Node; AST::Node *Node;
AST::PropertyName *PropertyName; AST::PropertyName *PropertyName;
AST::PropertyAssignment *PropertyAssignment;
AST::PropertyAssignmentList *PropertyAssignmentList;
AST::SourceElement *SourceElement;
AST::SourceElements *SourceElements;
AST::Statement *Statement; AST::Statement *Statement;
AST::StatementList *StatementList; AST::StatementList *StatementList;
AST::Block *Block; AST::Block *Block;
AST::VariableDeclaration *VariableDeclaration;
AST::VariableDeclarationList *VariableDeclarationList; 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::UiProgram *UiProgram;
AST::UiHeaderItemList *UiHeaderItemList; AST::UiHeaderItemList *UiHeaderItemList;
@@ -110,7 +138,6 @@ public:
AST::UiObjectMemberList *UiObjectMemberList; AST::UiObjectMemberList *UiObjectMemberList;
AST::UiArrayMemberList *UiArrayMemberList; AST::UiArrayMemberList *UiArrayMemberList;
AST::UiQualifiedId *UiQualifiedId; AST::UiQualifiedId *UiQualifiedId;
AST::UiQualifiedPragmaId *UiQualifiedPragmaId;
AST::UiEnumMemberList *UiEnumMemberList; AST::UiEnumMemberList *UiEnumMemberList;
}; };
@@ -119,12 +146,13 @@ public:
~Parser(); ~Parser();
// parse a UI program // 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 parseStatement() { return parse(T_FEED_JS_STATEMENT); }
bool parseExpression() { return parse(T_FEED_JS_EXPRESSION); } bool parseExpression() { return parse(T_FEED_JS_EXPRESSION); }
bool parseSourceElement() { return parse(T_FEED_JS_SOURCE_ELEMENT); } bool parseUiObjectMember() { ++functionNestingLevel; bool r = parse(T_FEED_UI_OBJECT_MEMBER); --functionNestingLevel; return r; }
bool parseUiObjectMember() { return parse(T_FEED_UI_OBJECT_MEMBER); } bool parseProgram() { return parse(T_FEED_JS_SCRIPT); }
bool parseProgram() { return parse(T_FEED_JS_PROGRAM); } bool parseScript() { return parse(T_FEED_JS_SCRIPT); }
bool parseModule() { return parse(T_FEED_JS_MODULE); }
AST::UiProgram *ast() const AST::UiProgram *ast() const
{ return AST::cast<AST::UiProgram *>(program); } { return AST::cast<AST::UiProgram *>(program); }
@@ -193,22 +221,31 @@ protected:
{ return location_stack [tos + index - 1]; } { return location_stack [tos + index - 1]; }
AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr); 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: protected:
Engine *driver; Engine *driver;
MemoryPool *pool; MemoryPool *pool;
int tos; int tos = 0;
int stack_size; int stack_size = 0;
Value *sym_stack; Value *sym_stack = nullptr;
int *state_stack; int *state_stack = nullptr;
AST::SourceLocation *location_stack; AST::SourceLocation *location_stack = nullptr;
QStringRef *string_stack; QVector<QStringRef> string_stack;
AST::Node *program; AST::Node *program = nullptr;
// error recovery // error recovery and lookahead handling
enum { TOKEN_BUFFER_SIZE = 3 }; enum { TOKEN_BUFFER_SIZE = 5 };
struct SavedToken { struct SavedToken {
int token; int token;
@@ -217,14 +254,25 @@ protected:
QStringRef spell; QStringRef spell;
}; };
double yylval; int yytoken = -1;
double yylval = 0.;
QStringRef yytokenspell; QStringRef yytokenspell;
AST::SourceLocation yylloc; AST::SourceLocation yylloc;
AST::SourceLocation yyprevlloc; AST::SourceLocation yyprevlloc;
SavedToken token_buffer[TOKEN_BUFFER_SIZE]; SavedToken token_buffer[TOKEN_BUFFER_SIZE];
SavedToken *first_token; SavedToken *first_token = nullptr;
SavedToken *last_token; 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; 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 QT_QML_END_NAMESPACE

View File

@@ -306,14 +306,14 @@ bool Bind::visit(UiArrayBinding *)
return true; return true;
} }
bool Bind::visit(VariableDeclaration *ast) bool Bind::visit(PatternElement *ast)
{ {
if (ast->name.isEmpty()) if (ast->bindingIdentifier.isEmpty() || !ast->isVariableDeclaration())
return false; return false;
ASTVariableReference *ref = new ASTVariableReference(ast, _doc, &_valueOwner); ASTVariableReference *ref = new ASTVariableReference(ast, _doc, &_valueOwner);
if (_currentObjectValue) if (_currentObjectValue)
_currentObjectValue->setMember(ast->name.toString(), ref); _currentObjectValue->setMember(ast->bindingIdentifier, ref);
return true; return true;
} }
@@ -337,8 +337,8 @@ bool Bind::visit(FunctionExpression *ast)
// 1. Function formal arguments // 1. Function formal arguments
for (FormalParameterList *it = ast->formals; it; it = it->next) { for (FormalParameterList *it = ast->formals; it; it = it->next) {
if (!it->name.isEmpty()) if (!it->element->bindingIdentifier.isEmpty())
functionScope->setMember(it->name.toString(), _valueOwner.unknownValue()); functionScope->setMember(it->element->bindingIdentifier, _valueOwner.unknownValue());
} }
// 2. Functions defined inside the function body // 2. Functions defined inside the function body

View File

@@ -79,7 +79,7 @@ protected:
// QML/JS // QML/JS
bool visit(AST::FunctionDeclaration *ast) override; bool visit(AST::FunctionDeclaration *ast) override;
bool visit(AST::FunctionExpression *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 *switchObjectValue(ObjectValue *newObjectValue);
ObjectValue *bindObject(AST::UiQualifiedId *qualifiedTypeNameId, AST::UiObjectInitializer *initializer); ObjectValue *bindObject(AST::UiQualifiedId *qualifiedTypeNameId, AST::UiObjectInitializer *initializer);

View File

@@ -197,10 +197,6 @@ protected:
return true; return true;
if (Statement *stmt = ast->statementCast()) if (Statement *stmt = ast->statementCast())
onUnreachable(stmt); onUnreachable(stmt);
if (FunctionSourceElement *fun = cast<FunctionSourceElement *>(ast))
onUnreachable(fun->declaration);
if (StatementSourceElement *stmt = cast<StatementSourceElement *>(ast))
onUnreachable(stmt->statement);
return false; return false;
} }
@@ -306,8 +302,6 @@ protected:
bool visit(WhileStatement *ast) override { return preconditionLoopStatement(ast, ast->statement); } bool visit(WhileStatement *ast) override { return preconditionLoopStatement(ast, ast->statement); }
bool visit(ForStatement *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(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 bool visit(DoWhileStatement *ast) override
{ {
@@ -367,8 +361,8 @@ public:
{ {
clear(); clear();
for (FormalParameterList *plist = function->formals; plist; plist = plist->next) { for (FormalParameterList *plist = function->formals; plist; plist = plist->next) {
if (!plist->name.isEmpty()) if (!plist->element->bindingIdentifier.isEmpty())
_formalParameterNames += plist->name.toString(); _formalParameterNames += plist->element->bindingIdentifier.toString();
} }
Node::accept(function->body, this); Node::accept(function->body, this);
@@ -418,11 +412,11 @@ protected:
return true; return true;
} }
bool visit(VariableDeclaration *ast) bool visit(PatternElement *ast)
{ {
if (ast->name.isEmpty()) if (ast->bindingIdentifier.isEmpty() || !ast->isVariableDeclaration())
return true; return true;
const QString &name = ast->name.toString(); const QString &name = ast->bindingIdentifier.toString();
if (_formalParameterNames.contains(name)) if (_formalParameterNames.contains(name))
addMessage(WarnAlreadyFormalParameter, ast->identifierToken, name); addMessage(WarnAlreadyFormalParameter, ast->identifierToken, name);
@@ -484,7 +478,7 @@ private:
QList<Message> _messages; QList<Message> _messages;
QStringList _formalParameterNames; QStringList _formalParameterNames;
QHash<QString, VariableDeclaration *> _declaredVariables; QHash<QString, PatternElement *> _declaredVariables;
QHash<QString, FunctionDeclaration *> _declaredFunctions; QHash<QString, FunctionDeclaration *> _declaredFunctions;
QHash<QString, QList<SourceLocation> > _possiblyUndeclaredUses; QHash<QString, QList<SourceLocation> > _possiblyUndeclaredUses;
bool _seenNonDeclarationStatement; bool _seenNonDeclarationStatement;
@@ -1039,8 +1033,8 @@ bool Check::visit(UiArrayBinding *ast)
bool Check::visit(UiPublicMember *ast) bool Check::visit(UiPublicMember *ast)
{ {
if (ast->type == UiPublicMember::Property) { if (ast->type == UiPublicMember::Property) {
if (ast->isValid()) { if (ast->defaultToken.isValid() || ast->readonlyToken.isValid()) {
const QStringRef typeName = ast->memberTypeName(); const QStringRef typeName = ast->memberType->name;
if (!typeName.isEmpty() && typeName.at(0).isLower()) { if (!typeName.isEmpty() && typeName.at(0).isLower()) {
const QString typeNameS = typeName.toString(); const QString typeNameS = typeName.toString();
if (!isValidBuiltinPropertyType(typeNameS)) if (!isValidBuiltinPropertyType(typeNameS))
@@ -1277,8 +1271,6 @@ bool Check::visit(Block *ast)
&& !cast<Finally *>(p) && !cast<Finally *>(p)
&& !cast<ForStatement *>(p) && !cast<ForStatement *>(p)
&& !cast<ForEachStatement *>(p) && !cast<ForEachStatement *>(p)
&& !cast<LocalForStatement *>(p)
&& !cast<LocalForEachStatement *>(p)
&& !cast<DoWhileStatement *>(p) && !cast<DoWhileStatement *>(p)
&& !cast<WhileStatement *>(p) && !cast<WhileStatement *>(p)
&& !cast<IfStatement *>(p) && !cast<IfStatement *>(p)
@@ -1311,8 +1303,7 @@ bool Check::visit(Expression *ast)
{ {
if (ast->left && ast->right) { if (ast->left && ast->right) {
Node *p = parent(); Node *p = parent();
if (!cast<ForStatement *>(p) if (!cast<ForStatement *>(p)) {
&& !cast<LocalForStatement *>(p)) {
addMessage(WarnComma, ast->commaToken); addMessage(WarnComma, ast->commaToken);
} }
} }
@@ -1372,13 +1363,6 @@ bool Check::visit(ForStatement *ast)
return true; return true;
} }
bool Check::visit(LocalForStatement *ast)
{
if (ast->condition)
checkAssignInCondition(ast->condition);
return true;
}
bool Check::visit(WhileStatement *ast) bool Check::visit(WhileStatement *ast)
{ {
if (ast->expression) if (ast->expression)

View File

@@ -84,7 +84,6 @@ protected:
bool visit(AST::ExpressionStatement *ast) override; bool visit(AST::ExpressionStatement *ast) override;
bool visit(AST::IfStatement *ast) override; bool visit(AST::IfStatement *ast) override;
bool visit(AST::ForStatement *ast) override; bool visit(AST::ForStatement *ast) override;
bool visit(AST::LocalForStatement *ast) override;
bool visit(AST::WhileStatement *ast) override; bool visit(AST::WhileStatement *ast) override;
bool visit(AST::DoWhileStatement *ast) override; bool visit(AST::DoWhileStatement *ast) override;
bool visit(AST::CaseBlock *ast) override; bool visit(AST::CaseBlock *ast) override;

View File

@@ -366,11 +366,11 @@ void DescribeValueVisitor::visit(const Reference *value)
} }
} else if (const ASTVariableReference *v = value->asAstVariableReference()) { } else if (const ASTVariableReference *v = value->asAstVariableReference()) {
basicDump("ASTVariableReference", v, printDetail); basicDump("ASTVariableReference", v, printDetail);
const AST::VariableDeclaration *var = v->ast(); const AST::PatternElement *var = v->ast();
if (printDetail && var) { if (printDetail && var && var->isVariableDeclaration()) {
dumpNewline(); dumpNewline();
dump("variable:"); dump("variable:");
dump(var->name.toString()); dump(var->bindingIdentifier.toString());
} }
} else if (const QmlPrototypeReference *v = value->asQmlPrototypeReference()) { } else if (const QmlPrototypeReference *v = value->asQmlPrototypeReference()) {
basicDump("QmlPrototypeReference", v, printDetail); basicDump("QmlPrototypeReference", v, printDetail);

View File

@@ -248,7 +248,7 @@ public:
{} {}
void pragmaLibrary(int line, int column) override void pragmaLibrary(int line, int column)
{ {
isLibrary = true; isLibrary = true;
addLocation(line, column); addLocation(line, column);
@@ -305,12 +305,14 @@ bool Document::parse_helper(int startToken)
case QmlJSGrammar::T_FEED_UI_PROGRAM: case QmlJSGrammar::T_FEED_UI_PROGRAM:
_parsedCorrectly = parser.parse(); _parsedCorrectly = parser.parse();
break; break;
case QmlJSGrammar::T_FEED_JS_PROGRAM: case QmlJSGrammar::T_FEED_JS_SCRIPT:
case QmlJSGrammar::T_FEED_JS_MODULE:
_parsedCorrectly = parser.parseProgram(); _parsedCorrectly = parser.parseProgram();
for (const auto &d: directives.locations()) { for (const auto &d: directives.locations()) {
_jsdirectives << d; _jsdirectives << d;
} }
break; break;
case QmlJSGrammar::T_FEED_JS_EXPRESSION: case QmlJSGrammar::T_FEED_JS_EXPRESSION:
_parsedCorrectly = parser.parseExpression(); _parsedCorrectly = parser.parseExpression();
break; break;
@@ -341,7 +343,7 @@ bool Document::parseQml()
bool Document::parseJavaScript() bool Document::parseJavaScript()
{ {
return parse_helper(QmlJSGrammar::T_FEED_JS_PROGRAM); return parse_helper(QmlJSGrammar::T_FEED_JS_SCRIPT);
} }
bool Document::parseExpression() bool Document::parseExpression()

View File

@@ -126,11 +126,6 @@ bool Evaluate::visit(AST::UiHeaderItemList *)
return false; return false;
} }
bool Evaluate::visit(AST::UiQualifiedPragmaId *)
{
return false;
}
bool Evaluate::visit(AST::UiPragma *) bool Evaluate::visit(AST::UiPragma *)
{ {
return false; return false;
@@ -264,20 +259,20 @@ bool Evaluate::visit(AST::RegExpLiteral *)
return false; return false;
} }
bool Evaluate::visit(AST::ArrayLiteral *) bool Evaluate::visit(AST::ArrayPattern *)
{ {
_result = _valueOwner->arrayCtor()->returnValue(); _result = _valueOwner->arrayCtor()->returnValue();
return false; return false;
} }
bool Evaluate::visit(AST::ObjectLiteral *) bool Evaluate::visit(AST::ObjectPattern *)
{ {
// ### properties // ### properties
_result = _valueOwner->newObject(); _result = _valueOwner->newObject();
return false; return false;
} }
bool Evaluate::visit(AST::ElementList *) bool Evaluate::visit(AST::PatternElementList *)
{ {
return false; return false;
} }
@@ -287,17 +282,12 @@ bool Evaluate::visit(AST::Elision *)
return false; return false;
} }
bool Evaluate::visit(AST::PropertyAssignmentList *) bool Evaluate::visit(AST::PatternPropertyList *)
{ {
return false; return false;
} }
bool Evaluate::visit(AST::PropertyGetterSetter *) bool Evaluate::visit(AST::PatternProperty *)
{
return false;
}
bool Evaluate::visit(AST::PropertyNameAndValue *)
{ {
return false; return false;
} }
@@ -529,11 +519,6 @@ bool Evaluate::visit(AST::Block *)
return false; return false;
} }
bool Evaluate::visit(AST::StatementList *)
{
return false;
}
bool Evaluate::visit(AST::VariableStatement *) bool Evaluate::visit(AST::VariableStatement *)
{ {
return false; return false;
@@ -544,7 +529,7 @@ bool Evaluate::visit(AST::VariableDeclarationList *)
return false; return false;
} }
bool Evaluate::visit(AST::VariableDeclaration *) bool Evaluate::visit(AST::PatternElement *)
{ {
return false; return false;
} }
@@ -579,21 +564,11 @@ bool Evaluate::visit(AST::ForStatement *)
return false; return false;
} }
bool Evaluate::visit(AST::LocalForStatement *)
{
return false;
}
bool Evaluate::visit(AST::ForEachStatement *) bool Evaluate::visit(AST::ForEachStatement *)
{ {
return false; return false;
} }
bool Evaluate::visit(AST::LocalForEachStatement *)
{
return false;
}
bool Evaluate::visit(AST::ContinueStatement *) bool Evaluate::visit(AST::ContinueStatement *)
{ {
return false; return false;
@@ -679,27 +654,12 @@ bool Evaluate::visit(AST::FormalParameterList *)
return false; return false;
} }
bool Evaluate::visit(AST::FunctionBody *)
{
return false;
}
bool Evaluate::visit(AST::Program *) bool Evaluate::visit(AST::Program *)
{ {
return false; return false;
} }
bool Evaluate::visit(AST::SourceElements *) bool Evaluate::visit(AST::StatementList *)
{
return false;
}
bool Evaluate::visit(AST::FunctionSourceElement *)
{
return false;
}
bool Evaluate::visit(AST::StatementSourceElement *)
{ {
return false; return false;
} }

View File

@@ -61,7 +61,6 @@ protected:
// Ui // Ui
bool visit(AST::UiProgram *ast) override; bool visit(AST::UiProgram *ast) override;
bool visit(AST::UiHeaderItemList *ast) override; bool visit(AST::UiHeaderItemList *ast) override;
bool visit(AST::UiQualifiedPragmaId *ast) override;
bool visit(AST::UiPragma *ast) override; bool visit(AST::UiPragma *ast) override;
bool visit(AST::UiImport *ast) override; bool visit(AST::UiImport *ast) override;
bool visit(AST::UiPublicMember *ast) override; bool visit(AST::UiPublicMember *ast) override;
@@ -84,13 +83,12 @@ protected:
bool visit(AST::StringLiteral *ast) override; bool visit(AST::StringLiteral *ast) override;
bool visit(AST::NumericLiteral *ast) override; bool visit(AST::NumericLiteral *ast) override;
bool visit(AST::RegExpLiteral *ast) override; bool visit(AST::RegExpLiteral *ast) override;
bool visit(AST::ArrayLiteral *ast) override; bool visit(AST::ArrayPattern *ast) override;
bool visit(AST::ObjectLiteral *ast) override; bool visit(AST::ObjectPattern *ast) override;
bool visit(AST::ElementList *ast) override;
bool visit(AST::Elision *ast) override; bool visit(AST::Elision *ast) override;
bool visit(AST::PropertyAssignmentList *ast) override; bool visit(AST::PatternElementList *ast) override;
bool visit(AST::PropertyGetterSetter *ast) override; bool visit(AST::PatternPropertyList *ast) override;
bool visit(AST::PropertyNameAndValue *ast) override; bool visit(AST::PatternProperty *ast) override;
bool visit(AST::NestedExpression *ast) override; bool visit(AST::NestedExpression *ast) override;
bool visit(AST::IdentifierPropertyName *ast) override; bool visit(AST::IdentifierPropertyName *ast) override;
bool visit(AST::StringLiteralPropertyName *ast) override; bool visit(AST::StringLiteralPropertyName *ast) override;
@@ -116,19 +114,16 @@ protected:
bool visit(AST::ConditionalExpression *ast) override; bool visit(AST::ConditionalExpression *ast) override;
bool visit(AST::Expression *ast) override; bool visit(AST::Expression *ast) override;
bool visit(AST::Block *ast) override; bool visit(AST::Block *ast) override;
bool visit(AST::StatementList *ast) override;
bool visit(AST::VariableStatement *ast) override; bool visit(AST::VariableStatement *ast) override;
bool visit(AST::VariableDeclarationList *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::EmptyStatement *ast) override;
bool visit(AST::ExpressionStatement *ast) override; bool visit(AST::ExpressionStatement *ast) override;
bool visit(AST::IfStatement *ast) override; bool visit(AST::IfStatement *ast) override;
bool visit(AST::DoWhileStatement *ast) override; bool visit(AST::DoWhileStatement *ast) override;
bool visit(AST::WhileStatement *ast) override; bool visit(AST::WhileStatement *ast) override;
bool visit(AST::ForStatement *ast) override; bool visit(AST::ForStatement *ast) override;
bool visit(AST::LocalForStatement *ast) override;
bool visit(AST::ForEachStatement *ast) override; bool visit(AST::ForEachStatement *ast) override;
bool visit(AST::LocalForEachStatement *ast) override;
bool visit(AST::ContinueStatement *ast) override; bool visit(AST::ContinueStatement *ast) override;
bool visit(AST::BreakStatement *ast) override; bool visit(AST::BreakStatement *ast) override;
bool visit(AST::ReturnStatement *ast) override; bool visit(AST::ReturnStatement *ast) override;
@@ -146,11 +141,8 @@ protected:
bool visit(AST::FunctionDeclaration *ast) override; bool visit(AST::FunctionDeclaration *ast) override;
bool visit(AST::FunctionExpression *ast) override; bool visit(AST::FunctionExpression *ast) override;
bool visit(AST::FormalParameterList *ast) override; bool visit(AST::FormalParameterList *ast) override;
bool visit(AST::FunctionBody *ast) override;
bool visit(AST::Program *ast) override; bool visit(AST::Program *ast) override;
bool visit(AST::SourceElements *ast) override; bool visit(AST::StatementList *ast) override;
bool visit(AST::FunctionSourceElement *ast) override;
bool visit(AST::StatementSourceElement *ast) override;
bool visit(AST::DebuggerStatement *ast) override; bool visit(AST::DebuggerStatement *ast) override;
private: private:

View File

@@ -1052,6 +1052,11 @@ void ObjectValue::setMember(const QString &name, const Value *value)
m_members[name].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) void ObjectValue::setPropertyInfo(const QString &name, const PropertyInfo &propertyInfo)
{ {
m_members[name].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) { for (UiObjectMemberList *it = m_initializer->members; it; it = it->next) {
UiObjectMember *member = it->member; UiObjectMember *member = it->member;
if (UiPublicMember *def = cast<UiPublicMember *>(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); ASTPropertyReference *ref = new ASTPropertyReference(def, m_doc, valueOwner);
m_properties.append(ref); m_properties.append(ref);
if (def->defaultToken.isValid()) if (def->defaultToken.isValid())
@@ -1931,7 +1936,7 @@ const Document *ASTObjectValue::document() const
return m_doc; return m_doc;
} }
ASTVariableReference::ASTVariableReference(VariableDeclaration *ast, const Document *doc, ValueOwner *valueOwner) ASTVariableReference::ASTVariableReference(PatternElement *ast, const Document *doc, ValueOwner *valueOwner)
: Reference(valueOwner) : Reference(valueOwner)
, m_ast(ast) , m_ast(ast)
, m_doc(doc) , m_doc(doc)
@@ -1947,7 +1952,7 @@ const ASTVariableReference *ASTVariableReference::asAstVariableReference() const
return this; return this;
} }
const VariableDeclaration *ASTVariableReference::ast() const const PatternElement *ASTVariableReference::ast() const
{ {
return m_ast; return m_ast;
} }
@@ -1955,16 +1960,16 @@ const VariableDeclaration *ASTVariableReference::ast() const
const Value *ASTVariableReference::value(ReferenceContext *referenceContext) const const Value *ASTVariableReference::value(ReferenceContext *referenceContext) const
{ {
// may be assigned to later // may be assigned to later
if (!m_ast->expression) if (!m_ast->expressionCast())
return valueOwner()->unknownValue(); return valueOwner()->unknownValue();
Document::Ptr doc = m_doc->ptr(); Document::Ptr doc = m_doc->ptr();
ScopeChain scopeChain(doc, referenceContext->context()); ScopeChain scopeChain(doc, referenceContext->context());
ScopeBuilder builder(&scopeChain); 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); Evaluate evaluator(&scopeChain, referenceContext);
return evaluator(m_ast->expression); return evaluator(m_ast->expressionCast());
} }
bool ASTVariableReference::getSourceLocation(QString *fileName, int *line, int *column) const bool ASTVariableReference::getSourceLocation(QString *fileName, int *line, int *column) const
@@ -1981,12 +1986,12 @@ class UsesArgumentsArray : protected Visitor
bool m_usesArgumentsArray; bool m_usesArgumentsArray;
public: public:
bool operator()(FunctionBody *ast) bool operator()(StatementList *ast)
{ {
if (!ast || !ast->elements) if (!ast)
return false; return false;
m_usesArgumentsArray = false; m_usesArgumentsArray = false;
Node::accept(ast->elements, this); Node::accept(ast, this);
return m_usesArgumentsArray; return m_usesArgumentsArray;
} }
@@ -2001,7 +2006,8 @@ protected:
} }
// don't go into nested functions // don't go into nested functions
bool visit(FunctionBody *) { return false; } bool visit(Program *) { return false; }
bool visit(StatementList *) { return false; }
}; };
} // anonymous namespace } // anonymous namespace
@@ -2013,7 +2019,7 @@ ASTFunctionValue::ASTFunctionValue(FunctionExpression *ast, const Document *doc,
setPrototype(valueOwner->functionPrototype()); setPrototype(valueOwner->functionPrototype());
for (FormalParameterList *it = ast->formals; it; it = it->next) 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); m_isVariadic = UsesArgumentsArray()(ast->body);
} }
@@ -2121,10 +2127,9 @@ bool ASTPropertyReference::getSourceLocation(QString *fileName, int *line, int *
const Value *ASTPropertyReference::value(ReferenceContext *referenceContext) const const Value *ASTPropertyReference::value(ReferenceContext *referenceContext) const
{ {
if (m_ast->statement if (m_ast->statement
&& (!m_ast->isValid() && (m_ast->memberType->name == QLatin1String("variant")
|| m_ast->memberTypeName() == QLatin1String("variant") || m_ast->memberType->name == QLatin1String("var")
|| m_ast->memberTypeName() == QLatin1String("var") || m_ast->memberType->name == QLatin1String("alias"))) {
|| m_ast->memberTypeName() == QLatin1String("alias"))) {
// Adjust the context for the current location - expensive! // Adjust the context for the current location - expensive!
// ### Improve efficiency by caching the 'use chain' constructed in ScopeBuilder. // ### 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); 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); const Value *builtin = valueOwner()->defaultValueForBuiltinType(memberType);
if (!builtin->asUndefinedValue()) if (!builtin->asUndefinedValue())

View File

@@ -508,6 +508,7 @@ public:
virtual void processMembers(MemberProcessor *processor) const; virtual void processMembers(MemberProcessor *processor) const;
virtual void setMember(const QString &name, const Value *value); 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 setPropertyInfo(const QString &name, const PropertyInfo &propertyInfo);
virtual void removeMember(const QString &name); virtual void removeMember(const QString &name);
@@ -884,14 +885,14 @@ private:
class QMLJS_EXPORT ASTVariableReference: public Reference class QMLJS_EXPORT ASTVariableReference: public Reference
{ {
AST::VariableDeclaration *m_ast; AST::PatternElement *m_ast;
const Document *m_doc; const Document *m_doc;
public: public:
ASTVariableReference(AST::VariableDeclaration *ast, const Document *doc, ValueOwner *valueOwner); ASTVariableReference(AST::PatternElement *ast, const Document *doc, ValueOwner *valueOwner);
~ASTVariableReference(); ~ASTVariableReference();
const ASTVariableReference *asAstVariableReference() const override; const ASTVariableReference *asAstVariableReference() const override;
const AST::VariableDeclaration *ast() const; const AST::PatternElement *ast() const;
private: private:
const Value *value(ReferenceContext *referenceContext) const override; const Value *value(ReferenceContext *referenceContext) const override;
bool getSourceLocation(QString *fileName, int *line, int *column) const override; bool getSourceLocation(QString *fileName, int *line, int *column) const override;

View File

@@ -531,7 +531,6 @@ protected:
bool visit(UiPragma *ast) override bool visit(UiPragma *ast) override
{ {
out("pragma ", ast->pragmaToken); out("pragma ", ast->pragmaToken);
accept(ast->pragmaType);
return false; return false;
} }
@@ -666,20 +665,16 @@ protected:
bool visit(NumericLiteral *ast) override { out(ast->literalToken); return true; } bool visit(NumericLiteral *ast) override { out(ast->literalToken); return true; }
bool visit(RegExpLiteral *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); out(ast->lbracketToken);
if (ast->elements) if (ast->elements)
accept(ast->elements); accept(ast->elements);
if (ast->elements && ast->elision)
out(", ", ast->commaToken);
if (ast->elision)
accept(ast->elision);
out(ast->rbracketToken); out(ast->rbracketToken);
return false; return false;
} }
bool visit(ObjectLiteral *ast) override bool visit(ObjectPattern *ast) override
{ {
out(ast->lbraceToken); out(ast->lbraceToken);
lnAcceptIndented(ast->properties); lnAcceptIndented(ast->properties);
@@ -688,55 +683,57 @@ protected:
return false; 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) if (it->elision)
accept(it->elision); accept(it->elision);
if (it->elision && it->expression) if (it->elision && it->element)
out(", "); out(", ");
if (it->expression) if (it->element)
accept(it->expression); accept(it->element);
if (it->next) if (it->next)
out(", ", ast->commaToken); out(", ");
} }
return false; return false;
} }
bool visit(PropertyAssignmentList *ast) override bool visit(PatternPropertyList *ast) override
{ {
for (PropertyAssignmentList *it = ast; it; it = it->next) { for (PatternPropertyList *it = ast; it; it = it->next) {
PropertyNameAndValue *assignment = AST::cast<PropertyNameAndValue *>(it->assignment); PatternProperty *assignment = AST::cast<PatternProperty *>(it->property);
if (assignment) { if (assignment) {
out("\""); out("\"");
accept(assignment->name); accept(assignment->name);
out("\""); out("\"");
out(": ", assignment->colonToken); out(": ", assignment->colonToken);
accept(assignment->value); accept(assignment->initializer);
if (it->next) { if (it->next) {
out(",", ast->commaToken); // always invalid? out(","); // always invalid?
newLine(); newLine();
} }
continue; continue;
} }
PropertyGetterSetter *getterSetter = AST::cast<PropertyGetterSetter *>(it->assignment); PatternPropertyList *getterSetter = AST::cast<PatternPropertyList *>(it->next);
if (getterSetter) { if (getterSetter->property) {
switch (getterSetter->type) { switch (getterSetter->property->type) {
case PropertyGetterSetter::Getter: case PatternElement::Getter:
out("get"); out("get");
break; break;
case PropertyGetterSetter::Setter: case PatternElement::Setter:
out("set"); out("set");
break; break;
default:
break;
} }
accept(getterSetter->name); accept(getterSetter->property->name);
out("(", getterSetter->lparenToken); out("(");
accept(getterSetter->formals); //accept(getterSetter->formals); // TODO
out("(", getterSetter->rparenToken); out(")");
out(" {", getterSetter->lbraceToken); out(" {");
accept(getterSetter->functionBody); //accept(getterSetter->functionBody); // TODO
out(" }", getterSetter->rbraceToken); out(" }");
} }
} }
return false; return false;
@@ -922,12 +919,15 @@ protected:
return false; return false;
} }
bool visit(VariableDeclaration *ast) override bool visit(PatternElement *ast) override
{ {
if (!ast->isVariableDeclaration())
return false;
out(ast->identifierToken); out(ast->identifierToken);
if (ast->expression) { if (ast->initializer) {
out(" = "); out(" = ");
accept(ast->expression); accept(ast->initializer);
} }
return false; return false;
} }
@@ -996,45 +996,13 @@ protected:
return false; 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 bool visit(ForEachStatement *ast) override
{ {
out(ast->forToken); out(ast->forToken);
out(" "); out(" ");
out(ast->lparenToken); out(ast->lparenToken);
accept(ast->initialiser); accept(ast->lhs);
out(" in ", ast->inToken); out(" in ");
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->expression); accept(ast->expression);
out(ast->rparenToken); out(ast->rparenToken);
acceptBlockOrIndented(ast->statement); acceptBlockOrIndented(ast->statement);
@@ -1245,12 +1213,6 @@ protected:
return false; return false;
} }
bool visit(UiQualifiedPragmaId *ast) override
{
out(ast->identifierToken);
return false;
}
bool visit(Elision *ast) override bool visit(Elision *ast) override
{ {
for (Elision *it = ast; it; it = it->next) { for (Elision *it = ast; it; it = it->next) {
@@ -1288,16 +1250,6 @@ protected:
return false; 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 bool visit(VariableDeclarationList *ast) override
{ {
for (VariableDeclarationList *it = ast; it; it = it->next) { for (VariableDeclarationList *it = ast; it; it = it->next) {
@@ -1321,9 +1273,7 @@ protected:
bool visit(FormalParameterList *ast) override bool visit(FormalParameterList *ast) override
{ {
for (FormalParameterList *it = ast; it; it = it->next) { for (FormalParameterList *it = ast; it; it = it->next) {
if (it->commaToken.isValid()) out(it->element->bindingIdentifier.toString()); // TODO
out(", ", it->commaToken);
out(it->identifierToken);
} }
return false; return false;
} }

View File

@@ -250,12 +250,12 @@ QVariant SimpleAbstractStreamReader::parsePropertyExpression(AST::ExpressionNode
{ {
Q_ASSERT(expressionNode); Q_ASSERT(expressionNode);
AST::ArrayLiteral *arrayLiteral = AST::cast<AST::ArrayLiteral *>(expressionNode); AST::ArrayPattern *arrayLiteral = AST::cast<AST::ArrayPattern *>(expressionNode);
if (arrayLiteral) { if (arrayLiteral) {
QList<QVariant> variantList; QList<QVariant> variantList;
for (AST::ElementList *it = arrayLiteral->elements; it; it = it->next) for (AST::PatternElementList *it = arrayLiteral->elements; it; it = it->next)
variantList << parsePropertyExpression(it->expression); variantList << parsePropertyExpression(it->element->initializer);
return variantList; return variantList;
} }

View File

@@ -189,13 +189,14 @@ void TypeDescriptionReader::readDependencies(UiScriptBinding *ast)
addError(ast->statement->firstSourceLocation(), tr("Expected dependency definitions")); addError(ast->statement->firstSourceLocation(), tr("Expected dependency definitions"));
return; return;
} }
ArrayLiteral *exp = AST::cast<ArrayLiteral *>(stmt->expression); ArrayPattern *exp = AST::cast<ArrayPattern *>(stmt->expression);
if (!exp) { if (!exp) {
addError(stmt->expression->firstSourceLocation(), tr("Expected dependency definitions")); addError(stmt->expression->firstSourceLocation(), tr("Expected dependency definitions"));
return; return;
} }
for (ElementList *l = exp->elements; l; l = l->next) { for (PatternElementList *l = exp->elements; l; l = l->next) {
StringLiteral *str = AST::cast<StringLiteral *>(l->expression); //StringLiteral *str = AST::cast<StringLiteral *>(l->element->initializer);
StringLiteral *str = AST::cast<StringLiteral *>(l->element->initializer);
*_dependencies << str->value.toString(); *_dependencies << str->value.toString();
} }
} }
@@ -231,7 +232,7 @@ void TypeDescriptionReader::readComponent(UiObjectDefinition *ast)
} else if (name == QLatin1String("exports")) { } else if (name == QLatin1String("exports")) {
readExports(script, fmo); readExports(script, fmo);
} else if (name == QLatin1String("exportMetaObjectRevisions")) { } else if (name == QLatin1String("exportMetaObjectRevisions")) {
readMetaObjectRevisions(script, fmo); //readMetaObjectRevisions(script, fmo);
} else if (name == QLatin1String("attachedType")) { } else if (name == QLatin1String("attachedType")) {
fmo->setAttachedTypeName(readStringBinding(script)); fmo->setAttachedTypeName(readStringBinding(script));
} else if (name == QLatin1String("isSingleton")) { } else if (name == QLatin1String("isSingleton")) {
@@ -562,14 +563,14 @@ void TypeDescriptionReader::readExports(UiScriptBinding *ast, FakeMetaObject::Pt
return; return;
} }
ArrayLiteral *arrayLit = AST::cast<ArrayLiteral *>(expStmt->expression); ArrayPattern *arrayLit = AST::cast<ArrayPattern *>(expStmt->expression);
if (!arrayLit) { if (!arrayLit) {
addError(expStmt->firstSourceLocation(), tr("Expected array of strings after colon.")); addError(expStmt->firstSourceLocation(), tr("Expected array of strings after colon."));
return; return;
} }
for (ElementList *it = arrayLit->elements; it; it = it->next) { for (PatternElementList *it = arrayLit->elements; it; it = it->next) {
StringLiteral *stringLit = AST::cast<StringLiteral *>(it->expression); StringLiteral *stringLit = AST::cast<StringLiteral *>(it->element->initializer);
if (!stringLit) { if (!stringLit) {
addError(arrayLit->firstSourceLocation(), tr("Expected array literal with only string literal members.")); addError(arrayLit->firstSourceLocation(), tr("Expected array literal with only string literal members."));
return; return;
@@ -608,7 +609,7 @@ void TypeDescriptionReader::readMetaObjectRevisions(UiScriptBinding *ast, FakeMe
return; return;
} }
ArrayLiteral *arrayLit = AST::cast<ArrayLiteral *>(expStmt->expression); ArrayPattern *arrayLit = AST::cast<ArrayPattern *>(expStmt->expression);
if (!arrayLit) { if (!arrayLit) {
addError(expStmt->firstSourceLocation(), tr("Expected array of numbers after colon.")); addError(expStmt->firstSourceLocation(), tr("Expected array of numbers after colon."));
return; return;
@@ -616,8 +617,8 @@ void TypeDescriptionReader::readMetaObjectRevisions(UiScriptBinding *ast, FakeMe
int exportIndex = 0; int exportIndex = 0;
const int exportCount = fmo->exports().size(); const int exportCount = fmo->exports().size();
for (ElementList *it = arrayLit->elements; it; it = it->next, ++exportIndex) { for (PatternElementList *it = arrayLit->elements; it; it = it->next, ++exportIndex) {
NumericLiteral *numberLit = cast<NumericLiteral *>(it->expression); NumericLiteral *numberLit = cast<NumericLiteral *>(it->element->initializer);
if (!numberLit) { if (!numberLit) {
addError(arrayLit->firstSourceLocation(), tr("Expected array literal with only number literal members.")); addError(arrayLit->firstSourceLocation(), tr("Expected array literal with only number literal members."));
return; return;
@@ -654,18 +655,18 @@ void TypeDescriptionReader::readEnumValues(AST::UiScriptBinding *ast, LanguageUt
return; return;
} }
ObjectLiteral *objectLit = AST::cast<ObjectLiteral *>(expStmt->expression); ObjectPattern *objectLit = AST::cast<ObjectPattern *>(expStmt->expression);
if (!objectLit) { if (!objectLit) {
addError(expStmt->firstSourceLocation(), tr("Expected object literal after colon.")); addError(expStmt->firstSourceLocation(), tr("Expected object literal after colon."));
return; return;
} }
for (PropertyAssignmentList *it = objectLit->properties; it; it = it->next) { for (PatternPropertyList *it = objectLit->properties; it; it = it->next) {
PropertyNameAndValue *assignement = AST::cast<PropertyNameAndValue *>(it->assignment); PatternProperty *assignement = AST::cast<PatternProperty *>(it->property);
if (assignement) { if (assignement) {
StringLiteralPropertyName *propName = AST::cast<StringLiteralPropertyName *>(assignement->name); StringLiteralPropertyName *propName = AST::cast<StringLiteralPropertyName *>(assignement->name);
NumericLiteral *value = AST::cast<NumericLiteral *>(assignement->value); NumericLiteral *value = AST::cast<NumericLiteral *>(assignement->initializer);
UnaryMinusExpression *minus = AST::cast<UnaryMinusExpression *>(assignement->value); UnaryMinusExpression *minus = AST::cast<UnaryMinusExpression *>(assignement->initializer);
if (minus) if (minus)
value = AST::cast<NumericLiteral *>(minus->expression); value = AST::cast<NumericLiteral *>(minus->expression);
if (!propName || !value) { if (!propName || !value) {
@@ -679,7 +680,7 @@ void TypeDescriptionReader::readEnumValues(AST::UiScriptBinding *ast, LanguageUt
fme->addKey(propName->id.toString(), v); fme->addKey(propName->id.toString(), v);
continue; continue;
} }
PropertyGetterSetter *getterSetter = AST::cast<PropertyGetterSetter *>(it->assignment); PatternPropertyList *getterSetter = AST::cast<PatternPropertyList *>(it->next);
if (getterSetter) if (getterSetter)
addError(objectLit->firstSourceLocation(), tr("Enum should not contain getter and setters, but only 'string: number' elements.")); addError(objectLit->firstSourceLocation(), tr("Enum should not contain getter and setters, but only 'string: number' elements."));
} }

View File

@@ -35,7 +35,8 @@ bool InteractiveInterpreter::canEvaluate()
int yytos = -1; int yytos = -1;
setCode(m_code, 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 { do {
if (++yytos == m_stateStack.size()) if (++yytos == m_stateStack.size())

View File

@@ -160,15 +160,12 @@ public:
bool visit(VariableStatement *ast) override { test(ast); return true; } bool visit(VariableStatement *ast) override { test(ast); return true; }
bool visit(VariableDeclarationList *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(ExpressionStatement *ast) override { test(ast); return true; }
bool visit(IfStatement *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(DoWhileStatement *ast) override { test(ast); return true; }
bool visit(WhileStatement *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(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(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(ContinueStatement *ast) override { test(ast); return true; }
bool visit(BreakStatement *ast) override { test(ast); return true; } bool visit(BreakStatement *ast) override { test(ast); return true; }
bool visit(ReturnStatement *ast) override { test(ast); return true; } bool visit(ReturnStatement *ast) override { test(ast); return true; }

View File

@@ -84,7 +84,7 @@ protected:
bool visit(AST::UiPublicMember *node) override 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)); const ObjectValue * objectValue = m_context->lookupType(m_document.data(), QStringList(m_typeName));
if (objectValue == m_typeValue) if (objectValue == m_typeValue)
m_implemenations.append(node->typeToken); m_implemenations.append(node->typeToken);
@@ -187,9 +187,10 @@ protected:
return false; 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; return false;
} }

View File

@@ -81,6 +81,7 @@ void AddPropertyVisitor::addInMembers(QmlJS::AST::UiObjectInitializer *initializ
QmlJS::AST::UiObjectMemberList *insertAfter = searchMemberToInsertAfter(initializer->members, m_name, m_propertyOrder); QmlJS::AST::UiObjectMemberList *insertAfter = searchMemberToInsertAfter(initializer->members, m_name, m_propertyOrder);
QmlJS::AST::SourceLocation endOfPreviousMember; QmlJS::AST::SourceLocation endOfPreviousMember;
QmlJS::AST::SourceLocation startOfNextMember; QmlJS::AST::SourceLocation startOfNextMember;
bool previousMemberSemicolon = false;
unsigned depth; unsigned depth;
if (insertAfter == nullptr || insertAfter->member == nullptr) { if (insertAfter == nullptr || insertAfter->member == nullptr) {
@@ -96,6 +97,16 @@ void AddPropertyVisitor::addInMembers(QmlJS::AST::UiObjectInitializer *initializ
} else { } else {
endOfPreviousMember = insertAfter->member->lastSourceLocation(); 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) if (insertAfter->next && insertAfter->next->member)
startOfNextMember = insertAfter->next->member->firstSourceLocation(); startOfNextMember = insertAfter->next->member->firstSourceLocation();
else else
@@ -113,7 +124,7 @@ void AddPropertyVisitor::addInMembers(QmlJS::AST::UiObjectInitializer *initializ
needsTrailingSemicolon = m_propertyType == QmlRefactoring::ScriptBinding; needsTrailingSemicolon = m_propertyType == QmlRefactoring::ScriptBinding;
} }
} else { // we're inserting after a member, not after the lbrace } 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: if (insertAfter->next && insertAfter->next->member) { // and the after us there is a member, not an rbrace, so:
needsTrailingSemicolon = m_propertyType == QmlRefactoring::ScriptBinding; needsTrailingSemicolon = m_propertyType == QmlRefactoring::ScriptBinding;
} }

View File

@@ -85,8 +85,8 @@ static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPt
{ {
TypeName type = "unknown"; TypeName type = "unknown";
if (ref->ast()->isValid()) { if (ref->ast()->defaultToken.isValid()) {
type = ref->ast()->memberTypeName().toUtf8(); type = ref->ast()->memberType->name.toUtf8();
if (type == "alias") { if (type == "alias") {
const Value *value = context->lookupReference(ref); const Value *value = context->lookupReference(ref);

View File

@@ -1178,9 +1178,6 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
if (property->type == AST::UiPublicMember::Signal) if (property->type == AST::UiPublicMember::Signal)
continue; // QML designer doesn't support this yet. continue; // QML designer doesn't support this yet.
if (property->name.isEmpty() || !property->isValid())
continue; // better safe than sorry.
const QStringRef astName = property->name; const QStringRef astName = property->name;
QString astValue; QString astValue;
if (property->statement) if (property->statement)
@@ -1193,7 +1190,7 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
astValue = astValue.left(astValue.length() - 1); astValue = astValue.left(astValue.length() - 1);
astValue = astValue.trimmed(); astValue = astValue.trimmed();
const TypeName &astType = property->memberTypeName().toUtf8(); const TypeName &astType = property->memberType->name.toUtf8();
AbstractProperty modelProperty = modelNode.property(astName.toUtf8()); AbstractProperty modelProperty = modelNode.property(astName.toUtf8());
if (property->binding) { if (property->binding) {
@@ -1250,12 +1247,12 @@ static QVariant parsePropertyExpression(AST::ExpressionNode *expressionNode)
{ {
Q_ASSERT(expressionNode); Q_ASSERT(expressionNode);
auto arrayLiteral = AST::cast<AST::ArrayLiteral *>(expressionNode); auto arrayLiteral = AST::cast<AST::ArrayPattern *>(expressionNode);
if (arrayLiteral) { if (arrayLiteral) {
QList<QVariant> variantList; QList<QVariant> variantList;
for (AST::ElementList *it = arrayLiteral->elements; it; it = it->next) for (AST::PatternElementList *it = arrayLiteral->elements; it; it = it->next)
variantList << parsePropertyExpression(it->expression); variantList << parsePropertyExpression(it->element->initializer);
return variantList; return variantList;
} }

View File

@@ -295,8 +295,8 @@ protected:
decl.text += QLatin1Char('('); decl.text += QLatin1Char('(');
for (FormalParameterList *it = ast->formals; it; it = it->next) { for (FormalParameterList *it = ast->formals; it; it = it->next) {
if (!it->name.isEmpty()) if (!it->element->bindingIdentifier.isEmpty())
decl.text += it->name; decl.text += it->element->bindingIdentifier;
if (it->next) if (it->next)
decl.text += QLatin1String(", "); decl.text += QLatin1String(", ");
@@ -309,14 +309,14 @@ protected:
return false; 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; return false;
Declaration decl; Declaration decl;
decl.text.fill(QLatin1Char(' '), _depth); decl.text.fill(QLatin1Char(' '), _depth);
decl.text += ast->name; decl.text += ast->bindingIdentifier;
const SourceLocation first = ast->identifierToken; const SourceLocation first = ast->identifierToken;
decl.startLine = first.startLine; decl.startLine = first.startLine;
@@ -343,8 +343,8 @@ protected:
decl.text += QLatin1Char('('); decl.text += QLatin1Char('(');
for (FormalParameterList *it = funcExpr->formals; it; it = it->next) { for (FormalParameterList *it = funcExpr->formals; it; it = it->next) {
if (!it->name.isEmpty()) if (!it->element->bindingIdentifier.isEmpty())
decl.text += it->name; decl.text += it->element->bindingIdentifier;
if (it->next) if (it->next)
decl.text += QLatin1String(", "); decl.text += QLatin1String(", ");

View File

@@ -227,9 +227,9 @@ protected:
return false; 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()) if (checkLookup())
_usages.append(node->identifierToken); _usages.append(node->identifierToken);
} }
@@ -322,7 +322,7 @@ protected:
bool visit(AST::UiPublicMember *node) override bool visit(AST::UiPublicMember *node) override
{ {
if (node->memberTypeName() == _name){ if (node->memberType->name == _name){
const ObjectValue * tVal = _context->lookupType(_doc.data(), QStringList(_name)); const ObjectValue * tVal = _context->lookupType(_doc.data(), QStringList(_name));
if (tVal == _typeValue) if (tVal == _typeValue)
_usages.append(node->typeToken); _usages.append(node->typeToken);
@@ -406,9 +406,10 @@ protected:
return false; 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; return false;
} }
@@ -583,8 +584,8 @@ protected:
bool visit(UiPublicMember *node) override bool visit(UiPublicMember *node) override
{ {
if (containsOffset(node->typeToken)){ if (containsOffset(node->typeToken)){
if (node->isValid()) { if (node->defaultToken.isValid()) {
_name = node->memberTypeName().toString(); _name = node->memberType->name.toString();
_targetValue = _scopeChain->context()->lookupType(_doc.data(), QStringList(_name)); _targetValue = _scopeChain->context()->lookupType(_doc.data(), QStringList(_name));
_scope = 0; _scope = 0;
_typeKind = TypeKind; _typeKind = TypeKind;
@@ -612,10 +613,10 @@ protected:
return true; return true;
} }
bool visit(VariableDeclaration *node) override bool visit(PatternElement *node) override
{ {
if (containsOffset(node->identifierToken)) { if (node->isVariableDeclaration() && containsOffset(node->identifierToken)) {
_name = node->name.toString(); _name = node->bindingIdentifier.toString();
return false; return false;
} }
return true; return true;

View File

@@ -323,8 +323,8 @@ protected:
bool visit(UiPublicMember *ast) bool visit(UiPublicMember *ast)
{ {
if (ast->typeToken.isValid() && ast->isValid()) { if (ast->typeToken.isValid()) { // TODO: ast->isValid() ?
if (m_scopeChain.context()->lookupType(m_scopeChain.document().data(), QStringList(ast->memberTypeName().toString()))) if (m_scopeChain.context()->lookupType(m_scopeChain.document().data(), QStringList(ast->memberType->name.toString())))
addUse(ast->typeToken, SemanticHighlighter::QmlTypeType); addUse(ast->typeToken, SemanticHighlighter::QmlTypeType);
} }
if (ast->identifierToken.isValid()) if (ast->identifierToken.isValid())
@@ -350,9 +350,10 @@ protected:
return visit(static_cast<FunctionExpression *>(ast)); 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; return true;
} }

View File

@@ -263,14 +263,14 @@ private:
bool visit(AST::BinaryExpression *binExp) bool visit(AST::BinaryExpression *binExp)
{ {
AST::IdentifierExpression *lhsIdent = AST::cast<AST::IdentifierExpression *>(binExp->left); 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")) if (lhsIdent && rhsObjLit && (lhsIdent->name == QLatin1String("testcase"))
&& (binExp->op == QSOperator::Assign)) { && (binExp->op == QSOperator::Assign)) {
QModelIndex index = m_model->enterTestCase(rhsObjLit); QModelIndex index = m_model->enterTestCase(rhsObjLit);
m_nodeToIndex.insert(rhsObjLit, index); m_nodeToIndex.insert(rhsObjLit, index);
if (AST::PropertyAssignmentList *properties = rhsObjLit->properties) if (AST::PatternPropertyList *properties = rhsObjLit->properties)
visitProperties(properties); visitProperties(properties);
m_model->leaveTestCase(); m_model->leaveTestCase();
@@ -290,13 +290,13 @@ private:
return true; return true;
} }
void visitProperties(AST::PropertyAssignmentList *properties) void visitProperties(AST::PatternPropertyList *properties)
{ {
while (properties) { while (properties) {
QModelIndex index = m_model->enterTestCaseProperties(properties); QModelIndex index = m_model->enterTestCaseProperties(properties);
m_nodeToIndex.insert(properties, index); m_nodeToIndex.insert(properties, index);
if (AST::PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(properties->assignment)) if (AST::PatternProperty *assignment = AST::cast<AST::PatternProperty *>(properties->property))
if (AST::ObjectLiteral *objLiteral = AST::cast<AST::ObjectLiteral *>(assignment->value)) if (AST::ObjectPattern *objLiteral = AST::cast<AST::ObjectPattern *>(assignment->initializer))
visitProperties(objLiteral->properties); visitProperties(objLiteral->properties);
m_model->leaveTestCaseProperties(); m_model->leaveTestCaseProperties();
@@ -592,7 +592,7 @@ static QString functionDisplayName(QStringRef name, AST::FormalParameterList *fo
if (!name.isEmpty()) if (!name.isEmpty())
display += name.toString() + QLatin1Char('('); display += name.toString() + QLatin1Char('(');
for (AST::FormalParameterList *param = formals; param; param = param->next) { for (AST::FormalParameterList *param = formals; param; param = param->next) {
display += param->name.toString(); display += param->element->bindingIdentifier.toString();
if (param->next) if (param->next)
display += QLatin1String(", "); display += QLatin1String(", ");
} }
@@ -650,7 +650,7 @@ void QmlOutlineModel::leaveFieldMemberExpression()
leaveNode(); leaveNode();
} }
QModelIndex QmlOutlineModel::enterTestCase(AST::ObjectLiteral *objectLiteral) QModelIndex QmlOutlineModel::enterTestCase(AST::ObjectPattern *objectLiteral)
{ {
QMap<int, QVariant> objectData; QMap<int, QVariant> objectData;
@@ -667,18 +667,18 @@ void QmlOutlineModel::leaveTestCase()
leaveNode(); leaveNode();
} }
QModelIndex QmlOutlineModel::enterTestCaseProperties(AST::PropertyAssignmentList *propertyAssignmentList) QModelIndex QmlOutlineModel::enterTestCaseProperties(AST::PatternPropertyList *propertyAssignmentList)
{ {
QMap<int, QVariant> objectData; QMap<int, QVariant> objectData;
if (AST::PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>( if (AST::PatternProperty *assignment = AST::cast<AST::PatternProperty *>(
propertyAssignmentList->assignment)) { propertyAssignmentList->property)) {
if (AST::IdentifierPropertyName *propertyName = AST::cast<AST::IdentifierPropertyName *>(assignment->name)) { if (AST::IdentifierPropertyName *propertyName = AST::cast<AST::IdentifierPropertyName *>(assignment->name)) {
objectData.insert(Qt::DisplayRole, propertyName->id.toString()); objectData.insert(Qt::DisplayRole, propertyName->id.toString());
objectData.insert(ItemTypeRole, ElementBindingType); objectData.insert(ItemTypeRole, ElementBindingType);
QmlOutlineItem *item; 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()); 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()); item = enterNode(objectData, assignment, 0, Icons::objectDefinitionIcon());
else else
item = enterNode(objectData, assignment, 0, Icons::scriptBindingIcon()); item = enterNode(objectData, assignment, 0, Icons::scriptBindingIcon());
@@ -686,8 +686,8 @@ QModelIndex QmlOutlineModel::enterTestCaseProperties(AST::PropertyAssignmentList
return item->index(); return item->index();
} }
} }
if (AST::PropertyGetterSetter *getterSetter = AST::cast<AST::PropertyGetterSetter *>( if (AST::PatternProperty *getterSetter = AST::cast<AST::PatternProperty *>(
propertyAssignmentList->assignment)) { propertyAssignmentList->property)) {
if (AST::IdentifierPropertyName *propertyName = AST::cast<AST::IdentifierPropertyName *>(getterSetter->name)) { if (AST::IdentifierPropertyName *propertyName = AST::cast<AST::IdentifierPropertyName *>(getterSetter->name)) {
objectData.insert(Qt::DisplayRole, propertyName->id.toString()); objectData.insert(Qt::DisplayRole, propertyName->id.toString());
objectData.insert(ItemTypeRole, ElementBindingType); objectData.insert(ItemTypeRole, ElementBindingType);
@@ -728,7 +728,7 @@ AST::SourceLocation QmlOutlineModel::sourceLocation(const QModelIndex &index) co
location = getLocation(member); location = getLocation(member);
else if (AST::ExpressionNode *expression = node->expressionCast()) else if (AST::ExpressionNode *expression = node->expressionCast())
location = getLocation(expression); 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); location = getLocation(propertyAssignmentList);
} }
return location; return location;
@@ -999,26 +999,16 @@ AST::SourceLocation QmlOutlineModel::getLocation(AST::ExpressionNode *exprNode)
return location; return location;
} }
AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyAssignmentList *propertyNode) { AST::SourceLocation QmlOutlineModel::getLocation(AST::PatternPropertyList *propertyNode) {
if (AST::PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(propertyNode->assignment)) if (AST::PatternProperty *assignment = AST::cast<AST::PatternProperty *>(propertyNode->property))
return getLocation(assignment); return getLocation(assignment);
if (AST::PropertyGetterSetter *getterSetter = AST::cast<AST::PropertyGetterSetter *>(propertyNode->assignment)) return propertyNode->firstSourceLocation(); // should never happen
return getLocation(getterSetter);
return propertyNode->commaToken; // should never happen
} }
AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyNameAndValue *propertyNode) { AST::SourceLocation QmlOutlineModel::getLocation(AST::PatternProperty *propertyNode) {
AST::SourceLocation location; AST::SourceLocation location;
location = propertyNode->name->propertyNameToken; location = propertyNode->name->propertyNameToken;
location.length = propertyNode->value->lastSourceLocation().end() - location.offset; location.length = propertyNode->initializer->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;
return location; return location;
} }

View File

@@ -120,10 +120,10 @@ private:
QmlJS::AST::FunctionExpression *functionExpression); QmlJS::AST::FunctionExpression *functionExpression);
void leaveFieldMemberExpression(); void leaveFieldMemberExpression();
QModelIndex enterTestCase(QmlJS::AST::ObjectLiteral *objectLiteral); QModelIndex enterTestCase(QmlJS::AST::ObjectPattern *objectLiteral);
void leaveTestCase(); void leaveTestCase();
QModelIndex enterTestCaseProperties(QmlJS::AST::PropertyAssignmentList *propertyAssignmentList); QModelIndex enterTestCaseProperties(QmlJS::AST::PatternPropertyList *propertyAssignmentList);
void leaveTestCaseProperties(); void leaveTestCaseProperties();
private: private:
@@ -140,9 +140,8 @@ private:
static QString asString(QmlJS::AST::UiQualifiedId *id); static QString asString(QmlJS::AST::UiQualifiedId *id);
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::UiObjectMember *objMember); 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::ExpressionNode *exprNode);
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyAssignmentList *propertyNode); static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PatternProperty *propertyNode);
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyNameAndValue *propertyNode); static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PatternPropertyList *propertyNode);
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyGetterSetter *propertyNode);
QIcon getIcon(QmlJS::AST::UiQualifiedId *objDef); QIcon getIcon(QmlJS::AST::UiQualifiedId *objDef);
QString getAnnotation(QmlJS::AST::UiObjectInitializer *objInitializer); QString getAnnotation(QmlJS::AST::UiObjectInitializer *objInitializer);

View File

@@ -134,8 +134,8 @@ protected:
for (FormalParameterList *it = ast->formals; it; it = it->next) { for (FormalParameterList *it = ast->formals; it; it = it->next) {
if (it != ast->formals) if (it != ast->formals)
entry.displayName += QLatin1String(", "); entry.displayName += QLatin1String(", ");
if (!it->name.isEmpty()) if (!it->element->bindingIdentifier.isEmpty())
entry.displayName += it->name.toString(); entry.displayName += it->element->bindingIdentifier.toString();
} }
entry.displayName += QLatin1Char(')'); entry.displayName += QLatin1Char(')');
entry.symbolName = entry.displayName; entry.symbolName = entry.displayName;
@@ -214,8 +214,8 @@ protected:
for (FormalParameterList *it = funcExpr->formals; it; it = it->next) { for (FormalParameterList *it = funcExpr->formals; it; it = it->next) {
if (it != funcExpr->formals) if (it != funcExpr->formals)
entry.displayName += QLatin1String(", "); entry.displayName += QLatin1String(", ");
if (!it->name.isEmpty()) if (!it->element->bindingIdentifier.isEmpty())
entry.displayName += it->name.toString(); entry.displayName += it->element->bindingIdentifier.toString();
} }
entry.displayName += QLatin1Char(')'); entry.displayName += QLatin1Char(')');
entry.symbolName = entry.displayName; entry.symbolName = entry.displayName;