forked from qt-creator/qt-creator
qmljs: use new qml parser
adds support for singleton and getter/setter properties Change-Id: Ia6691ac7799a46885db0df44617617dcc3c13189 Reviewed-by: Kai Koehne <kai.koehne@digia.com> Reviewed-by: Thomas Hartmann <Thomas.Hartmann@digia.com>
This commit is contained in:
@@ -100,8 +100,9 @@ bool JsonCheck::visit(ObjectLiteral *ast)
|
||||
return false;
|
||||
|
||||
QSet<QString> propertiesFound;
|
||||
for (PropertyNameAndValueList *it = ast->properties; it; it = it->next) {
|
||||
StringLiteralPropertyName *literalName = cast<StringLiteralPropertyName *>(it->name);
|
||||
for (PropertyAssignmentList *it = ast->properties; it; it = it->next) {
|
||||
PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(it->assignment);
|
||||
StringLiteralPropertyName *literalName = cast<StringLiteralPropertyName *>(assignment->name);
|
||||
if (literalName) {
|
||||
const QString &propertyName = literalName->id.toString();
|
||||
if (m_schema->hasPropertySchema(propertyName)) {
|
||||
@@ -109,7 +110,7 @@ bool JsonCheck::visit(ObjectLiteral *ast)
|
||||
propertiesFound.insert(propertyName);
|
||||
// Sec. 5.2: "... each property definition's value MUST be a schema..."
|
||||
m_schema->enterNestedPropertySchema(propertyName);
|
||||
processSchema(it->value);
|
||||
processSchema(assignment->value);
|
||||
m_schema->leaveNestedSchema();
|
||||
} else {
|
||||
analysis()->m_messages.append(Message(ErrInvalidPropertyName,
|
||||
@@ -119,7 +120,7 @@ bool JsonCheck::visit(ObjectLiteral *ast)
|
||||
}
|
||||
} else {
|
||||
analysis()->m_messages.append(Message(ErrStringValueExpected,
|
||||
it->name->firstSourceLocation(),
|
||||
assignment->name->firstSourceLocation(),
|
||||
QString(), QString(),
|
||||
false));
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
me=$(dirname $0)
|
||||
|
||||
for i in $QTDIR/src/qml/qml/parser/*.{g,h,cpp,pri}; do
|
||||
for i in $QTDIR/src/qml/parser/*.{g,h,cpp,pri}; do
|
||||
sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qqmljs/qmljs/)
|
||||
done
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ bool QmlDirParser::parse(const QString &source)
|
||||
if (ch->isNull())
|
||||
break;
|
||||
|
||||
QString sections[3];
|
||||
QString sections[4];
|
||||
int sectionCount = 0;
|
||||
|
||||
do {
|
||||
@@ -114,7 +114,7 @@ bool QmlDirParser::parse(const QString &source)
|
||||
}
|
||||
const QChar *start = ch;
|
||||
scanWord(ch);
|
||||
if (sectionCount < 3) {
|
||||
if (sectionCount < 4) {
|
||||
sections[sectionCount++] = source.mid(start-source.constData(), ch-start);
|
||||
} else {
|
||||
reportError(lineNumber, start-lineStart, QLatin1String("unexpected token"));
|
||||
@@ -148,14 +148,14 @@ bool QmlDirParser::parse(const QString &source)
|
||||
}
|
||||
if (!firstLine) {
|
||||
reportError(lineNumber, 0,
|
||||
QString::fromUtf8("module identifier directive must be the first command in a qmldir file"));
|
||||
QString::fromUtf8("module identifier directive must be the first directive in a qmldir file"));
|
||||
continue;
|
||||
}
|
||||
|
||||
_typeNamespace = sections[1];
|
||||
|
||||
} else if (sections[0] == QLatin1String("plugin")) {
|
||||
if (sectionCount < 2) {
|
||||
if (sectionCount < 2 || sectionCount > 3) {
|
||||
reportError(lineNumber, 0,
|
||||
QString::fromUtf8("plugin directive requires one or two arguments, but %1 were provided").arg(sectionCount - 1));
|
||||
|
||||
@@ -175,6 +175,43 @@ bool QmlDirParser::parse(const QString &source)
|
||||
Component entry(sections[1], sections[2], -1, -1);
|
||||
entry.internal = true;
|
||||
_components.insertMulti(entry.typeName, entry);
|
||||
} else if (sections[0] == QLatin1String("singleton")) {
|
||||
if (sectionCount < 3 || sectionCount > 4) {
|
||||
reportError(lineNumber, 0,
|
||||
QString::fromUtf8("singleton types require 2 or 3 arguments, but %1 were provided").arg(sectionCount - 1));
|
||||
continue;
|
||||
} else if (sectionCount == 3) {
|
||||
// handle qmldir directory listing case where singleton is defined in the following pattern:
|
||||
// singleton TestSingletonType TestSingletonType.qml
|
||||
Component entry(sections[1], sections[2], -1, -1);
|
||||
entry.singleton = true;
|
||||
_components.insertMulti(entry.typeName, entry);
|
||||
} else {
|
||||
// handle qmldir module listing case where singleton is defined in the following pattern:
|
||||
// singleton TestSingletonType 2.0 TestSingletonType20.qml
|
||||
const QString &version = sections[2];
|
||||
const int dotIndex = version.indexOf(QLatin1Char('.'));
|
||||
|
||||
if (dotIndex == -1) {
|
||||
reportError(lineNumber, 0, QLatin1String("expected '.'"));
|
||||
} else if (version.indexOf(QLatin1Char('.'), dotIndex + 1) != -1) {
|
||||
reportError(lineNumber, 0, QLatin1String("unexpected '.'"));
|
||||
} else {
|
||||
bool validVersionNumber = false;
|
||||
const int majorVersion = parseInt(QStringRef(&version, 0, dotIndex), &validVersionNumber);
|
||||
|
||||
if (validVersionNumber) {
|
||||
const int minorVersion = parseInt(QStringRef(&version, dotIndex+1, version.length()-dotIndex-1), &validVersionNumber);
|
||||
|
||||
if (validVersionNumber) {
|
||||
const QString &fileName = sections[3];
|
||||
Component entry(sections[1], fileName, majorVersion, minorVersion);
|
||||
entry.singleton = true;
|
||||
_components.insertMulti(entry.typeName, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (sections[0] == QLatin1String("typeinfo")) {
|
||||
if (sectionCount != 2) {
|
||||
reportError(lineNumber, 0,
|
||||
|
||||
@@ -83,17 +83,18 @@ public:
|
||||
struct Component
|
||||
{
|
||||
Component()
|
||||
: majorVersion(0), minorVersion(0), internal(false) {}
|
||||
: majorVersion(0), minorVersion(0), internal(false), singleton(false) {}
|
||||
|
||||
Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
|
||||
: typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
|
||||
internal(false) {}
|
||||
internal(false), singleton(false) {}
|
||||
|
||||
QString typeName;
|
||||
QString fileName;
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
bool internal;
|
||||
bool singleton;
|
||||
};
|
||||
|
||||
struct Script
|
||||
|
||||
@@ -44,13 +44,13 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
QmlError includes a textual description of the error, as well
|
||||
as location information (the file, line, and column). The toString()
|
||||
function creates a single-line, human-readable string containing all of
|
||||
method creates a single-line, human-readable string containing all of
|
||||
this information, for example:
|
||||
\code
|
||||
file:///home/user/test.qml:7:8: Invalid property assignment: double expected
|
||||
\endcode
|
||||
|
||||
You can use qDebug() or qWarning() to output errors to the console. This function
|
||||
You can use qDebug() or qWarning() to output errors to the console. This method
|
||||
will attempt to open the file indicated by the error
|
||||
and include additional contextual information.
|
||||
\code
|
||||
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
|
||||
^
|
||||
\endcode
|
||||
|
||||
\note The QtQuick 1 version is named QDeclarativeError.
|
||||
Note that the \l {Qt Quick 1} version is named QDeclarativeError
|
||||
|
||||
\sa QQuickView::errors(), QmlComponent::errors()
|
||||
*/
|
||||
@@ -78,10 +78,11 @@ public:
|
||||
QString description;
|
||||
quint16 line;
|
||||
quint16 column;
|
||||
QObject *object;
|
||||
};
|
||||
|
||||
QmlErrorPrivate::QmlErrorPrivate()
|
||||
: line(0), column(0)
|
||||
: line(0), column(0), object()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -116,6 +117,7 @@ QmlError &QmlError::operator=(const QmlError &other)
|
||||
d->description = other.d->description;
|
||||
d->line = other.d->line;
|
||||
d->column = other.d->column;
|
||||
d->object = other.d->object;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -137,7 +139,7 @@ bool QmlError::isValid() const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the URL for the file that caused this error.
|
||||
Returns the url for the file that caused this error.
|
||||
*/
|
||||
QUrl QmlError::url() const
|
||||
{
|
||||
@@ -208,6 +210,27 @@ void QmlError::setColumn(int column)
|
||||
d->column = qmlSourceCoordinate(column);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the nearest object where this error occurred.
|
||||
Exceptions in bound property expressions set this to the object
|
||||
to which the property belongs. It will be 0 for all
|
||||
other exceptions.
|
||||
*/
|
||||
QObject *QmlError::object() const
|
||||
{
|
||||
if (d) return d->object;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the nearest \a object where this error occurred.
|
||||
*/
|
||||
void QmlError::setObject(QObject *object)
|
||||
{
|
||||
if (!d) d = new QmlErrorPrivate;
|
||||
d->object = object;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the error as a human readable string.
|
||||
*/
|
||||
@@ -237,6 +260,7 @@ QString QmlError::toString() const
|
||||
|
||||
/*!
|
||||
\relates QmlError
|
||||
\fn QDebug operator<<(QDebug debug, const QmlError &error)
|
||||
|
||||
Outputs a human readable version of \a error to \a debug.
|
||||
*/
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
class QDebug;
|
||||
class QmlErrorPrivate;
|
||||
class QmlError
|
||||
@@ -58,6 +57,8 @@ public:
|
||||
void setLine(int);
|
||||
int column() const;
|
||||
void setColumn(int);
|
||||
QObject *object() const;
|
||||
void setObject(QObject *);
|
||||
|
||||
QString toString() const;
|
||||
private:
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
%parser QmlJSGrammar
|
||||
%decl qmljsparser_p.h
|
||||
%impl qmljsparser.cpp
|
||||
%expect 2
|
||||
%expect 5
|
||||
%expect-rr 2
|
||||
|
||||
%token T_AND "&" T_AND_AND "&&" T_AND_EQ "&="
|
||||
@@ -65,8 +65,11 @@
|
||||
--- context keywords.
|
||||
%token T_PUBLIC "public"
|
||||
%token T_IMPORT "import"
|
||||
%token T_PRAGMA "pragma"
|
||||
%token T_AS "as"
|
||||
%token T_ON "on"
|
||||
%token T_GET "get"
|
||||
%token T_SET "set"
|
||||
|
||||
%token T_ERROR
|
||||
|
||||
@@ -79,7 +82,7 @@
|
||||
%token T_FEED_JS_PROGRAM
|
||||
|
||||
%nonassoc SHIFT_THERE
|
||||
%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY
|
||||
%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET
|
||||
%nonassoc REDUCE_HERE
|
||||
|
||||
%start TopLevel
|
||||
@@ -125,16 +128,16 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtCore/QtDebug>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "qmljsengine_p.h"
|
||||
#include "qmljslexer_p.h"
|
||||
#include "qmljsast_p.h"
|
||||
#include "qmljsmemorypool_p.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
./
|
||||
|
||||
/:/****************************************************************************
|
||||
@@ -210,8 +213,8 @@
|
||||
#include "qmljsast_p.h"
|
||||
#include "qmljsengine_p.h"
|
||||
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
@@ -240,7 +243,8 @@ public:
|
||||
AST::FunctionDeclaration *FunctionDeclaration;
|
||||
AST::Node *Node;
|
||||
AST::PropertyName *PropertyName;
|
||||
AST::PropertyNameAndValueList *PropertyNameAndValueList;
|
||||
AST::PropertyAssignment *PropertyAssignment;
|
||||
AST::PropertyAssignmentList *PropertyAssignmentList;
|
||||
AST::SourceElement *SourceElement;
|
||||
AST::SourceElements *SourceElements;
|
||||
AST::Statement *Statement;
|
||||
@@ -250,7 +254,8 @@ public:
|
||||
AST::VariableDeclarationList *VariableDeclarationList;
|
||||
|
||||
AST::UiProgram *UiProgram;
|
||||
AST::UiImportList *UiImportList;
|
||||
AST::UiHeaderItemList *UiHeaderItemList;
|
||||
AST::UiPragma *UiPragma;
|
||||
AST::UiImport *UiImport;
|
||||
AST::UiParameterList *UiParameterList;
|
||||
AST::UiPublicMember *UiPublicMember;
|
||||
@@ -263,6 +268,7 @@ public:
|
||||
AST::UiObjectMemberList *UiObjectMemberList;
|
||||
AST::UiArrayMemberList *UiArrayMemberList;
|
||||
AST::UiQualifiedId *UiQualifiedId;
|
||||
AST::UiQualifiedPragmaId *UiQualifiedPragmaId;
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -344,6 +350,7 @@ protected:
|
||||
{ return location_stack [tos + index - 1]; }
|
||||
|
||||
AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr);
|
||||
AST::UiQualifiedPragmaId *reparseAsQualifiedPragmaId(AST::ExpressionNode *expr);
|
||||
|
||||
protected:
|
||||
Engine *driver;
|
||||
@@ -388,7 +395,8 @@ protected:
|
||||
/.
|
||||
|
||||
#include "qmljsparser_p.h"
|
||||
#include <QVarLengthArray>
|
||||
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
@@ -482,6 +490,19 @@ AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
AST::UiQualifiedPragmaId *Parser::reparseAsQualifiedPragmaId(AST::ExpressionNode *expr)
|
||||
{
|
||||
if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(expr)) {
|
||||
AST::UiQualifiedPragmaId *q = new (pool) AST::UiQualifiedPragmaId(idExpr->name);
|
||||
q->identifierToken = idExpr->identifierToken;
|
||||
|
||||
return q->finish();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool Parser::parse(int startToken)
|
||||
{
|
||||
Lexer *lexer = driver->lexer();
|
||||
@@ -590,38 +611,62 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
UiProgram: UiImportListOpt UiRootMember ;
|
||||
UiProgram: UiHeaderItemListOpt UiRootMember;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiImportList,
|
||||
sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiHeaderItemList,
|
||||
sym(2).UiObjectMemberList->finish());
|
||||
} break;
|
||||
./
|
||||
|
||||
UiImportListOpt: Empty ;
|
||||
UiImportListOpt: UiImportList ;
|
||||
UiHeaderItemListOpt: Empty ;
|
||||
UiHeaderItemListOpt: UiHeaderItemList ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).Node = sym(1).UiImportList->finish();
|
||||
sym(1).Node = sym(1).UiHeaderItemList->finish();
|
||||
} break;
|
||||
./
|
||||
|
||||
UiImportList: UiImport ;
|
||||
UiHeaderItemList: UiPragma ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).Node = new (pool) AST::UiImportList(sym(1).UiImport);
|
||||
sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiPragma);
|
||||
} break;
|
||||
./
|
||||
|
||||
UiImportList: UiImportList UiImport ;
|
||||
UiHeaderItemList: UiImport ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).Node = new (pool) AST::UiImportList(sym(1).UiImportList, sym(2).UiImport);
|
||||
sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiImport);
|
||||
} break;
|
||||
./
|
||||
|
||||
UiHeaderItemList: UiHeaderItemList UiPragma ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiPragma);
|
||||
} break;
|
||||
./
|
||||
|
||||
UiHeaderItemList: UiHeaderItemList UiImport ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiImport);
|
||||
} break;
|
||||
./
|
||||
|
||||
PragmaId: MemberExpression ;
|
||||
|
||||
ImportId: MemberExpression ;
|
||||
|
||||
UiPragma: UiPragmaHead T_AUTOMATIC_SEMICOLON ;
|
||||
UiPragma: UiPragmaHead T_SEMICOLON ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).UiPragma->semicolonToken = loc(2);
|
||||
} break;
|
||||
./
|
||||
|
||||
UiImport: UiImportHead T_AUTOMATIC_SEMICOLON ;
|
||||
UiImport: UiImportHead T_SEMICOLON ;
|
||||
/.
|
||||
@@ -662,6 +707,28 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
UiPragmaHead: T_PRAGMA PragmaId ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPragma *node = 0;
|
||||
|
||||
if (AST::UiQualifiedPragmaId *qualifiedId = reparseAsQualifiedPragmaId(sym(2).Expression)) {
|
||||
node = new (pool) AST::UiPragma(qualifiedId);
|
||||
}
|
||||
|
||||
sym(1).Node = node;
|
||||
|
||||
if (node) {
|
||||
node->pragmaToken = loc(1);
|
||||
} else {
|
||||
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1),
|
||||
QLatin1String("Expected a qualified name id")));
|
||||
|
||||
return false; // ### remove me
|
||||
}
|
||||
} break;
|
||||
./
|
||||
|
||||
|
||||
UiImportHead: T_IMPORT ImportId ;
|
||||
/.
|
||||
@@ -1043,6 +1110,8 @@ JsIdentifier: T_PROPERTY ;
|
||||
JsIdentifier: T_SIGNAL ;
|
||||
JsIdentifier: T_READONLY ;
|
||||
JsIdentifier: T_ON ;
|
||||
JsIdentifier: T_GET ;
|
||||
JsIdentifier: T_SET ;
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
-- Expressions
|
||||
@@ -1219,13 +1288,13 @@ case $rule_number: {
|
||||
-- } break;
|
||||
-- ./
|
||||
|
||||
PrimaryExpression: T_LBRACE PropertyNameAndValueListOpt T_RBRACE ;
|
||||
PrimaryExpression: T_LBRACE PropertyAssignmentListOpt T_RBRACE ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::ObjectLiteral *node = 0;
|
||||
if (sym(2).Node)
|
||||
node = new (pool) AST::ObjectLiteral(
|
||||
sym(2).PropertyNameAndValueList->finish ());
|
||||
sym(2).PropertyAssignmentList->finish ());
|
||||
else
|
||||
node = new (pool) AST::ObjectLiteral();
|
||||
node->lbraceToken = loc(1);
|
||||
@@ -1234,11 +1303,11 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
PrimaryExpression: T_LBRACE PropertyNameAndValueList T_COMMA T_RBRACE ;
|
||||
PrimaryExpression: T_LBRACE PropertyAssignmentList T_COMMA T_RBRACE ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
|
||||
sym(2).PropertyNameAndValueList->finish ());
|
||||
sym(2).PropertyAssignmentList->finish ());
|
||||
node->lbraceToken = loc(1);
|
||||
node->rbraceToken = loc(4);
|
||||
sym(1).Node = node;
|
||||
@@ -1255,6 +1324,7 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
|
||||
UiQualifiedId: MemberExpression ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
@@ -1330,40 +1400,62 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
PropertyNameAndValueList: PropertyName T_COLON AssignmentExpression ;
|
||||
PropertyAssignment: PropertyName T_COLON AssignmentExpression ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
|
||||
AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue(
|
||||
sym(1).PropertyName, sym(3).Expression);
|
||||
node->colonToken = loc(2);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
PropertyNameAndValueList: PropertyNameAndValueList T_COMMA PropertyName T_COLON AssignmentExpression ;
|
||||
PropertyAssignment: T_GET PropertyName T_LPAREN T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList(
|
||||
sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression);
|
||||
AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
|
||||
sym(2).PropertyName, sym(6).FunctionBody);
|
||||
node->getSetToken = loc(1);
|
||||
node->lparenToken = loc(3);
|
||||
node->rparenToken = loc(4);
|
||||
node->lbraceToken = loc(5);
|
||||
node->rbraceToken = loc(7);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
PropertyAssignment: T_SET PropertyName T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
|
||||
sym(2).PropertyName, sym(4).FormalParameterList, sym(7).FunctionBody);
|
||||
node->getSetToken = loc(1);
|
||||
node->lparenToken = loc(3);
|
||||
node->rparenToken = loc(5);
|
||||
node->lbraceToken = loc(6);
|
||||
node->rbraceToken = loc(8);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
PropertyAssignmentList: PropertyAssignment ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment);
|
||||
} break;
|
||||
./
|
||||
|
||||
PropertyAssignmentList: PropertyAssignmentList T_COMMA PropertyAssignment ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList(
|
||||
sym(1).PropertyAssignmentList, sym(3).PropertyAssignment);
|
||||
node->commaToken = loc(2);
|
||||
node->colonToken = loc(4);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
PropertyName: T_IDENTIFIER %prec SHIFT_THERE ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
|
||||
node->propertyNameToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
PropertyName: T_SIGNAL ;
|
||||
/.case $rule_number:./
|
||||
|
||||
PropertyName: T_PROPERTY ;
|
||||
PropertyName: JsIdentifier %prec SHIFT_THERE ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
|
||||
@@ -2669,20 +2761,7 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
LabelledStatement: T_SIGNAL T_COLON Statement ;
|
||||
/.case $rule_number:./
|
||||
|
||||
LabelledStatement: T_PROPERTY T_COLON Statement ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
|
||||
node->identifierToken = loc(1);
|
||||
node->colonToken = loc(2);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
LabelledStatement: T_IDENTIFIER T_COLON Statement ;
|
||||
LabelledStatement: JsIdentifier T_COLON Statement ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
|
||||
@@ -2762,7 +2841,12 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
FunctionDeclaration: T_FUNCTION JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
|
||||
-- tell the parser to prefer function declarations to function expressions.
|
||||
-- That is, the `Function' symbol is used to mark the start of a function
|
||||
-- declaration.
|
||||
Function: T_FUNCTION %prec REDUCE_HERE ;
|
||||
|
||||
FunctionDeclaration: Function JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
|
||||
@@ -2776,7 +2860,7 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
FunctionExpression: T_FUNCTION IdentifierOpt T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
|
||||
FunctionExpression: T_FUNCTION JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
|
||||
@@ -2791,6 +2875,19 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
FunctionExpression: T_FUNCTION T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).FunctionBody);
|
||||
node->functionToken = loc(1);
|
||||
node->lparenToken = loc(2);
|
||||
node->rparenToken = loc(4);
|
||||
node->lbraceToken = loc(5);
|
||||
node->rbraceToken = loc(7);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
FormalParameterList: JsIdentifier ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
@@ -2877,23 +2974,14 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
IdentifierOpt: ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
stringRef(1) = QStringRef();
|
||||
} break;
|
||||
./
|
||||
|
||||
IdentifierOpt: JsIdentifier ;
|
||||
|
||||
PropertyNameAndValueListOpt: ;
|
||||
PropertyAssignmentListOpt: ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).Node = 0;
|
||||
} break;
|
||||
./
|
||||
|
||||
PropertyNameAndValueListOpt: PropertyNameAndValueList ;
|
||||
PropertyAssignmentListOpt: PropertyAssignmentList ;
|
||||
|
||||
/.
|
||||
} // switch
|
||||
|
||||
@@ -201,12 +201,32 @@ void Elision::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PropertyNameAndValueList::accept0(Visitor *visitor)
|
||||
void PropertyNameAndValue::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
for (PropertyNameAndValueList *it = this; it; it = it->next) {
|
||||
accept(it->name, visitor);
|
||||
accept(it->value, visitor);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -789,7 +809,7 @@ void DebuggerStatement::accept0(Visitor *visitor)
|
||||
void UiProgram::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(imports, visitor);
|
||||
accept(headers, visitor);
|
||||
accept(members, visitor);
|
||||
}
|
||||
|
||||
@@ -900,16 +920,34 @@ void UiImport::accept0(Visitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void UiImportList::accept0(Visitor *visitor)
|
||||
void UiQualifiedPragmaId::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(import, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void UiPragma::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(pragmaType, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void UiHeaderItemList::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(headerItem, visitor);
|
||||
accept(next, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
|
||||
void UiSourceElement::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#include "qmljsglobal_p.h"
|
||||
#include "qmljsmemorypool_p.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
@@ -164,8 +164,10 @@ public:
|
||||
Kind_PreDecrementExpression,
|
||||
Kind_PreIncrementExpression,
|
||||
Kind_Program,
|
||||
Kind_PropertyAssignmentList,
|
||||
Kind_PropertyGetterSetter,
|
||||
Kind_PropertyName,
|
||||
Kind_PropertyNameAndValueList,
|
||||
Kind_PropertyNameAndValue,
|
||||
Kind_RegExpLiteral,
|
||||
Kind_ReturnStatement,
|
||||
Kind_SourceElement,
|
||||
@@ -193,18 +195,20 @@ public:
|
||||
|
||||
Kind_UiArrayBinding,
|
||||
Kind_UiImport,
|
||||
Kind_UiImportList,
|
||||
Kind_UiObjectBinding,
|
||||
Kind_UiObjectDefinition,
|
||||
Kind_UiObjectInitializer,
|
||||
Kind_UiObjectMemberList,
|
||||
Kind_UiArrayMemberList,
|
||||
Kind_UiPragma,
|
||||
Kind_UiProgram,
|
||||
Kind_UiParameterList,
|
||||
Kind_UiPublicMember,
|
||||
Kind_UiQualifiedId,
|
||||
Kind_UiQualifiedPragmaId,
|
||||
Kind_UiScriptBinding,
|
||||
Kind_UiSourceElement
|
||||
Kind_UiSourceElement,
|
||||
Kind_UiHeaderItemList
|
||||
};
|
||||
|
||||
inline Node()
|
||||
@@ -475,7 +479,7 @@ public:
|
||||
ObjectLiteral():
|
||||
properties (0) { kind = K; }
|
||||
|
||||
ObjectLiteral(PropertyNameAndValueList *plist):
|
||||
ObjectLiteral(PropertyAssignmentList *plist):
|
||||
properties (plist) { kind = K; }
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
@@ -487,7 +491,7 @@ public:
|
||||
{ return rbraceToken; }
|
||||
|
||||
// attributes
|
||||
PropertyNameAndValueList *properties;
|
||||
PropertyAssignmentList *properties;
|
||||
SourceLocation lbraceToken;
|
||||
SourceLocation rbraceToken;
|
||||
};
|
||||
@@ -591,50 +595,113 @@ public:
|
||||
SourceLocation propertyNameToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT PropertyNameAndValueList: public Node
|
||||
class QML_PARSER_EXPORT PropertyAssignment: public Node
|
||||
{
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(PropertyNameAndValueList)
|
||||
PropertyAssignment() {}
|
||||
};
|
||||
|
||||
PropertyNameAndValueList(PropertyName *n, ExpressionNode *v):
|
||||
name (n), value (v), next (this)
|
||||
{ kind = K; }
|
||||
class QML_PARSER_EXPORT PropertyAssignmentList: public Node
|
||||
{
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(PropertyAssignmentList)
|
||||
|
||||
PropertyNameAndValueList(PropertyNameAndValueList *previous, PropertyName *n, ExpressionNode *v):
|
||||
name (n), value (v)
|
||||
PropertyAssignmentList(PropertyAssignment *assignment)
|
||||
: assignment(assignment)
|
||||
, next(this)
|
||||
{ kind = K; }
|
||||
|
||||
PropertyAssignmentList(PropertyAssignmentList *previous, PropertyAssignment *assignment)
|
||||
: assignment(assignment)
|
||||
{
|
||||
kind = K;
|
||||
next = previous->next;
|
||||
previous->next = this;
|
||||
}
|
||||
|
||||
inline PropertyAssignmentList *finish ()
|
||||
{
|
||||
PropertyAssignmentList *front = next;
|
||||
next = 0;
|
||||
return front;
|
||||
}
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual SourceLocation firstSourceLocation() const
|
||||
{ return assignment->firstSourceLocation(); }
|
||||
|
||||
virtual SourceLocation lastSourceLocation() const
|
||||
{ return next ? next->lastSourceLocation() : assignment->lastSourceLocation(); }
|
||||
|
||||
// attributes
|
||||
PropertyAssignment *assignment;
|
||||
PropertyAssignmentList *next;
|
||||
SourceLocation commaToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT PropertyNameAndValue: public PropertyAssignment
|
||||
{
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(PropertyNameAndValue)
|
||||
|
||||
PropertyNameAndValue(PropertyName *n, ExpressionNode *v)
|
||||
: name(n), value(v)
|
||||
{ kind = K; }
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual SourceLocation firstSourceLocation() const
|
||||
{ return name->firstSourceLocation(); }
|
||||
|
||||
virtual SourceLocation lastSourceLocation() const
|
||||
{
|
||||
if (next)
|
||||
return next->lastSourceLocation();
|
||||
return value->lastSourceLocation();
|
||||
}
|
||||
|
||||
inline PropertyNameAndValueList *finish ()
|
||||
{
|
||||
PropertyNameAndValueList *front = next;
|
||||
next = 0;
|
||||
return front;
|
||||
}
|
||||
{ return value->lastSourceLocation(); }
|
||||
|
||||
// attributes
|
||||
PropertyName *name;
|
||||
ExpressionNode *value;
|
||||
PropertyNameAndValueList *next;
|
||||
SourceLocation colonToken;
|
||||
ExpressionNode *value;
|
||||
SourceLocation commaToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT PropertyGetterSetter: public PropertyAssignment
|
||||
{
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(PropertyGetterSetter)
|
||||
|
||||
enum Type {
|
||||
Getter,
|
||||
Setter
|
||||
};
|
||||
|
||||
PropertyGetterSetter(PropertyName *n, FunctionBody *b)
|
||||
: type(Getter), name(n), formals(0), functionBody (b)
|
||||
{ kind = K; }
|
||||
|
||||
PropertyGetterSetter(PropertyName *n, FormalParameterList *f, FunctionBody *b)
|
||||
: type(Setter), name(n), formals(f), functionBody (b)
|
||||
{ kind = K; }
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual SourceLocation firstSourceLocation() const
|
||||
{ return getSetToken; }
|
||||
|
||||
virtual SourceLocation lastSourceLocation() const
|
||||
{ return rbraceToken; }
|
||||
|
||||
// attributes
|
||||
Type type;
|
||||
SourceLocation getSetToken;
|
||||
PropertyName *name;
|
||||
SourceLocation lparenToken;
|
||||
FormalParameterList *formals;
|
||||
SourceLocation rparenToken;
|
||||
SourceLocation lbraceToken;
|
||||
FunctionBody *functionBody;
|
||||
SourceLocation rbraceToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT IdentifierPropertyName: public PropertyName
|
||||
{
|
||||
public:
|
||||
@@ -2194,44 +2261,6 @@ public:
|
||||
SourceLocation semicolonToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiImportList: public Node
|
||||
{
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(UiImportList)
|
||||
|
||||
UiImportList(UiImport *import)
|
||||
: import(import),
|
||||
next(this)
|
||||
{ kind = K; }
|
||||
|
||||
UiImportList(UiImportList *previous, UiImport *import)
|
||||
: import(import)
|
||||
{
|
||||
kind = K;
|
||||
next = previous->next;
|
||||
previous->next = this;
|
||||
}
|
||||
|
||||
UiImportList *finish()
|
||||
{
|
||||
UiImportList *head = next;
|
||||
next = 0;
|
||||
return head;
|
||||
}
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual SourceLocation firstSourceLocation() const
|
||||
{ return import->firstSourceLocation(); }
|
||||
|
||||
virtual SourceLocation lastSourceLocation() const
|
||||
{ return next ? next->lastSourceLocation() : import->lastSourceLocation(); }
|
||||
|
||||
// attributes
|
||||
UiImport *import;
|
||||
UiImportList *next;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiObjectMember: public Node
|
||||
{
|
||||
public:
|
||||
@@ -2278,21 +2307,131 @@ public:
|
||||
UiObjectMember *member;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiQualifiedPragmaId: public Node
|
||||
{
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(UiQualifiedPragmaId)
|
||||
|
||||
UiQualifiedPragmaId(const QStringRef &name)
|
||||
: next(this), name(name)
|
||||
{ kind = K; }
|
||||
|
||||
UiQualifiedPragmaId(UiQualifiedPragmaId *previous, const QStringRef &name)
|
||||
: name(name)
|
||||
{
|
||||
kind = K;
|
||||
next = previous->next;
|
||||
previous->next = this;
|
||||
}
|
||||
|
||||
UiQualifiedPragmaId *finish()
|
||||
{
|
||||
UiQualifiedPragmaId *head = next;
|
||||
next = 0;
|
||||
return head;
|
||||
}
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual SourceLocation firstSourceLocation() const
|
||||
{ return identifierToken; }
|
||||
|
||||
virtual SourceLocation lastSourceLocation() const
|
||||
{ return next ? next->lastSourceLocation() : identifierToken; }
|
||||
|
||||
// attributes
|
||||
UiQualifiedPragmaId *next;
|
||||
QStringRef name;
|
||||
SourceLocation identifierToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiPragma: public Node
|
||||
{
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(UiPragma)
|
||||
|
||||
UiPragma(UiQualifiedPragmaId *type)
|
||||
: pragmaType(type)
|
||||
{ kind = K; }
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual SourceLocation firstSourceLocation() const
|
||||
{ return pragmaToken; }
|
||||
|
||||
virtual SourceLocation lastSourceLocation() const
|
||||
{ return semicolonToken; }
|
||||
|
||||
// attributes
|
||||
UiQualifiedPragmaId *pragmaType;
|
||||
SourceLocation pragmaToken;
|
||||
SourceLocation semicolonToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiHeaderItemList: public Node
|
||||
{
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(UiHeaderItemList)
|
||||
|
||||
UiHeaderItemList(UiImport *import)
|
||||
: headerItem(import), next(this)
|
||||
{ kind = K; }
|
||||
|
||||
UiHeaderItemList(UiPragma *pragma)
|
||||
: headerItem(pragma), next(this)
|
||||
{ kind = K; }
|
||||
|
||||
UiHeaderItemList(UiHeaderItemList *previous, UiImport *import)
|
||||
: headerItem(import)
|
||||
{
|
||||
kind = K;
|
||||
next = previous->next;
|
||||
previous->next = this;
|
||||
}
|
||||
|
||||
UiHeaderItemList(UiHeaderItemList *previous, UiPragma *pragma)
|
||||
: headerItem(pragma)
|
||||
{
|
||||
kind = K;
|
||||
next = previous->next;
|
||||
previous->next = this;
|
||||
}
|
||||
|
||||
UiHeaderItemList *finish()
|
||||
{
|
||||
UiHeaderItemList *head = next;
|
||||
next = 0;
|
||||
return head;
|
||||
}
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual SourceLocation firstSourceLocation() const
|
||||
{ return headerItem->firstSourceLocation(); }
|
||||
|
||||
virtual SourceLocation lastSourceLocation() const
|
||||
{ return next ? next->lastSourceLocation() : headerItem->lastSourceLocation(); }
|
||||
|
||||
// attributes
|
||||
Node *headerItem;
|
||||
UiHeaderItemList *next;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiProgram: public Node
|
||||
{
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(UiProgram)
|
||||
|
||||
UiProgram(UiImportList *imports, UiObjectMemberList *members)
|
||||
: imports(imports), members(members)
|
||||
UiProgram(UiHeaderItemList *headers, UiObjectMemberList *members)
|
||||
: headers(headers), members(members)
|
||||
{ kind = K; }
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual SourceLocation firstSourceLocation() const
|
||||
{
|
||||
if (imports)
|
||||
return imports->firstSourceLocation();
|
||||
if (headers)
|
||||
return headers->firstSourceLocation();
|
||||
else if (members)
|
||||
return members->firstSourceLocation();
|
||||
return SourceLocation();
|
||||
@@ -2302,13 +2441,13 @@ public:
|
||||
{
|
||||
if (members)
|
||||
return members->lastSourceLocation();
|
||||
else if (imports)
|
||||
return imports->lastSourceLocation();
|
||||
else if (headers)
|
||||
return headers->lastSourceLocation();
|
||||
return SourceLocation();
|
||||
}
|
||||
|
||||
// attributes
|
||||
UiImportList *imports;
|
||||
UiHeaderItemList *headers;
|
||||
UiObjectMemberList *members;
|
||||
};
|
||||
|
||||
|
||||
@@ -86,7 +86,9 @@ class ArrayLiteral;
|
||||
class ObjectLiteral;
|
||||
class ElementList;
|
||||
class Elision;
|
||||
class PropertyNameAndValueList;
|
||||
class PropertyAssignmentList;
|
||||
class PropertyGetterSetter;
|
||||
class PropertyNameAndValue;
|
||||
class PropertyName;
|
||||
class IdentifierPropertyName;
|
||||
class StringLiteralPropertyName;
|
||||
@@ -153,7 +155,7 @@ class NestedExpression;
|
||||
|
||||
// ui elements
|
||||
class UiProgram;
|
||||
class UiImportList;
|
||||
class UiPragma;
|
||||
class UiImport;
|
||||
class UiPublicMember;
|
||||
class UiParameterList;
|
||||
@@ -167,6 +169,8 @@ class UiObjectMember;
|
||||
class UiObjectMemberList;
|
||||
class UiArrayMemberList;
|
||||
class UiQualifiedId;
|
||||
class UiQualifiedPragmaId;
|
||||
class UiHeaderItemList;
|
||||
|
||||
} } // namespace AST
|
||||
|
||||
|
||||
@@ -59,7 +59,8 @@ public:
|
||||
|
||||
// Ui
|
||||
virtual bool visit(UiProgram *) { return true; }
|
||||
virtual bool visit(UiImportList *) { return true; }
|
||||
virtual bool visit(UiHeaderItemList *) { return true; }
|
||||
virtual bool visit(UiPragma *) { return true; }
|
||||
virtual bool visit(UiImport *) { return true; }
|
||||
virtual bool visit(UiPublicMember *) { return true; }
|
||||
virtual bool visit(UiSourceElement *) { return true; }
|
||||
@@ -72,10 +73,12 @@ public:
|
||||
virtual bool visit(UiObjectMemberList *) { return true; }
|
||||
virtual bool visit(UiArrayMemberList *) { return true; }
|
||||
virtual bool visit(UiQualifiedId *) { return true; }
|
||||
virtual bool visit(UiQualifiedPragmaId *) { return true; }
|
||||
|
||||
virtual void endVisit(UiProgram *) {}
|
||||
virtual void endVisit(UiImportList *) {}
|
||||
virtual void endVisit(UiImport *) {}
|
||||
virtual void endVisit(UiHeaderItemList *) {}
|
||||
virtual void endVisit(UiPragma *) {}
|
||||
virtual void endVisit(UiPublicMember *) {}
|
||||
virtual void endVisit(UiSourceElement *) {}
|
||||
virtual void endVisit(UiObjectDefinition *) {}
|
||||
@@ -87,6 +90,7 @@ public:
|
||||
virtual void endVisit(UiObjectMemberList *) {}
|
||||
virtual void endVisit(UiArrayMemberList *) {}
|
||||
virtual void endVisit(UiQualifiedId *) {}
|
||||
virtual void endVisit(UiQualifiedPragmaId *) {}
|
||||
|
||||
// QmlJS
|
||||
virtual bool visit(ThisExpression *) { return true; }
|
||||
@@ -125,8 +129,14 @@ public:
|
||||
virtual bool visit(Elision *) { return true; }
|
||||
virtual void endVisit(Elision *) {}
|
||||
|
||||
virtual bool visit(PropertyNameAndValueList *) { return true; }
|
||||
virtual void endVisit(PropertyNameAndValueList *) {}
|
||||
virtual bool visit(PropertyAssignmentList *) { return true; }
|
||||
virtual void endVisit(PropertyAssignmentList *) {}
|
||||
|
||||
virtual bool visit(PropertyNameAndValue *) { return true; }
|
||||
virtual void endVisit(PropertyNameAndValue *) {}
|
||||
|
||||
virtual bool visit(PropertyGetterSetter *) { return true; }
|
||||
virtual void endVisit(PropertyGetterSetter *) {}
|
||||
|
||||
virtual bool visit(NestedExpression *) { return true; }
|
||||
virtual void endVisit(NestedExpression *) {}
|
||||
|
||||
@@ -30,15 +30,15 @@
|
||||
#include "qmljsengine_p.h"
|
||||
#include "qmljsglobal_p.h"
|
||||
|
||||
#include <qnumeric.h>
|
||||
#include <QHash>
|
||||
#include <QDebug>
|
||||
#include <QtCore/qnumeric.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
namespace QmlJS {
|
||||
|
||||
static int toDigit(char c)
|
||||
static inline int toDigit(char c)
|
||||
{
|
||||
if ((c >= '0') && (c <= '9'))
|
||||
return c - '0';
|
||||
|
||||
@@ -91,6 +91,7 @@ public:
|
||||
~Engine();
|
||||
|
||||
void setCode(const QString &code);
|
||||
const QString &code() const { return _code; }
|
||||
|
||||
void addComment(int pos, int len, int line, int col);
|
||||
QList<AST::SourceLocation> comments() const;
|
||||
|
||||
@@ -49,8 +49,10 @@
|
||||
# if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB)
|
||||
// QmlDevTools is a static library
|
||||
# define QML_PARSER_EXPORT
|
||||
# else
|
||||
# elif defined(QT_BUILD_QML_LIB)
|
||||
# define QML_PARSER_EXPORT Q_AUTOTEST_EXPORT
|
||||
# else
|
||||
# define QML_PARSER_EXPORT
|
||||
# endif
|
||||
#endif // QT_CREATOR
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,12 +52,12 @@ class QML_PARSER_EXPORT QmlJSGrammar
|
||||
public:
|
||||
enum VariousConstants {
|
||||
EOF_SYMBOL = 0,
|
||||
REDUCE_HERE = 102,
|
||||
SHIFT_THERE = 101,
|
||||
REDUCE_HERE = 105,
|
||||
SHIFT_THERE = 104,
|
||||
T_AND = 1,
|
||||
T_AND_AND = 2,
|
||||
T_AND_EQ = 3,
|
||||
T_AS = 92,
|
||||
T_AS = 93,
|
||||
T_AUTOMATIC_SEMICOLON = 62,
|
||||
T_BREAK = 4,
|
||||
T_CASE = 5,
|
||||
@@ -79,18 +79,19 @@ public:
|
||||
T_EQ = 17,
|
||||
T_EQ_EQ = 18,
|
||||
T_EQ_EQ_EQ = 19,
|
||||
T_ERROR = 94,
|
||||
T_ERROR = 97,
|
||||
T_FALSE = 83,
|
||||
T_FEED_JS_EXPRESSION = 98,
|
||||
T_FEED_JS_PROGRAM = 100,
|
||||
T_FEED_JS_SOURCE_ELEMENT = 99,
|
||||
T_FEED_JS_STATEMENT = 97,
|
||||
T_FEED_UI_OBJECT_MEMBER = 96,
|
||||
T_FEED_UI_PROGRAM = 95,
|
||||
T_FEED_JS_EXPRESSION = 101,
|
||||
T_FEED_JS_PROGRAM = 103,
|
||||
T_FEED_JS_SOURCE_ELEMENT = 102,
|
||||
T_FEED_JS_STATEMENT = 100,
|
||||
T_FEED_UI_OBJECT_MEMBER = 99,
|
||||
T_FEED_UI_PROGRAM = 98,
|
||||
T_FINALLY = 20,
|
||||
T_FOR = 21,
|
||||
T_FUNCTION = 22,
|
||||
T_GE = 23,
|
||||
T_GET = 95,
|
||||
T_GT = 24,
|
||||
T_GT_GT = 25,
|
||||
T_GT_GT_EQ = 26,
|
||||
@@ -118,13 +119,14 @@ public:
|
||||
T_NOT_EQ_EQ = 46,
|
||||
T_NULL = 81,
|
||||
T_NUMERIC_LITERAL = 47,
|
||||
T_ON = 93,
|
||||
T_ON = 94,
|
||||
T_OR = 48,
|
||||
T_OR_EQ = 49,
|
||||
T_OR_OR = 50,
|
||||
T_PLUS = 51,
|
||||
T_PLUS_EQ = 52,
|
||||
T_PLUS_PLUS = 53,
|
||||
T_PRAGMA = 92,
|
||||
T_PROPERTY = 66,
|
||||
T_PUBLIC = 90,
|
||||
T_QUESTION = 54,
|
||||
@@ -137,6 +139,7 @@ public:
|
||||
T_RETURN = 59,
|
||||
T_RPAREN = 60,
|
||||
T_SEMICOLON = 61,
|
||||
T_SET = 96,
|
||||
T_SIGNAL = 67,
|
||||
T_STAR = 63,
|
||||
T_STAR_EQ = 64,
|
||||
@@ -155,15 +158,15 @@ public:
|
||||
T_XOR = 79,
|
||||
T_XOR_EQ = 80,
|
||||
|
||||
ACCEPT_STATE = 645,
|
||||
RULE_COUNT = 350,
|
||||
STATE_COUNT = 646,
|
||||
TERMINAL_COUNT = 103,
|
||||
NON_TERMINAL_COUNT = 107,
|
||||
ACCEPT_STATE = 663,
|
||||
RULE_COUNT = 357,
|
||||
STATE_COUNT = 664,
|
||||
TERMINAL_COUNT = 106,
|
||||
NON_TERMINAL_COUNT = 111,
|
||||
|
||||
GOTO_INDEX_OFFSET = 646,
|
||||
GOTO_INFO_OFFSET = 3019,
|
||||
GOTO_CHECK_OFFSET = 3019
|
||||
GOTO_INDEX_OFFSET = 664,
|
||||
GOTO_INFO_OFFSET = 3104,
|
||||
GOTO_CHECK_OFFSET = 3104
|
||||
};
|
||||
|
||||
static const char *const spell [];
|
||||
|
||||
@@ -41,6 +41,12 @@
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qmljslexer_p.h"
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
namespace QmlJS {
|
||||
|
||||
// Note on the int() casts in the following code:
|
||||
// they casts values from Lexer's anonymous enum (aliasing some of the inherited
|
||||
// QmlJSGrammar::VariousConstants) to int when used with inherited values of the
|
||||
@@ -82,10 +88,17 @@ static inline int classify3(const QChar *s, bool qmlMode) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s[0].unicode() == 'g') {
|
||||
if (s[1].unicode() == 'e') {
|
||||
if (s[2].unicode() == 't') {
|
||||
return Lexer::T_GET;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s[0].unicode() == 'i') {
|
||||
if (s[1].unicode() == 'n') {
|
||||
if (s[2].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_INT) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_INT) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,6 +109,13 @@ static inline int classify3(const QChar *s, bool qmlMode) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s[0].unicode() == 's') {
|
||||
if (s[1].unicode() == 'e') {
|
||||
if (s[2].unicode() == 't') {
|
||||
return Lexer::T_SET;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s[0].unicode() == 't') {
|
||||
if (s[1].unicode() == 'r') {
|
||||
if (s[2].unicode() == 'y') {
|
||||
@@ -118,7 +138,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
|
||||
if (s[1].unicode() == 'y') {
|
||||
if (s[2].unicode() == 't') {
|
||||
if (s[3].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_BYTE) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_BYTE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +154,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
|
||||
else if (s[1].unicode() == 'h') {
|
||||
if (s[2].unicode() == 'a') {
|
||||
if (s[3].unicode() == 'r') {
|
||||
return qmlMode ? int(Lexer::T_CHAR) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_CHAR) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +179,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
|
||||
if (s[1].unicode() == 'o') {
|
||||
if (s[2].unicode() == 't') {
|
||||
if (s[3].unicode() == 'o') {
|
||||
return qmlMode ? int(Lexer::T_GOTO) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_GOTO) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,7 +188,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
|
||||
if (s[1].unicode() == 'o') {
|
||||
if (s[2].unicode() == 'n') {
|
||||
if (s[3].unicode() == 'g') {
|
||||
return qmlMode ? int(Lexer::T_LONG) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_LONG) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,7 +274,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
if (s[2].unicode() == 'n') {
|
||||
if (s[3].unicode() == 's') {
|
||||
if (s[4].unicode() == 't') {
|
||||
return qmlMode ? Lexer::T_CONST : Lexer::T_RESERVED_WORD;
|
||||
return qmlMode ? int(Lexer::T_CONST) : int(Lexer::T_RESERVED_WORD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -274,7 +294,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
if (s[2].unicode() == 'n') {
|
||||
if (s[3].unicode() == 'a') {
|
||||
if (s[4].unicode() == 'l') {
|
||||
return qmlMode ? int(Lexer::T_FINAL) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_FINAL) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -283,7 +303,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
if (s[2].unicode() == 'o') {
|
||||
if (s[3].unicode() == 'a') {
|
||||
if (s[4].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_FLOAT) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_FLOAT) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,7 +314,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
if (s[2].unicode() == 'o') {
|
||||
if (s[3].unicode() == 'r') {
|
||||
if (s[4].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_SHORT) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_SHORT) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -303,7 +323,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
|
||||
if (s[2].unicode() == 'p') {
|
||||
if (s[3].unicode() == 'e') {
|
||||
if (s[4].unicode() == 'r') {
|
||||
return qmlMode ? int(Lexer::T_SUPER) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_SUPER) : int(Lexer::T_RESERVED_WORD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,7 +372,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 'b') {
|
||||
if (s[4].unicode() == 'l') {
|
||||
if (s[5].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_DOUBLE) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_DOUBLE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -378,7 +398,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 'o') {
|
||||
if (s[4].unicode() == 'r') {
|
||||
if (s[5].unicode() == 't') {
|
||||
return qmlMode ? Lexer::T_IMPORT : Lexer::T_RESERVED_WORD;
|
||||
return qmlMode ? int(Lexer::T_IMPORT) : int(Lexer::T_RESERVED_WORD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -391,7 +411,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 'i') {
|
||||
if (s[4].unicode() == 'v') {
|
||||
if (s[5].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_NATIVE) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_NATIVE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -410,6 +430,17 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s[1].unicode() == 'r') {
|
||||
if (s[2].unicode() == 'a') {
|
||||
if (s[3].unicode() == 'g') {
|
||||
if (s[4].unicode() == 'm') {
|
||||
if (s[5].unicode() == 'a') {
|
||||
return qmlMode ? Lexer::T_PRAGMA : Lexer::T_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s[0].unicode() == 'r') {
|
||||
if (s[1].unicode() == 'e') {
|
||||
@@ -441,7 +472,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 't') {
|
||||
if (s[4].unicode() == 'i') {
|
||||
if (s[5].unicode() == 'c') {
|
||||
return qmlMode ? int(Lexer::T_STATIC) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_STATIC) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -465,7 +496,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
|
||||
if (s[3].unicode() == 'o') {
|
||||
if (s[4].unicode() == 'w') {
|
||||
if (s[5].unicode() == 's') {
|
||||
return qmlMode ? int(Lexer::T_THROWS) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_THROWS) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -494,7 +525,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
|
||||
if (s[4].unicode() == 'e') {
|
||||
if (s[5].unicode() == 'a') {
|
||||
if (s[6].unicode() == 'n') {
|
||||
return qmlMode ? int(Lexer::T_BOOLEAN) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_BOOLEAN) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -554,7 +585,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
|
||||
if (s[4].unicode() == 'a') {
|
||||
if (s[5].unicode() == 'g') {
|
||||
if (s[6].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_PACKAGE) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_PACKAGE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -567,7 +598,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
|
||||
if (s[4].unicode() == 'a') {
|
||||
if (s[5].unicode() == 't') {
|
||||
if (s[6].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_PRIVATE) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_PRIVATE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -587,7 +618,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
|
||||
if (s[5].unicode() == 'a') {
|
||||
if (s[6].unicode() == 'c') {
|
||||
if (s[7].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_ABSTRACT) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_ABSTRACT) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -689,7 +720,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
|
||||
if (s[5].unicode() == 'i') {
|
||||
if (s[6].unicode() == 'l') {
|
||||
if (s[7].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_VOLATILE) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_VOLATILE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -711,7 +742,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
|
||||
if (s[6].unicode() == 'a') {
|
||||
if (s[7].unicode() == 'c') {
|
||||
if (s[8].unicode() == 'e') {
|
||||
return qmlMode ? int(Lexer::T_INTERFACE) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_INTERFACE) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -730,7 +761,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
|
||||
if (s[6].unicode() == 't') {
|
||||
if (s[7].unicode() == 'e') {
|
||||
if (s[8].unicode() == 'd') {
|
||||
return qmlMode ? int(Lexer::T_PROTECTED) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_PROTECTED) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -749,7 +780,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
|
||||
if (s[6].unicode() == 'e') {
|
||||
if (s[7].unicode() == 'n') {
|
||||
if (s[8].unicode() == 't') {
|
||||
return qmlMode ? int(Lexer::T_TRANSIENT) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_TRANSIENT) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -773,7 +804,7 @@ static inline int classify10(const QChar *s, bool qmlMode) {
|
||||
if (s[7].unicode() == 'n') {
|
||||
if (s[8].unicode() == 't') {
|
||||
if (s[9].unicode() == 's') {
|
||||
return qmlMode ? int(Lexer::T_IMPLEMENTS) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_IMPLEMENTS) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -819,7 +850,7 @@ static inline int classify12(const QChar *s, bool qmlMode) {
|
||||
if (s[9].unicode() == 'z') {
|
||||
if (s[10].unicode() == 'e') {
|
||||
if (s[11].unicode() == 'd') {
|
||||
return qmlMode ? int(Lexer::T_SYNCHRONIZED) : Lexer::T_IDENTIFIER;
|
||||
return qmlMode ? int(Lexer::T_SYNCHRONIZED) : int(Lexer::T_IDENTIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -851,4 +882,8 @@ int Lexer::classify(const QChar *s, int n, bool qmlMode) {
|
||||
} // switch
|
||||
}
|
||||
|
||||
} // namespace QmlJS
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
|
||||
#endif // QMLJSKEYWORDS_P_H
|
||||
|
||||
@@ -30,10 +30,11 @@
|
||||
#include "qmljslexer_p.h"
|
||||
#include "qmljsengine_p.h"
|
||||
#include "qmljsmemorypool_p.h"
|
||||
#include "qmljskeywords_p.h"
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QVarLengthArray>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
|
||||
@@ -41,7 +42,7 @@ QT_END_NAMESPACE
|
||||
|
||||
using namespace QmlJS;
|
||||
|
||||
static int regExpFlagFromChar(const QChar &ch)
|
||||
static inline int regExpFlagFromChar(const QChar &ch)
|
||||
{
|
||||
switch (ch.unicode()) {
|
||||
case 'g': return Lexer::RegExp_Global;
|
||||
@@ -51,7 +52,7 @@ static int regExpFlagFromChar(const QChar &ch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned char convertHex(ushort c)
|
||||
static inline unsigned char convertHex(ushort c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return (c - '0');
|
||||
@@ -61,12 +62,12 @@ static unsigned char convertHex(ushort c)
|
||||
return (c - 'A' + 10);
|
||||
}
|
||||
|
||||
static QChar convertHex(QChar c1, QChar c2)
|
||||
static inline QChar convertHex(QChar c1, QChar c2)
|
||||
{
|
||||
return QChar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
|
||||
}
|
||||
|
||||
static QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
|
||||
static inline QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
|
||||
{
|
||||
return QChar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode()),
|
||||
(convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
|
||||
@@ -124,6 +125,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
|
||||
_tokenSpell = QStringRef();
|
||||
|
||||
_codePtr = code.unicode();
|
||||
_endPtr = _codePtr + code.length();
|
||||
_lastLinePtr = _codePtr;
|
||||
_tokenLinePtr = _codePtr;
|
||||
_tokenStartPtr = _codePtr;
|
||||
@@ -165,6 +167,52 @@ void Lexer::scanChar()
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
inline bool isBinop(int tok)
|
||||
{
|
||||
switch (tok) {
|
||||
case Lexer::T_AND:
|
||||
case Lexer::T_AND_AND:
|
||||
case Lexer::T_AND_EQ:
|
||||
case Lexer::T_DIVIDE_:
|
||||
case Lexer::T_DIVIDE_EQ:
|
||||
case Lexer::T_EQ:
|
||||
case Lexer::T_EQ_EQ:
|
||||
case Lexer::T_EQ_EQ_EQ:
|
||||
case Lexer::T_GE:
|
||||
case Lexer::T_GT:
|
||||
case Lexer::T_GT_GT:
|
||||
case Lexer::T_GT_GT_EQ:
|
||||
case Lexer::T_GT_GT_GT:
|
||||
case Lexer::T_GT_GT_GT_EQ:
|
||||
case Lexer::T_LE:
|
||||
case Lexer::T_LT:
|
||||
case Lexer::T_LT_LT:
|
||||
case Lexer::T_LT_LT_EQ:
|
||||
case Lexer::T_MINUS:
|
||||
case Lexer::T_MINUS_EQ:
|
||||
case Lexer::T_NOT_EQ:
|
||||
case Lexer::T_NOT_EQ_EQ:
|
||||
case Lexer::T_OR:
|
||||
case Lexer::T_OR_EQ:
|
||||
case Lexer::T_OR_OR:
|
||||
case Lexer::T_PLUS:
|
||||
case Lexer::T_PLUS_EQ:
|
||||
case Lexer::T_REMAINDER:
|
||||
case Lexer::T_REMAINDER_EQ:
|
||||
case Lexer::T_RETURN:
|
||||
case Lexer::T_STAR:
|
||||
case Lexer::T_STAR_EQ:
|
||||
case Lexer::T_XOR:
|
||||
case Lexer::T_XOR_EQ:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
int Lexer::lex()
|
||||
{
|
||||
const int previousTokenKind = _tokenKind;
|
||||
@@ -181,9 +229,15 @@ int Lexer::lex()
|
||||
switch (_tokenKind) {
|
||||
case T_LBRACE:
|
||||
case T_SEMICOLON:
|
||||
case T_QUESTION:
|
||||
case T_COLON:
|
||||
case T_TILDE:
|
||||
_delimited = true;
|
||||
break;
|
||||
default:
|
||||
if (isBinop(_tokenKind))
|
||||
_delimited = true;
|
||||
break;
|
||||
|
||||
case T_IF:
|
||||
case T_FOR:
|
||||
@@ -193,6 +247,7 @@ int Lexer::lex()
|
||||
_parenthesesCount = 0;
|
||||
break;
|
||||
|
||||
case T_ELSE:
|
||||
case T_DO:
|
||||
_parenthesesState = BalancedParentheses;
|
||||
break;
|
||||
@@ -221,7 +276,8 @@ int Lexer::lex()
|
||||
break;
|
||||
|
||||
case BalancedParentheses:
|
||||
_parenthesesState = IgnoreParentheses;
|
||||
if (_tokenKind != T_DO && _tokenKind != T_ELSE)
|
||||
_parenthesesState = IgnoreParentheses;
|
||||
break;
|
||||
} // switch
|
||||
|
||||
@@ -263,6 +319,80 @@ QChar Lexer::decodeUnicodeEscapeCharacter(bool *ok)
|
||||
return QChar();
|
||||
}
|
||||
|
||||
QChar Lexer::decodeHexEscapeCharacter(bool *ok)
|
||||
{
|
||||
if (isHexDigit(_codePtr[0]) && isHexDigit(_codePtr[1])) {
|
||||
scanChar();
|
||||
|
||||
const QChar c1 = _char;
|
||||
scanChar();
|
||||
|
||||
const QChar c2 = _char;
|
||||
scanChar();
|
||||
|
||||
if (ok)
|
||||
*ok = true;
|
||||
|
||||
return convertHex(c1, c2);
|
||||
}
|
||||
|
||||
*ok = false;
|
||||
return QChar();
|
||||
}
|
||||
|
||||
static inline bool isIdentifierStart(QChar ch)
|
||||
{
|
||||
// fast path for ascii
|
||||
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
|
||||
(ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
|
||||
ch == QLatin1Char('$') || ch == QLatin1Char('_'))
|
||||
return true;
|
||||
|
||||
switch (ch.category()) {
|
||||
case QChar::Number_Letter:
|
||||
case QChar::Letter_Uppercase:
|
||||
case QChar::Letter_Lowercase:
|
||||
case QChar::Letter_Titlecase:
|
||||
case QChar::Letter_Modifier:
|
||||
case QChar::Letter_Other:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isIdentifierPart(QChar ch)
|
||||
{
|
||||
// fast path for ascii
|
||||
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
|
||||
(ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
|
||||
(ch.unicode() >= '0' && ch.unicode() <= '9') ||
|
||||
ch == QLatin1Char('$') || ch == QLatin1Char('_') ||
|
||||
ch.unicode() == 0x200c /* ZWNJ */ || ch.unicode() == 0x200d /* ZWJ */)
|
||||
return true;
|
||||
|
||||
switch (ch.category()) {
|
||||
case QChar::Mark_NonSpacing:
|
||||
case QChar::Mark_SpacingCombining:
|
||||
|
||||
case QChar::Number_DecimalDigit:
|
||||
case QChar::Number_Letter:
|
||||
|
||||
case QChar::Letter_Uppercase:
|
||||
case QChar::Letter_Lowercase:
|
||||
case QChar::Letter_Titlecase:
|
||||
case QChar::Letter_Modifier:
|
||||
case QChar::Letter_Other:
|
||||
|
||||
case QChar::Punctuation_Connector:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int Lexer::scanToken()
|
||||
{
|
||||
if (_stackToken != -1) {
|
||||
@@ -298,7 +428,7 @@ again:
|
||||
_tokenStartPtr = _codePtr - 1;
|
||||
_tokenLine = _currentLineNumber;
|
||||
|
||||
if (_char.isNull())
|
||||
if (_codePtr > _endPtr)
|
||||
return EOF_SYMBOL;
|
||||
|
||||
const QChar ch = _char;
|
||||
@@ -383,7 +513,7 @@ again:
|
||||
case '/':
|
||||
if (_char == QLatin1Char('*')) {
|
||||
scanChar();
|
||||
while (!_char.isNull()) {
|
||||
while (_codePtr <= _endPtr) {
|
||||
if (_char == QLatin1Char('*')) {
|
||||
scanChar();
|
||||
if (_char == QLatin1Char('/')) {
|
||||
@@ -401,7 +531,7 @@ again:
|
||||
}
|
||||
}
|
||||
} else if (_char == QLatin1Char('/')) {
|
||||
while (!_char.isNull() && !isLineTerminator()) {
|
||||
while (_codePtr <= _endPtr && !isLineTerminator()) {
|
||||
scanChar();
|
||||
}
|
||||
if (_engine) {
|
||||
@@ -543,8 +673,14 @@ again:
|
||||
const QChar *startCode = _codePtr;
|
||||
|
||||
if (_engine) {
|
||||
while (!_char.isNull()) {
|
||||
if (isLineTerminator() || _char == QLatin1Char('\\')) {
|
||||
while (_codePtr <= _endPtr) {
|
||||
if (isLineTerminator()) {
|
||||
if (qmlMode())
|
||||
break;
|
||||
_errorCode = IllegalCharacter;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Stray newline in string literal");
|
||||
return T_ERROR;
|
||||
} else if (_char == QLatin1Char('\\')) {
|
||||
break;
|
||||
} else if (_char == quote) {
|
||||
_tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode);
|
||||
@@ -562,7 +698,7 @@ again:
|
||||
while (startCode != _codePtr - 1)
|
||||
_tokenText += *startCode++;
|
||||
|
||||
while (! _char.isNull()) {
|
||||
while (_codePtr <= _endPtr) {
|
||||
if (unsigned sequenceLength = isLineTerminatorSequence()) {
|
||||
multilineStringLiteral = true;
|
||||
_tokenText += _char;
|
||||
@@ -580,32 +716,29 @@ again:
|
||||
scanChar();
|
||||
|
||||
QChar u;
|
||||
bool ok = false;
|
||||
|
||||
switch (_char.unicode()) {
|
||||
// unicode escape sequence
|
||||
case 'u':
|
||||
case 'u': {
|
||||
bool ok = false;
|
||||
u = decodeUnicodeEscapeCharacter(&ok);
|
||||
if (! ok)
|
||||
u = _char;
|
||||
break;
|
||||
if (! ok) {
|
||||
_errorCode = IllegalUnicodeEscapeSequence;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
|
||||
return T_ERROR;
|
||||
}
|
||||
} break;
|
||||
|
||||
// hex escape sequence
|
||||
case 'x':
|
||||
if (isHexDigit(_codePtr[0]) && isHexDigit(_codePtr[1])) {
|
||||
scanChar();
|
||||
|
||||
const QChar c1 = _char;
|
||||
scanChar();
|
||||
|
||||
const QChar c2 = _char;
|
||||
scanChar();
|
||||
|
||||
u = convertHex(c1, c2);
|
||||
} else {
|
||||
u = _char;
|
||||
case 'x': {
|
||||
bool ok = false;
|
||||
u = decodeHexEscapeCharacter(&ok);
|
||||
if (!ok) {
|
||||
_errorCode = IllegalHexadecimalEscapeSequence;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Illegal hexadecimal escape sequence");
|
||||
return T_ERROR;
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
// single character escape sequence
|
||||
case '\\': u = QLatin1Char('\\'); scanChar(); break;
|
||||
@@ -619,32 +752,31 @@ again:
|
||||
case 'v': u = QLatin1Char('\v'); scanChar(); break;
|
||||
|
||||
case '0':
|
||||
if (! _codePtr[1].isDigit()) {
|
||||
if (! _codePtr->isDigit()) {
|
||||
scanChar();
|
||||
u = QLatin1Char('\0');
|
||||
} else {
|
||||
// ### parse deprecated octal escape sequence ?
|
||||
u = _char;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
// fall through
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
_errorCode = IllegalEscapeSequence;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Octal escape sequences are not allowed");
|
||||
return T_ERROR;
|
||||
|
||||
case '\r':
|
||||
if (isLineTerminatorSequence() == 2) {
|
||||
_tokenText += QLatin1Char('\r');
|
||||
u = QLatin1Char('\n');
|
||||
} else {
|
||||
u = QLatin1Char('\r');
|
||||
}
|
||||
scanChar();
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
case 0x2028u:
|
||||
case 0x2029u:
|
||||
u = _char;
|
||||
scanChar();
|
||||
break;
|
||||
|
||||
continue;
|
||||
|
||||
default:
|
||||
// non escape character
|
||||
@@ -675,28 +807,28 @@ again:
|
||||
case '9':
|
||||
return scanNumber(ch);
|
||||
|
||||
default:
|
||||
if (ch.isLetter() || ch == QLatin1Char('$') || ch == QLatin1Char('_') || (ch == QLatin1Char('\\') && _char == QLatin1Char('u'))) {
|
||||
bool identifierWithEscapeChars = false;
|
||||
if (ch == QLatin1Char('\\')) {
|
||||
identifierWithEscapeChars = true;
|
||||
default: {
|
||||
QChar c = ch;
|
||||
bool identifierWithEscapeChars = false;
|
||||
if (c == QLatin1Char('\\') && _char == QLatin1Char('u')) {
|
||||
identifierWithEscapeChars = true;
|
||||
bool ok = false;
|
||||
c = decodeUnicodeEscapeCharacter(&ok);
|
||||
if (! ok) {
|
||||
_errorCode = IllegalUnicodeEscapeSequence;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
|
||||
return T_ERROR;
|
||||
}
|
||||
}
|
||||
if (isIdentifierStart(c)) {
|
||||
if (identifierWithEscapeChars) {
|
||||
_tokenText.resize(0);
|
||||
bool ok = false;
|
||||
_tokenText += decodeUnicodeEscapeCharacter(&ok);
|
||||
_tokenText += c;
|
||||
_validTokenText = true;
|
||||
if (! ok) {
|
||||
_errorCode = IllegalUnicodeEscapeSequence;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
|
||||
return T_ERROR;
|
||||
}
|
||||
}
|
||||
while (true) {
|
||||
if (_char.isLetterOrNumber() || _char == QLatin1Char('$') || _char == QLatin1Char('_')) {
|
||||
if (identifierWithEscapeChars)
|
||||
_tokenText += _char;
|
||||
|
||||
scanChar();
|
||||
} else if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
|
||||
c = _char;
|
||||
if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
|
||||
if (! identifierWithEscapeChars) {
|
||||
identifierWithEscapeChars = true;
|
||||
_tokenText.resize(0);
|
||||
@@ -706,31 +838,41 @@ again:
|
||||
|
||||
scanChar(); // skip '\\'
|
||||
bool ok = false;
|
||||
_tokenText += decodeUnicodeEscapeCharacter(&ok);
|
||||
c = decodeUnicodeEscapeCharacter(&ok);
|
||||
if (! ok) {
|
||||
_errorCode = IllegalUnicodeEscapeSequence;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence");
|
||||
return T_ERROR;
|
||||
}
|
||||
} else {
|
||||
_tokenLength = _codePtr - _tokenStartPtr - 1;
|
||||
if (isIdentifierPart(c))
|
||||
_tokenText += c;
|
||||
continue;
|
||||
} else if (isIdentifierPart(c)) {
|
||||
if (identifierWithEscapeChars)
|
||||
_tokenText += c;
|
||||
|
||||
int kind = T_IDENTIFIER;
|
||||
|
||||
if (! identifierWithEscapeChars)
|
||||
kind = classify(_tokenStartPtr, _tokenLength, _qmlMode);
|
||||
|
||||
if (_engine) {
|
||||
if (kind == T_IDENTIFIER && identifierWithEscapeChars)
|
||||
_tokenSpell = _engine->newStringRef(_tokenText);
|
||||
else
|
||||
_tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
|
||||
}
|
||||
|
||||
return kind;
|
||||
scanChar();
|
||||
continue;
|
||||
}
|
||||
|
||||
_tokenLength = _codePtr - _tokenStartPtr - 1;
|
||||
|
||||
int kind = T_IDENTIFIER;
|
||||
|
||||
if (! identifierWithEscapeChars)
|
||||
kind = classify(_tokenStartPtr, _tokenLength, _qmlMode);
|
||||
|
||||
if (_engine) {
|
||||
if (kind == T_IDENTIFIER && identifierWithEscapeChars)
|
||||
_tokenSpell = _engine->newStringRef(_tokenText);
|
||||
else
|
||||
_tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
|
||||
}
|
||||
|
||||
return kind;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -741,12 +883,14 @@ again:
|
||||
int Lexer::scanNumber(QChar ch)
|
||||
{
|
||||
if (ch != QLatin1Char('0')) {
|
||||
double integer = ch.unicode() - '0';
|
||||
QByteArray buf;
|
||||
buf.reserve(64);
|
||||
buf += ch.toLatin1();
|
||||
|
||||
QChar n = _char;
|
||||
const QChar *code = _codePtr;
|
||||
while (n.isDigit()) {
|
||||
integer = integer * 10 + (n.unicode() - '0');
|
||||
buf += n.toLatin1();
|
||||
n = *code++;
|
||||
}
|
||||
|
||||
@@ -755,17 +899,23 @@ int Lexer::scanNumber(QChar ch)
|
||||
_codePtr = code - 1;
|
||||
scanChar();
|
||||
}
|
||||
_tokenValue = integer;
|
||||
buf.append('\0');
|
||||
_tokenValue = strtod(buf.constData(), 0);
|
||||
return T_NUMERIC_LITERAL;
|
||||
}
|
||||
} else if (_char.isDigit() && !qmlMode()) {
|
||||
_errorCode = IllegalCharacter;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Decimal numbers can't start with '0'");
|
||||
return T_ERROR;
|
||||
}
|
||||
|
||||
QVarLengthArray<char,32> chars;
|
||||
chars.append(ch.unicode());
|
||||
|
||||
if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) {
|
||||
// parse hex integer literal
|
||||
ch = _char; // remember the x or X to use it in the error message below.
|
||||
|
||||
// parse hex integer literal
|
||||
chars.append(_char.unicode());
|
||||
scanChar(); // consume `x'
|
||||
|
||||
@@ -774,6 +924,12 @@ int Lexer::scanNumber(QChar ch)
|
||||
scanChar();
|
||||
}
|
||||
|
||||
if (chars.size() < 3) {
|
||||
_errorCode = IllegalHexNumber;
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "At least one hexadecimal digit is required after '0%1'").arg(ch);
|
||||
return T_ERROR;
|
||||
}
|
||||
|
||||
_tokenValue = integerFromString(chars.constData(), chars.size(), 16);
|
||||
return T_NUMERIC_LITERAL;
|
||||
}
|
||||
@@ -871,7 +1027,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
|
||||
_patternFlags = 0;
|
||||
while (isIdentLetter(_char)) {
|
||||
int flag = regExpFlagFromChar(_char);
|
||||
if (flag == 0) {
|
||||
if (flag == 0 || _patternFlags & flag) {
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Invalid regular expression flag '%0'")
|
||||
.arg(QChar(_char));
|
||||
return false;
|
||||
@@ -888,7 +1044,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
|
||||
_tokenText += _char;
|
||||
scanChar();
|
||||
|
||||
if (_char.isNull() || isLineTerminator()) {
|
||||
if (_codePtr > _endPtr || isLineTerminator()) {
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Unterminated regular expression backslash sequence");
|
||||
return false;
|
||||
}
|
||||
@@ -902,15 +1058,15 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
|
||||
_tokenText += _char;
|
||||
scanChar();
|
||||
|
||||
while (! _char.isNull() && ! isLineTerminator()) {
|
||||
while (_codePtr <= _endPtr && ! isLineTerminator()) {
|
||||
if (_char == QLatin1Char(']'))
|
||||
break;
|
||||
if (_char == QLatin1Char('\\')) {
|
||||
else if (_char == QLatin1Char('\\')) {
|
||||
// regular expression backslash sequence
|
||||
_tokenText += _char;
|
||||
scanChar();
|
||||
|
||||
if (_char.isNull() || isLineTerminator()) {
|
||||
if (_codePtr > _endPtr || isLineTerminator()) {
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Unterminated regular expression backslash sequence");
|
||||
return false;
|
||||
}
|
||||
@@ -933,7 +1089,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (_char.isNull() || isLineTerminator()) {
|
||||
if (_codePtr > _endPtr || isLineTerminator()) {
|
||||
_errorMessage = QCoreApplication::translate("QmlParser", "Unterminated regular expression literal");
|
||||
return false;
|
||||
} else {
|
||||
@@ -1160,5 +1316,3 @@ bool Lexer::scanDirectives(Directives *directives)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "qmljskeywords_p.h"
|
||||
|
||||
@@ -43,7 +43,8 @@
|
||||
|
||||
#include "qmljsglobal_p.h"
|
||||
#include "qmljsgrammar_p.h"
|
||||
#include <QtCore/QString>
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
@@ -109,12 +110,14 @@ public:
|
||||
enum Error {
|
||||
NoError,
|
||||
IllegalCharacter,
|
||||
IllegalHexNumber,
|
||||
UnclosedStringLiteral,
|
||||
IllegalEscapeSequence,
|
||||
IllegalUnicodeEscapeSequence,
|
||||
UnclosedComment,
|
||||
IllegalExponentIndicator,
|
||||
IllegalIdentifier
|
||||
IllegalIdentifier,
|
||||
IllegalHexadecimalEscapeSequence
|
||||
};
|
||||
|
||||
enum RegExpBodyPrefix {
|
||||
@@ -189,6 +192,7 @@ private:
|
||||
|
||||
void syncProhibitAutomaticSemicolon();
|
||||
QChar decodeUnicodeEscapeCharacter(bool *ok);
|
||||
QChar decodeHexEscapeCharacter(bool *ok);
|
||||
|
||||
private:
|
||||
Engine *_engine;
|
||||
@@ -199,6 +203,7 @@ private:
|
||||
QStringRef _tokenSpell;
|
||||
|
||||
const QChar *_codePtr;
|
||||
const QChar *_endPtr;
|
||||
const QChar *_lastLinePtr;
|
||||
const QChar *_tokenLinePtr;
|
||||
const QChar *_tokenStartPtr;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -59,8 +59,8 @@
|
||||
#include "qmljsast_p.h"
|
||||
#include "qmljsengine_p.h"
|
||||
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
@@ -89,7 +89,8 @@ public:
|
||||
AST::FunctionDeclaration *FunctionDeclaration;
|
||||
AST::Node *Node;
|
||||
AST::PropertyName *PropertyName;
|
||||
AST::PropertyNameAndValueList *PropertyNameAndValueList;
|
||||
AST::PropertyAssignment *PropertyAssignment;
|
||||
AST::PropertyAssignmentList *PropertyAssignmentList;
|
||||
AST::SourceElement *SourceElement;
|
||||
AST::SourceElements *SourceElements;
|
||||
AST::Statement *Statement;
|
||||
@@ -99,7 +100,8 @@ public:
|
||||
AST::VariableDeclarationList *VariableDeclarationList;
|
||||
|
||||
AST::UiProgram *UiProgram;
|
||||
AST::UiImportList *UiImportList;
|
||||
AST::UiHeaderItemList *UiHeaderItemList;
|
||||
AST::UiPragma *UiPragma;
|
||||
AST::UiImport *UiImport;
|
||||
AST::UiParameterList *UiParameterList;
|
||||
AST::UiPublicMember *UiPublicMember;
|
||||
@@ -112,6 +114,7 @@ public:
|
||||
AST::UiObjectMemberList *UiObjectMemberList;
|
||||
AST::UiArrayMemberList *UiArrayMemberList;
|
||||
AST::UiQualifiedId *UiQualifiedId;
|
||||
AST::UiQualifiedPragmaId *UiQualifiedPragmaId;
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -193,6 +196,7 @@ protected:
|
||||
{ return location_stack [tos + index - 1]; }
|
||||
|
||||
AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr);
|
||||
AST::UiQualifiedPragmaId *reparseAsQualifiedPragmaId(AST::ExpressionNode *expr);
|
||||
|
||||
protected:
|
||||
Engine *driver;
|
||||
@@ -232,9 +236,9 @@ protected:
|
||||
|
||||
|
||||
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE1 79
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE1 87
|
||||
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE2 80
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE2 88
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
|
||||
|
||||
@@ -363,11 +363,12 @@ void Delta::insert(UiObjectMember *member, UiObjectMember *parentMember, const Q
|
||||
qmlText += doc->source().midRef(begin, end - begin);
|
||||
|
||||
QStringList importList;
|
||||
for (UiImportList *it = doc->qmlProgram()->imports; it; it = it->next) {
|
||||
if (!it->import)
|
||||
for (UiHeaderItemList *it = doc->qmlProgram()->headers; it; it = it->next) {
|
||||
UiImport *import = AST::cast<UiImport *>(it->headerItem);
|
||||
if (!import)
|
||||
continue;
|
||||
unsigned importBegin = it->import->firstSourceLocation().begin();
|
||||
unsigned importEnd = it->import->lastSourceLocation().end();
|
||||
unsigned importBegin = import->firstSourceLocation().begin();
|
||||
unsigned importEnd = import->lastSourceLocation().end();
|
||||
|
||||
importList << doc->source().mid(importBegin, importEnd - importBegin);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "parser/qmldirparser_p.h"
|
||||
#include "parser/qmljsengine_p.h"
|
||||
#include "qmljs_global.h"
|
||||
#include "qmljsconstants.h"
|
||||
|
||||
namespace QmlJS {
|
||||
|
||||
|
||||
@@ -125,7 +125,17 @@ bool Evaluate::visit(AST::UiProgram *)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::UiImportList *)
|
||||
bool Evaluate::visit(AST::UiHeaderItemList *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::UiQualifiedPragmaId *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::UiPragma *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -281,7 +291,17 @@ bool Evaluate::visit(AST::Elision *)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::PropertyNameAndValueList *)
|
||||
bool Evaluate::visit(AST::PropertyAssignmentList *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::PropertyGetterSetter *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Evaluate::visit(AST::PropertyNameAndValue *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,9 @@ protected:
|
||||
|
||||
// Ui
|
||||
virtual bool visit(AST::UiProgram *ast);
|
||||
virtual bool visit(AST::UiImportList *ast);
|
||||
virtual bool visit(AST::UiHeaderItemList *ast);
|
||||
virtual bool visit(AST::UiQualifiedPragmaId *ast);
|
||||
virtual bool visit(AST::UiPragma *ast);
|
||||
virtual bool visit(AST::UiImport *ast);
|
||||
virtual bool visit(AST::UiPublicMember *ast);
|
||||
virtual bool visit(AST::UiSourceElement *ast);
|
||||
@@ -90,7 +92,9 @@ protected:
|
||||
virtual bool visit(AST::ObjectLiteral *ast);
|
||||
virtual bool visit(AST::ElementList *ast);
|
||||
virtual bool visit(AST::Elision *ast);
|
||||
virtual bool visit(AST::PropertyNameAndValueList *ast);
|
||||
virtual bool visit(AST::PropertyAssignmentList *ast);
|
||||
virtual bool visit(AST::PropertyGetterSetter *ast);
|
||||
virtual bool visit(AST::PropertyNameAndValue *ast);
|
||||
virtual bool visit(AST::NestedExpression *ast);
|
||||
virtual bool visit(AST::IdentifierPropertyName *ast);
|
||||
virtual bool visit(AST::StringLiteralPropertyName *ast);
|
||||
|
||||
@@ -662,15 +662,38 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool visit(PropertyNameAndValueList *ast)
|
||||
virtual bool visit(PropertyAssignmentList *ast)
|
||||
{
|
||||
for (PropertyNameAndValueList *it = ast; it; it = it->next) {
|
||||
accept(it->name);
|
||||
out(": ", ast->colonToken);
|
||||
accept(it->value);
|
||||
if (it->next) {
|
||||
out(",", ast->commaToken); // always invalid?
|
||||
newLine();
|
||||
for (PropertyAssignmentList *it = ast; it; it = it->next) {
|
||||
PropertyNameAndValue *assignment = AST::cast<PropertyNameAndValue *>(it->assignment);
|
||||
if (assignment) {
|
||||
accept(assignment->name);
|
||||
out(": ", assignment->colonToken);
|
||||
accept(assignment->value);
|
||||
if (it->next) {
|
||||
out(",", ast->commaToken); // always invalid?
|
||||
newLine();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
PropertyGetterSetter *getterSetter = AST::cast<PropertyGetterSetter *>(it->assignment);
|
||||
if (getterSetter) {
|
||||
switch (getterSetter->type) {
|
||||
case PropertyGetterSetter::Getter:
|
||||
out("get");
|
||||
break;
|
||||
case PropertyGetterSetter::Setter:
|
||||
out("set");
|
||||
break;
|
||||
}
|
||||
|
||||
accept(getterSetter->name);
|
||||
out("(", getterSetter->lparenToken);
|
||||
accept(getterSetter->formals);
|
||||
out("(", getterSetter->rparenToken);
|
||||
out(" {", getterSetter->lbraceToken);
|
||||
accept(getterSetter->functionBody);
|
||||
out(" }", getterSetter->rbraceToken);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -1136,10 +1159,10 @@ protected:
|
||||
}
|
||||
|
||||
|
||||
virtual bool visit(UiImportList *ast)
|
||||
virtual bool visit(UiHeaderItemList *ast)
|
||||
{
|
||||
for (UiImportList *it = ast; it; it = it->next) {
|
||||
accept(it->import);
|
||||
for (UiHeaderItemList *it = ast; it; it = it->next) {
|
||||
accept(it->headerItem);
|
||||
newLine();
|
||||
}
|
||||
requireEmptyLine();
|
||||
|
||||
@@ -93,12 +93,12 @@ void TypeDescriptionReader::readDocument(UiProgram *ast)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ast->imports || ast->imports->next) {
|
||||
if (!ast->headers || ast->headers->next || !AST::cast<AST::UiImport *>(ast->headers->headerItem)) {
|
||||
addError(SourceLocation(), tr("Expected a single import."));
|
||||
return;
|
||||
}
|
||||
|
||||
UiImport *import = ast->imports->import;
|
||||
UiImport *import = AST::cast<AST::UiImport *>(ast->headers->headerItem);
|
||||
if (toString(import->importUri) != QLatin1String("QtQuick.tooling")) {
|
||||
addError(import->importToken, tr("Expected import of QtQuick.tooling."));
|
||||
return;
|
||||
@@ -612,20 +612,28 @@ void TypeDescriptionReader::readEnumValues(AST::UiScriptBinding *ast, LanguageUt
|
||||
return;
|
||||
}
|
||||
|
||||
for (PropertyNameAndValueList *it = objectLit->properties; it; it = it->next) {
|
||||
StringLiteralPropertyName *propName = dynamic_cast<StringLiteralPropertyName *>(it->name);
|
||||
NumericLiteral *value = dynamic_cast<NumericLiteral *>(it->value);
|
||||
UnaryMinusExpression *minus = dynamic_cast<UnaryMinusExpression *>(it->value);
|
||||
if (minus)
|
||||
value = dynamic_cast<NumericLiteral *>(minus->expression);
|
||||
if (!propName || !value) {
|
||||
addError(objectLit->firstSourceLocation(), tr("Expected object literal to contain only 'string: number' elements."));
|
||||
for (PropertyAssignmentList *it = objectLit->properties; it; it = it->next) {
|
||||
PropertyNameAndValue *assignement = AST::cast<PropertyNameAndValue *>(it->assignment);
|
||||
if (assignement) {
|
||||
StringLiteralPropertyName *propName = dynamic_cast<StringLiteralPropertyName *>(assignement->name);
|
||||
NumericLiteral *value = dynamic_cast<NumericLiteral *>(assignement->value);
|
||||
UnaryMinusExpression *minus = dynamic_cast<UnaryMinusExpression *>(assignement->value);
|
||||
if (minus)
|
||||
value = dynamic_cast<NumericLiteral *>(minus->expression);
|
||||
if (!propName || !value) {
|
||||
addError(objectLit->firstSourceLocation(), tr("Expected object literal to contain only 'string: number' elements."));
|
||||
continue;
|
||||
}
|
||||
|
||||
double v = value->value;
|
||||
if (minus)
|
||||
v = -v;
|
||||
fme->addKey(propName->id.toString(), v);
|
||||
continue;
|
||||
}
|
||||
|
||||
double v = value->value;
|
||||
if (minus)
|
||||
v = -v;
|
||||
fme->addKey(propName->id.toString(), v);
|
||||
PropertyGetterSetter *getterSetter = AST::cast<PropertyGetterSetter *>(it->assignment);
|
||||
if (getterSetter) {
|
||||
addError(objectLit->firstSourceLocation(), tr("Enum should not contain getter and setters, but only 'string: number' elements."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#define QMLJS_QMLJSUTILS_H
|
||||
|
||||
#include "qmljs_global.h"
|
||||
#include "qmljsconstants.h"
|
||||
#include "parser/qmljsastfwd_p.h"
|
||||
#include "parser/qmljsengine_p.h"
|
||||
|
||||
@@ -67,7 +68,7 @@ AST::SourceLocation locationFromRange(const T *node)
|
||||
template <class T>
|
||||
DiagnosticMessage errorMessage(const T *node, const QString &message)
|
||||
{
|
||||
return DiagnosticMessage(Severity::Error,
|
||||
return DiagnosticMessage(QmlJS::Severity::Error,
|
||||
locationFromRange(node),
|
||||
message);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ bool ChangeImportsVisitor::add(QmlJS::AST::UiProgram *ast, const Import &import)
|
||||
if (!ast)
|
||||
return false;
|
||||
|
||||
if (ast->imports && ast->imports->import) {
|
||||
if (ast->headers && ast->headers->headerItem) {
|
||||
int insertionPoint = 0;
|
||||
if (ast->members && ast->members->member)
|
||||
insertionPoint = ast->members->member->firstSourceLocation().begin();
|
||||
@@ -77,10 +77,11 @@ bool ChangeImportsVisitor::remove(QmlJS::AST::UiProgram *ast, const Import &impo
|
||||
if (!ast)
|
||||
return false;
|
||||
|
||||
for (UiImportList *iter = ast->imports; iter; iter = iter->next) {
|
||||
if (equals(iter->import, import)) {
|
||||
int start = iter->import->firstSourceLocation().begin();
|
||||
int end = iter->import->lastSourceLocation().end();
|
||||
for (UiHeaderItemList *iter = ast->headers; iter; iter = iter->next) {
|
||||
UiImport *iterImport = AST::cast<UiImport *>(iter->headerItem);
|
||||
if (equals(iterImport, import)) {
|
||||
int start = iterImport->firstSourceLocation().begin();
|
||||
int end = iterImport->lastSourceLocation().end();
|
||||
includeSurroundingWhitespace(start, end);
|
||||
replace(start, end - start, QString());
|
||||
setDidRewriting(true);
|
||||
|
||||
@@ -89,12 +89,13 @@ protected:
|
||||
return oldStateName;
|
||||
}
|
||||
|
||||
bool visit(UiImportList *ast) {
|
||||
for (UiImportList *it = ast; it; it = it->next) {
|
||||
if (it->import) {
|
||||
m_paster->addImports(createImport(it->import));
|
||||
bool visit(UiHeaderItemList *ast) {
|
||||
for (UiHeaderItemList *it = ast; it; it = it->next) {
|
||||
AST::UiImport *import = AST::cast<AST::UiImport *>(it->headerItem)
|
||||
if (import) {
|
||||
m_paster->addImports(createImport(import));
|
||||
|
||||
m_locations.remove(toLocation(it->import->firstSourceLocation(), it->import->lastSourceLocation()));
|
||||
m_locations.remove(toLocation(import->firstSourceLocation(), import->lastSourceLocation()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -690,8 +690,8 @@ void TextToModelMerger::setupImports(const Document::Ptr &doc,
|
||||
{
|
||||
QList<Import> existingImports = m_rewriterView->model()->imports();
|
||||
|
||||
for (UiImportList *iter = doc->qmlProgram()->imports; iter; iter = iter->next) {
|
||||
UiImport *import = iter->import;
|
||||
for (UiHeaderItemList *iter = doc->qmlProgram()->headers; iter; iter = iter->next) {
|
||||
UiImport *import = AST::cast<UiImport *>(iter->headerItem);
|
||||
if (!import)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -93,8 +93,8 @@ public:
|
||||
|
||||
QString imports;
|
||||
UiProgram *prog = currentFile->qmljsDocument()->qmlProgram();
|
||||
if (prog && prog->imports) {
|
||||
const int start = currentFile->startOf(prog->imports->firstSourceLocation());
|
||||
if (prog && prog->headers) {
|
||||
const int start = currentFile->startOf(prog->headers->firstSourceLocation());
|
||||
const int end = currentFile->startOf(prog->members->member->firstSourceLocation());
|
||||
imports = currentFile->textOf(start, end);
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ private:
|
||||
QModelIndex index = m_model->enterTestCase(rhsObjLit);
|
||||
m_nodeToIndex.insert(rhsObjLit, index);
|
||||
|
||||
if (AST::PropertyNameAndValueList *properties = rhsObjLit->properties)
|
||||
if (AST::PropertyAssignmentList *properties = rhsObjLit->properties)
|
||||
visitProperties(properties);
|
||||
|
||||
m_model->leaveTestCase();
|
||||
@@ -278,14 +278,14 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
void visitProperties(AST::PropertyNameAndValueList *properties)
|
||||
void visitProperties(AST::PropertyAssignmentList *properties)
|
||||
{
|
||||
while (properties) {
|
||||
QModelIndex index = m_model->enterTestCaseProperties(properties);
|
||||
m_nodeToIndex.insert(properties, index);
|
||||
|
||||
if (AST::ObjectLiteral *objLiteral = AST::cast<AST::ObjectLiteral *>(properties->value))
|
||||
visitProperties(objLiteral->properties);
|
||||
if (AST::PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(properties->assignment))
|
||||
if (AST::ObjectLiteral *objLiteral = AST::cast<AST::ObjectLiteral *>(assignment->value))
|
||||
visitProperties(objLiteral->properties);
|
||||
|
||||
m_model->leaveTestCaseProperties();
|
||||
properties = properties->next;
|
||||
@@ -595,24 +595,38 @@ void QmlOutlineModel::leaveTestCase()
|
||||
leaveNode();
|
||||
}
|
||||
|
||||
QModelIndex QmlOutlineModel::enterTestCaseProperties(AST::PropertyNameAndValueList *propertyNameAndValueList)
|
||||
QModelIndex QmlOutlineModel::enterTestCaseProperties(AST::PropertyAssignmentList *propertyAssignmentList)
|
||||
{
|
||||
QMap<int, QVariant> objectData;
|
||||
if (AST::IdentifierPropertyName *propertyName = AST::cast<AST::IdentifierPropertyName *>(propertyNameAndValueList->name)) {
|
||||
objectData.insert(Qt::DisplayRole, propertyName->id.toString());
|
||||
objectData.insert(ItemTypeRole, ElementBindingType);
|
||||
QmlOutlineItem *item;
|
||||
if (propertyNameAndValueList->value->kind == AST::Node::Kind_FunctionExpression)
|
||||
item = enterNode(objectData, propertyNameAndValueList, 0, m_icons->functionDeclarationIcon());
|
||||
else if (propertyNameAndValueList->value->kind == AST::Node::Kind_ObjectLiteral)
|
||||
item = enterNode(objectData, propertyNameAndValueList, 0, m_icons->objectDefinitionIcon());
|
||||
else
|
||||
item = enterNode(objectData, propertyNameAndValueList, 0, m_icons->scriptBindingIcon());
|
||||
if (AST::PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(
|
||||
propertyAssignmentList->assignment)) {
|
||||
if (AST::IdentifierPropertyName *propertyName = AST::cast<AST::IdentifierPropertyName *>(assignment->name)) {
|
||||
objectData.insert(Qt::DisplayRole, propertyName->id.toString());
|
||||
objectData.insert(ItemTypeRole, ElementBindingType);
|
||||
QmlOutlineItem *item;
|
||||
if (assignment->value->kind == AST::Node::Kind_FunctionExpression)
|
||||
item = enterNode(objectData, assignment, 0, m_icons->functionDeclarationIcon());
|
||||
else if (assignment->value->kind == AST::Node::Kind_ObjectLiteral)
|
||||
item = enterNode(objectData, assignment, 0, m_icons->objectDefinitionIcon());
|
||||
else
|
||||
item = enterNode(objectData, assignment, 0, m_icons->scriptBindingIcon());
|
||||
|
||||
return item->index();
|
||||
} else {
|
||||
return QModelIndex();
|
||||
return item->index();
|
||||
}
|
||||
}
|
||||
if (AST::PropertyGetterSetter *getterSetter = AST::cast<AST::PropertyGetterSetter *>(
|
||||
propertyAssignmentList->assignment)) {
|
||||
if (AST::IdentifierPropertyName *propertyName = AST::cast<AST::IdentifierPropertyName *>(getterSetter->name)) {
|
||||
objectData.insert(Qt::DisplayRole, propertyName->id.toString());
|
||||
objectData.insert(ItemTypeRole, ElementBindingType);
|
||||
QmlOutlineItem *item;
|
||||
item = enterNode(objectData, getterSetter, 0, m_icons->functionDeclarationIcon());
|
||||
|
||||
return item->index();
|
||||
|
||||
}
|
||||
}
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
void QmlOutlineModel::leaveTestCaseProperties()
|
||||
@@ -642,8 +656,8 @@ AST::SourceLocation QmlOutlineModel::sourceLocation(const QModelIndex &index) co
|
||||
location = getLocation(member);
|
||||
else if (AST::ExpressionNode *expression = node->expressionCast())
|
||||
location = getLocation(expression);
|
||||
else if (AST::PropertyNameAndValueList *propertyNameAndValueList = AST::cast<AST::PropertyNameAndValueList *>(node))
|
||||
location = getLocation(propertyNameAndValueList);
|
||||
else if (AST::PropertyAssignmentList *propertyAssignmentList = AST::cast<AST::PropertyAssignmentList *>(node))
|
||||
location = getLocation(propertyAssignmentList);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
@@ -913,7 +927,15 @@ AST::SourceLocation QmlOutlineModel::getLocation(AST::ExpressionNode *exprNode)
|
||||
return location;
|
||||
}
|
||||
|
||||
AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyNameAndValueList *propertyNode) {
|
||||
AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyAssignmentList *propertyNode) {
|
||||
if (AST::PropertyNameAndValue *assignment = AST::cast<AST::PropertyNameAndValue *>(propertyNode->assignment))
|
||||
return getLocation(assignment);
|
||||
if (AST::PropertyGetterSetter *getterSetter = AST::cast<AST::PropertyGetterSetter *>(propertyNode->assignment))
|
||||
return getLocation(getterSetter);
|
||||
return propertyNode->commaToken; // should never happen
|
||||
}
|
||||
|
||||
AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyNameAndValue *propertyNode) {
|
||||
AST::SourceLocation location;
|
||||
location.offset = propertyNode->name->propertyNameToken.offset;
|
||||
location.length = propertyNode->value->lastSourceLocation().end() - location.offset;
|
||||
@@ -921,6 +943,14 @@ AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyNameAndValueList *
|
||||
return location;
|
||||
}
|
||||
|
||||
AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyGetterSetter *propertyNode) {
|
||||
AST::SourceLocation location;
|
||||
location.offset = propertyNode->name->propertyNameToken.offset;
|
||||
location.length = propertyNode->rbraceToken.end() - location.offset;
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
QIcon QmlOutlineModel::getIcon(AST::UiQualifiedId *qualifiedId) {
|
||||
QIcon icon;
|
||||
if (qualifiedId) {
|
||||
|
||||
@@ -122,7 +122,7 @@ private:
|
||||
QModelIndex enterTestCase(QmlJS::AST::ObjectLiteral *objectLiteral);
|
||||
void leaveTestCase();
|
||||
|
||||
QModelIndex enterTestCaseProperties(QmlJS::AST::PropertyNameAndValueList *propertyNameAndValueList);
|
||||
QModelIndex enterTestCaseProperties(QmlJS::AST::PropertyAssignmentList *propertyAssignmentList);
|
||||
void leaveTestCaseProperties();
|
||||
|
||||
private:
|
||||
@@ -139,7 +139,9 @@ private:
|
||||
static QString asString(QmlJS::AST::UiQualifiedId *id);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::UiObjectMember *objMember);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::ExpressionNode *exprNode);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyNameAndValueList *propertyNode);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyAssignmentList *propertyNode);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyNameAndValue *propertyNode);
|
||||
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyGetterSetter *propertyNode);
|
||||
QIcon getIcon(QmlJS::AST::UiQualifiedId *objDef);
|
||||
|
||||
QString getAnnotation(QmlJS::AST::UiObjectInitializer *objInitializer);
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace {
|
||||
|
||||
// ### does not necessarily give the full AST path!
|
||||
// intentionally does not contain lists like
|
||||
// UiImportList, SourceElements, UiObjectMemberList
|
||||
// UiHeaderItemList, SourceElements, UiObjectMemberList
|
||||
class AstPath: protected AST::Visitor
|
||||
{
|
||||
QList<AST::Node *> _path;
|
||||
|
||||
Reference in New Issue
Block a user