aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/animations/qabstractanimationjob_p.h2
-rw-r--r--src/qml/animations/qanimationgroupjob_p.h2
-rw-r--r--src/qml/animations/qanimationjobutil_p.h2
-rw-r--r--src/qml/animations/qcontinuinganimationgroupjob_p.h2
-rw-r--r--src/qml/animations/qparallelanimationgroupjob_p.h2
-rw-r--r--src/qml/animations/qpauseanimationjob_p.h2
-rw-r--r--src/qml/animations/qsequentialanimationgroupjob_p.h2
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp65
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h8
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp13
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h6
-rw-r--r--src/qml/compiler/qv4codegen.cpp352
-rw-r--r--src/qml/compiler/qv4codegen_p.h25
-rw-r--r--src/qml/compiler/qv4compileddata.cpp51
-rw-r--r--src/qml/compiler/qv4compileddata_p.h5
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h5
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp114
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions_p.h8
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp8
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h4
-rw-r--r--src/qml/configure.json45
-rw-r--r--src/qml/debugger/qqmlabstractprofileradapter_p.h6
-rw-r--r--src/qml/debugger/qqmlprofiler.cpp9
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h2
-rw-r--r--src/qml/jit/qv4assembler.cpp19
-rw-r--r--src/qml/jit/qv4assembler_p.h1
-rw-r--r--src/qml/jit/qv4jit.cpp16
-rw-r--r--src/qml/jit/qv4jit_p.h2
-rw-r--r--src/qml/jsapi/qjsengine.cpp8
-rw-r--r--src/qml/jsruntime/jsruntime.pri10
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h2
-rw-r--r--src/qml/jsruntime/qv4context_p.h22
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp2
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp257
-rw-r--r--src/qml/jsruntime/qv4engine_p.h25
-rw-r--r--src/qml/jsruntime/qv4enginebase_p.h8
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h21
-rw-r--r--src/qml/jsruntime/qv4function.cpp12
-rw-r--r--src/qml/jsruntime/qv4function_p.h2
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp26
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h16
-rw-r--r--src/qml/jsruntime/qv4global_p.h3
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp532
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h101
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp41
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h42
-rw-r--r--src/qml/jsruntime/qv4managed.cpp7
-rw-r--r--src/qml/jsruntime/qv4managed_p.h48
-rw-r--r--src/qml/jsruntime/qv4object.cpp17
-rw-r--r--src/qml/jsruntime/qv4object_p.h8
-rw-r--r--src/qml/jsruntime/qv4profiling.cpp9
-rw-r--r--src/qml/jsruntime/qv4profiling_p.h2
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp4
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp20
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp28
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h1
-rw-r--r--src/qml/jsruntime/qv4runtimecodegen.cpp5
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4serialize.cpp18
-rw-r--r--src/qml/jsruntime/qv4string.cpp3
-rw-r--r--src/qml/jsruntime/qv4string_p.h6
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp6
-rw-r--r--src/qml/jsruntime/qv4value.cpp2
-rw-r--r--src/qml/jsruntime/qv4value_p.h11
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp19
-rw-r--r--src/qml/memory/qv4heap_p.h81
-rw-r--r--src/qml/memory/qv4mm.cpp25
-rw-r--r--src/qml/memory/qv4mm_p.h225
-rw-r--r--src/qml/parser/parser.pri14
-rw-r--r--src/qml/parser/qqmljs.g4165
-rw-r--r--src/qml/parser/qqmljsast.cpp173
-rw-r--r--src/qml/parser/qqmljsast_p.h476
-rw-r--r--src/qml/parser/qqmljsastfwd_p.h17
-rw-r--r--src/qml/parser/qqmljsastvisitor_p.h40
-rw-r--r--src/qml/parser/qqmljsengine_p.cpp7
-rw-r--r--src/qml/parser/qqmljsengine_p.h28
-rw-r--r--src/qml/parser/qqmljsgrammar.cpp1167
-rw-r--r--src/qml/parser/qqmljsgrammar_p.h215
-rw-r--r--src/qml/parser/qqmljskeywords_p.h128
-rw-r--r--src/qml/parser/qqmljslexer.cpp752
-rw-r--r--src/qml/parser/qqmljslexer_p.h88
-rw-r--r--src/qml/parser/qqmljsparser.cpp2010
-rw-r--r--src/qml/parser/qqmljsparser_p.h258
-rw-r--r--src/qml/qml.pro2
-rw-r--r--src/qml/qml/qml.pri21
-rw-r--r--src/qml/qml/qqmlcomponent.cpp2
-rw-r--r--src/qml/qml/qqmlengine.cpp15
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp4
-rw-r--r--src/qml/qml/qqmllocale.cpp2
-rw-r--r--src/qml/qml/qqmllocale_p.h2
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp6
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp4
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp14
-rw-r--r--src/qml/qml/qqmlxmlhttprequest_p.h4
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp10
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h2
-rw-r--r--src/qml/qml/v8/qv8engine.cpp24
-rw-r--r--src/qml/qml/v8/qv8engine_p.h9
-rw-r--r--src/qml/qtqmlglobal.h1
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp58
-rw-r--r--src/qml/types/qqmldelegatemodel_p.h7
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h2
-rw-r--r--src/qml/types/qqmllistmodel.cpp2
-rw-r--r--src/qml/types/qqmllistmodel_p.h2
-rw-r--r--src/qml/types/qqmllistmodel_p_p.h2
-rw-r--r--src/qml/types/qqmllistmodelworkeragent_p.h2
-rw-r--r--src/qml/types/qqmlmodelsmodule.cpp5
-rw-r--r--src/qml/types/qqmltimer_p.h2
-rw-r--r--src/qml/types/qquickworkerscript.cpp5
-rw-r--r--src/qml/types/types.pri18
-rw-r--r--src/qml/util/qqmladaptormodel.cpp107
-rw-r--r--src/qml/util/qqmladaptormodel_p.h11
117 files changed, 5098 insertions, 7260 deletions
diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h
index 63fd4b0dac..0be6ca96ea 100644
--- a/src/qml/animations/qabstractanimationjob_p.h
+++ b/src/qml/animations/qabstractanimationjob_p.h
@@ -56,6 +56,8 @@
#include <QtCore/private/qabstractanimation_p.h>
#include <vector>
+QT_REQUIRE_CONFIG(qml_animation);
+
QT_BEGIN_NAMESPACE
class QAnimationGroupJob;
diff --git a/src/qml/animations/qanimationgroupjob_p.h b/src/qml/animations/qanimationgroupjob_p.h
index fb567dc019..b01b2f3b36 100644
--- a/src/qml/animations/qanimationgroupjob_p.h
+++ b/src/qml/animations/qanimationgroupjob_p.h
@@ -54,6 +54,8 @@
#include "private/qabstractanimationjob_p.h"
#include <QtCore/qdebug.h>
+QT_REQUIRE_CONFIG(qml_animation);
+
QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QAnimationGroupJob : public QAbstractAnimationJob
diff --git a/src/qml/animations/qanimationjobutil_p.h b/src/qml/animations/qanimationjobutil_p.h
index 0bb9e83b2d..e3d6fe9178 100644
--- a/src/qml/animations/qanimationjobutil_p.h
+++ b/src/qml/animations/qanimationjobutil_p.h
@@ -51,6 +51,8 @@
// We mean it.
//
+QT_REQUIRE_CONFIG(qml_animation);
+
#define RETURN_IF_DELETED(func) \
{ \
bool *prevWasDeleted = m_wasDeleted; \
diff --git a/src/qml/animations/qcontinuinganimationgroupjob_p.h b/src/qml/animations/qcontinuinganimationgroupjob_p.h
index baf4ff1ae5..c67b8d39ad 100644
--- a/src/qml/animations/qcontinuinganimationgroupjob_p.h
+++ b/src/qml/animations/qcontinuinganimationgroupjob_p.h
@@ -53,6 +53,8 @@
#include "private/qanimationgroupjob_p.h"
+QT_REQUIRE_CONFIG(qml_animation);
+
QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QContinuingAnimationGroupJob : public QAnimationGroupJob
diff --git a/src/qml/animations/qparallelanimationgroupjob_p.h b/src/qml/animations/qparallelanimationgroupjob_p.h
index 67ba626247..0265fe3274 100644
--- a/src/qml/animations/qparallelanimationgroupjob_p.h
+++ b/src/qml/animations/qparallelanimationgroupjob_p.h
@@ -53,6 +53,8 @@
#include "private/qanimationgroupjob_p.h"
+QT_REQUIRE_CONFIG(qml_animation);
+
QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QParallelAnimationGroupJob : public QAnimationGroupJob
diff --git a/src/qml/animations/qpauseanimationjob_p.h b/src/qml/animations/qpauseanimationjob_p.h
index d0e8d57fc7..6c9bbf0dab 100644
--- a/src/qml/animations/qpauseanimationjob_p.h
+++ b/src/qml/animations/qpauseanimationjob_p.h
@@ -53,6 +53,8 @@
#include <private/qanimationgroupjob_p.h>
+QT_REQUIRE_CONFIG(qml_animation);
+
QT_BEGIN_NAMESPACE
class Q_QML_PRIVATE_EXPORT QPauseAnimationJob : public QAbstractAnimationJob
diff --git a/src/qml/animations/qsequentialanimationgroupjob_p.h b/src/qml/animations/qsequentialanimationgroupjob_p.h
index 800f0c3b90..13f9806be1 100644
--- a/src/qml/animations/qsequentialanimationgroupjob_p.h
+++ b/src/qml/animations/qsequentialanimationgroupjob_p.h
@@ -53,6 +53,8 @@
#include <private/qanimationgroupjob_p.h>
+QT_REQUIRE_CONFIG(qml_animation);
+
QT_BEGIN_NAMESPACE
class QPauseAnimationJob;
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 4a1b27d7aa..9de27a2588 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -96,23 +96,24 @@ void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, cons
declarationsOverride = nullptr;
}
-QString Object::sanityCheckFunctionNames(const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation)
+QString IRBuilder::sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation)
{
QSet<int> functionNames;
- for (Function *f = functions->first; f; f = f->next) {
- QQmlJS::AST::FunctionDeclaration *function = f->functionDeclaration;
- Q_ASSERT(function);
- *errorLocation = function->identifierToken;
+ for (auto functionit = obj->functionsBegin(); functionit != obj->functionsEnd(); ++functionit) {
+ Function *f = functionit.ptr;
+ errorLocation->startLine = f->location.line;
+ errorLocation->startColumn = f->location.column;
if (functionNames.contains(f->nameIndex))
return tr("Duplicate method name");
functionNames.insert(f->nameIndex);
- for (QmlIR::Signal *s = qmlSignals->first; s; s = s->next) {
+ for (auto signalit = obj->signalsBegin(); signalit != obj->signalsEnd(); ++signalit) {
+ QmlIR::Signal *s = signalit.ptr;
if (s->nameIndex == f->nameIndex)
return tr("Duplicate method name");
}
- const QString name = function->name.toString();
+ const QString name = stringAt(f->nameIndex);
if (name.at(0).isUpper())
return tr("Method names cannot begin with an upper case letter");
if (illegalNames.contains(name))
@@ -601,7 +602,7 @@ bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qu
return false;
QQmlJS::AST::SourceLocation loc;
- QString error = obj->sanityCheckFunctionNames(illegalNames, &loc);
+ QString error = sanityCheckFunctionNames(obj, illegalNames, &loc);
if (!error.isEmpty()) {
recordError(loc, error);
return false;
@@ -976,21 +977,21 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node)
const int index = _object->functionsAndExpressions->append(foe);
Function *f = New<Function>();
- f->functionDeclaration = funDecl;
QQmlJS::AST::SourceLocation loc = funDecl->identifierToken;
f->location.line = loc.startLine;
f->location.column = loc.startColumn;
f->index = index;
f->nameIndex = registerString(funDecl->name.toString());
- int formalsCount = 0;
- for (QQmlJS::AST::FormalParameterList *it = funDecl->formals; it; it = it->next)
- ++formalsCount;
+ const QStringList formals = funDecl->formals->formals();
+ int formalsCount = formals.size();
f->formals.allocate(pool, formalsCount);
int i = 0;
- for (QQmlJS::AST::FormalParameterList *it = funDecl->formals; it; it = it->next, ++i)
- f->formals[i] = registerString(it->name.toString());
+ for (const QString &arg : formals) {
+ f->formals[i] = registerString(arg);
+ ++i;
+ }
_object->appendFunction(f);
} else {
@@ -1824,6 +1825,9 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
}
scan.leaveEnvironment();
+ if (hasError)
+ return QVector<int>();
+
_context = nullptr;
for (int i = 0; i < functions.count(); ++i) {
@@ -1841,10 +1845,10 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
else
name = QStringLiteral("%qml-expression-entry");
- QQmlJS::AST::SourceElements *body;
- if (function)
- body = function->body ? function->body->elements : nullptr;
- else {
+ QQmlJS::AST::StatementList *body;
+ if (function) {
+ body = function->body;
+ } else {
// Synthesize source elements.
QQmlJS::MemoryPool *pool = jsEngine->pool();
@@ -1854,8 +1858,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
QQmlJS::AST::ExpressionNode *expr = node->expressionCast();
stmt = new (pool) QQmlJS::AST::ExpressionStatement(expr);
}
- QQmlJS::AST::SourceElement *element = new (pool) QQmlJS::AST::StatementSourceElement(stmt);
- body = new (pool) QQmlJS::AST::SourceElements(element);
+ body = new (pool) QQmlJS::AST::StatementList(stmt);
body = body->finish();
}
@@ -1869,7 +1872,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
return runtimeFunctionIndices;
}
-int JSCodeGen::defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals, AST::SourceElements *body)
+int JSCodeGen::defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals, AST::StatementList *body)
{
int qmlContextTemp = -1;
int importedScriptsTemp = -1;
@@ -2430,8 +2433,6 @@ QmlIR::Object *IRLoader::loadObject(const QV4::CompiledData::Object *serializedO
}
}
- QQmlJS::Engine *jsParserEngine = &output->jsParserEngine;
-
const quint32_le *functionIdx = serializedObject->functionOffsetTable();
for (uint i = 0; i < serializedObject->nFunctions; ++i, ++functionIdx) {
QmlIR::Function *f = pool->New<QmlIR::Function>();
@@ -2442,26 +2443,10 @@ QmlIR::Object *IRLoader::loadObject(const QV4::CompiledData::Object *serializedO
f->location = compiledFunction->location;
f->nameIndex = compiledFunction->nameIndex;
- QQmlJS::AST::FormalParameterList *paramList = nullptr;
- const quint32_le *formalNameIdx = compiledFunction->formalsTable();
- for (uint i = 0; i < compiledFunction->nFormals; ++i, ++formalNameIdx) {
- const QString formal = unit->stringAt(*formalNameIdx);
- QStringRef paramNameRef = jsParserEngine->newStringRef(formal);
-
- if (paramList)
- paramList = new (pool) QQmlJS::AST::FormalParameterList(paramList, paramNameRef);
- else
- paramList = new (pool) QQmlJS::AST::FormalParameterList(paramNameRef);
- }
-
- if (paramList)
- paramList = paramList->finish();
-
const QString name = unit->stringAt(compiledFunction->nameIndex);
- f->functionDeclaration = new(pool) QQmlJS::AST::FunctionDeclaration(jsParserEngine->newStringRef(name), paramList, /*body*/nullptr);
f->formals.allocate(pool, int(compiledFunction->nFormals));
- formalNameIdx = compiledFunction->formalsTable();
+ const quint32_le *formalNameIdx = compiledFunction->formalsTable();
for (uint i = 0; i < compiledFunction->nFormals; ++i, ++formalNameIdx)
f->formals[i] = *formalNameIdx;
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index c2cf18e3c4..14f59dd7e8 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -57,7 +57,6 @@
#include <private/qqmljsmemorypool_p.h>
#include <private/qv4codegen_p.h>
#include <private/qv4compiler_p.h>
-#include <private/qqmljslexer_p.h>
#include <QTextStream>
#include <QCoreApplication>
@@ -325,7 +324,6 @@ struct Alias : public QV4::CompiledData::Alias
struct Function
{
- QQmlJS::AST::FunctionDeclaration *functionDeclaration;
QV4::CompiledData::Location location;
int nameIndex;
quint32 index; // index in parsedQML::functions
@@ -400,8 +398,6 @@ public:
void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::AST::SourceLocation &location = QQmlJS::AST::SourceLocation());
- QString sanityCheckFunctionNames(const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation);
-
QString appendEnum(Enum *enumeration);
QString appendSignal(Signal *signal);
QString appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation);
@@ -548,6 +544,8 @@ public:
static bool isStatementNodeScript(QQmlJS::AST::Statement *statement);
static bool isRedundantNullInitializerForPropertyDeclaration(Property *property, QQmlJS::AST::Statement *statement);
+ QString sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation);
+
QList<QQmlJS::DiagnosticMessage> errors;
QSet<QString> illegalNames;
@@ -623,7 +621,7 @@ struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen
int defineFunction(const QString &name, AST::Node *ast,
AST::FormalParameterList *formals,
- AST::SourceElements *body) override;
+ AST::StatementList *body) override;
protected:
void beginFunctionBodyHook() override;
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index a896745b3f..34c2c3ffc9 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -466,10 +466,8 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
for (const QString &param : qAsConst(parameters)) {
QStringRef paramNameRef = compiler->newStringRef(param);
- if (paramList)
- paramList = new (pool) QQmlJS::AST::FormalParameterList(paramList, paramNameRef);
- else
- paramList = new (pool) QQmlJS::AST::FormalParameterList(paramNameRef);
+ QQmlJS::AST::BindingElement *b = new (pool) QQmlJS::AST::BindingElement(paramNameRef, nullptr);
+ paramList = new (pool) QQmlJS::AST::FormalParameterList(paramList, b);
}
if (paramList)
@@ -490,11 +488,8 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
}
if (!functionDeclaration) {
QQmlJS::AST::Statement *statement = static_cast<QQmlJS::AST::Statement*>(foe->node);
- QQmlJS::AST::SourceElement *sourceElement = new (pool) QQmlJS::AST::StatementSourceElement(statement);
- QQmlJS::AST::SourceElements *elements = new (pool) QQmlJS::AST::SourceElements(sourceElement);
- elements = elements->finish();
-
- QQmlJS::AST::FunctionBody *body = new (pool) QQmlJS::AST::FunctionBody(elements);
+ QQmlJS::AST::StatementList *body = new (pool) QQmlJS::AST::StatementList(statement);
+ body = body->finish();
functionDeclaration = new (pool) QQmlJS::AST::FunctionDeclaration(compiler->newStringRef(stringAt(binding->propertyNameIndex)), paramList, body);
functionDeclaration->lbraceToken = functionDeclaration->functionToken
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index e69f2cd310..9bd9d82e0d 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -181,6 +181,12 @@ public:
return addJumpInstruction(data);
}
+ Q_REQUIRED_RESULT Jump jumpNotUndefined()
+ {
+ Instruction::JumpNotUndefined data;
+ return addJumpInstruction(data);
+ }
+
void jumpStrictEqual(const StackSlot &lhs, const Label &target)
{
Instruction::CmpStrictEqual cmp;
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 8ada1d505e..f7617c66de 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -58,6 +58,8 @@
#include <cmath>
#include <iostream>
+static const bool disable_lookups = false;
+
#ifdef CONST
#undef CONST
#endif
@@ -120,7 +122,10 @@ void Codegen::generateFromProgram(const QString &fileName,
ScanFunctions scan(this, sourceCode, mode);
scan(node);
- defineFunction(QStringLiteral("%entry"), node, nullptr, node->elements);
+ if (hasError)
+ return;
+
+ defineFunction(QStringLiteral("%entry"), node, nullptr, node->statements);
}
void Codegen::enterContext(Node *node)
@@ -337,45 +342,10 @@ Codegen::Reference Codegen::expression(ExpressionNode *ast)
return r.result();
}
-Codegen::Result Codegen::sourceElement(SourceElement *ast)
-{
- Result r(nx);
- if (ast) {
- qSwap(_expr, r);
- accept(ast);
- qSwap(_expr, r);
- }
- return r;
-}
-
-void Codegen::functionBody(FunctionBody *ast)
-{
- if (ast)
- sourceElements(ast->elements);
-}
-
void Codegen::program(Program *ast)
{
if (ast) {
- sourceElements(ast->elements);
- }
-}
-
-void Codegen::sourceElements(SourceElements *ast)
-{
- bool _requiresReturnValue = false;
- qSwap(_requiresReturnValue, requiresReturnValue);
- for (SourceElements *it = ast; it; it = it->next) {
- if (!it->next)
- qSwap(_requiresReturnValue, requiresReturnValue);
- sourceElement(it->element);
- if (hasError)
- return;
- if (StatementSourceElement *sse = AST::cast<StatementSourceElement *>(it->element)) {
- if (AST::cast<ThrowStatement *>(sse->statement) ||
- AST::cast<ReturnStatement *>(sse->statement))
- return;
- }
+ statementList(ast->statements);
}
}
@@ -389,7 +359,10 @@ void Codegen::statementList(StatementList *ast)
it->next->statement->kind == Statement::Kind_ContinueStatement ||
it->next->statement->kind == Statement::Kind_ReturnStatement)
requiresReturnValue = _requiresReturnValue;
- statement(it->statement);
+ if (FunctionDeclaration *decl = cast<FunctionDeclaration *>(it->statement))
+ statement(decl);
+ else
+ statement(static_cast<Statement *>(it->statement));
requiresReturnValue = false;
if (it->statement->kind == Statement::Kind_ThrowStatement ||
it->statement->kind == Statement::Kind_BreakStatement ||
@@ -424,6 +397,67 @@ void Codegen::variableDeclarationList(VariableDeclarationList *ast)
}
}
+void Codegen::initializeAndDestructureBindingElement(AST::BindingElement *e, const Codegen::Reference &baseRef)
+{
+ RegisterScope scope(this);
+ Reference varToStore = e->name.isNull() ? Reference::fromStackSlot(this, bytecodeGenerator->newRegister()) : referenceForName(e->name, true);
+ if (e->initializer && baseRef == varToStore) {
+ baseRef.loadInAccumulator();
+ BytecodeGenerator::Jump jump = bytecodeGenerator->jumpNotUndefined();
+ expression(e->initializer).loadInAccumulator();
+ varToStore.storeConsumeAccumulator();
+ jump.link();
+ } else if (e->initializer) {
+ baseRef.loadInAccumulator();
+ BytecodeGenerator::Jump jump = bytecodeGenerator->jumpNotUndefined();
+ expression(e->initializer).loadInAccumulator();
+ jump.link();
+ varToStore.storeConsumeAccumulator();
+ } else if (baseRef != varToStore) {
+ baseRef.loadInAccumulator();
+ varToStore.storeConsumeAccumulator();
+ }
+ if (BindingElementList *l = e->elementList()) {
+ destructureElementList(varToStore, l);
+ } else if (BindingPropertyList *p = e->propertyList()) {
+ destructurePropertyList(varToStore, p);
+ }
+}
+
+void Codegen::destructurePropertyList(const Codegen::Reference &object, BindingPropertyList *bindingList)
+{
+ RegisterScope scope(this);
+
+ for (BindingPropertyList *p = bindingList; p; p = p->next) {
+ RegisterScope scope(this);
+ QString propertyName = p->propertyName->asString();
+ Reference property = Reference::fromMember(object, propertyName);
+ initializeAndDestructureBindingElement(p->binding, property);
+ }
+}
+
+void Codegen::destructureElementList(const Codegen::Reference &array, BindingElementList *bindingList)
+{
+ RegisterScope scope(this);
+
+ int index = 0;
+ for (BindingElementList *p = bindingList; p; p = p->next) {
+ for (Elision *elision = p->elision; elision; elision = elision->next)
+ ++index;
+
+ RegisterScope scope(this);
+
+ Reference idx = Reference::fromConst(this, Encode(index));
+ Reference property = Reference::fromSubscript(array, idx);
+ BindingElement *e = p->bindingElement();
+ if (e)
+ initializeAndDestructureBindingElement(e, property);
+ else {
+ throwSyntaxError(bindingList->firstSourceLocation(), QString::fromLatin1("Support for rest elements in binding arrays not implemented!"));
+ }
+ }
+}
+
bool Codegen::visit(ArgumentList *)
{
@@ -485,19 +519,13 @@ bool Codegen::visit(FormalParameterList *)
return false;
}
-bool Codegen::visit(FunctionBody *)
-{
- Q_UNREACHABLE();
- return false;
-}
-
bool Codegen::visit(Program *)
{
Q_UNREACHABLE();
return false;
}
-bool Codegen::visit(PropertyAssignmentList *)
+bool Codegen::visit(PropertyDefinitionList *)
{
Q_UNREACHABLE();
return false;
@@ -515,12 +543,6 @@ bool Codegen::visit(PropertyGetterSetter *)
return false;
}
-bool Codegen::visit(SourceElements *)
-{
- Q_UNREACHABLE();
- return false;
-}
-
bool Codegen::visit(StatementList *)
{
Q_UNREACHABLE();
@@ -1279,6 +1301,12 @@ bool Codegen::visit(CallExpression *ast)
if (hasError)
return false;
+ handleCall(base, calldata);
+ return false;
+}
+
+void Codegen::handleCall(Reference &base, Arguments calldata)
+{
//### Do we really need all these call instructions? can's we load the callee in a temp?
if (base.type == Reference::QmlScopeObject) {
Instruction::CallScopeObjectProperty call;
@@ -1295,7 +1323,7 @@ bool Codegen::visit(CallExpression *ast)
call.argv = calldata.argv;
bytecodeGenerator->addInstruction(call);
} else if (base.type == Reference::Member) {
- if (useFastLookups) {
+ if (!disable_lookups && useFastLookups) {
Instruction::CallPropertyLookup call;
call.base = base.propertyBase.stackSlot();
call.lookupIndex = registerGetterLookup(base.propertyNameIndex);
@@ -1323,7 +1351,7 @@ bool Codegen::visit(CallExpression *ast)
call.argc = calldata.argc;
call.argv = calldata.argv;
bytecodeGenerator->addInstruction(call);
- } else if (useFastLookups && base.global) {
+ } else if (!disable_lookups && useFastLookups && base.global) {
Instruction::CallGlobalLookup call;
call.index = registerGlobalGetterLookup(base.nameAsIndex());
call.argc = calldata.argc;
@@ -1346,7 +1374,6 @@ bool Codegen::visit(CallExpression *ast)
}
_expr.setResult(Reference::fromAccumulator(this));
- return false;
}
Codegen::Arguments Codegen::pushArgs(ArgumentList *args)
@@ -1378,6 +1405,30 @@ Codegen::Arguments Codegen::pushArgs(ArgumentList *args)
return { argc, calldata };
}
+Codegen::Arguments Codegen::pushTemplateArgs(TemplateLiteral *args)
+{
+ int argc = 0;
+ for (TemplateLiteral *it = args; it; it = it->next)
+ ++argc;
+
+ if (!argc)
+ return { 0, 0 };
+
+ int calldata = bytecodeGenerator->newRegisterArray(argc);
+
+ argc = 0;
+ for (TemplateLiteral *it = args; it && it->expression; it = it->next) {
+ RegisterScope scope(this);
+ Reference e = expression(it->expression);
+ if (hasError)
+ break;
+ (void) e.storeOnStack(calldata + argc);
+ ++argc;
+ }
+
+ return { argc, calldata };
+}
+
bool Codegen::visit(ConditionalExpression *ast)
{
if (hasError)
@@ -1490,6 +1541,86 @@ bool Codegen::visit(FieldMemberExpression *ast)
return false;
}
+bool Codegen::visit(TaggedTemplate *ast)
+{
+ if (hasError)
+ return false;
+
+ RegisterScope scope(this);
+
+ Reference base = expression(ast->base);
+ if (hasError)
+ return false;
+ switch (base.type) {
+ case Reference::Member:
+ case Reference::Subscript:
+ base = base.asLValue();
+ break;
+ case Reference::Name:
+ break;
+ default:
+ base = base.storeOnStack();
+ break;
+ }
+
+ int arrayTemp = createTemplateArray(ast->templateLiteral);
+ Q_UNUSED(arrayTemp);
+ auto calldata = pushTemplateArgs(ast->templateLiteral);
+ if (hasError)
+ return false;
+ ++calldata.argc;
+ Q_ASSERT(calldata.argv == arrayTemp + 1);
+ --calldata.argv;
+
+ handleCall(base, calldata);
+ return false;
+
+
+ return false;
+}
+
+int Codegen::createTemplateArray(TemplateLiteral *t)
+{
+ int arrayTemp = bytecodeGenerator->newRegister();
+
+ RegisterScope scope(this);
+
+ int argc = 0;
+ int args = -1;
+ auto push = [this, &argc, &args](const QStringRef &arg) {
+ int temp = bytecodeGenerator->newRegister();
+ if (args == -1)
+ args = temp;
+ Instruction::LoadRuntimeString instr;
+ instr.stringId = registerString(arg.toString());
+ bytecodeGenerator->addInstruction(instr);
+ Instruction::StoreReg store;
+ store.reg = temp;
+ bytecodeGenerator->addInstruction(store);
+
+ ++argc;
+ };
+
+ for (TemplateLiteral *it = t; it; it = it->next)
+ push(it->value);
+
+ if (args == -1) {
+ Q_ASSERT(argc == 0);
+ args = 0;
+ }
+
+ Instruction::DefineArray call;
+ call.argc = argc;
+ call.args = Moth::StackSlot::createRegister(args);
+ bytecodeGenerator->addInstruction(call);
+
+ Instruction::StoreReg store;
+ store.reg = arrayTemp;
+ bytecodeGenerator->addInstruction(store);
+
+ return arrayTemp;
+}
+
bool Codegen::visit(FunctionExpression *ast)
{
if (hasError)
@@ -1497,7 +1628,7 @@ bool Codegen::visit(FunctionExpression *ast)
RegisterScope scope(this);
- int function = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : nullptr);
+ int function = defineFunction(ast->name.toString(), ast, ast->formals, ast->body);
loadClosure(function);
_expr.setResult(Reference::fromAccumulator(this));
return false;
@@ -1705,7 +1836,7 @@ bool Codegen::visit(ObjectLiteral *ast)
RegisterScope scope(this);
- for (PropertyAssignmentList *it = ast->properties; it; it = it->next) {
+ for (PropertyDefinitionList *it = ast->properties; it; it = it->next) {
QString name = it->assignment->name->asString();
if (PropertyNameAndValue *nv = AST::cast<AST::PropertyNameAndValue *>(it->assignment)) {
Reference value = expression(nv->value);
@@ -1721,7 +1852,7 @@ bool Codegen::visit(ObjectLiteral *ast)
v.rvalue = value.storeOnStack();
} else if (PropertyGetterSetter *gs = AST::cast<AST::PropertyGetterSetter *>(it->assignment)) {
- const int function = defineFunction(name, gs, gs->formals, gs->functionBody ? gs->functionBody->elements : nullptr);
+ const int function = defineFunction(name, gs, gs->formals, gs->functionBody);
ObjectPropertyValue &v = valueMap[name];
if (v.rvalue.isValid() ||
(gs->type == PropertyGetterSetter::Getter && v.hasGetter()) ||
@@ -1933,6 +2064,49 @@ bool Codegen::visit(StringLiteral *ast)
return false;
}
+bool Codegen::visit(TemplateLiteral *ast)
+{
+ if (hasError)
+ return false;
+
+ Instruction::LoadRuntimeString instr;
+ instr.stringId = registerString(ast->value.toString());
+ bytecodeGenerator->addInstruction(instr);
+
+ if (ast->expression) {
+ RegisterScope scope(this);
+ int temp = bytecodeGenerator->newRegister();
+ Instruction::StoreReg store;
+ store.reg = temp;
+ bytecodeGenerator->addInstruction(store);
+
+ Reference expr = expression(ast->expression);
+
+ if (ast->next) {
+ int temp2 = bytecodeGenerator->newRegister();
+ expr.storeOnStack(temp2);
+ visit(ast->next);
+
+ Instruction::Add instr;
+ instr.lhs = temp2;
+ bytecodeGenerator->addInstruction(instr);
+ } else {
+ expr.loadInAccumulator();
+ }
+
+ Instruction::Add instr;
+ instr.lhs = temp;
+ bytecodeGenerator->addInstruction(instr);
+ }
+
+ auto r = Reference::fromAccumulator(this);
+ r.isReadonly = true;
+
+ _expr.setResult(r);
+ return false;
+
+}
+
bool Codegen::visit(ThisExpression *)
{
if (hasError)
@@ -2024,7 +2198,7 @@ bool Codegen::visit(FunctionDeclaration * ast)
RegisterScope scope(this);
if (_context->compilationMode == QmlBinding)
- Reference::fromName(this, ast->name.toString()).loadInAccumulator();
+ referenceForName(ast->name.toString(), true).loadInAccumulator();
_expr.accept(nx);
return false;
}
@@ -2038,14 +2212,7 @@ static bool endsWithReturn(Node *node)
if (AST::cast<ThrowStatement *>(node))
return true;
if (Program *p = AST::cast<Program *>(node))
- return endsWithReturn(p->elements);
- if (SourceElements *se = AST::cast<SourceElements *>(node)) {
- while (se->next)
- se = se->next;
- return endsWithReturn(se->element);
- }
- if (StatementSourceElement *sse = AST::cast<StatementSourceElement *>(node))
- return endsWithReturn(sse->statement);
+ return endsWithReturn(p->statements);
if (StatementList *sl = AST::cast<StatementList *>(node)) {
while (sl->next)
sl = sl->next;
@@ -2060,10 +2227,8 @@ static bool endsWithReturn(Node *node)
int Codegen::defineFunction(const QString &name, AST::Node *ast,
AST::FormalParameterList *formals,
- AST::SourceElements *body)
+ AST::StatementList *body)
{
- Q_UNUSED(formals);
-
enterContext(ast);
if (_context->functionIndex >= 0)
@@ -2151,7 +2316,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
for (const Context::Member &member : qAsConst(_context->members)) {
if (member.function) {
const int function = defineFunction(member.function->name.toString(), member.function, member.function->formals,
- member.function->body ? member.function->body->elements : nullptr);
+ member.function->body);
loadClosure(function);
if (! _context->parent) {
Reference::fromName(this, member.function->name.toString()).storeConsumeAccumulator();
@@ -2164,7 +2329,7 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
}
}
if (_context->usesArgumentsObject == Context::ArgumentsObjectUsed) {
- if (_context->isStrict) {
+ if (_context->isStrict || !formals->isSimpleParameterList()) {
Instruction::CreateUnmappedArgumentsObject setup;
bytecodeGenerator->addInstruction(setup);
} else {
@@ -2179,9 +2344,28 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
bytecodeGenerator->addInstruction(convert);
}
+ int argc = 0;
+ while (formals) {
+ if (AST::BindingRestElement *r = formals->bindingRestElement()) {
+ Q_ASSERT(!formals->next);
+ Instruction::CreateRestParameter rest;
+ rest.argIndex = argc;
+ bytecodeGenerator->addInstruction(rest);
+ Reference f = referenceForName(r->name.toString(), true);
+ f.storeConsumeAccumulator();
+ } else if (BindingElement *e = formals->bindingElement()) {
+ Reference arg = referenceForName(e->name, true);
+ initializeAndDestructureBindingElement(e, arg);
+ } else {
+ Q_UNREACHABLE();
+ }
+ formals = formals->next;
+ ++argc;
+ }
+
beginFunctionBodyHook();
- sourceElements(body);
+ statementList(body);
if (hasError || !endsWithReturn(body)) {
bytecodeGenerator->setLocation(ast->lastSourceLocation());
@@ -2215,24 +2399,6 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
return leaveContext();
}
-bool Codegen::visit(FunctionSourceElement *ast)
-{
- if (hasError)
- return false;
-
- statement(ast->declaration);
- return false;
-}
-
-bool Codegen::visit(StatementSourceElement *ast)
-{
- if (hasError)
- return false;
-
- statement(ast->statement);
- return false;
-}
-
bool Codegen::visit(Block *ast)
{
if (hasError)
@@ -3306,7 +3472,7 @@ void Codegen::Reference::storeAccumulator() const
}
} return;
case Member:
- if (codegen->useFastLookups) {
+ if (!disable_lookups && codegen->useFastLookups) {
Instruction::SetLookup store;
store.base = propertyBase.stackSlot();
store.index = codegen->registerSetterLookup(propertyNameIndex);
@@ -3422,7 +3588,7 @@ QT_WARNING_POP
return;
}
}
- if (codegen->useFastLookups && global) {
+ if (!disable_lookups && codegen->useFastLookups && global) {
Instruction::LoadGlobalLookup load;
load.index = codegen->registerGlobalGetterLookup(nameAsIndex());
codegen->bytecodeGenerator->addInstruction(load);
@@ -3433,7 +3599,7 @@ QT_WARNING_POP
}
return;
case Member:
- if (codegen->useFastLookups) {
+ if (!disable_lookups && codegen->useFastLookups) {
if (propertyBase.isAccumulator()) {
Instruction::GetLookupA load;
load.index = codegen->registerGetterLookup(propertyNameIndex);
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index d51dc29517..5ff0aa5c30 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -197,6 +197,8 @@ public:
Reference &operator =(const Reference &other);
bool operator==(const Reference &other) const;
+ bool operator!=(const Reference &other) const
+ { return !(*this == other); }
bool isValid() const { return type != Invalid; }
bool loadTriggersSideEffect() const {
@@ -493,7 +495,7 @@ protected:
// Returns index in _module->functions
virtual int defineFunction(const QString &name, AST::Node *ast,
AST::FormalParameterList *formals,
- AST::SourceElements *body);
+ AST::StatementList *body);
void statement(AST::Statement *ast);
void statement(AST::ExpressionNode *ast);
@@ -501,17 +503,18 @@ protected:
const BytecodeGenerator::Label *iffalse,
bool trueBlockFollowsCondition);
Reference expression(AST::ExpressionNode *ast);
- Result sourceElement(AST::SourceElement *ast);
void accept(AST::Node *node);
- void functionBody(AST::FunctionBody *ast);
void program(AST::Program *ast);
- void sourceElements(AST::SourceElements *ast);
void statementList(AST::StatementList *ast);
void variableDeclaration(AST::VariableDeclaration *ast);
void variableDeclarationList(AST::VariableDeclarationList *ast);
+ void initializeAndDestructureBindingElement(AST::BindingElement *e, const Reference &baseRef);
+ void destructurePropertyList(const Reference &object, AST::BindingPropertyList *bindingList);
+ void destructureElementList(const Reference &array, AST::BindingElementList *bindingList);
+
Reference referenceForName(const QString &name, bool lhs);
void loadClosure(int index);
@@ -531,12 +534,10 @@ protected:
bool visit(AST::Elision *ast) override;
bool visit(AST::Finally *ast) override;
bool visit(AST::FormalParameterList *ast) override;
- bool visit(AST::FunctionBody *ast) override;
bool visit(AST::Program *ast) override;
bool visit(AST::PropertyNameAndValue *ast) override;
- bool visit(AST::PropertyAssignmentList *ast) override;
+ bool visit(AST::PropertyDefinitionList *ast) override;
bool visit(AST::PropertyGetterSetter *ast) override;
- bool visit(AST::SourceElements *ast) override;
bool visit(AST::StatementList *ast) override;
bool visit(AST::UiArrayMemberList *ast) override;
bool visit(AST::UiImport *ast) override;
@@ -561,6 +562,7 @@ protected:
bool visit(AST::DeleteExpression *ast) override;
bool visit(AST::FalseLiteral *ast) override;
bool visit(AST::FieldMemberExpression *ast) override;
+ bool visit(AST::TaggedTemplate *ast) override;
bool visit(AST::FunctionExpression *ast) override;
bool visit(AST::IdentifierExpression *ast) override;
bool visit(AST::NestedExpression *ast) override;
@@ -576,6 +578,7 @@ protected:
bool visit(AST::PreIncrementExpression *ast) override;
bool visit(AST::RegExpLiteral *ast) override;
bool visit(AST::StringLiteral *ast) override;
+ bool visit(AST::TemplateLiteral *ast) override;
bool visit(AST::ThisExpression *ast) override;
bool visit(AST::TildeExpression *ast) override;
bool visit(AST::TrueLiteral *ast) override;
@@ -585,10 +588,6 @@ protected:
bool visit(AST::VoidExpression *ast) override;
bool visit(AST::FunctionDeclaration *ast) override;
- // source elements
- bool visit(AST::FunctionSourceElement *ast) override;
- bool visit(AST::StatementSourceElement *ast) override;
-
// statements
bool visit(AST::Block *ast) override;
bool visit(AST::BreakStatement *ast) override;
@@ -633,6 +632,10 @@ public:
Reference jumpBinop(QSOperator::Op oper, Reference &left, Reference &right);
struct Arguments { int argc; int argv; };
Arguments pushArgs(AST::ArgumentList *args);
+ void handleCall(Reference &base, Arguments calldata);
+
+ Arguments pushTemplateArgs(AST::TemplateLiteral *args);
+ int createTemplateArray(AST::TemplateLiteral *t);
void setUseFastLookups(bool b) { useFastLookups = b; }
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 8dcc068a06..a17ee43446 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -96,8 +96,9 @@ static QString cacheFilePath(const QUrl &url)
#endif
CompilationUnit::CompilationUnit(const Unit *unitData)
- : data(unitData)
-{}
+{
+ data = unitData;
+}
#ifndef V4_BOOTSTRAP
CompilationUnit::~CompilationUnit()
@@ -157,15 +158,15 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
}
if (data->jsClassTableSize) {
- runtimeClasses = (QV4::InternalClass**)malloc(data->jsClassTableSize * sizeof(QV4::InternalClass*));
+ runtimeClasses = (QV4::Heap::InternalClass **)malloc(data->jsClassTableSize * sizeof(QV4::Heap::InternalClass *));
+ // memset the regexps to 0 in case a GC run happens while we're within the loop below
+ memset(runtimeClasses, 0, data->jsClassTableSize * sizeof(QV4::Heap::InternalClass *));
for (uint i = 0; i < data->jsClassTableSize; ++i) {
int memberCount = 0;
const CompiledData::JSClassMember *member = data->jsClassAt(i, &memberCount);
- QV4::InternalClass *klass = engine->internalClasses[QV4::ExecutionEngine::Class_Object];
+ runtimeClasses[i] = engine->internalClasses(QV4::ExecutionEngine::Class_Object);
for (int j = 0; j < memberCount; ++j, ++member)
- klass = klass->addMember(engine->identifierTable->identifier(runtimeStrings[member->nameOffset]), member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
-
- runtimeClasses[i] = klass;
+ runtimeClasses[i] = runtimeClasses[i]->addMember(engine->identifierTable->identifier(runtimeStrings[member->nameOffset]), member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
}
}
@@ -244,13 +245,28 @@ void CompilationUnit::unlink()
void CompilationUnit::markObjects(QV4::MarkStack *markStack)
{
- for (uint i = 0; i < data->stringTableSize; ++i)
- if (runtimeStrings[i])
- runtimeStrings[i]->mark(markStack);
+ if (runtimeStrings) {
+ for (uint i = 0; i < data->stringTableSize; ++i)
+ if (runtimeStrings[i])
+ runtimeStrings[i]->mark(markStack);
+ }
if (runtimeRegularExpressions) {
for (uint i = 0; i < data->regexpTableSize; ++i)
runtimeRegularExpressions[i].mark(markStack);
}
+ if (runtimeClasses) {
+ for (uint i = 0; i < data->jsClassTableSize; ++i)
+ if (runtimeClasses[i])
+ runtimeClasses[i]->mark(markStack);
+ }
+ for (QV4::Function *f : qAsConst(runtimeFunctions))
+ if (f && f->internalClass)
+ f->internalClass->mark(markStack);
+
+ if (runtimeLookups) {
+ for (uint i = 0; i < data->lookupTableSize; ++i)
+ runtimeLookups[i].markObjects(markStack);
+ }
}
IdentifierHash CompilationUnit::namedObjectsPerComponent(int componentObjectIndex)
@@ -476,8 +492,9 @@ Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument)
QQmlJS::AST::FormalParameterList *parameters = QQmlJS::AST::cast<QQmlJS::AST::FunctionDeclaration*>(foe->node)->formals;
changedSignalParameters << parameters;
- for (; parameters; parameters = parameters->next)
- stringTable.registerString(parameters->name.toString());
+ const QStringList formals = parameters->formals();
+ for (const QString &arg : formals)
+ stringTable.registerString(arg);
}
}
@@ -500,11 +517,11 @@ Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument)
function->formalsOffset = signalParameterNameTableOffset - jsUnit->functionOffsetTable()[functionIndex];
- for (QQmlJS::AST::FormalParameterList *parameters = changedSignalParameters.at(i);
- parameters; parameters = parameters->next) {
- signalParameterNameTable.append(stringTable.getStringId(parameters->name.toString()));
- function->nFormals = function->nFormals + 1;
- }
+ const QStringList formals = changedSignalParameters.at(i)->formals();
+ for (const QString &arg : formals)
+ signalParameterNameTable.append(stringTable.getStringId(arg));
+
+ function->nFormals = formals.size();
// Hack to ensure an activation is created.
function->flags |= QV4::CompiledData::Function::HasCatchOrWith | QV4::CompiledData::Function::HasDirectEval;
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 1df9d6794f..66707456cd 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -881,6 +881,8 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnitBase
QV4::Heap::String **runtimeStrings = nullptr; // Array
const Value* constants = nullptr;
QV4::Value *runtimeRegularExpressions = nullptr;
+ const Unit *data = nullptr;
+ QV4::Heap::InternalClass **runtimeClasses = nullptr;
};
Q_STATIC_ASSERT(std::is_standard_layout<CompilationUnitBase>::value);
@@ -915,8 +917,6 @@ public:
return refCount.load();
}
- const Unit *data = nullptr;
-
// Called only when building QML, when we build the header for JS first and append QML data
QV4::CompiledData::Unit *createUnitData(QmlIR::Document *irDocument);
@@ -943,7 +943,6 @@ public:
}
QV4::Lookup *runtimeLookups = nullptr;
- QV4::InternalClass **runtimeClasses = nullptr;
QVector<QV4::Function *> runtimeFunctions;
mutable QQmlNullableValue<QUrl> m_url;
mutable QQmlNullableValue<QUrl> m_finalUrl;
diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h
index 455a76c729..fef2b56055 100644
--- a/src/qml/compiler/qv4compilercontext_p.h
+++ b/src/qml/compiler/qv4compilercontext_p.h
@@ -263,9 +263,8 @@ struct Context {
return true;
if (type != FunctionDefinition) {
- for (QQmlJS::AST::FormalParameterList *it = formals; it; it = it->next)
- if (it->name == name)
- return (scope == QQmlJS::AST::VariableDeclaration::FunctionScope);
+ if (formals->containsName(name))
+ return (scope == QQmlJS::AST::VariableDeclaration::FunctionScope);
}
MemberMap::iterator it = members.find(name);
if (it != members.end()) {
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp
index 84ee452332..3f7211b95e 100644
--- a/src/qml/compiler/qv4compilerscanfunctions.cpp
+++ b/src/qml/compiler/qv4compilerscanfunctions.cpp
@@ -95,25 +95,23 @@ void ScanFunctions::leaveEnvironment()
_context = _contextStack.isEmpty() ? 0 : _contextStack.top();
}
-void ScanFunctions::checkDirectivePrologue(SourceElements *ast)
+void ScanFunctions::checkDirectivePrologue(StatementList *ast)
{
- for (SourceElements *it = ast; it; it = it->next) {
- if (StatementSourceElement *stmt = cast<StatementSourceElement *>(it->element)) {
- if (ExpressionStatement *expr = cast<ExpressionStatement *>(stmt->statement)) {
- if (StringLiteral *strLit = cast<StringLiteral *>(expr->expression)) {
- // Use the source code, because the StringLiteral's
- // value might have escape sequences in it, which is not
- // allowed.
- if (strLit->literalToken.length < 2)
- continue;
- QStringRef str = _sourceCode.midRef(strLit->literalToken.offset + 1, strLit->literalToken.length - 2);
- if (str == QLatin1String("use strict")) {
- _context->isStrict = true;
- } else {
- // TODO: give a warning.
- }
+ for (StatementList *it = ast; it; it = it->next) {
+ if (ExpressionStatement *expr = cast<ExpressionStatement *>(it->statement)) {
+ if (StringLiteral *strLit = cast<StringLiteral *>(expr->expression)) {
+ // Use the source code, because the StringLiteral's
+ // value might have escape sequences in it, which is not
+ // allowed.
+ if (strLit->literalToken.length < 2)
continue;
+ QStringRef str = _sourceCode.midRef(strLit->literalToken.offset + 1, strLit->literalToken.length - 2);
+ if (str == QLatin1String("use strict")) {
+ _context->isStrict = true;
+ } else {
+ // TODO: give a warning.
}
+ continue;
}
}
@@ -138,20 +136,10 @@ void ScanFunctions::checkName(const QStringRef &name, const SourceLocation &loc)
}
}
-bool ScanFunctions::formalsContainName(AST::FormalParameterList *parameters, const QString &name)
-{
- while (parameters) {
- if (parameters->name == name)
- return true;
- parameters = parameters->next;
- }
- return false;
-}
-
bool ScanFunctions::visit(Program *ast)
{
enterEnvironment(ast, defaultProgramMode);
- checkDirectivePrologue(ast->elements);
+ checkDirectivePrologue(ast->statements);
return true;
}
@@ -237,7 +225,8 @@ bool ScanFunctions::visit(ExpressionStatement *ast)
if (!_allowFuncDecls)
_cg->throwSyntaxError(expr->functionToken, QStringLiteral("conditional function or closure declaration"));
- enterFunction(expr, /*enterName*/ true);
+ if (!enterFunction(expr, /*enterName*/ true))
+ return false;
Node::accept(expr->formals, this);
Node::accept(expr->body, this);
leaveEnvironment();
@@ -253,15 +242,25 @@ bool ScanFunctions::visit(ExpressionStatement *ast)
bool ScanFunctions::visit(FunctionExpression *ast)
{
- enterFunction(ast, /*enterName*/ false);
+ return enterFunction(ast, /*enterName*/ false);
+}
+
+bool ScanFunctions::visit(TemplateLiteral *ast)
+{
+ while (ast) {
+ if (ast->expression)
+ Node::accept(ast->expression, this);
+ ast = ast->next;
+ }
return true;
+
}
-void ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName)
+bool ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName)
{
if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
_cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode"));
- enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : nullptr);
+ return enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : nullptr);
}
void ScanFunctions::endVisit(FunctionExpression *)
@@ -272,7 +271,7 @@ void ScanFunctions::endVisit(FunctionExpression *)
bool ScanFunctions::visit(ObjectLiteral *ast)
{
int argc = 0;
- for (PropertyAssignmentList *it = ast->properties; it; it = it->next) {
+ for (PropertyDefinitionList *it = ast->properties; it; it = it->next) {
QString key = it->assignment->name->asString();
if (QV4::String::toArrayIndex(key) != UINT_MAX)
++argc;
@@ -290,8 +289,7 @@ bool ScanFunctions::visit(ObjectLiteral *ast)
bool ScanFunctions::visit(PropertyGetterSetter *ast)
{
TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
- enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/nullptr);
- return true;
+ return enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/nullptr);
}
void ScanFunctions::endVisit(PropertyGetterSetter *)
@@ -301,8 +299,7 @@ void ScanFunctions::endVisit(PropertyGetterSetter *)
bool ScanFunctions::visit(FunctionDeclaration *ast)
{
- enterFunction(ast, /*enterName*/ true);
- return true;
+ return enterFunction(ast, /*enterName*/ true);
}
void ScanFunctions::endVisit(FunctionDeclaration *)
@@ -391,7 +388,7 @@ bool ScanFunctions::visit(Block *ast) {
return false;
}
-void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionExpression *expr)
+bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, StatementList *body, FunctionExpression *expr)
{
Context *outerContext = _context;
enterEnvironment(ast, FunctionCode);
@@ -402,47 +399,48 @@ void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete
if (expr) {
if (!outerContext->addLocalVar(name, Context::FunctionDefinition, AST::VariableDeclaration::FunctionScope, expr)) {
_cg->throwSyntaxError(ast->firstSourceLocation(), QStringLiteral("Identifier %1 has already been declared").arg(name));
- return;
+ return false;
}
}
if (name == QLatin1String("arguments"))
outerContext->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
}
- if (formalsContainName(formals, QStringLiteral("arguments")))
+ if (formals->containsName(QStringLiteral("arguments")))
_context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
- if (!name.isEmpty() && !formalsContainName(formals, name))
+ if (!name.isEmpty() && !formals->containsName(name))
_context->addLocalVar(name, Context::ThisFunctionName, QQmlJS::AST::VariableDeclaration::FunctionScope);
_context->formals = formals;
if (body && !_context->isStrict)
- checkDirectivePrologue(body->elements);
-
- for (FormalParameterList *it = formals; it; it = it->next) {
- QString arg = it->name.toString();
- int duplicateIndex = _context->arguments.indexOf(arg);
- if (duplicateIndex != -1) {
- if (_context->isStrict) {
- _cg->throwSyntaxError(it->identifierToken, QStringLiteral("Duplicate parameter name '%1' is not allowed in strict mode").arg(arg));
- return;
- } else {
- // change the name of the earlier argument to enforce the specified lookup semantics
- QString modified = arg;
- while (_context->arguments.contains(modified))
- modified += QString(0xfffe);
- _context->arguments[duplicateIndex] = modified;
+ checkDirectivePrologue(body);
+
+ bool isSimpleParameterList = formals->isSimpleParameterList();
+
+ _context->arguments = formals->formals();
+
+ const QStringList boundNames = formals->boundNames();
+ for (int i = 0; i < boundNames.size(); ++i) {
+ const QString &arg = boundNames.at(i);
+ if (_context->isStrict || !isSimpleParameterList) {
+ bool duplicate = (boundNames.indexOf(arg, i + 1) != -1);
+ if (duplicate) {
+ _cg->throwSyntaxError(formals->firstSourceLocation(), QStringLiteral("Duplicate parameter name '%1' is not allowed.").arg(arg));
+ return false;
}
}
if (_context->isStrict) {
if (arg == QLatin1String("eval") || arg == QLatin1String("arguments")) {
- _cg->throwSyntaxError(it->identifierToken, QStringLiteral("'%1' cannot be used as parameter name in strict mode").arg(arg));
- return;
+ _cg->throwSyntaxError(formals->firstSourceLocation(), QStringLiteral("'%1' cannot be used as parameter name in strict mode").arg(arg));
+ return false;
}
}
- _context->arguments += arg;
+ if (!_context->arguments.contains(arg))
+ _context->addLocalVar(arg, Context::VariableDefinition, QQmlJS::AST::VariableDeclaration::FunctionScope);
}
+ return true;
}
void ScanFunctions::calcEscapingVariables()
diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h
index 87b7210879..cf79da2203 100644
--- a/src/qml/compiler/qv4compilerscanfunctions_p.h
+++ b/src/qml/compiler/qv4compilerscanfunctions_p.h
@@ -95,10 +95,9 @@ protected:
using Visitor::visit;
using Visitor::endVisit;
- void checkDirectivePrologue(AST::SourceElements *ast);
+ void checkDirectivePrologue(AST::StatementList *ast);
void checkName(const QStringRef &name, const AST::SourceLocation &loc);
- bool formalsContainName(AST::FormalParameterList *parameters, const QString &name);
bool visit(AST::Program *ast) override;
void endVisit(AST::Program *) override;
@@ -110,8 +109,9 @@ protected:
bool visit(AST::IdentifierExpression *ast) override;
bool visit(AST::ExpressionStatement *ast) override;
bool visit(AST::FunctionExpression *ast) override;
+ bool visit(AST::TemplateLiteral *ast) override;
- void enterFunction(AST::FunctionExpression *ast, bool enterName);
+ bool enterFunction(AST::FunctionExpression *ast, bool enterName);
void endVisit(AST::FunctionExpression *) override;
@@ -136,7 +136,7 @@ protected:
bool visit(AST::Block *ast) override;
protected:
- void enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::FunctionBody *body, AST::FunctionExpression *expr);
+ bool enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::StatementList *body, AST::FunctionExpression *expr);
void calcEscapingVariables();
// fields:
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 450fa50528..3a9cecdae0 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -454,6 +454,10 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
MOTH_BEGIN_INSTR(CreateUnmappedArgumentsObject)
MOTH_END_INSTR(CreateUnmappedArgumentsObject)
+ MOTH_BEGIN_INSTR(CreateRestParameter)
+ d << argIndex;
+ MOTH_END_INSTR(CreateRestParameter)
+
MOTH_BEGIN_INSTR(ConvertThisToObject)
MOTH_END_INSTR(ConvertThisToObject)
@@ -473,6 +477,10 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << ABSOLUTE_OFFSET();
MOTH_END_INSTR(JumpFalse)
+ MOTH_BEGIN_INSTR(JumpNotUndefined)
+ d << ABSOLUTE_OFFSET();
+ MOTH_END_INSTR(JumpNotUndefined)
+
MOTH_BEGIN_INSTR(CmpEqNull)
MOTH_END_INSTR(CmpEqNull)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 7dd639c94c..8ce72f4942 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -128,11 +128,13 @@ QT_BEGIN_NAMESPACE
#define INSTR_DefineObjectLiteral(op) INSTRUCTION(op, DefineObjectLiteral, 4, internalClassId, arrayValueCount, arrayGetterSetterCountAndFlags, args)
#define INSTR_CreateMappedArgumentsObject(op) INSTRUCTION(op, CreateMappedArgumentsObject, 0)
#define INSTR_CreateUnmappedArgumentsObject(op) INSTRUCTION(op, CreateUnmappedArgumentsObject, 0)
+#define INSTR_CreateRestParameter(op) INSTRUCTION(op, CreateRestParameter, 1, argIndex)
#define INSTR_ConvertThisToObject(op) INSTRUCTION(op, ConvertThisToObject, 0)
#define INSTR_Construct(op) INSTRUCTION(op, Construct, 3, func, argc, argv)
#define INSTR_Jump(op) INSTRUCTION(op, Jump, 1, offset)
#define INSTR_JumpTrue(op) INSTRUCTION(op, JumpTrue, 1, offset)
#define INSTR_JumpFalse(op) INSTRUCTION(op, JumpFalse, 1, offset)
+#define INSTR_JumpNotUndefined(op) INSTRUCTION(op, JumpNotUndefined, 1, offset)
#define INSTR_CmpEqNull(op) INSTRUCTION(op, CmpEqNull, 0)
#define INSTR_CmpNeNull(op) INSTRUCTION(op, CmpNeNull, 0)
#define INSTR_CmpEqInt(op) INSTRUCTION(op, CmpEqInt, 1, lhs)
@@ -244,11 +246,13 @@ QT_BEGIN_NAMESPACE
F(DefineObjectLiteral) \
F(CreateMappedArgumentsObject) \
F(CreateUnmappedArgumentsObject) \
+ F(CreateRestParameter) \
F(ConvertThisToObject) \
F(Construct) \
F(Jump) \
F(JumpTrue) \
F(JumpFalse) \
+ F(JumpNotUndefined) \
F(CmpEqNull) \
F(CmpNeNull) \
F(CmpEqInt) \
diff --git a/src/qml/configure.json b/src/qml/configure.json
index 681cecea99..7d67db8b2c 100644
--- a/src/qml/configure.json
+++ b/src/qml/configure.json
@@ -40,6 +40,47 @@
],
"output": [ "privateFeature" ]
},
+ "qml-devtools": {
+ "label": "QML Development Tools",
+ "purpose": "Provides the QmlDevtools library and various utilities.",
+ "section": "QML",
+ "output": [ "privateFeature" ]
+ },
+ "qml-sequence-object": {
+ "label": "QML sequence object",
+ "purpose": "Supports mapping sequence types into QML.",
+ "section": "QML",
+ "output": [ "privateFeature" ]
+ },
+ "qml-list-model": {
+ "label": "QML list model",
+ "purpose": "Provides the ListModel QML type.",
+ "section": "QML",
+ "output": [ "privateFeature" ]
+ },
+ "qml-xml-http-request": {
+ "label": "QML XML http request",
+ "purpose": "Provides support for sending XML http requests.",
+ "section": "QML",
+ "condition": [
+ "features.xmlstreamreader",
+ "features.qml-network"
+ ],
+ "output": [ "privateFeature" ]
+ },
+ "qml-locale": {
+ "label": "QML Locale",
+ "purpose": "Provides support for locales in QML.",
+ "section": "QML",
+ "output": [ "privateFeature" ]
+ },
+ "qml-animation": {
+ "label": "QML Animations",
+ "purpose": "Provides support for animations and timers in QML.",
+ "section": "QML",
+ "condition": "features.animation",
+ "output": [ "privateFeature" ]
+ },
"qml-delegate-model": {
"label": "QML delegate model",
"purpose": "Provides the DelegateModel QML type.",
@@ -54,6 +95,10 @@
"entries": [
"qml-network",
"qml-debug",
+ "qml-sequence-object",
+ "qml-list-model",
+ "qml-xml-http-request",
+ "qml-locale",
"qml-delegate-model"
]
}
diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h
index c63e694c7e..f39f8fccd2 100644
--- a/src/qml/debugger/qqmlabstractprofileradapter_p.h
+++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h
@@ -73,13 +73,13 @@ public:
~QQmlAbstractProfilerAdapter() override {}
void setService(QQmlProfilerService *new_service) { service = new_service; }
- virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages, bool trackLocations) = 0;
+ virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages) = 0;
void startProfiling(quint64 features);
void stopProfiling();
- void reportData(bool trackLocations) { emit dataRequested(trackLocations); }
+ void reportData() { emit dataRequested(); }
void stopWaiting() { waiting = false; }
void startWaiting() { waiting = true; }
@@ -96,7 +96,7 @@ signals:
void profilingDisabled();
void profilingDisabledWhileWaiting();
- void dataRequested(bool trackLocations);
+ void dataRequested();
void referenceTimeKnown(const QElapsedTimer &timer);
protected:
diff --git a/src/qml/debugger/qqmlprofiler.cpp b/src/qml/debugger/qqmlprofiler.cpp
index 8c0bd73822..da0b14dd85 100644
--- a/src/qml/debugger/qqmlprofiler.cpp
+++ b/src/qml/debugger/qqmlprofiler.cpp
@@ -59,19 +59,18 @@ void QQmlProfiler::startProfiling(quint64 features)
void QQmlProfiler::stopProfiling()
{
featuresEnabled = false;
- reportData(true);
+ reportData();
m_locations.clear();
}
-void QQmlProfiler::reportData(bool trackLocations)
+void QQmlProfiler::reportData()
{
LocationHash resolved;
resolved.reserve(m_locations.size());
for (auto it = m_locations.begin(), end = m_locations.end(); it != end; ++it) {
- if (!trackLocations || !it->sent) {
+ if (!it->sent) {
resolved.insert(it.key(), it.value());
- if (trackLocations)
- it->sent = true;
+ it->sent = true;
}
}
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index 287c53ea05..d01e2bc429 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -383,7 +383,7 @@ public:
void startProfiling(quint64 features);
void stopProfiling();
- void reportData(bool trackLocations);
+ void reportData();
void setTimer(const QElapsedTimer &timer) { m_timer = timer; }
signals:
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index c3e16c4093..890d9d03a1 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -701,6 +701,12 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
PlatformAssemblerCommon::generateCatchTrampoline([this](){loadUndefined();});
}
+ void jumpNotUndefined(int offset)
+ {
+ auto jump = branch64(NotEqual, AccumulatorRegister, TrustedImm64(0));
+ patches.push_back({ jump, offset });
+ }
+
void toBoolean(std::function<void(RegisterID)> continuation)
{
urshift64(AccumulatorRegister, TrustedImm32(Value::IsIntegerConvertible_Shift), ScratchRegister);
@@ -1136,6 +1142,14 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
push(TrustedImm32(v));
}
+ void jumpNotUndefined(int offset)
+ {
+ move(AccumulatorRegisterTag, ScratchRegister);
+ or32(AccumulatorRegisterValue, ScratchRegister);
+ auto jump = branch32(NotEqual, ScratchRegister, TrustedImm32(0));
+ patches.push_back({ jump, offset });
+ }
+
void toBoolean(std::function<void(RegisterID)> continuation)
{
urshift32(AccumulatorRegisterTag, TrustedImm32(Value::IsIntegerConvertible_Shift - 32),
@@ -1982,6 +1996,11 @@ void Assembler::jumpFalse(int offset)
});
}
+void Assembler::jumpNotUndefined(int offset)
+{
+ pasm()->jumpNotUndefined(offset);
+}
+
void Assembler::jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset)
{
pasm()->jumpStrictEqualStackSlotInt(lhs, rhs, offset);
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index 37d4232a17..a98761c6ab 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -140,6 +140,7 @@ public:
void jump(int offset);
void jumpTrue(int offset);
void jumpFalse(int offset);
+ void jumpNotUndefined(int offset);
void jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset);
void jumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset);
diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp
index bc46c0ca1d..b2dde4fca2 100644
--- a/src/qml/jit/qv4jit.cpp
+++ b/src/qml/jit/qv4jit.cpp
@@ -781,6 +781,14 @@ void BaselineJIT::generate_CreateUnmappedArgumentsObject()
Assembler::ResultInAccumulator);
}
+void BaselineJIT::generate_CreateRestParameter(int argIndex)
+{
+ as->prepareCallWithArgCount(2);
+ as->passInt32AsArg(argIndex, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_createRestParameter, Assembler::ResultInAccumulator);
+}
+
static void convertThisToObjectHelper(ExecutionEngine *engine, Value *t)
{
if (!t->isObject()) {
@@ -816,6 +824,7 @@ void BaselineJIT::generate_Construct(int func, int argc, int argv)
void BaselineJIT::generate_Jump(int offset) { as->jump(instructionOffset() + offset); }
void BaselineJIT::generate_JumpTrue(int offset) { as->jumpTrue(instructionOffset() + offset); }
void BaselineJIT::generate_JumpFalse(int offset) { as->jumpFalse(instructionOffset() + offset); }
+void BaselineJIT::generate_JumpNotUndefined(int offset) { as->jumpNotUndefined(instructionOffset() + offset); }
void BaselineJIT::generate_CmpEqNull() { as->cmpeqNull(); }
void BaselineJIT::generate_CmpNeNull() { as->cmpneNull(); }
@@ -1172,6 +1181,9 @@ void BaselineJIT::collectLabelsInBytecode()
MOTH_BEGIN_INSTR(CreateUnmappedArgumentsObject)
MOTH_END_INSTR(CreateUnmappedArgumentsObject)
+ MOTH_BEGIN_INSTR(CreateRestParameter)
+ MOTH_END_INSTR(CreateRestParameter)
+
MOTH_BEGIN_INSTR(ConvertThisToObject)
MOTH_END_INSTR(ConvertThisToObject)
@@ -1190,6 +1202,10 @@ void BaselineJIT::collectLabelsInBytecode()
addLabel(code - start + offset);
MOTH_END_INSTR(JumpFalse)
+ MOTH_BEGIN_INSTR(JumpNotUndefined)
+ addLabel(code - start + offset);
+ MOTH_END_INSTR(JumpUndefined)
+
MOTH_BEGIN_INSTR(CmpEqNull)
MOTH_END_INSTR(CmpEqNull)
diff --git a/src/qml/jit/qv4jit_p.h b/src/qml/jit/qv4jit_p.h
index 5aebf78a8d..9ff2d99191 100644
--- a/src/qml/jit/qv4jit_p.h
+++ b/src/qml/jit/qv4jit_p.h
@@ -192,11 +192,13 @@ public:
int args) override;
void generate_CreateMappedArgumentsObject() override;
void generate_CreateUnmappedArgumentsObject() override;
+ void generate_CreateRestParameter(int argIndex) override;
void generate_ConvertThisToObject() override;
void generate_Construct(int func, int argc, int argv) override;
void generate_Jump(int offset) override;
void generate_JumpTrue(int offset) override;
void generate_JumpFalse(int offset) override;
+ void generate_JumpNotUndefined(int offset) override;
void generate_CmpEqNull() override;
void generate_CmpNeNull() override;
void generate_CmpEqInt(int lhs) override;
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index c483af638b..924de14bc7 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -304,9 +304,9 @@ QJSEngine::QJSEngine()
QJSEngine::QJSEngine(QObject *parent)
: QObject(*new QJSEnginePrivate, parent)
- , m_v4Engine(new QV4::ExecutionEngine)
+ , m_v4Engine(new QV4::ExecutionEngine(this))
{
- m_v4Engine->v8Engine = new QV8Engine(this, m_v4Engine);
+ m_v4Engine->v8Engine = new QV8Engine(m_v4Engine);
checkForApplicationInstance();
QJSEnginePrivate::addToDebugServer(this);
@@ -317,9 +317,9 @@ QJSEngine::QJSEngine(QObject *parent)
*/
QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
: QObject(dd, parent)
- , m_v4Engine(new QV4::ExecutionEngine)
+ , m_v4Engine(new QV4::ExecutionEngine(this))
{
- m_v4Engine->v8Engine = new QV8Engine(this, m_v4Engine);
+ m_v4Engine->v8Engine = new QV8Engine(m_v4Engine);
checkForApplicationInstance();
}
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index 4bc877bd9d..1ec00cc744 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -36,7 +36,6 @@ SOURCES += \
$$PWD/qv4runtimecodegen.cpp \
$$PWD/qv4serialize.cpp \
$$PWD/qv4script.cpp \
- $$PWD/qv4sequenceobject.cpp \
$$PWD/qv4include.cpp \
$$PWD/qv4qobjectwrapper.cpp \
$$PWD/qv4arraybuffer.cpp \
@@ -89,7 +88,6 @@ HEADERS += \
$$PWD/qv4script_p.h \
$$PWD/qv4scopedvalue_p.h \
$$PWD/qv4executableallocator_p.h \
- $$PWD/qv4sequenceobject_p.h \
$$PWD/qv4include_p.h \
$$PWD/qv4qobjectwrapper_p.h \
$$PWD/qv4profiling_p.h \
@@ -98,6 +96,14 @@ HEADERS += \
$$PWD/qv4dataview_p.h \
$$PWD/qv4vme_moth_p.h
+qtConfig(qml-sequence-object) {
+ HEADERS += \
+ $$PWD/qv4sequenceobject_p.h
+
+ SOURCES += \
+ $$PWD/qv4sequenceobject.cpp
+}
+
}
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index ac281f555a..d163bbaf88 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -142,7 +142,7 @@ struct ArgumentsObject: Object {
bool fullyCreated() const { return d()->fullyCreated; }
static bool isNonStrictArgumentsObject(Managed *m) {
- return m->d()->vtable() == staticVTable();
+ return m->vtable() == staticVTable();
}
bool defineOwnProperty(ExecutionEngine *engine, uint index, const Property *desc, PropertyAttributes attrs);
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index b2573b4491..613c3b2b50 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -117,7 +117,7 @@ DECLARE_HEAP_OBJECT(ArrayData, Base) {
bool isSparse() const { return type == Sparse; }
- const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(Base::vtable()); }
+ const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(internalClass->vtable); }
inline ReturnedValue get(uint i) const {
return vtable()->get(this, i);
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 512bfa06d8..ccc1653c36 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -55,23 +55,8 @@
QT_BEGIN_NAMESPACE
-class QObject;
-class QQmlContextData;
-
namespace QV4 {
-namespace CompiledData {
-struct CompilationUnitBase;
-struct Function;
-}
-
-struct Function;
-struct Identifier;
-struct CallContext;
-struct CatchContext;
-struct QmlContext;
-struct QQmlContextWrapper;
-
struct CallData
{
enum Offsets {
@@ -113,8 +98,6 @@ Q_STATIC_ASSERT(offsetof(CallData, args) == 5*sizeof(Value));
namespace Heap {
-struct QmlContext;
-
#define ExecutionContextMembers(class, Member) \
Member(class, Pointer, ExecutionContext *, outer) \
Member(class, Pointer, Object *, activation)
@@ -137,6 +120,10 @@ DECLARE_HEAP_OBJECT(ExecutionContext, Base) {
type = t;
}
+ const VTable *vtable() const {
+ return internalClass->vtable;
+ }
+
quint32 type : 8;
quint32 nArgs : 24;
#if QT_POINTER_SIZE == 8
@@ -242,6 +229,7 @@ struct Q_QML_EXPORT CallContext : public ExecutionContext
struct CatchContext : public ExecutionContext
{
V4_MANAGED(CatchContext, ExecutionContext)
+ V4_INTERNALCLASS(CatchContext)
};
inline CallContext *ExecutionContext::asCallContext()
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index d894d909ff..78b83e4a87 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -69,7 +69,7 @@ ReturnedValue DataViewCtor::callAsConstructor(const FunctionObject *f, const Val
if (bo != byteOffset || bl != byteLength || byteOffset + byteLength > bufferLength)
return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range"));
- Scoped<DataView> a(scope, scope.engine->memoryManager->allocObject<DataView>());
+ Scoped<DataView> a(scope, scope.engine->memoryManager->allocate<DataView>());
a->d()->buffer.set(scope.engine, buffer->d());
a->d()->byteLength = byteLength;
a->d()->byteOffset = byteOffset;
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 2b9a580288..0750d3bc75 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -101,7 +101,7 @@ struct DateObject: Object {
template<>
inline const DateObject *Value::as() const {
- return isManaged() && m()->vtable()->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : nullptr;
+ return isManaged() && m()->internalClass->vtable->type == Managed::Type_DateObject ? static_cast<const DateObject *>(this) : nullptr;
}
struct DateCtor: FunctionObject
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 5521633db7..dc9a37b406 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -63,7 +63,11 @@
#include "qv4debugging_p.h"
#include "qv4profiling_p.h"
#include "qv4executableallocator_p.h"
+
+#if QT_CONFIG(qml_sequence_object)
#include "qv4sequenceobject_p.h"
+#endif
+
#include "qv4qobjectwrapper_p.h"
#include "qv4memberdata_p.h"
#include "qv4arraybuffer_p.h"
@@ -76,7 +80,9 @@
#include <private/qqmlvaluetype_p.h>
#include <private/qqmllistwrapper_p.h>
#include <private/qqmllist_p.h>
+#if QT_CONFIG(qml_locale)
#include <private/qqmllocale_p.h>
+#endif
#include <QtCore/QTextStream>
#include <QDateTime>
@@ -110,7 +116,7 @@ ReturnedValue throwTypeError(const FunctionObject *b, const QV4::Value *, const
#ifdef V4_BOOTSTRAP
QJSEngine *ExecutionEngine::jsEngine() const
{
- return v8Engine->publicEngine();
+ return publicEngine;
}
QQmlEngine *ExecutionEngine::qmlEngine() const
@@ -121,7 +127,7 @@ QQmlEngine *ExecutionEngine::qmlEngine() const
qint32 ExecutionEngine::maxCallDepth = -1;
-ExecutionEngine::ExecutionEngine()
+ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
: executableAllocator(new QV4::ExecutableAllocator)
, regExpAllocator(new QV4::ExecutableAllocator)
, bumperPointerAllocator(new WTF::BumpPointerAllocator)
@@ -129,6 +135,7 @@ ExecutionEngine::ExecutionEngine()
, gcStack(new WTF::PageAllocation)
, globalCode(nullptr)
, v8Engine(nullptr)
+ , publicEngine(jsEngine)
, argumentsAccessors(nullptr)
, nArgumentsAccessors(0)
, m_engineId(engineSerial.fetchAndAddOrdered(1))
@@ -192,16 +199,18 @@ ExecutionEngine::ExecutionEngine()
identifierTable = new IdentifierTable(this);
- classPool = new InternalClassPool;
+ memset(classes, 0, sizeof(classes));
+ classes[Class_Empty] = memoryManager->allocIC<InternalClass>();
+ classes[Class_Empty]->init(this);
- internalClasses[Class_Empty] = new (classPool) InternalClass(this);
- internalClasses[Class_String] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::String::staticVTable());
- internalClasses[Class_MemberData] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::MemberData::staticVTable());
- internalClasses[Class_SimpleArrayData] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::SimpleArrayData::staticVTable());
- internalClasses[Class_SparseArrayData] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::SparseArrayData::staticVTable());
- internalClasses[Class_ExecutionContext] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::ExecutionContext::staticVTable());
- internalClasses[Class_QmlContext] = internalClasses[EngineBase::Class_ExecutionContext]->changeVTable(QV4::QmlContext::staticVTable());
- internalClasses[Class_CallContext] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::CallContext::staticVTable());
+ classes[Class_String] = classes[Class_Empty]->changeVTable(QV4::String::staticVTable());
+ classes[Class_MemberData] = classes[Class_Empty]->changeVTable(QV4::MemberData::staticVTable());
+ classes[Class_SimpleArrayData] = classes[Class_Empty]->changeVTable(QV4::SimpleArrayData::staticVTable());
+ classes[Class_SparseArrayData] = classes[Class_Empty]->changeVTable(QV4::SparseArrayData::staticVTable());
+ classes[Class_ExecutionContext] = classes[Class_Empty]->changeVTable(QV4::ExecutionContext::staticVTable());
+ classes[Class_CallContext] = classes[Class_Empty]->changeVTable(QV4::CallContext::staticVTable());
+ classes[Class_CatchContext] = classes[Class_Empty]->changeVTable(QV4::CatchContext::staticVTable());
+ classes[Class_QmlContext] = classes[Class_Empty]->changeVTable(QV4::QmlContext::staticVTable());
jsStrings[String_Empty] = newIdentifier(QString());
jsStrings[String_undefined] = newIdentifier(QStringLiteral("undefined"));
@@ -240,26 +249,29 @@ ExecutionEngine::ExecutionEngine()
jsStrings[String_buffer] = newIdentifier(QStringLiteral("buffer"));
jsStrings[String_lastIndex] = newIdentifier(QStringLiteral("lastIndex"));
- InternalClass *ic = internalClasses[Class_Empty]->changeVTable(QV4::Object::staticVTable());
- jsObjects[ObjectProto] = memoryManager->allocObject<ObjectPrototype>(ic);
- internalClasses[Class_Object] = ic->changePrototype(objectPrototype()->d());
- internalClasses[EngineBase::Class_QmlContextWrapper] = internalClasses[Class_Object]->changeVTable(QV4::QQmlContextWrapper::staticVTable());
+ Scope scope(this);
+ Scoped<InternalClass> ic(scope);
+ ic = classes[Class_Empty]->changeVTable(QV4::Object::staticVTable());
+ jsObjects[ObjectProto] = memoryManager->allocObject<ObjectPrototype>(ic->d());
+ classes[Class_Object] = ic->changePrototype(objectPrototype()->d());
+ classes[EngineBase::Class_QmlContextWrapper] = classes[Class_Object]->changeVTable(QV4::QQmlContextWrapper::staticVTable());
ic = newInternalClass(ArrayPrototype::staticVTable(), objectPrototype());
- Q_ASSERT(ic->prototype);
+ Q_ASSERT(ic->d()->prototype);
ic = ic->addMember(id_length(), Attr_NotConfigurable|Attr_NotEnumerable);
- Q_ASSERT(ic->prototype);
- jsObjects[ArrayProto] = memoryManager->allocObject<ArrayPrototype>(ic, objectPrototype());
- internalClasses[Class_ArrayObject] = ic->changePrototype(arrayPrototype()->d());
- jsObjects[PropertyListProto] = memoryManager->allocObject<PropertyListPrototype>();
+ Q_ASSERT(ic->d()->prototype);
+ jsObjects[ArrayProto] = memoryManager->allocObject<ArrayPrototype>(ic->d());
+ classes[Class_ArrayObject] = ic->changePrototype(arrayPrototype()->d());
+ jsObjects[PropertyListProto] = memoryManager->allocate<PropertyListPrototype>();
- InternalClass *argsClass = newInternalClass(ArgumentsObject::staticVTable(), objectPrototype());
+ Scoped<InternalClass> argsClass(scope);
+ argsClass = newInternalClass(ArgumentsObject::staticVTable(), objectPrototype());
argsClass = argsClass->addMember(id_length(), Attr_NotEnumerable);
- internalClasses[EngineBase::Class_ArgumentsObject] = argsClass->addMember(id_callee(), Attr_Data|Attr_NotEnumerable);
+ classes[Class_ArgumentsObject] = argsClass->addMember(id_callee(), Attr_Data|Attr_NotEnumerable);
argsClass = newInternalClass(StrictArgumentsObject::staticVTable(), objectPrototype());
argsClass = argsClass->addMember(id_length(), Attr_NotEnumerable);
argsClass = argsClass->addMember(id_callee(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
- internalClasses[EngineBase::Class_StrictArgumentsObject] = argsClass->addMember(id_caller(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
+ classes[Class_StrictArgumentsObject] = argsClass->addMember(id_caller(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
*static_cast<Value *>(globalObject) = newObject();
Q_ASSERT(globalObject->d()->vtable());
@@ -267,34 +279,33 @@ ExecutionEngine::ExecutionEngine()
ic = newInternalClass(QV4::StringObject::staticVTable(), objectPrototype());
ic = ic->addMember(id_length(), Attr_ReadOnly);
- jsObjects[StringProto] = memoryManager->allocObject<StringPrototype>(ic);
- internalClasses[Class_StringObject] = ic->changePrototype(stringPrototype()->d());
- Q_ASSERT(internalClasses[EngineBase::Class_StringObject]->find(id_length()) == Heap::StringObject::LengthPropertyIndex);
+ jsObjects[StringProto] = memoryManager->allocObject<StringPrototype>(ic->d());
+ classes[Class_StringObject] = ic->changePrototype(stringPrototype()->d());
+ Q_ASSERT(classes[Class_StringObject]->find(id_length()) == Heap::StringObject::LengthPropertyIndex);
- jsObjects[NumberProto] = memoryManager->allocObject<NumberPrototype>();
- jsObjects[BooleanProto] = memoryManager->allocObject<BooleanPrototype>();
- jsObjects[DateProto] = memoryManager->allocObject<DatePrototype>();
+ jsObjects[NumberProto] = memoryManager->allocate<NumberPrototype>();
+ jsObjects[BooleanProto] = memoryManager->allocate<BooleanPrototype>();
+ jsObjects[DateProto] = memoryManager->allocate<DatePrototype>();
uint index;
ic = newInternalClass(QV4::FunctionPrototype::staticVTable(), objectPrototype());
ic = ic->addMember(id_prototype(), Attr_NotEnumerable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_Prototype);
- jsObjects[FunctionProto] = memoryManager->allocObject<FunctionPrototype>(ic, objectPrototype());
+ jsObjects[FunctionProto] = memoryManager->allocObject<FunctionPrototype>(ic->d());
ic = newInternalClass(FunctionObject::staticVTable(), functionPrototype());
ic = ic->addMember(id_prototype(), Attr_NotEnumerable|Attr_NotConfigurable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_Prototype);
- internalClasses[EngineBase::Class_FunctionObject] = ic;
+ classes[Class_FunctionObject] = ic->d();
ic = ic->addMember(id_name(), Attr_ReadOnly, &index);
Q_ASSERT(index == Heap::ScriptFunction::Index_Name);
ic = ic->changeVTable(ScriptFunction::staticVTable());
- internalClasses[EngineBase::Class_ScriptFunction] = ic->addMember(id_length(), Attr_ReadOnly, &index);
+ classes[Class_ScriptFunction] = ic->addMember(id_length(), Attr_ReadOnly, &index);
Q_ASSERT(index == Heap::ScriptFunction::Index_Length);
- internalClasses[EngineBase::Class_ObjectProto] = internalClasses[Class_Object]->addMember(id_constructor(), Attr_NotEnumerable, &index);
+ classes[Class_ObjectProto] = classes[Class_Object]->addMember(id_constructor(), Attr_NotEnumerable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_ProtoConstructor);
- Scope scope(this);
ScopedString str(scope);
- internalClasses[Class_RegExp] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::RegExp::staticVTable());
+ classes[Class_RegExp] = classes[Class_Empty]->changeVTable(QV4::RegExp::staticVTable());
ic = newInternalClass(QV4::RegExpObject::staticVTable(), objectPrototype());
ic = ic->addMember(id_lastIndex(), Attr_NotEnumerable|Attr_NotConfigurable, &index);
Q_ASSERT(index == RegExpObject::Index_LastIndex);
@@ -306,12 +317,12 @@ ExecutionEngine::ExecutionEngine()
Q_ASSERT(index == RegExpObject::Index_IgnoreCase);
ic = ic->addMember((str = newIdentifier(QStringLiteral("multiline"))), Attr_ReadOnly, &index);
Q_ASSERT(index == RegExpObject::Index_Multiline);
- jsObjects[RegExpProto] = memoryManager->allocObject<RegExpPrototype>(ic, objectPrototype());
- internalClasses[Class_RegExpObject] = ic->changePrototype(regExpPrototype()->d());
+ jsObjects[RegExpProto] = memoryManager->allocObject<RegExpPrototype>(ic->d());
+ classes[Class_RegExpObject] = ic->changePrototype(regExpPrototype()->d());
- ic = internalClasses[Class_ArrayObject]->addMember(id_index(), Attr_Data, &index);
+ ic = classes[Class_ArrayObject]->addMember(id_index(), Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayIndex);
- internalClasses[EngineBase::Class_RegExpExecArray] = ic->addMember(id_input(), Attr_Data, &index);
+ classes[Class_RegExpExecArray] = ic->addMember(id_input(), Attr_Data, &index);
Q_ASSERT(index == RegExpObject::Index_ArrayInput);
ic = newInternalClass(ErrorObject::staticVTable(), nullptr);
@@ -320,51 +331,54 @@ ExecutionEngine::ExecutionEngine()
ic = ic->addMember((str = newIdentifier(QStringLiteral("fileName"))), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorObject::Index_FileName);
ic = ic->addMember((str = newIdentifier(QStringLiteral("lineNumber"))), Attr_Data|Attr_NotEnumerable, &index);
- internalClasses[EngineBase::Class_ErrorObject] = ic;
+ classes[Class_ErrorObject] = ic->d();
Q_ASSERT(index == ErrorObject::Index_LineNumber);
- internalClasses[EngineBase::Class_ErrorObjectWithMessage] = ic->addMember((str = newIdentifier(QStringLiteral("message"))), Attr_Data|Attr_NotEnumerable, &index);
+ classes[Class_ErrorObjectWithMessage] = ic->addMember((str = newIdentifier(QStringLiteral("message"))), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorObject::Index_Message);
ic = newInternalClass(ErrorObject::staticVTable(), objectPrototype());
ic = ic->addMember(id_constructor(), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorPrototype::Index_Constructor);
ic = ic->addMember((str = newIdentifier(QStringLiteral("message"))), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorPrototype::Index_Message);
- internalClasses[EngineBase::Class_ErrorProto] = ic->addMember(id_name(), Attr_Data|Attr_NotEnumerable, &index);
+ classes[Class_ErrorProto] = ic->addMember(id_name(), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorPrototype::Index_Name);
jsObjects[GetStack_Function] = FunctionObject::createBuiltinFunction(rootContext(), str = newIdentifier(QStringLiteral("stack")), ErrorObject::method_get_stack);
getStackFunction()->defineReadonlyProperty(id_length(), Primitive::fromInt32(0));
- jsObjects[ErrorProto] = memoryManager->allocObject<ErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto], objectPrototype());
- jsObjects[EvalErrorProto] = memoryManager->allocObject<EvalErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto]->changePrototype(errorPrototype()->d()), errorPrototype());
- jsObjects[RangeErrorProto] = memoryManager->allocObject<RangeErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto]->changePrototype(errorPrototype()->d()), errorPrototype());
- jsObjects[ReferenceErrorProto] = memoryManager->allocObject<ReferenceErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto]->changePrototype(errorPrototype()->d()), errorPrototype());
- jsObjects[SyntaxErrorProto] = memoryManager->allocObject<SyntaxErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto]->changePrototype(errorPrototype()->d()), errorPrototype());
- jsObjects[TypeErrorProto] = memoryManager->allocObject<TypeErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto]->changePrototype(errorPrototype()->d()), errorPrototype());
- jsObjects[URIErrorProto] = memoryManager->allocObject<URIErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto]->changePrototype(errorPrototype()->d()), errorPrototype());
+ jsObjects[ErrorProto] = memoryManager->allocObject<ErrorPrototype>(classes[Class_ErrorProto]);
+ ic = classes[Class_ErrorProto]->changePrototype(errorPrototype()->d());
+ jsObjects[EvalErrorProto] = memoryManager->allocObject<EvalErrorPrototype>(ic->d());
+ jsObjects[RangeErrorProto] = memoryManager->allocObject<RangeErrorPrototype>(ic->d());
+ jsObjects[ReferenceErrorProto] = memoryManager->allocObject<ReferenceErrorPrototype>(ic->d());
+ jsObjects[SyntaxErrorProto] = memoryManager->allocObject<SyntaxErrorPrototype>(ic->d());
+ jsObjects[TypeErrorProto] = memoryManager->allocObject<TypeErrorPrototype>(ic->d());
+ jsObjects[URIErrorProto] = memoryManager->allocObject<URIErrorPrototype>(ic->d());
- jsObjects[VariantProto] = memoryManager->allocObject<VariantPrototype>();
+ jsObjects[VariantProto] = memoryManager->allocate<VariantPrototype>();
Q_ASSERT(variantPrototype()->prototype() == objectPrototype()->d());
+#if QT_CONFIG(qml_sequence_object)
ic = newInternalClass(SequencePrototype::staticVTable(), SequencePrototype::defaultPrototype(this));
- jsObjects[SequenceProto] = ScopedValue(scope, memoryManager->allocObject<SequencePrototype>(ic, SequencePrototype::defaultPrototype(this)));
+ jsObjects[SequenceProto] = ScopedValue(scope, memoryManager->allocObject<SequencePrototype>(ic->d()));
+#endif
ExecutionContext *global = rootContext();
- jsObjects[Object_Ctor] = memoryManager->allocObject<ObjectCtor>(global);
- jsObjects[String_Ctor] = memoryManager->allocObject<StringCtor>(global);
- jsObjects[Number_Ctor] = memoryManager->allocObject<NumberCtor>(global);
- jsObjects[Boolean_Ctor] = memoryManager->allocObject<BooleanCtor>(global);
- jsObjects[Array_Ctor] = memoryManager->allocObject<ArrayCtor>(global);
- jsObjects[Function_Ctor] = memoryManager->allocObject<FunctionCtor>(global);
- jsObjects[Date_Ctor] = memoryManager->allocObject<DateCtor>(global);
- jsObjects[RegExp_Ctor] = memoryManager->allocObject<RegExpCtor>(global);
- jsObjects[Error_Ctor] = memoryManager->allocObject<ErrorCtor>(global);
- jsObjects[EvalError_Ctor] = memoryManager->allocObject<EvalErrorCtor>(global);
- jsObjects[RangeError_Ctor] = memoryManager->allocObject<RangeErrorCtor>(global);
- jsObjects[ReferenceError_Ctor] = memoryManager->allocObject<ReferenceErrorCtor>(global);
- jsObjects[SyntaxError_Ctor] = memoryManager->allocObject<SyntaxErrorCtor>(global);
- jsObjects[TypeError_Ctor] = memoryManager->allocObject<TypeErrorCtor>(global);
- jsObjects[URIError_Ctor] = memoryManager->allocObject<URIErrorCtor>(global);
+ jsObjects[Object_Ctor] = memoryManager->allocate<ObjectCtor>(global);
+ jsObjects[String_Ctor] = memoryManager->allocate<StringCtor>(global);
+ jsObjects[Number_Ctor] = memoryManager->allocate<NumberCtor>(global);
+ jsObjects[Boolean_Ctor] = memoryManager->allocate<BooleanCtor>(global);
+ jsObjects[Array_Ctor] = memoryManager->allocate<ArrayCtor>(global);
+ jsObjects[Function_Ctor] = memoryManager->allocate<FunctionCtor>(global);
+ jsObjects[Date_Ctor] = memoryManager->allocate<DateCtor>(global);
+ jsObjects[RegExp_Ctor] = memoryManager->allocate<RegExpCtor>(global);
+ jsObjects[Error_Ctor] = memoryManager->allocate<ErrorCtor>(global);
+ jsObjects[EvalError_Ctor] = memoryManager->allocate<EvalErrorCtor>(global);
+ jsObjects[RangeError_Ctor] = memoryManager->allocate<RangeErrorCtor>(global);
+ jsObjects[ReferenceError_Ctor] = memoryManager->allocate<ReferenceErrorCtor>(global);
+ jsObjects[SyntaxError_Ctor] = memoryManager->allocate<SyntaxErrorCtor>(global);
+ jsObjects[TypeError_Ctor] = memoryManager->allocate<TypeErrorCtor>(global);
+ jsObjects[URIError_Ctor] = memoryManager->allocate<URIErrorCtor>(global);
static_cast<ObjectPrototype *>(objectPrototype())->init(this, objectCtor());
static_cast<StringPrototype *>(stringPrototype())->init(this, stringCtor());
@@ -382,26 +396,27 @@ ExecutionEngine::ExecutionEngine()
static_cast<SyntaxErrorPrototype *>(syntaxErrorPrototype())->init(this, syntaxErrorCtor());
static_cast<TypeErrorPrototype *>(typeErrorPrototype())->init(this, typeErrorCtor());
static_cast<URIErrorPrototype *>(uRIErrorPrototype())->init(this, uRIErrorCtor());
-
static_cast<VariantPrototype *>(variantPrototype())->init();
- sequencePrototype()->cast<SequencePrototype>()->init();
+#if QT_CONFIG(qml_sequence_object)
+ sequencePrototype()->cast<SequencePrototype>()->init();
+#endif
// typed arrays
- jsObjects[ArrayBuffer_Ctor] = memoryManager->allocObject<ArrayBufferCtor>(global);
- jsObjects[ArrayBufferProto] = memoryManager->allocObject<ArrayBufferPrototype>();
+ jsObjects[ArrayBuffer_Ctor] = memoryManager->allocate<ArrayBufferCtor>(global);
+ jsObjects[ArrayBufferProto] = memoryManager->allocate<ArrayBufferPrototype>();
static_cast<ArrayBufferPrototype *>(arrayBufferPrototype())->init(this, arrayBufferCtor());
- jsObjects[DataView_Ctor] = memoryManager->allocObject<DataViewCtor>(global);
- jsObjects[DataViewProto] = memoryManager->allocObject<DataViewPrototype>();
+ jsObjects[DataView_Ctor] = memoryManager->allocate<DataViewCtor>(global);
+ jsObjects[DataViewProto] = memoryManager->allocate<DataViewPrototype>();
static_cast<DataViewPrototype *>(dataViewPrototype())->init(this, dataViewCtor());
jsObjects[ValueTypeProto] = (Heap::Base *) nullptr;
jsObjects[SignalHandlerProto] = (Heap::Base *) nullptr;
for (int i = 0; i < Heap::TypedArray::NTypes; ++i) {
- static_cast<Value &>(typedArrayCtors[i]) = memoryManager->allocObject<TypedArrayCtor>(global, Heap::TypedArray::Type(i));
- static_cast<Value &>(typedArrayPrototype[i]) = memoryManager->allocObject<TypedArrayPrototype>(Heap::TypedArray::Type(i));
+ static_cast<Value &>(typedArrayCtors[i]) = memoryManager->allocate<TypedArrayCtor>(global, Heap::TypedArray::Type(i));
+ static_cast<Value &>(typedArrayPrototype[i]) = memoryManager->allocate<TypedArrayPrototype>(Heap::TypedArray::Type(i));
typedArrayPrototype[i].as<TypedArrayPrototype>()->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].as<Object>()));
}
@@ -433,15 +448,15 @@ ExecutionEngine::ExecutionEngine()
for (int i = 0; i < Heap::TypedArray::NTypes; ++i)
globalObject->defineDefaultProperty((str = typedArrayCtors[i].as<FunctionObject>()->name())->toQString(), typedArrayCtors[i]);
ScopedObject o(scope);
- globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->allocObject<MathObject>()));
- globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->allocObject<JsonObject>()));
+ globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->allocate<MathObject>()));
+ globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->allocate<JsonObject>()));
globalObject->defineReadonlyProperty(QStringLiteral("undefined"), Primitive::undefinedValue());
globalObject->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(std::numeric_limits<double>::quiet_NaN()));
globalObject->defineReadonlyProperty(QStringLiteral("Infinity"), Primitive::fromDouble(Q_INFINITY));
- jsObjects[Eval_Function] = memoryManager->allocObject<EvalFunction>(global);
+ jsObjects[Eval_Function] = memoryManager->allocate<EvalFunction>(global);
globalObject->defineDefaultProperty(QStringLiteral("eval"), *evalFunction());
// ES6: 20.1.2.12 & 20.1.2.13:
@@ -487,8 +502,6 @@ ExecutionEngine::~ExecutionEngine()
while (!compilationUnits.isEmpty())
(*compilationUnits.begin())->unlink();
- internalClasses[Class_Empty]->destroy();
- delete classPool;
delete bumperPointerAllocator;
delete regExpCache;
delete regExpAllocator;
@@ -524,24 +537,28 @@ void ExecutionEngine::initRootContext()
jsObjects[IntegerNull] = Encode((int)0);
}
-InternalClass *ExecutionEngine::newClass(const InternalClass &other)
+Heap::InternalClass *ExecutionEngine::newClass(Heap::InternalClass *other)
{
- return new (classPool) InternalClass(other);
+ Heap::InternalClass *ic = memoryManager->allocIC<InternalClass>();
+ ic->init(other);
+ return ic;
}
-InternalClass *ExecutionEngine::newInternalClass(const VTable *vtable, Object *prototype)
+Heap::InternalClass *ExecutionEngine::newInternalClass(const VTable *vtable, Object *prototype)
{
- return internalClasses[EngineBase::Class_Empty]->changeVTable(vtable)->changePrototype(prototype ? prototype->d() : nullptr);
+ Scope scope(this);
+ Scoped<InternalClass> ic(scope, internalClasses(Class_Empty)->changeVTable(vtable));
+ return ic->changePrototype(prototype ? prototype->d() : nullptr);
}
Heap::Object *ExecutionEngine::newObject()
{
- return memoryManager->allocObject<Object>();
+ return memoryManager->allocate<Object>();
}
-Heap::Object *ExecutionEngine::newObject(InternalClass *internalClass, QV4::Object *prototype)
+Heap::Object *ExecutionEngine::newObject(Heap::InternalClass *internalClass)
{
- return memoryManager->allocObject<Object>(internalClass, prototype);
+ return memoryManager->allocObject<Object>(internalClass);
}
Heap::String *ExecutionEngine::newString(const QString &s)
@@ -557,23 +574,23 @@ Heap::String *ExecutionEngine::newIdentifier(const QString &text)
Heap::Object *ExecutionEngine::newStringObject(const String *string)
{
- return memoryManager->allocObject<StringObject>(string);
+ return memoryManager->allocate<StringObject>(string);
}
Heap::Object *ExecutionEngine::newNumberObject(double value)
{
- return memoryManager->allocObject<NumberObject>(value);
+ return memoryManager->allocate<NumberObject>(value);
}
Heap::Object *ExecutionEngine::newBooleanObject(bool b)
{
- return memoryManager->allocObject<BooleanObject>(b);
+ return memoryManager->allocate<BooleanObject>(b);
}
Heap::ArrayObject *ExecutionEngine::newArrayObject(int count)
{
Scope scope(this);
- ScopedArrayObject object(scope, memoryManager->allocObject<ArrayObject>());
+ ScopedArrayObject object(scope, memoryManager->allocate<ArrayObject>());
if (count) {
if (count < 0x1000)
@@ -586,7 +603,7 @@ Heap::ArrayObject *ExecutionEngine::newArrayObject(int count)
Heap::ArrayObject *ExecutionEngine::newArrayObject(const Value *values, int length)
{
Scope scope(this);
- ScopedArrayObject a(scope, memoryManager->allocObject<ArrayObject>());
+ ScopedArrayObject a(scope, memoryManager->allocate<ArrayObject>());
if (length) {
size_t size = sizeof(Heap::ArrayData) + (length-1)*sizeof(Value);
@@ -613,45 +630,41 @@ Heap::ArrayObject *ExecutionEngine::newArrayObject(const Value *values, int leng
Heap::ArrayObject *ExecutionEngine::newArrayObject(const QStringList &list)
{
- Scope scope(this);
- ScopedArrayObject object(scope, memoryManager->allocObject<ArrayObject>(list));
- return object->d();
+ return memoryManager->allocate<ArrayObject>(list);
}
-Heap::ArrayObject *ExecutionEngine::newArrayObject(InternalClass *internalClass, Object *prototype)
+Heap::ArrayObject *ExecutionEngine::newArrayObject(Heap::InternalClass *internalClass)
{
- Scope scope(this);
- ScopedArrayObject object(scope, memoryManager->allocObject<ArrayObject>(internalClass, prototype));
- return object->d();
+ return memoryManager->allocObject<ArrayObject>(internalClass);
}
Heap::ArrayBuffer *ExecutionEngine::newArrayBuffer(const QByteArray &array)
{
- return memoryManager->allocObject<ArrayBuffer>(array);
+ return memoryManager->allocate<ArrayBuffer>(array);
}
Heap::ArrayBuffer *ExecutionEngine::newArrayBuffer(size_t length)
{
- return memoryManager->allocObject<ArrayBuffer>(length);
+ return memoryManager->allocate<ArrayBuffer>(length);
}
Heap::DateObject *ExecutionEngine::newDateObject(const Value &value)
{
- return memoryManager->allocObject<DateObject>(value);
+ return memoryManager->allocate<DateObject>(value);
}
Heap::DateObject *ExecutionEngine::newDateObject(const QDateTime &dt)
{
Scope scope(this);
- Scoped<DateObject> object(scope, memoryManager->allocObject<DateObject>(dt));
+ Scoped<DateObject> object(scope, memoryManager->allocate<DateObject>(dt));
return object->d();
}
Heap::DateObject *ExecutionEngine::newDateObjectFromTime(const QTime &t)
{
Scope scope(this);
- Scoped<DateObject> object(scope, memoryManager->allocObject<DateObject>(t));
+ Scoped<DateObject> object(scope, memoryManager->allocate<DateObject>(t));
return object->d();
}
@@ -668,12 +681,12 @@ Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QString &pattern, int
Heap::RegExpObject *ExecutionEngine::newRegExpObject(RegExp *re)
{
- return memoryManager->allocObject<RegExpObject>(re);
+ return memoryManager->allocate<RegExpObject>(re);
}
Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QRegExp &re)
{
- return memoryManager->allocObject<RegExpObject>(re);
+ return memoryManager->allocate<RegExpObject>(re);
}
Heap::Object *ExecutionEngine::newErrorObject(const Value &value)
@@ -720,13 +733,13 @@ Heap::Object *ExecutionEngine::newURIErrorObject(const Value &message)
Heap::Object *ExecutionEngine::newVariantObject(const QVariant &v)
{
- return memoryManager->allocObject<VariantObject>(v);
+ return memoryManager->allocate<VariantObject>(v);
}
Heap::Object *ExecutionEngine::newForEachIteratorObject(Object *o)
{
Scope scope(this);
- ScopedObject obj(scope, memoryManager->allocObject<ForEachIteratorObject>(o));
+ ScopedObject obj(scope, memoryManager->allocate<ForEachIteratorObject>(o));
return obj->d();
}
@@ -894,8 +907,8 @@ void ExecutionEngine::requireArgumentsAccessors(int n)
}
ExecutionContext *global = rootContext();
for (int i = oldSize; i < nArgumentsAccessors; ++i) {
- argumentsAccessors[i].value = ScopedValue(scope, memoryManager->allocObject<ArgumentsGetterFunction>(global, i));
- argumentsAccessors[i].set = ScopedValue(scope, memoryManager->allocObject<ArgumentsSetterFunction>(global, i));
+ argumentsAccessors[i].value = ScopedValue(scope, memoryManager->allocate<ArgumentsGetterFunction>(global, i));
+ argumentsAccessors[i].set = ScopedValue(scope, memoryManager->allocate<ArgumentsSetterFunction>(global, i));
}
}
}
@@ -912,7 +925,9 @@ void ExecutionEngine::markObjects(MarkStack *markStack)
setter->mark(markStack);
}
- classPool->markObjects(markStack);
+ for (int i = 0; i < NClasses; ++i)
+ if (classes[i])
+ classes[i]->mark(markStack);
markStack->drain();
for (auto compilationUnit: compilationUnits) {
@@ -1056,12 +1071,7 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError()
error.setColumn(frame.column);
}
QV4::Scoped<QV4::ErrorObject> errorObj(scope, exception);
- if (!!errorObj && errorObj->asSyntaxError()) {
- QV4::ScopedString m(scope, newString(QStringLiteral("message")));
- QV4::ScopedValue v(scope, errorObj->get(m));
- error.setDescription(v->toQStringNoThrow());
- } else
- error.setDescription(exception->toQStringNoThrow());
+ error.setDescription(exception->toQStringNoThrow());
return error;
}
@@ -1120,8 +1130,11 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return v->toVariant();
} else if (QV4::QmlListWrapper *l = object->as<QV4::QmlListWrapper>()) {
return l->toVariant();
- } else if (object->isListType())
+#if QT_CONFIG(qml_sequence_object)
+ } else if (object->isListType()) {
return QV4::SequencePrototype::toVariant(object);
+#endif
+ }
}
if (value.as<ArrayObject>()) {
@@ -1144,10 +1157,12 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return QVariant::fromValue(QV4::JsonObject::toJsonArray(a));
}
+#if QT_CONFIG(qml_sequence_object)
bool succeeded = false;
QVariant retn = QV4::SequencePrototype::toVariant(value, typeHint, &succeeded);
if (succeeded)
return retn;
+#endif
}
if (value.isUndefined())
@@ -1167,8 +1182,10 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return str.at(0);
return str;
}
+#if QT_CONFIG(qml_locale)
if (const QV4::QQmlLocaleData *ld = value.as<QV4::QQmlLocaleData>())
return *ld->d()->locale;
+#endif
if (const QV4::DateObject *d = value.as<DateObject>())
return d->toQDateTime();
if (const ArrayBuffer *d = value.as<ArrayBuffer>())
@@ -1324,6 +1341,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
return QV4::Encode(newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr)));
case QMetaType::QObjectStar:
return QV4::QObjectWrapper::wrap(this, *reinterpret_cast<QObject* const *>(ptr));
+#if QT_CONFIG(qml_sequence_object)
case QMetaType::QStringList:
{
bool succeeded = false;
@@ -1333,6 +1351,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
return retn->asReturnedValue();
return QV4::Encode(newArrayObject(*reinterpret_cast<const QStringList *>(ptr)));
}
+#endif
case QMetaType::QVariantList:
return arrayFromVariantList(this, *reinterpret_cast<const QVariantList *>(ptr));
case QMetaType::QVariantMap:
@@ -1343,8 +1362,10 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
return QV4::JsonObject::fromJsonObject(this, *reinterpret_cast<const QJsonObject *>(ptr));
case QMetaType::QJsonArray:
return QV4::JsonObject::fromJsonArray(this, *reinterpret_cast<const QJsonArray *>(ptr));
+#if QT_CONFIG(qml_locale)
case QMetaType::QLocale:
return QQmlLocale::wrap(this, *reinterpret_cast<const QLocale*>(ptr));
+#endif
default:
break;
}
@@ -1384,10 +1405,12 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
if (objOk)
return QV4::QObjectWrapper::wrap(this, obj);
+#if QT_CONFIG(qml_sequence_object)
bool succeeded = false;
QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(this, variant, &succeeded));
if (succeeded)
return retn->asReturnedValue();
+#endif
if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type))
return QV4::QQmlValueTypeWrapper::create(this, variant, vtmo, type);
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index c7fb743088..4316967484 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -88,8 +88,6 @@ struct CompilationUnit;
}
struct Function;
-struct InternalClass;
-struct InternalClassPool;
struct Q_QML_EXPORT CppStackFrame {
CppStackFrame *parent;
@@ -153,10 +151,11 @@ public:
QJSEngine *jsEngine() const;
QQmlEngine *qmlEngine() const;
#else // !V4_BOOTSTRAP
- QJSEngine *jsEngine() const { return v8Engine->publicEngine(); }
+ QJSEngine *jsEngine() const { return publicEngine; }
QQmlEngine *qmlEngine() const { return v8Engine ? v8Engine->engine() : nullptr; }
#endif // V4_BOOTSTRAP
QV8Engine *v8Engine;
+ QJSEngine *publicEngine;
enum JSObjects {
RootContext,
@@ -178,7 +177,9 @@ public:
TypeErrorProto,
URIErrorProto,
VariantProto,
+#if QT_CONFIG(qml_sequence_object)
SequenceProto,
+#endif
ArrayBufferProto,
DataViewProto,
ValueTypeProto,
@@ -247,7 +248,9 @@ public:
Object *typeErrorPrototype() const { return reinterpret_cast<Object *>(jsObjects + TypeErrorProto); }
Object *uRIErrorPrototype() const { return reinterpret_cast<Object *>(jsObjects + URIErrorProto); }
Object *variantPrototype() const { return reinterpret_cast<Object *>(jsObjects + VariantProto); }
+#if QT_CONFIG(qml_sequence_object)
Object *sequencePrototype() const { return reinterpret_cast<Object *>(jsObjects + SequenceProto); }
+#endif
Object *arrayBufferPrototype() const { return reinterpret_cast<Object *>(jsObjects + ArrayBufferProto); }
Object *dataViewPrototype() const { return reinterpret_cast<Object *>(jsObjects + DataViewProto); }
@@ -256,7 +259,6 @@ public:
Object *valueTypeWrapperPrototype() const { return reinterpret_cast<Object *>(jsObjects + ValueTypeProto); }
Object *signalHandlerPrototype() const { return reinterpret_cast<Object *>(jsObjects + SignalHandlerProto); }
- InternalClassPool *classPool;
EvalFunction *evalFunction() const { return reinterpret_cast<EvalFunction *>(jsObjects + Eval_Function); }
FunctionObject *getStackFunction() const { return reinterpret_cast<FunctionObject *>(jsObjects + GetStack_Function); }
FunctionObject *thrower() const { return reinterpret_cast<FunctionObject *>(jsObjects + ThrowerObject); }
@@ -372,9 +374,9 @@ public:
const bool m_canAllocateExecutableMemory;
#endif
- int internalClassIdCount = 0;
+ quintptr protoIdCount = 1;
- ExecutionEngine();
+ ExecutionEngine(QJSEngine *jsEngine = nullptr);
~ExecutionEngine();
#if !QT_CONFIG(qml_debug)
@@ -396,12 +398,13 @@ public:
return static_cast<ExecutionContext *>(&currentStackFrame->jsFrame->context);
}
- int newInternalClassId() { return ++internalClassIdCount; }
+ // ensure we always get odd prototype IDs. This helps make marking in QV4::Lookup fast
+ quintptr newProtoId() { return (protoIdCount += 2); }
- InternalClass *newInternalClass(const VTable *vtable, Object *prototype);
+ Heap::InternalClass *newInternalClass(const VTable *vtable, Object *prototype);
Heap::Object *newObject();
- Heap::Object *newObject(InternalClass *internalClass, Object *prototype);
+ Heap::Object *newObject(Heap::InternalClass *internalClass);
Heap::String *newString(const QString &s = QString());
Heap::String *newIdentifier(const QString &text);
@@ -413,7 +416,7 @@ public:
Heap::ArrayObject *newArrayObject(int count = 0);
Heap::ArrayObject *newArrayObject(const Value *values, int length);
Heap::ArrayObject *newArrayObject(const QStringList &list);
- Heap::ArrayObject *newArrayObject(InternalClass *ic, Object *prototype);
+ Heap::ArrayObject *newArrayObject(Heap::InternalClass *ic);
Heap::ArrayBuffer *newArrayBuffer(const QByteArray &array);
Heap::ArrayBuffer *newArrayBuffer(size_t length);
@@ -453,7 +456,7 @@ public:
void initRootContext();
- InternalClass *newClass(const InternalClass &other);
+ Heap::InternalClass *newClass(Heap::InternalClass *other);
StackTrace exceptionStackTrace;
diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h
index 59fb4a564a..b7f6b8d3cd 100644
--- a/src/qml/jsruntime/qv4enginebase_p.h
+++ b/src/qml/jsruntime/qv4enginebase_p.h
@@ -88,7 +88,7 @@ struct Q_QML_EXPORT EngineBase {
// Exception handling
Value *exceptionValue = nullptr;
- enum {
+ enum InternalClassType {
Class_Empty,
Class_String,
Class_MemberData,
@@ -96,6 +96,8 @@ struct Q_QML_EXPORT EngineBase {
Class_SparseArrayData,
Class_ExecutionContext,
Class_CallContext,
+ Class_CatchContext,
+ Class_QmlContext,
Class_Object,
Class_ArrayObject,
Class_FunctionObject,
@@ -111,10 +113,10 @@ struct Q_QML_EXPORT EngineBase {
Class_ErrorObjectWithMessage,
Class_ErrorProto,
Class_QmlContextWrapper,
- Class_QmlContext,
NClasses
};
- InternalClass *internalClasses[NClasses];
+ Heap::InternalClass *classes[NClasses];
+ Heap::InternalClass *internalClasses(InternalClassType icType) { return classes[icType]; }
};
#if defined(Q_CC_MSVC) || defined(Q_CC_GNU)
#pragma pack(pop)
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 90e158ba37..56eb98b6b6 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -47,10 +47,6 @@
#include "qv4string_p.h"
#include <private/qv4mm_p.h>
-#include <private/qqmljsengine_p.h>
-#include <private/qqmljslexer_p.h>
-#include <private/qqmljsparser_p.h>
-#include <private/qqmljsast_p.h>
#include <qv4codegen_p.h>
#ifndef Q_OS_WIN
@@ -74,7 +70,7 @@ void Heap::ErrorObject::init()
Scope scope(internalClass->engine);
Scoped<QV4::ErrorObject> e(scope, this);
- if (internalClass == scope.engine->internalClasses[EngineBase::Class_ErrorProto])
+ if (internalClass == scope.engine->internalClasses(EngineBase::Class_ErrorProto))
return;
setProperty(scope.engine, QV4::ErrorObject::Index_Stack, scope.engine->getStackFunction()->d());
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 6b578e8c38..44b88f0d31 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -180,7 +180,7 @@ struct ErrorObject: Object {
template<>
inline const ErrorObject *Value::as() const {
- return isManaged() && m()->vtable()->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : nullptr;
+ return isManaged() && m()->internalClass->vtable->isErrorObject ? reinterpret_cast<const ErrorObject *>(this) : nullptr;
}
struct EvalErrorObject: ErrorObject {
@@ -328,25 +328,26 @@ inline SyntaxErrorObject *ErrorObject::asSyntaxError()
template <typename T>
Heap::Object *ErrorObject::create(ExecutionEngine *e, const Value &message) {
- InternalClass *ic = e->internalClasses[message.isUndefined() ? EngineBase::Class_ErrorObject : EngineBase::Class_ErrorObjectWithMessage];
- ic = ic->changePrototype(T::defaultPrototype(e)->d());
- return e->memoryManager->allocObject<T>(ic, T::defaultPrototype(e), message);
+ EngineBase::InternalClassType klass = message.isUndefined() ? EngineBase::Class_ErrorObject : EngineBase::Class_ErrorObjectWithMessage;
+ Scope scope(e);
+ Scoped<InternalClass> ic(scope, e->internalClasses(klass)->changePrototype(T::defaultPrototype(e)->d()));
+ return e->memoryManager->allocObject<T>(ic->d(), message);
}
template <typename T>
Heap::Object *ErrorObject::create(ExecutionEngine *e, const QString &message) {
Scope scope(e);
ScopedValue v(scope, message.isEmpty() ? Encode::undefined() : e->newString(message)->asReturnedValue());
- InternalClass *ic = e->internalClasses[v->isUndefined() ? EngineBase::Class_ErrorObject : EngineBase::Class_ErrorObjectWithMessage];
- ic = ic->changePrototype(T::defaultPrototype(e)->d());
- return e->memoryManager->allocObject<T>(ic, T::defaultPrototype(e), v);
+ EngineBase::InternalClassType klass = v->isUndefined() ? EngineBase::Class_ErrorObject : EngineBase::Class_ErrorObjectWithMessage;
+ Scoped<InternalClass> ic(scope, e->internalClasses(klass)->changePrototype(T::defaultPrototype(e)->d()));
+ return e->memoryManager->allocObject<T>(ic->d(), v);
}
template <typename T>
Heap::Object *ErrorObject::create(ExecutionEngine *e, const QString &message, const QString &filename, int line, int column) {
Scope scope(e);
ScopedValue v(scope, message.isEmpty() ? Encode::undefined() : e->newString(message)->asReturnedValue());
- InternalClass *ic = e->internalClasses[v->isUndefined() ? EngineBase::Class_ErrorObject : EngineBase::Class_ErrorObjectWithMessage];
- ic = ic->changePrototype(T::defaultPrototype(e)->d());
- return e->memoryManager->allocObject<T>(ic, T::defaultPrototype(e), v, filename, line, column);
+ EngineBase::InternalClassType klass = v->isUndefined() ? EngineBase::Class_ErrorObject : EngineBase::Class_ErrorObjectWithMessage;
+ Scoped<InternalClass> ic(scope, e->internalClasses(klass)->changePrototype(T::defaultPrototype(e)->d()));
+ return e->memoryManager->allocObject<T>(ic->d(), v, filename, line, column);
}
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 83e861138b..493147e99b 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -61,18 +61,18 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
, codeRef(nullptr)
, hasQmlDependencies(function->hasQmlDependencies())
{
- Q_UNUSED(engine);
-
- internalClass = engine->internalClasses[EngineBase::Class_CallContext];
+ Scope scope(engine);
+ Scoped<InternalClass> ic(scope, engine->internalClasses(EngineBase::Class_CallContext));
// first locals
const quint32_le *localsIndices = compiledFunction->localsTable();
for (quint32 i = 0; i < compiledFunction->nLocals; ++i)
- internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable);
+ ic = ic->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable);
const quint32_le *formalsIndices = compiledFunction->formalsTable();
for (quint32 i = 0; i < compiledFunction->nFormals; ++i)
- internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[formalsIndices[i]]), Attr_NotConfigurable);
+ ic = ic->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[formalsIndices[i]]), Attr_NotConfigurable);
+ internalClass = ic->d();
nFormals = compiledFunction->nFormals;
}
@@ -110,7 +110,7 @@ void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArr
}
- internalClass = engine->internalClasses[EngineBase::Class_CallContext];
+ internalClass = engine->internalClasses(EngineBase::Class_CallContext);
Scope scope(engine);
ScopedString arg(scope);
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 59a94e5dde..c8dbcec51d 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -81,7 +81,7 @@ struct Q_QML_EXPORT Function {
JSC::MacroAssemblerCodeRef *codeRef;
// first nArguments names in internalClass are the actual arguments
- InternalClass *internalClass;
+ Heap::InternalClass *internalClass;
uint nFormals;
int interpreterCallCount = 0;
bool hasQmlDependencies;
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index dc8ee550d5..390e0d5161 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -146,8 +146,8 @@ void FunctionObject::init(String *n, bool createProto)
Q_ASSERT(internalClass() && internalClass()->find(s.engine->id_prototype()) == Heap::FunctionObject::Index_Prototype);
if (createProto) {
- ScopedObject proto(s, s.engine->newObject(s.engine->internalClasses[EngineBase::Class_ObjectProto], s.engine->objectPrototype()));
- Q_ASSERT(s.engine->internalClasses[EngineBase::Class_ObjectProto]->find(s.engine->id_constructor()) == Heap::FunctionObject::Index_ProtoConstructor);
+ ScopedObject proto(s, s.engine->newObject(s.engine->internalClasses(EngineBase::Class_ObjectProto)));
+ Q_ASSERT(s.engine->internalClasses(EngineBase::Class_ObjectProto)->find(s.engine->id_constructor()) == Heap::FunctionObject::Index_ProtoConstructor);
proto->setProperty(Heap::FunctionObject::Index_ProtoConstructor, d());
setProperty(Heap::FunctionObject::Index_Prototype, proto);
} else {
@@ -175,7 +175,7 @@ ReturnedValue FunctionObject::call(const FunctionObject *, const Value *, const
Heap::FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *scope, Function *function)
{
- return scope->engine()->memoryManager->allocObject<ScriptFunction>(scope, function);
+ return scope->engine()->memoryManager->allocate<ScriptFunction>(scope, function);
}
bool FunctionObject::isBinding() const
@@ -240,6 +240,9 @@ ReturnedValue FunctionCtor::callAsConstructor(const FunctionObject *f, const Val
RuntimeCodegen cg(scope.engine, &jsGenerator, false);
cg.generateFromFunctionExpression(QString(), function, fe, &module);
+ if (scope.hasException())
+ return Encode::undefined();
+
QQmlRefPointer<CompiledData::CompilationUnit> compilationUnit = cg.generateCompilationUnit();
Function *vmf = compilationUnit->linkToEngine(scope.engine);
@@ -389,8 +392,7 @@ ReturnedValue ScriptFunction::callAsConstructor(const FunctionObject *fo, const
const ScriptFunction *f = static_cast<const ScriptFunction *>(fo);
Scope scope(v4);
- InternalClass *ic = f->classForConstructor();
- ScopedValue thisObject(scope, v4->memoryManager->allocObject<Object>(ic));
+ ScopedValue thisObject(scope, v4->memoryManager->allocObject<Object>(f->classForConstructor()));
ReturnedValue result = Moth::VME::exec(fo, thisObject, argv, argc);
@@ -432,19 +434,19 @@ void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function
}
}
-InternalClass *ScriptFunction::classForConstructor() const
+Heap::InternalClass *ScriptFunction::classForConstructor() const
{
const Object *o = d()->protoProperty();
- InternalClass *ic = d()->cachedClassForConstructor;
- if (ic && ic->prototype == o->d())
- return ic;
+ if (d()->cachedClassForConstructor && d()->cachedClassForConstructor->prototype == o->d())
+ return d()->cachedClassForConstructor;
- ic = engine()->internalClasses[EngineBase::Class_Object];
+ Scope scope(engine());
+ Scoped<InternalClass> ic(scope, engine()->internalClasses(EngineBase::Class_Object));
if (o)
ic = ic->changePrototype(o->d());
- d()->cachedClassForConstructor = ic;
+ d()->cachedClassForConstructor.set(scope.engine, ic->d());
- return ic;
+ return ic->d();
}
DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index 32e71a175b..bd5b756aed 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -111,14 +111,16 @@ struct IndexedBuiltinFunction : FunctionObject {
uint index;
};
-struct ScriptFunction : FunctionObject {
+#define ScriptFunctionMembers(class, Member) \
+ Member(class, Pointer, InternalClass *, cachedClassForConstructor)
+
+DECLARE_HEAP_OBJECT(ScriptFunction, FunctionObject) {
+ DECLARE_MARKOBJECTS(ScriptFunction)
enum {
Index_Name = FunctionObject::Index_Prototype + 1,
Index_Length
};
void init(QV4::ExecutionContext *scope, Function *function);
-
- QV4::InternalClass *cachedClassForConstructor;
};
#define BoundFunctionMembers(class, Member) \
@@ -169,7 +171,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
static Heap::FunctionObject *createBuiltinFunction(ExecutionContext *scope, String *name,
ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc))
{
- return scope->engine()->memoryManager->allocObject<FunctionObject>(scope, name, code);
+ return scope->engine()->memoryManager->allocate<FunctionObject>(scope, name, code);
}
bool strictMode() const { return d()->function ? d()->function->isStrict() : false; }
@@ -181,7 +183,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
template<>
inline const FunctionObject *Value::as() const {
- return isManaged() && m()->vtable()->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : nullptr;
+ return isManaged() && m()->internalClass->vtable->isFunctionObject ? reinterpret_cast<const FunctionObject *>(this) : nullptr;
}
@@ -227,7 +229,7 @@ struct ScriptFunction : FunctionObject {
static ReturnedValue callAsConstructor(const FunctionObject *, const Value *argv, int argc);
static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
- InternalClass *classForConstructor() const;
+ Heap::InternalClass *classForConstructor() const;
};
@@ -236,7 +238,7 @@ struct BoundFunction: FunctionObject {
static Heap::BoundFunction *create(ExecutionContext *scope, FunctionObject *target, const Value &boundThis, QV4::MemberData *boundArgs)
{
- return scope->engine()->memoryManager->allocObject<BoundFunction>(scope, target, boundThis, boundArgs);
+ return scope->engine()->memoryManager->allocate<BoundFunction>(scope, target, boundThis, boundArgs);
}
Heap::FunctionObject *target() const { return d()->target; }
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 9b13d4e341..9cc63a98c5 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -166,7 +166,9 @@ namespace Heap {
struct ExecutionContext;
struct CallContext;
+ struct QmlContext;
struct ScriptFunction;
+ struct InternalClass;
struct BooleanObject;
struct NumberObject;
@@ -196,6 +198,7 @@ struct ObjectPrototype;
struct ObjectIterator;
struct ExecutionContext;
struct CallContext;
+struct QmlContext;
struct ScriptFunction;
struct InternalClass;
struct Property;
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index 9da854e7d7..4c7eb7b185 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -47,7 +47,7 @@
QT_BEGIN_NAMESPACE
-using namespace QV4;
+namespace QV4 {
static const uchar prime_deltas[] = {
0, 0, 1, 3, 1, 5, 3, 3, 1, 9, 7, 5, 3, 9, 25, 3,
@@ -74,24 +74,8 @@ void PropertyHash::addEntry(const PropertyHash::Entry &entry, int classSize)
// fill up to max 50%
bool grow = (d->alloc <= d->size*2);
- if (classSize < d->size || grow) {
- PropertyHashData *dd = new PropertyHashData(grow ? d->numBits + 1 : d->numBits);
- for (int i = 0; i < d->alloc; ++i) {
- const Entry &e = d->entries[i];
- if (!e.identifier || e.index >= static_cast<unsigned>(classSize))
- continue;
- uint idx = e.identifier->hashValue % dd->alloc;
- while (dd->entries[idx].identifier) {
- ++idx;
- idx %= dd->alloc;
- }
- dd->entries[idx] = e;
- }
- dd->size = classSize;
- Q_ASSERT(d->refCount > 1);
- --d->refCount;
- d = dd;
- }
+ if (classSize < d->size || grow)
+ detach(grow, classSize);
uint idx = entry.identifier->hashValue % d->alloc;
while (d->entries[idx].identifier) {
@@ -102,38 +86,125 @@ void PropertyHash::addEntry(const PropertyHash::Entry &entry, int classSize)
++d->size;
}
+int PropertyHash::removeIdentifier(Identifier *identifier, int classSize)
+{
+ int val = -1;
+ PropertyHashData *dd = new PropertyHashData(d->numBits);
+ for (int i = 0; i < d->alloc; ++i) {
+ const Entry &e = d->entries[i];
+ if (!e.identifier || e.index >= static_cast<unsigned>(classSize))
+ continue;
+ if (e.identifier == identifier) {
+ val = e.index;
+ continue;
+ }
+ uint idx = e.identifier->hashValue % dd->alloc;
+ while (dd->entries[idx].identifier) {
+ ++idx;
+ idx %= dd->alloc;
+ }
+ dd->entries[idx] = e;
+ }
+ dd->size = classSize;
+ if (!--d->refCount)
+ delete d;
+ d = dd;
-InternalClass::InternalClass(ExecutionEngine *engine)
- : engine(engine)
- , vtable(nullptr)
- , prototype(nullptr)
- , m_sealed(nullptr)
- , m_frozen(nullptr)
- , size(0)
- , extensible(true)
+ Q_ASSERT(val != -1);
+ return val;
+}
+
+void PropertyHash::detach(bool grow, int classSize)
{
- id = engine->newInternalClassId();
-}
-
-
-InternalClass::InternalClass(const QV4::InternalClass &other)
- : QQmlJS::Managed()
- , engine(other.engine)
- , vtable(other.vtable)
- , prototype(other.prototype)
- , propertyTable(other.propertyTable)
- , nameMap(other.nameMap)
- , propertyData(other.propertyData)
- , m_sealed(nullptr)
- , m_frozen(nullptr)
- , size(other.size)
- , extensible(other.extensible)
- , isUsedAsProto(other.isUsedAsProto)
+ if (d->refCount == 1 && !grow)
+ return;
+
+ PropertyHashData *dd = new PropertyHashData(grow ? d->numBits + 1 : d->numBits);
+ for (int i = 0; i < d->alloc; ++i) {
+ const Entry &e = d->entries[i];
+ if (!e.identifier || e.index >= static_cast<unsigned>(classSize))
+ continue;
+ uint idx = e.identifier->hashValue % dd->alloc;
+ while (dd->entries[idx].identifier) {
+ ++idx;
+ idx %= dd->alloc;
+ }
+ dd->entries[idx] = e;
+ }
+ dd->size = classSize;
+ if (!--d->refCount)
+ delete d;
+ d = dd;
+}
+
+namespace Heap {
+
+void InternalClass::init(ExecutionEngine *engine)
+{
+ Base::init();
+ new (&propertyTable) PropertyHash();
+ new (&nameMap) SharedInternalClassData<Identifier *>();
+ new (&propertyData) SharedInternalClassData<PropertyAttributes>();
+ new (&transitions) std::vector<Transition>();
+
+ this->engine = engine;
+ vtable = QV4::InternalClass::staticVTable();
+// prototype = nullptr;
+// parent = nullptr;
+// size = 0;
+ extensible = true;
+ isFrozen = false;
+ isSealed = false;
+ isUsedAsProto = false;
+ protoId = engine->newProtoId();
+
+ // Also internal classes need an internal class pointer. Simply make it point to itself
+ internalClass.set(engine, this);
+}
+
+
+void InternalClass::init(Heap::InternalClass *other)
+{
+ Base::init();
+ Q_ASSERT(!other->isFrozen);
+ new (&propertyTable) PropertyHash(other->propertyTable);
+ new (&nameMap) SharedInternalClassData<Identifier *>(other->nameMap);
+ new (&propertyData) SharedInternalClassData<PropertyAttributes>(other->propertyData);
+ new (&transitions) std::vector<Transition>();
+
+ engine = other->engine;
+ vtable = other->vtable;
+ prototype = other->prototype;
+ parent = other;
+ size = other->size;
+ extensible = other->extensible;
+ isSealed = other->isSealed;
+ isFrozen = other->isFrozen;
+ isUsedAsProto = other->isUsedAsProto;
+ protoId = engine->newProtoId();
+
+ internalClass.set(engine, other->internalClass);
+}
+
+void InternalClass::destroy()
{
- id = engine->newInternalClassId();
+#ifndef QT_NO_DEBUG
+ for (const auto &t : transitions) {
+ Q_ASSERT(!t.lookup || !t.lookup->isMarked());
+ }
+#endif
+ if (parent && parent->engine && parent->isMarked())
+ parent->removeChildEntry(this);
+
+ propertyTable.~PropertyHash();
+ nameMap.~SharedInternalClassData<Identifier *>();
+ propertyData.~SharedInternalClassData<PropertyAttributes>();
+ transitions.~vector<Transition>();
+ engine = nullptr;
+ Base::destroy();
}
-static void insertHoleIntoPropertyData(Object *object, int idx)
+static void insertHoleIntoPropertyData(QV4::Object *object, int idx)
{
Heap::Object *o = object->d();
ExecutionEngine *v4 = o->internalClass->engine;
@@ -142,7 +213,7 @@ static void insertHoleIntoPropertyData(Object *object, int idx)
o->setProperty(v4, i, *o->propertyData(i - 1));
}
-static void removeFromPropertyData(Object *object, int idx, bool accessor = false)
+static void removeFromPropertyData(QV4::Object *object, int idx, bool accessor = false)
{
Heap::Object *o = object->d();
ExecutionEngine *v4 = o->internalClass->engine;
@@ -154,20 +225,22 @@ static void removeFromPropertyData(Object *object, int idx, bool accessor = fals
o->setProperty(v4, size + 1, Primitive::undefinedValue());
}
-void InternalClass::changeMember(Object *object, String *string, PropertyAttributes data, uint *index)
+void InternalClass::changeMember(QV4::Object *object, QV4::String *string, PropertyAttributes data, uint *index)
{
uint idx;
- InternalClass *oldClass = object->internalClass();
- InternalClass *newClass = oldClass->changeMember(string->identifier(), data, &idx);
+ Heap::InternalClass *oldClass = object->internalClass();
+ Heap::InternalClass *newClass = oldClass->changeMember(string->identifier(), data, &idx);
if (index)
*index = idx;
+ uint oldSize = oldClass->size;
object->setInternalClass(newClass);
- if (newClass->size > oldClass->size) {
- Q_ASSERT(newClass->size == oldClass->size + 1);
+ // don't use oldClass anymore, it could be GC'ed
+ if (newClass->size > oldSize) {
+ Q_ASSERT(newClass->size == oldSize + 1);
insertHoleIntoPropertyData(object, idx);
- } else if (newClass->size < oldClass->size) {
- Q_ASSERT(newClass->size == oldClass->size - 1);
+ } else if (newClass->size < oldSize) {
+ Q_ASSERT(newClass->size == oldSize - 1);
removeFromPropertyData(object, idx + 1);
}
}
@@ -183,7 +256,16 @@ InternalClassTransition &InternalClass::lookupOrInsertTransition(const InternalC
}
}
-InternalClass *InternalClass::changeMember(Identifier *identifier, PropertyAttributes data, uint *index)
+static void addDummyEntry(InternalClass *newClass, PropertyHash::Entry e)
+{
+ // add a dummy entry, since we need two entries for accessors
+ newClass->propertyTable.addEntry(e, newClass->size);
+ newClass->nameMap.add(newClass->size, nullptr);
+ newClass->propertyData.add(newClass->size, PropertyAttributes());
+ ++newClass->size;
+}
+
+Heap::InternalClass *InternalClass::changeMember(Identifier *identifier, PropertyAttributes data, uint *index)
{
data.resolve();
uint idx = find(identifier);
@@ -193,7 +275,7 @@ InternalClass *InternalClass::changeMember(Identifier *identifier, PropertyAttri
*index = idx;
if (data == propertyData.at(idx))
- return this;
+ return static_cast<Heap::InternalClass *>(this);
Transition temp = { { identifier }, nullptr, (int)data.flags() };
Transition &t = lookupOrInsertTransition(temp);
@@ -201,14 +283,34 @@ InternalClass *InternalClass::changeMember(Identifier *identifier, PropertyAttri
return t.lookup;
// create a new class and add it to the tree
- InternalClass *newClass = engine->internalClasses[EngineBase::Class_Empty]->changeVTable(vtable);
- newClass = newClass->changePrototype(prototype);
- for (uint i = 0; i < size; ++i) {
- if (i == idx) {
- newClass = newClass->addMember(nameMap.at(i), data);
- } else if (!propertyData.at(i).isEmpty()) {
- newClass = newClass->addMember(nameMap.at(i), propertyData.at(i));
+ Heap::InternalClass *newClass = engine->newClass(this);
+ if (data.isAccessor() != propertyData.at(idx).isAccessor()) {
+ // this changes the layout of the class, so we need to rebuild the data
+ newClass->propertyTable = PropertyHash();
+ newClass->nameMap = SharedInternalClassData<Identifier *>();
+ newClass->propertyData = SharedInternalClassData<PropertyAttributes>();
+ newClass->size = 0;
+ for (uint i = 0; i < size; ++i) {
+ Identifier *identifier = nameMap.at(i);
+ PropertyHash::Entry e = { identifier, newClass->size };
+ if (!identifier)
+ e.identifier = nameMap.at(i - 1);
+ newClass->propertyTable.addEntry(e, newClass->size);
+ newClass->nameMap.add(newClass->size, identifier);
+ if (i == idx) {
+ newClass->propertyData.add(newClass->size, data);
+ ++newClass->size;
+ if (data.isAccessor())
+ addDummyEntry(newClass, e);
+ else
+ ++i;
+ } else {
+ newClass->propertyData.add(newClass->size, propertyData.at(i));
+ ++newClass->size;
+ }
}
+ } else {
+ newClass->propertyData.set(idx, data);
}
t.lookup = newClass;
@@ -216,8 +318,10 @@ InternalClass *InternalClass::changeMember(Identifier *identifier, PropertyAttri
return newClass;
}
-InternalClass *InternalClass::changePrototypeImpl(Heap::Object *proto)
+Heap::InternalClass *InternalClass::changePrototypeImpl(Heap::Object *proto)
{
+ Scope scope(engine);
+ ScopedValue protectThis(scope, this);
if (proto)
proto->setUsedAsProto();
Q_ASSERT(prototype != proto);
@@ -231,25 +335,15 @@ InternalClass *InternalClass::changePrototypeImpl(Heap::Object *proto)
return t.lookup;
// create a new class and add it to the tree
- InternalClass *newClass;
- if (!size && !prototype) {
- newClass = engine->newClass(*this);
- newClass->prototype = proto;
- } else {
- newClass = engine->internalClasses[EngineBase::Class_Empty]->changeVTable(vtable);
- newClass = newClass->changePrototype(proto);
- for (uint i = 0; i < size; ++i) {
- if (!propertyData.at(i).isEmpty())
- newClass = newClass->addMember(nameMap.at(i), propertyData.at(i));
- }
- }
+ Heap::InternalClass *newClass = engine->newClass(this);
+ newClass->prototype = proto;
t.lookup = newClass;
return newClass;
}
-InternalClass *InternalClass::changeVTableImpl(const VTable *vt)
+Heap::InternalClass *InternalClass::changeVTableImpl(const VTable *vt)
{
Q_ASSERT(vtable != vt);
@@ -261,18 +355,8 @@ InternalClass *InternalClass::changeVTableImpl(const VTable *vt)
return t.lookup;
// create a new class and add it to the tree
- InternalClass *newClass;
- if (this == engine->internalClasses[EngineBase::Class_Empty]) {
- newClass = engine->newClass(*this);
- newClass->vtable = vt;
- } else {
- newClass = engine->internalClasses[EngineBase::Class_Empty]->changeVTable(vt);
- newClass = newClass->changePrototype(prototype);
- for (uint i = 0; i < size; ++i) {
- if (!propertyData.at(i).isEmpty())
- newClass = newClass->addMember(nameMap.at(i), propertyData.at(i));
- }
- }
+ Heap::InternalClass *newClass = engine->newClass(this);
+ newClass->vtable = vt;
t.lookup = newClass;
Q_ASSERT(t.lookup);
@@ -280,7 +364,7 @@ InternalClass *InternalClass::changeVTableImpl(const VTable *vt)
return newClass;
}
-InternalClass *InternalClass::nonExtensible()
+Heap::InternalClass *InternalClass::nonExtensible()
{
if (!extensible)
return this;
@@ -290,7 +374,7 @@ InternalClass *InternalClass::nonExtensible()
if (t.lookup)
return t.lookup;
- InternalClass *newClass = engine->newClass(*this);
+ Heap::InternalClass *newClass = engine->newClass(this);
newClass->extensible = false;
t.lookup = newClass;
@@ -298,7 +382,7 @@ InternalClass *InternalClass::nonExtensible()
return newClass;
}
-void InternalClass::addMember(Object *object, String *string, PropertyAttributes data, uint *index)
+void InternalClass::addMember(QV4::Object *object, QV4::String *string, PropertyAttributes data, uint *index)
{
data.resolve();
object->internalClass()->engine->identifierTable->identifier(string);
@@ -308,20 +392,20 @@ void InternalClass::addMember(Object *object, String *string, PropertyAttributes
}
uint idx;
- InternalClass *newClass = object->internalClass()->addMemberImpl(string->identifier(), data, &idx);
+ Heap::InternalClass *newClass = object->internalClass()->addMemberImpl(string->identifier(), data, &idx);
if (index)
*index = idx;
object->setInternalClass(newClass);
}
-InternalClass *InternalClass::addMember(String *string, PropertyAttributes data, uint *index)
+Heap::InternalClass *InternalClass::addMember(QV4::String *string, PropertyAttributes data, uint *index)
{
engine->identifierTable->identifier(string);
return addMember(string->identifier(), data, index);
}
-InternalClass *InternalClass::addMember(Identifier *identifier, PropertyAttributes data, uint *index)
+Heap::InternalClass *InternalClass::addMember(Identifier *identifier, PropertyAttributes data, uint *index)
{
data.resolve();
@@ -331,7 +415,7 @@ InternalClass *InternalClass::addMember(Identifier *identifier, PropertyAttribut
return addMemberImpl(identifier, data, index);
}
-InternalClass *InternalClass::addMemberImpl(Identifier *identifier, PropertyAttributes data, uint *index)
+Heap::InternalClass *InternalClass::addMemberImpl(Identifier *identifier, PropertyAttributes data, uint *index)
{
Transition temp = { { identifier }, nullptr, (int)data.flags() };
Transition &t = lookupOrInsertTransition(temp);
@@ -343,62 +427,59 @@ InternalClass *InternalClass::addMemberImpl(Identifier *identifier, PropertyAttr
return t.lookup;
// create a new class and add it to the tree
- InternalClass *newClass = engine->newClass(*this);
+ Heap::InternalClass *newClass = engine->newClass(this);
PropertyHash::Entry e = { identifier, newClass->size };
newClass->propertyTable.addEntry(e, newClass->size);
newClass->nameMap.add(newClass->size, identifier);
newClass->propertyData.add(newClass->size, data);
++newClass->size;
- if (data.isAccessor()) {
- // add a dummy entry, since we need two entries for accessors
- newClass->propertyTable.addEntry(e, newClass->size);
- newClass->nameMap.add(newClass->size, 0);
- newClass->propertyData.add(newClass->size, PropertyAttributes());
- ++newClass->size;
- }
+ if (data.isAccessor())
+ addDummyEntry(newClass, e);
t.lookup = newClass;
Q_ASSERT(t.lookup);
return newClass;
}
-void InternalClass::removeMember(Object *object, Identifier *id)
+void InternalClass::removeChildEntry(InternalClass *child)
+{
+ Q_ASSERT(engine);
+ for (auto &t : transitions) {
+ if (t.lookup == child) {
+ t.lookup = nullptr;
+ return;
+ }
+ }
+ Q_UNREACHABLE();
+
+}
+
+void InternalClass::removeMember(QV4::Object *object, Identifier *identifier)
{
- InternalClass *oldClass = object->internalClass();
- uint propIdx = oldClass->propertyTable.lookup(id);
- Q_ASSERT(propIdx < oldClass->size);
+ Heap::InternalClass *oldClass = object->internalClass();
+ Q_ASSERT(oldClass->propertyTable.lookup(identifier) < oldClass->size);
- Transition temp = { { id }, nullptr, -1 };
+ Transition temp = { { identifier }, nullptr, Transition::RemoveMember };
Transition &t = object->internalClass()->lookupOrInsertTransition(temp);
- bool accessor = oldClass->propertyData.at(propIdx).isAccessor();
-
- if (t.lookup) {
- object->setInternalClass(t.lookup);
- } else {
+ if (!t.lookup) {
// create a new class and add it to the tree
- InternalClass *newClass = oldClass->engine->internalClasses[EngineBase::Class_Empty]->changeVTable(oldClass->vtable);
- newClass = newClass->changePrototype(oldClass->prototype);
- for (uint i = 0; i < oldClass->size; ++i) {
- if (i == propIdx)
- continue;
- if (!oldClass->propertyData.at(i).isEmpty())
- newClass = newClass->addMember(oldClass->nameMap.at(i), oldClass->propertyData.at(i));
- }
- object->setInternalClass(newClass);
+ Heap::InternalClass *newClass = oldClass->engine->newClass(oldClass);
+ // simply make the entry inaccessible
+ int idx = newClass->propertyTable.removeIdentifier(identifier, oldClass->size);
+ newClass->nameMap.set(idx, nullptr);
+ newClass->propertyData.set(idx, PropertyAttributes());
+ t.lookup = newClass;
+ Q_ASSERT(t.lookup);
}
+ object->setInternalClass(t.lookup);
- Q_ASSERT(object->internalClass()->size == oldClass->size - (accessor ? 2 : 1));
-
- // remove the entry in the property data
- removeFromPropertyData(object, propIdx, accessor);
-
- t.lookup = object->internalClass();
- Q_ASSERT(t.lookup);
+ // we didn't remove the data slot, just made it inaccessible
+ Q_ASSERT(object->internalClass()->size == oldClass->size);
}
-uint InternalClass::find(const String *string)
+uint InternalClass::find(const QV4::String *string)
{
engine->identifierTable->identifier(string);
const Identifier *id = string->d()->identifier;
@@ -410,42 +491,104 @@ uint InternalClass::find(const String *string)
return UINT_MAX;
}
-InternalClass *InternalClass::sealed()
+Heap::InternalClass *InternalClass::sealed()
{
- if (m_sealed)
- return m_sealed;
+ if (isSealed)
+ return this;
+
+ bool alreadySealed = !extensible;
+ for (uint i = 0; i < size; ++i) {
+ PropertyAttributes attrs = propertyData.at(i);
+ if (attrs.isEmpty())
+ continue;
+ if (attrs.isConfigurable()) {
+ alreadySealed = false;
+ break;
+ }
+ }
+
+ if (alreadySealed) {
+ isSealed = true;
+ return this;
+ }
+
+ Transition temp = { { nullptr }, nullptr, InternalClassTransition::Sealed };
+ Transition &t = lookupOrInsertTransition(temp);
+
+ if (t.lookup) {
+ Q_ASSERT(t.lookup && t.lookup->isSealed);
+ return t.lookup;
+ }
+
+ Heap::InternalClass *s = engine->newClass(this);
- m_sealed = engine->internalClasses[EngineBase::Class_Empty]->changeVTable(vtable);
- m_sealed = m_sealed->changePrototype(prototype);
for (uint i = 0; i < size; ++i) {
PropertyAttributes attrs = propertyData.at(i);
if (attrs.isEmpty())
continue;
attrs.setConfigurable(false);
- m_sealed = m_sealed->addMember(nameMap.at(i), attrs);
+ s->propertyData.set(i, attrs);
}
- m_sealed = m_sealed->nonExtensible();
+ s->extensible = false;
+ s->isSealed = true;
- m_sealed->m_sealed = m_sealed;
- return m_sealed;
+ t.lookup = s;
+ return s;
}
-InternalClass *InternalClass::frozen()
+Heap::InternalClass *InternalClass::frozen()
{
- if (m_frozen)
- return m_frozen;
+ if (isFrozen)
+ return this;
+
+ bool alreadyFrozen = !extensible;
+ for (uint i = 0; i < size; ++i) {
+ PropertyAttributes attrs = propertyData.at(i);
+ if (attrs.isEmpty())
+ continue;
+ if ((attrs.isData() && attrs.isWritable()) || attrs.isConfigurable()) {
+ alreadyFrozen = false;
+ break;
+ }
+ }
+
+ if (alreadyFrozen) {
+ isSealed = true;
+ isFrozen = true;
+ return this;
+ }
+
+ Transition temp = { { nullptr }, nullptr, InternalClassTransition::Frozen };
+ Transition &t = lookupOrInsertTransition(temp);
+
+ if (t.lookup) {
+ Q_ASSERT(t.lookup && t.lookup->isSealed && t.lookup->isFrozen);
+ return t.lookup;
+ }
+
+ Heap::InternalClass *f = engine->newClass(this);
- m_frozen = propertiesFrozen();
- m_frozen = m_frozen->nonExtensible();
+ for (uint i = 0; i < size; ++i) {
+ PropertyAttributes attrs = propertyData.at(i);
+ if (attrs.isEmpty())
+ continue;
+ if (attrs.isData())
+ attrs.setWritable(false);
+ attrs.setConfigurable(false);
+ f->propertyData.set(i, attrs);
+ }
+ f->extensible = false;
+ f->isSealed = true;
+ f->isFrozen = true;
- m_frozen->m_frozen = m_frozen;
- m_frozen->m_sealed = m_frozen;
- return m_frozen;
+ t.lookup = f;
+ return f;
}
-InternalClass *InternalClass::propertiesFrozen() const
+Heap::InternalClass *InternalClass::propertiesFrozen() const
{
- InternalClass *frozen = engine->internalClasses[EngineBase::Class_Empty]->changeVTable(vtable);
+ Scope scope(engine);
+ Scoped<QV4::InternalClass> frozen(scope, engine->internalClasses(EngineBase::Class_Empty)->changeVTable(vtable));
frozen = frozen->changePrototype(prototype);
for (uint i = 0; i < size; ++i) {
PropertyAttributes attrs = propertyData.at(i);
@@ -455,10 +598,10 @@ InternalClass *InternalClass::propertiesFrozen() const
attrs.setConfigurable(false);
frozen = frozen->addMember(nameMap.at(i), attrs);
}
- return frozen;
+ return frozen->d();
}
-InternalClass *InternalClass::asProtoClass()
+Heap::InternalClass *InternalClass::asProtoClass()
{
if (isUsedAsProto)
return this;
@@ -468,7 +611,7 @@ InternalClass *InternalClass::asProtoClass()
if (t.lookup)
return t.lookup;
- InternalClass *newClass = engine->newClass(*this);
+ Heap::InternalClass *newClass = engine->newClass(this);
newClass->isUsedAsProto = true;
t.lookup = newClass;
@@ -476,88 +619,37 @@ InternalClass *InternalClass::asProtoClass()
return newClass;
}
-void InternalClass::destroy()
+static void updateProtoUsage(Heap::Object *o, Heap::InternalClass *ic)
{
- std::vector<InternalClass *> destroyStack;
- destroyStack.reserve(64);
- destroyStack.push_back(this);
-
- while (!destroyStack.empty()) {
- InternalClass *next = destroyStack.back();
- destroyStack.pop_back();
- if (!next->engine)
- continue;
- next->engine = nullptr;
- next->propertyTable.~PropertyHash();
- next->nameMap.~SharedInternalClassData<Identifier *>();
- next->propertyData.~SharedInternalClassData<PropertyAttributes>();
- if (next->m_sealed)
- destroyStack.push_back(next->m_sealed);
- if (next->m_frozen)
- destroyStack.push_back(next->m_frozen);
-
- for (size_t i = 0; i < next->transitions.size(); ++i) {
- Q_ASSERT(next->transitions.at(i).lookup);
- destroyStack.push_back(next->transitions.at(i).lookup);
- }
-
- next->transitions.~vector<Transition>();
+ if (ic->prototype == o)
+ ic->protoId = ic->engine->newProtoId();
+ for (auto &t : ic->transitions) {
+ if (t.lookup)
+ updateProtoUsage(o, t.lookup);
}
}
+
void InternalClass::updateProtoUsage(Heap::Object *o)
{
Q_ASSERT(isUsedAsProto);
- InternalClass *ic = engine->internalClasses[EngineBase::Class_Empty];
+ Heap::InternalClass *ic = engine->internalClasses(EngineBase::Class_Empty);
Q_ASSERT(!ic->prototype);
- // only need to go two levels into the IC hierarchy, as prototype changes
- // can only happen there
- for (auto &t : ic->transitions) {
- Q_ASSERT(t.lookup);
- if (t.flags == InternalClassTransition::VTableChange) {
- InternalClass *ic2 = t.lookup;
- for (auto &t2 : ic2->transitions) {
- if (t2.flags == InternalClassTransition::PrototypeChange &&
- t2.lookup->prototype == o)
- ic2->updateInternalClassIdRecursive();
- }
- } else if (t.flags == InternalClassTransition::PrototypeChange && t.lookup->prototype == o) {
- ic->updateInternalClassIdRecursive();
- }
- }
+ Heap::updateProtoUsage(o, ic);
}
-void InternalClass::updateInternalClassIdRecursive()
+void InternalClass::markObjects(Heap::Base *b, MarkStack *stack)
{
- id = engine->newInternalClassId();
- for (auto &t : transitions) {
- Q_ASSERT(t.lookup);
- t.lookup->updateInternalClassIdRecursive();
- }
+ Heap::InternalClass *ic = static_cast<Heap::InternalClass *>(b);
+ if (ic->prototype)
+ ic->prototype->mark(stack);
+ if (ic->parent)
+ ic->parent->mark(stack);
}
+}
-
-void InternalClassPool::markObjects(MarkStack *markStack)
-{
- InternalClass *ic = markStack->engine->internalClasses[EngineBase::Class_Empty];
- Q_ASSERT(!ic->prototype);
-
- // only need to go two levels into the IC hierarchy, as prototype changes
- // can only happen there
- for (auto &t : ic->transitions) {
- Q_ASSERT(t.lookup);
- if (t.flags == InternalClassTransition::VTableChange) {
- InternalClass *ic2 = t.lookup;
- for (auto &t2 : ic2->transitions) {
- if (t2.flags == InternalClassTransition::PrototypeChange)
- t2.lookup->prototype->mark(markStack);
- }
- } else if (t.flags == InternalClassTransition::PrototypeChange) {
- t.lookup->prototype->mark(markStack);
- }
- }
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index b689272006..0b6f088bd3 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -53,8 +53,8 @@
#include "qv4global_p.h"
#include <QHash>
-#include <private/qqmljsmemorypool_p.h>
#include <private/qv4identifier_p.h>
+#include <private/qv4heap_p.h>
QT_BEGIN_NAMESPACE
@@ -79,12 +79,12 @@ struct PropertyHash
inline PropertyHash();
inline PropertyHash(const PropertyHash &other);
inline ~PropertyHash();
+ PropertyHash &operator=(const PropertyHash &other);
void addEntry(const Entry &entry, int classSize);
uint lookup(const Identifier *identifier) const;
-
-private:
- PropertyHash &operator=(const PropertyHash &other);
+ int removeIdentifier(Identifier *identifier, int classSize);
+ void detach(bool grow, int classSize);
};
struct PropertyHashData
@@ -118,6 +118,17 @@ inline PropertyHash::~PropertyHash()
delete d;
}
+inline PropertyHash &PropertyHash::operator=(const PropertyHash &other)
+{
+ ++other.d->refCount;
+ if (!--d->refCount)
+ delete d;
+ d = other.d;
+ return *this;
+}
+
+
+
inline uint PropertyHash::lookup(const Identifier *identifier) const
{
Q_ASSERT(d->entries);
@@ -163,6 +174,13 @@ struct SharedInternalClassData {
if (!--d->refcount)
delete d;
}
+ SharedInternalClassData &operator=(const SharedInternalClassData &other) {
+ ++other.d->refcount;
+ if (!--d->refcount)
+ delete d;
+ d = other.d;
+ return *this;
+ }
void add(uint pos, T value) {
if (pos < d->size) {
@@ -214,9 +232,6 @@ struct SharedInternalClassData {
Q_ASSERT(i < d->size);
return d->data[i];
}
-
-private:
- SharedInternalClassData &operator=(const SharedInternalClassData &other);
};
struct InternalClassTransition
@@ -226,14 +241,17 @@ struct InternalClassTransition
const VTable *vtable;
Heap::Object *prototype;
};
- InternalClass *lookup;
+ Heap::InternalClass *lookup;
int flags;
enum {
// range 0-0xff is reserved for attribute changes
NotExtensible = 0x100,
VTableChange = 0x200,
PrototypeChange = 0x201,
- ProtoClass = 0x202
+ ProtoClass = 0x202,
+ Sealed = 0x203,
+ Frozen = 0x204,
+ RemoveMember = -1
};
bool operator==(const InternalClassTransition &other) const
@@ -243,11 +261,14 @@ struct InternalClassTransition
{ return id < other.id || (id == other.id && flags < other.flags); }
};
-struct InternalClass : public QQmlJS::Managed {
- int id = 0; // unique across the engine, gets changed also when proto chain changes
+namespace Heap {
+
+struct InternalClass : Base {
ExecutionEngine *engine;
const VTable *vtable;
+ quintptr protoId; // unique across the engine, gets changed whenever the proto chain changes
Heap::Object *prototype;
+ InternalClass *parent;
PropertyHash propertyTable; // id to valueIndex
SharedInternalClassData<Identifier *> nameMap;
@@ -257,32 +278,25 @@ struct InternalClass : public QQmlJS::Managed {
std::vector<Transition> transitions;
InternalClassTransition &lookupOrInsertTransition(const InternalClassTransition &t);
- InternalClass *m_sealed;
- InternalClass *m_frozen;
-
uint size;
bool extensible;
- bool isUsedAsProto = false;
+ bool isSealed;
+ bool isFrozen;
+ bool isUsedAsProto;
+
+ void init(ExecutionEngine *engine);
+ void init(InternalClass *other);
+ void destroy();
Q_REQUIRED_RESULT InternalClass *nonExtensible();
- Q_REQUIRED_RESULT InternalClass *changeVTable(const VTable *vt) {
- if (vtable == vt)
- return this;
- return changeVTableImpl(vt);
- }
- Q_REQUIRED_RESULT InternalClass *changePrototype(Heap::Object *proto) {
- if (prototype == proto)
- return this;
- return changePrototypeImpl(proto);
- }
- static void addMember(Object *object, String *string, PropertyAttributes data, uint *index);
- Q_REQUIRED_RESULT InternalClass *addMember(String *string, PropertyAttributes data, uint *index = nullptr);
+ static void addMember(QV4::Object *object, QV4::String *string, PropertyAttributes data, uint *index);
+ Q_REQUIRED_RESULT InternalClass *addMember(QV4::String *string, PropertyAttributes data, uint *index = nullptr);
Q_REQUIRED_RESULT InternalClass *addMember(Identifier *identifier, PropertyAttributes data, uint *index = nullptr);
Q_REQUIRED_RESULT InternalClass *changeMember(Identifier *identifier, PropertyAttributes data, uint *index = nullptr);
- static void changeMember(Object *object, String *string, PropertyAttributes data, uint *index = nullptr);
- static void removeMember(Object *object, Identifier *id);
- uint find(const String *string);
+ static void changeMember(QV4::Object *object, QV4::String *string, PropertyAttributes data, uint *index = nullptr);
+ static void removeMember(QV4::Object *object, Identifier *identifier);
+ uint find(const QV4::String *string);
uint find(const Identifier *id)
{
uint index = propertyTable.lookup(id);
@@ -298,24 +312,37 @@ struct InternalClass : public QQmlJS::Managed {
Q_REQUIRED_RESULT InternalClass *asProtoClass();
- void destroy();
+ Q_REQUIRED_RESULT InternalClass *changeVTable(const VTable *vt) {
+ if (vtable == vt)
+ return this;
+ return changeVTableImpl(vt);
+ }
+ Q_REQUIRED_RESULT InternalClass *changePrototype(Heap::Object *proto) {
+ if (prototype == proto)
+ return this;
+ return changePrototypeImpl(proto);
+ }
void updateProtoUsage(Heap::Object *o);
+ static void markObjects(Heap::Base *ic, MarkStack *stack);
+
private:
Q_QML_EXPORT InternalClass *changeVTableImpl(const VTable *vt);
Q_QML_EXPORT InternalClass *changePrototypeImpl(Heap::Object *proto);
InternalClass *addMemberImpl(Identifier *identifier, PropertyAttributes data, uint *index);
- void updateInternalClassIdRecursive();
+
+ void removeChildEntry(InternalClass *child);
friend struct ExecutionEngine;
- InternalClass(ExecutionEngine *engine);
- InternalClass(const InternalClass &other);
};
-struct InternalClassPool : public QQmlJS::MemoryPool
+inline
+void Base::markObjects(Base *b, MarkStack *stack)
{
- void markObjects(MarkStack *markStack);
-};
+ b->internalClass->mark(stack);
+}
+
+}
}
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 52ab03cd94..fdf3d7685d 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -92,7 +92,7 @@ ReturnedValue Lookup::resolveGetter(ExecutionEngine *engine, const Object *objec
return getter(this, engine, *object);
}
- protoLookup.icIdentifier = obj->internalClass->id;
+ protoLookup.protoId = obj->internalClass->protoId;
resolveProtoGetter(name, obj->prototype());
return getter(this, engine, *object);
}
@@ -126,7 +126,7 @@ ReturnedValue Lookup::resolvePrimitiveGetter(ExecutionEngine *engine, const Valu
}
Identifier *name = engine->identifierTable->identifier(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
- protoLookup.icIdentifier = primitiveLookup.proto->internalClass->id;
+ protoLookup.protoId = primitiveLookup.proto->internalClass->protoId;
resolveProtoGetter(name, primitiveLookup.proto);
if (getter == getterProto)
@@ -140,7 +140,7 @@ ReturnedValue Lookup::resolveGlobalGetter(ExecutionEngine *engine)
{
Object *o = engine->globalObject;
Identifier *name = engine->identifierTable->identifier(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
- protoLookup.icIdentifier = o->internalClass()->id;
+ protoLookup.protoId = o->internalClass()->protoId;
resolveProtoGetter(name, o->d());
if (getter == getterProto)
@@ -188,16 +188,16 @@ ReturnedValue Lookup::getterTwoClasses(Lookup *l, ExecutionEngine *engine, const
return result;
}
if (first.getter == getterProto && second.getter == getterProto) {
- l->protoLookupTwoClasses.icIdentifier = first.protoLookup.icIdentifier;
- l->protoLookupTwoClasses.icIdentifier2 = second.protoLookup.icIdentifier;
+ l->protoLookupTwoClasses.protoId = first.protoLookup.protoId;
+ l->protoLookupTwoClasses.protoId2 = second.protoLookup.protoId;
l->protoLookupTwoClasses.data = first.protoLookup.data;
l->protoLookupTwoClasses.data2 = second.protoLookup.data;
l->getter = getterProtoTwoClasses;
return result;
}
if (first.getter == getterProtoAccessor && second.getter == getterProtoAccessor) {
- l->protoLookupTwoClasses.icIdentifier = first.protoLookup.icIdentifier;
- l->protoLookupTwoClasses.icIdentifier2 = second.protoLookup.icIdentifier;
+ l->protoLookupTwoClasses.protoId = first.protoLookup.protoId;
+ l->protoLookupTwoClasses.protoId2 = second.protoLookup.protoId;
l->protoLookupTwoClasses.data = first.protoLookup.data;
l->protoLookupTwoClasses.data2 = second.protoLookup.data;
l->getter = getterProtoAccessorTwoClasses;
@@ -250,7 +250,7 @@ ReturnedValue Lookup::getterProto(Lookup *l, ExecutionEngine *engine, const Valu
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->protoLookup.icIdentifier == o->internalClass->id)
+ if (l->protoLookup.protoId == o->internalClass->protoId)
return l->protoLookup.data->asReturnedValue();
}
return getterTwoClasses(l, engine, object);
@@ -307,9 +307,9 @@ ReturnedValue Lookup::getterProtoTwoClasses(Lookup *l, ExecutionEngine *engine,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->protoLookupTwoClasses.icIdentifier == o->internalClass->id)
+ if (l->protoLookupTwoClasses.protoId == o->internalClass->protoId)
return l->protoLookupTwoClasses.data->asReturnedValue();
- if (l->protoLookupTwoClasses.icIdentifier2 == o->internalClass->id)
+ if (l->protoLookupTwoClasses.protoId2 == o->internalClass->protoId)
return l->protoLookupTwoClasses.data2->asReturnedValue();
return getterFallback(l, engine, object);
}
@@ -340,14 +340,13 @@ ReturnedValue Lookup::getterProtoAccessor(Lookup *l, ExecutionEngine *engine, co
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
- if (o && l->protoLookup.icIdentifier == o->internalClass->id) {
+ if (o && l->protoLookup.protoId == o->internalClass->protoId) {
const Value *getter = l->protoLookup.data;
if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
return static_cast<const FunctionObject *>(getter)->call(&object, nullptr, 0);
}
- l->getter = getterTwoClasses;
return getterTwoClasses(l, engine, object);
}
@@ -358,9 +357,9 @@ ReturnedValue Lookup::getterProtoAccessorTwoClasses(Lookup *l, ExecutionEngine *
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
const Value *getter = nullptr;
- if (l->protoLookupTwoClasses.icIdentifier == o->internalClass->id)
+ if (l->protoLookupTwoClasses.protoId == o->internalClass->protoId)
getter = l->protoLookupTwoClasses.data;
- else if (l->protoLookupTwoClasses.icIdentifier2 == o->internalClass->id)
+ else if (l->protoLookupTwoClasses.protoId2 == o->internalClass->protoId)
getter = l->protoLookupTwoClasses.data2;
if (getter) {
if (!getter->isFunctionObject()) // ### catch at resolve time
@@ -377,7 +376,7 @@ ReturnedValue Lookup::primitiveGetterProto(Lookup *l, ExecutionEngine *engine, c
{
if (object.type() == l->primitiveLookup.type) {
Heap::Object *o = l->primitiveLookup.proto;
- if (l->primitiveLookup.icIdentifier == o->internalClass->id)
+ if (l->primitiveLookup.protoId == o->internalClass->protoId)
return l->primitiveLookup.data->asReturnedValue();
}
l->getter = getterGeneric;
@@ -388,7 +387,7 @@ ReturnedValue Lookup::primitiveGetterAccessor(Lookup *l, ExecutionEngine *engine
{
if (object.type() == l->primitiveLookup.type) {
Heap::Object *o = l->primitiveLookup.proto;
- if (l->primitiveLookup.icIdentifier == o->internalClass->id) {
+ if (l->primitiveLookup.protoId == o->internalClass->protoId) {
const Value *getter = l->primitiveLookup.data;
if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
@@ -417,7 +416,7 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetterProto(Lookup *l, ExecutionEngine *engine)
{
Heap::Object *o = engine->globalObject->d();
- if (l->protoLookup.icIdentifier == o->internalClass->id)
+ if (l->protoLookup.protoId == o->internalClass->protoId)
return l->protoLookup.data->asReturnedValue();
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, engine);
@@ -426,7 +425,7 @@ ReturnedValue Lookup::globalGetterProto(Lookup *l, ExecutionEngine *engine)
ReturnedValue Lookup::globalGetterProtoAccessor(Lookup *l, ExecutionEngine *engine)
{
Heap::Object *o = engine->globalObject->d();
- if (l->protoLookup.icIdentifier == o->internalClass->id) {
+ if (l->protoLookup.protoId == o->internalClass->protoId) {
const Value *getter = l->protoLookup.data;
if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
@@ -442,7 +441,7 @@ bool Lookup::resolveSetter(ExecutionEngine *engine, Object *object, const Value
Scope scope(engine);
ScopedString name(scope, scope.engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
- InternalClass *c = object->internalClass();
+ Heap::InternalClass *c = object->internalClass();
uint idx = c->find(name);
if (idx != UINT_MAX) {
if (object->isArrayObject() && idx == Heap::ArrayObject::LengthPropertyIndex) {
@@ -460,7 +459,7 @@ bool Lookup::resolveSetter(ExecutionEngine *engine, Object *object, const Value
return setter(this, engine, *object, value);
}
- insertionLookup.icIdentifier = c->id;
+ insertionLookup.protoId = c->protoId;
if (!object->put(name, value)) {
setter = Lookup::setterFallback;
return false;
@@ -574,7 +573,7 @@ bool Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, c
bool Lookup::setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass()->id == l->insertionLookup.icIdentifier) {
+ if (o && o->internalClass()->protoId == l->insertionLookup.protoId) {
o->setInternalClass(l->insertionLookup.newClass);
o->d()->setProperty(engine, l->insertionLookup.offset, value);
return true;
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h
index 5f507733fd..49eb66d1fb 100644
--- a/src/qml/jsruntime/qv4lookup_p.h
+++ b/src/qml/jsruntime/qv4lookup_p.h
@@ -65,7 +65,6 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
struct Lookup {
- enum { Size = 4 };
union {
ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const Value &object);
ReturnedValue (*globalGetter)(Lookup *l, ExecutionEngine *engine);
@@ -73,35 +72,43 @@ struct Lookup {
};
union {
struct {
- InternalClass *ic;
+ Heap::Base *h1;
+ Heap::Base *h2;
+ quintptr unused;
+ quintptr unused2;
+ } markDef;
+ struct {
+ Heap::InternalClass *ic;
+ quintptr _unused;
int offset;
} objectLookup;
struct {
+ quintptr protoId;
+ quintptr _unused;
const Value *data;
- int icIdentifier;
} protoLookup;
struct {
- InternalClass *ic;
- InternalClass *ic2;
+ Heap::InternalClass *ic;
+ Heap::InternalClass *ic2;
int offset;
int offset2;
} objectLookupTwoClasses;
struct {
+ quintptr protoId;
+ quintptr protoId2;
const Value *data;
const Value *data2;
- int icIdentifier;
- int icIdentifier2;
} protoLookupTwoClasses;
struct {
// Make sure the next two values are in sync with protoLookup
- const Value *data;
- int icIdentifier;
- unsigned type;
+ quintptr protoId;
Heap::Object *proto;
+ const Value *data;
+ quintptr type;
} primitiveLookup;
struct {
- InternalClass *newClass;
- int icIdentifier;
+ Heap::InternalClass *newClass;
+ quintptr protoId;
int offset;
} insertionLookup;
};
@@ -144,6 +151,17 @@ struct Lookup {
static bool setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
static bool setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
static bool arrayLengthSetter(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+
+ void markObjects(MarkStack *stack) {
+ if (markDef.h1 && !(reinterpret_cast<quintptr>(markDef.h1) & 1))
+ markDef.h1->mark(stack);
+ if (markDef.h2 && !(reinterpret_cast<quintptr>(markDef.h2) & 1))
+ markDef.h2->mark(stack);
+ }
+
+ void clear() {
+ memset(&markDef, 0, sizeof(markDef));
+ }
};
Q_STATIC_ASSERT(std::is_standard_layout<Lookup>::value);
diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp
index b50e5f0355..c3def2f949 100644
--- a/src/qml/jsruntime/qv4managed.cpp
+++ b/src/qml/jsruntime/qv4managed.cpp
@@ -63,11 +63,13 @@ const VTable Managed::static_vtbl =
isEqualTo
};
+DEFINE_MANAGED_VTABLE(InternalClass);
+
QString Managed::className() const
{
const char *s = nullptr;
- switch (Type(d()->vtable()->type)) {
+ switch (Type(vtable()->type)) {
case Type_Invalid:
case Type_String:
return QString();
@@ -114,6 +116,9 @@ QString Managed::className() const
case Type_ForeachIteratorObject:
s = "__ForeachIterator";
break;
+ case Type_InternalClass:
+ s = "__InternalClass";
+ break;
case Type_RegExp:
s = "__RegExp";
break;
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 092c61b81c..b35788a711 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -92,14 +92,14 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
QV4::Heap::DataClass *dptr = d_unchecked(); \
dptr->_checkIsInitialized(); \
return dptr; \
- } \
- Q_STATIC_ASSERT(std::is_trivial< QV4::Heap::DataClass >::value);
+ }
#define V4_MANAGED(DataClass, superClass) \
private: \
DataClass() Q_DECL_EQ_DELETE; \
Q_DISABLE_COPY(DataClass) \
- V4_MANAGED_ITSELF(DataClass, superClass)
+ V4_MANAGED_ITSELF(DataClass, superClass) \
+ Q_STATIC_ASSERT(std::is_trivial< QV4::Heap::DataClass >::value);
#define Q_MANAGED_TYPE(type) \
public: \
@@ -154,8 +154,8 @@ const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname,
QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_OFF
#define V4_INTERNALCLASS(c) \
- static QV4::InternalClass *defaultInternalClass(QV4::EngineBase *e) \
- { return e->internalClasses[QV4::EngineBase::Class_##c]; }
+ static Heap::InternalClass *defaultInternalClass(QV4::EngineBase *e) \
+ { return e->internalClasses(QV4::EngineBase::Class_##c); }
struct Q_QML_PRIVATE_EXPORT Managed : Value
{
@@ -193,6 +193,7 @@ public:
Type_MathObject,
Type_ExecutionContext,
+ Type_InternalClass,
Type_ForeachIteratorObject,
Type_RegExp,
@@ -200,18 +201,19 @@ public:
};
Q_MANAGED_TYPE(Invalid)
- InternalClass *internalClass() const { return d()->internalClass; }
+ Heap::InternalClass *internalClass() const { return d()->internalClass; }
+ const VTable *vtable() const { return d()->internalClass->vtable; }
inline ExecutionEngine *engine() const { return internalClass()->engine; }
- bool isListType() const { return d()->vtable()->type == Type_QmlSequence; }
+ bool isListType() const { return d()->internalClass->vtable->type == Type_QmlSequence; }
- bool isArrayObject() const { return d()->vtable()->type == Type_ArrayObject; }
- bool isStringObject() const { return d()->vtable()->type == Type_StringObject; }
+ bool isArrayObject() const { return d()->internalClass->vtable->type == Type_ArrayObject; }
+ bool isStringObject() const { return d()->internalClass->vtable->type == Type_StringObject; }
QString className() const;
bool isEqualTo(const Managed *other) const
- { return d()->vtable()->isEqualTo(const_cast<Managed *>(this), const_cast<Managed *>(other)); }
+ { return d()->internalClass->vtable->isEqualTo(const_cast<Managed *>(this), const_cast<Managed *>(other)); }
static bool isEqualTo(Managed *m, Managed *other);
@@ -254,6 +256,32 @@ inline const Object *Value::as() const {
return objectValue();
}
+
+struct InternalClass : Managed
+{
+ V4_MANAGED_ITSELF(InternalClass, Managed)
+ Q_MANAGED_TYPE(InternalClass)
+ V4_INTERNALCLASS(Empty)
+ V4_NEEDS_DESTROY
+
+ Q_REQUIRED_RESULT Heap::InternalClass *changeVTable(const VTable *vt) {
+ return d()->changeVTable(vt);
+ }
+ Q_REQUIRED_RESULT Heap::InternalClass *changePrototype(Heap::Object *proto) {
+ return d()->changePrototype(proto);
+ }
+ Q_REQUIRED_RESULT Heap::InternalClass *addMember(QV4::String *string, PropertyAttributes data, uint *index = 0) {
+ return d()->addMember(string, data, index);
+ }
+ Q_REQUIRED_RESULT Heap::InternalClass *addMember(Identifier *identifier, PropertyAttributes data, uint *index = 0) {
+ return d()->addMember(identifier, data, index);
+ }
+
+ void operator =(Heap::InternalClass *ic) {
+ Value::operator=(ic);
+ }
+};
+
}
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index bcbe475c2c..170ad9f556 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -57,9 +57,9 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(Object);
-void Object::setInternalClass(InternalClass *ic)
+void Object::setInternalClass(Heap::InternalClass *ic)
{
- d()->internalClass = ic;
+ d()->internalClass.set(engine(), ic);
if (ic->isUsedAsProto)
ic->updateProtoUsage(d());
Q_ASSERT(ic && ic->vtable);
@@ -89,7 +89,7 @@ void Object::setProperty(uint index, const Property *p)
void Heap::Object::setUsedAsProto()
{
- internalClass = internalClass->asProtoClass();
+ internalClass.set(internalClass->engine, internalClass->asProtoClass());
}
bool Object::setPrototype(Object *proto)
@@ -121,7 +121,7 @@ ReturnedValue Object::getValue(const Value &thisObject, const Value &v, Property
bool Object::putValue(uint memberIndex, const Value &value)
{
- QV4::InternalClass *ic = internalClass();
+ Heap::InternalClass *ic = internalClass();
if (ic->engine->hasException)
return false;
@@ -228,6 +228,7 @@ void Object::defineReadonlyConfigurableProperty(String *name, const Value &value
void Heap::Object::markObjects(Heap::Base *b, MarkStack *stack)
{
+ Base::markObjects(b, stack);
Object *o = static_cast<Object *>(b);
if (o->memberData)
o->memberData->mark(stack);
@@ -248,7 +249,7 @@ void Heap::Object::markObjects(Heap::Base *b, MarkStack *stack)
void Object::insertMember(String *s, const Property *p, PropertyAttributes attributes)
{
uint idx;
- InternalClass::addMember(this, s, attributes, &idx);
+ Heap::InternalClass::addMember(this, s, attributes, &idx);
if (attributes.isAccessor()) {
setProperty(idx + GetterOffset, p->value);
@@ -776,7 +777,7 @@ bool Object::internalDeleteProperty(String *name)
uint memberIdx = internalClass()->find(name->identifier());
if (memberIdx != UINT_MAX) {
if (internalClass()->propertyData[memberIdx].isConfigurable()) {
- InternalClass::removeMember(this, name->identifier());
+ Heap::InternalClass::removeMember(this, name->identifier());
return true;
}
return false;
@@ -832,7 +833,7 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, String *name, const
}
if (attrs.hasWritable() && !attrs.isWritable()) {
cattrs.setWritable(false);
- InternalClass::changeMember(this, engine->id_length(), cattrs);
+ Heap::InternalClass::changeMember(this, engine->id_length(), cattrs);
}
if (!succeeded)
return false;
@@ -980,7 +981,7 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *
current->merge(cattrs, p, attrs);
if (member) {
- InternalClass::changeMember(this, member, cattrs);
+ Heap::InternalClass::changeMember(this, member, cattrs);
setProperty(index, current);
} else {
setArrayAttributes(index, cattrs);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 1731ae3c76..79ffef47ba 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -74,6 +74,10 @@ DECLARE_EXPORTED_HEAP_OBJECT(Object, Base) {
static void markObjects(Heap::Base *base, MarkStack *stack);
void init() { Base::init(); }
+ const VTable *vtable() const {
+ return internalClass->vtable;
+ }
+
const Value *inlinePropertyDataWithOffset(uint indexWithOffset) const {
Q_ASSERT(indexWithOffset >= vtable()->inlinePropertyOffset && indexWithOffset < vtable()->inlinePropertyOffset + vtable()->nInlineProperties);
return reinterpret_cast<const Value *>(this) + indexWithOffset;
@@ -218,7 +222,7 @@ struct Q_QML_EXPORT Object: Managed {
SetterOffset = 1
};
- void setInternalClass(InternalClass *ic);
+ void setInternalClass(Heap::InternalClass *ic);
const Value *propertyData(uint index) const { return d()->propertyData(index); }
@@ -551,7 +555,7 @@ inline void Object::arraySet(uint index, const Value &value)
template<>
inline const ArrayObject *Value::as() const {
- return isManaged() && m()->vtable()->type == Managed::Type_ArrayObject ? static_cast<const ArrayObject *>(this) : nullptr;
+ return isManaged() && m()->internalClass->vtable->type == Managed::Type_ArrayObject ? static_cast<const ArrayObject *>(this) : nullptr;
}
#ifndef V4_BOOTSTRAP
diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp
index 5fd200efc1..b337243204 100644
--- a/src/qml/jsruntime/qv4profiling.cpp
+++ b/src/qml/jsruntime/qv4profiling.cpp
@@ -78,7 +78,7 @@ Profiler::Profiler(QV4::ExecutionEngine *engine) : featuresEnabled(0), m_engine(
void Profiler::stopProfiling()
{
featuresEnabled = 0;
- reportData(true);
+ reportData();
m_sentLocations.clear();
}
@@ -89,7 +89,7 @@ bool operator<(const FunctionCall &call1, const FunctionCall &call2)
(call1.m_end == call2.m_end && call1.m_function < call2.m_function)));
}
-void Profiler::reportData(bool trackLocations)
+void Profiler::reportData()
{
std::sort(m_data.begin(), m_data.end());
QVector<FunctionCallProperties> properties;
@@ -100,12 +100,11 @@ void Profiler::reportData(bool trackLocations)
properties.append(call.properties());
Function *function = call.function();
SentMarker &marker = m_sentLocations[reinterpret_cast<quintptr>(function)];
- if (!trackLocations || !marker.isValid()) {
+ if (!marker.isValid()) {
FunctionLocation &location = locations[properties.constLast().id];
if (!location.isValid())
location = call.resolveLocation();
- if (trackLocations)
- marker.setFunction(function);
+ marker.setFunction(function);
}
}
diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h
index e8c154e4e7..8461384e9a 100644
--- a/src/qml/jsruntime/qv4profiling_p.h
+++ b/src/qml/jsruntime/qv4profiling_p.h
@@ -251,7 +251,7 @@ public:
void stopProfiling();
void startProfiling(quint64 features);
- void reportData(bool trackLocations);
+ void reportData();
void setTimer(const QElapsedTimer &timer) { m_timer = timer; }
signals:
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index 040f060476..1de5720d03 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -312,7 +312,7 @@ Heap::QmlContext *QmlContext::createWorkerContext(ExecutionContext *parent, cons
context->isInternal = true;
context->isJSContext = true;
- Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QQmlContextWrapper>(context, (QObject*)nullptr));
+ Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocate<QQmlContextWrapper>(context, (QObject*)nullptr));
qml->d()->isNullWrapper = true;
qml->setReadOnly(false);
@@ -330,7 +330,7 @@ Heap::QmlContext *QmlContext::create(ExecutionContext *parent, QQmlContextData *
{
Scope scope(parent);
- Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QQmlContextWrapper>(context, scopeObject));
+ Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocate<QQmlContextWrapper>(context, scopeObject));
Heap::QmlContext *c = scope.engine->memoryManager->alloc<QmlContext>(parent, qml);
Q_ASSERT(c->vtable() == staticVTable());
return c;
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 816c259b9b..157de0e96e 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -56,7 +56,11 @@
#include <private/qv4functionobject_p.h>
#include <private/qv4runtime_p.h>
#include <private/qv4variantobject_p.h>
+
+#if QT_CONFIG(qml_sequence_object)
#include <private/qv4sequenceobject_p.h>
+#endif
+
#include <private/qv4objectproto_p.h>
#include <private/qv4jsonobject_p.h>
#include <private/qv4regexpobject_p.h>
@@ -181,11 +185,13 @@ static QV4::ReturnedValue loadProperty(QV4::ExecutionEngine *v4, QObject *object
if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property.propType()))
return QV4::QQmlValueTypeWrapper::create(v4, object, property.coreIndex(), valueTypeMetaObject, property.propType());
} else {
+#if QT_CONFIG(qml_sequence_object)
// see if it's a sequence type
bool succeeded = false;
QV4::ScopedValue retn(scope, QV4::SequencePrototype::newSequence(v4, property.propType(), object, property.coreIndex(), &succeeded));
if (succeeded)
return retn->asReturnedValue();
+#endif
}
if (property.propType() == QMetaType::UnknownType) {
@@ -242,7 +248,7 @@ ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *obje
return QV4::QObjectMethod::create(global, object, property->coreIndex());
} else if (property->isSignalHandler()) {
QmlSignalHandler::initProto(engine);
- return engine->memoryManager->allocObject<QV4::QmlSignalHandler>(object, property->coreIndex())->asReturnedValue();
+ return engine->memoryManager->allocate<QV4::QmlSignalHandler>(object, property->coreIndex())->asReturnedValue();
} else {
ExecutionContext *global = engine->rootContext();
return QV4::QObjectMethod::create(global, object, property->coreIndex());
@@ -684,7 +690,7 @@ ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QObject *object)
return result;
}
}
- return (engine->memoryManager->allocObject<QV4::QObjectWrapper>(object))->asReturnedValue();
+ return (engine->memoryManager->allocate<QV4::QObjectWrapper>(object))->asReturnedValue();
}
QV4::ReturnedValue QObjectWrapper::get(const Managed *m, String *name, bool *hasProperty)
@@ -1619,6 +1625,7 @@ void CallArgument::initAsType(int callType)
}
}
+#if QT_CONFIG(qml_sequence_object)
template <class T, class M>
void CallArgument::fromContainerValue(const QV4::Object *object, int callType, M CallArgument::*member, bool &queryEngine)
{
@@ -1631,6 +1638,7 @@ void CallArgument::fromContainerValue(const QV4::Object *object, int callType, M
}
}
}
+#endif
void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const QV4::Value &value)
{
@@ -1713,6 +1721,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
type = callType;
} else if (callType == QMetaType::Void) {
*qvariantPtr = QVariant();
+#if QT_CONFIG(qml_sequence_object)
} else if (callType == qMetaTypeId<std::vector<int>>()
|| callType == qMetaTypeId<std::vector<qreal>>()
|| callType == qMetaTypeId<std::vector<bool>>()
@@ -1740,6 +1749,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
stdVectorQModelIndexPtr = nullptr;
fromContainerValue<std::vector<QModelIndex>>(object, callType, &CallArgument::stdVectorQModelIndexPtr, queryEngine);
}
+#endif
} else {
queryEngine = true;
}
@@ -1833,7 +1843,7 @@ QV4::ReturnedValue CallArgument::toValue(QV4::ExecutionEngine *engine)
ReturnedValue QObjectMethod::create(ExecutionContext *scope, QObject *object, int index)
{
Scope valueScope(scope);
- Scoped<QObjectMethod> method(valueScope, valueScope.engine->memoryManager->allocObject<QObjectMethod>(scope));
+ Scoped<QObjectMethod> method(valueScope, valueScope.engine->memoryManager->allocate<QObjectMethod>(scope));
method->d()->setObject(object);
if (QQmlData *ddata = QQmlData::get(object))
@@ -1846,7 +1856,7 @@ ReturnedValue QObjectMethod::create(ExecutionContext *scope, QObject *object, in
ReturnedValue QObjectMethod::create(ExecutionContext *scope, const QQmlValueTypeWrapper *valueType, int index)
{
Scope valueScope(scope);
- Scoped<QObjectMethod> method(valueScope, valueScope.engine->memoryManager->allocObject<QObjectMethod>(scope));
+ Scoped<QObjectMethod> method(valueScope, valueScope.engine->memoryManager->allocate<QObjectMethod>(scope));
method->d()->setPropertyCache(valueType->d()->propertyCache());
method->d()->index = index;
method->d()->valueTypeWrapper.set(valueScope.engine, valueType->d());
@@ -2019,7 +2029,7 @@ void Heap::QMetaObjectWrapper::ensureConstructorsCache() {
ReturnedValue QMetaObjectWrapper::create(ExecutionEngine *engine, const QMetaObject* metaObject) {
QV4::Scope scope(engine);
- Scoped<QMetaObjectWrapper> mo(scope, engine->memoryManager->allocObject<QV4::QMetaObjectWrapper>(metaObject)->asReturnedValue());
+ Scoped<QMetaObjectWrapper> mo(scope, engine->memoryManager->allocate<QV4::QMetaObjectWrapper>(metaObject)->asReturnedValue());
mo->init(engine);
return mo->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 000e2c3a7e..0b1979dfcc 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -45,10 +45,6 @@
#include "qv4scopedvalue_p.h"
#include "qv4jscall_p.h"
-#include <private/qqmljsengine_p.h>
-#include <private/qqmljslexer_p.h>
-#include <private/qqmljsparser_p.h>
-#include <private/qqmljsast_p.h>
#include "private/qlocale_tools_p.h"
#include <QtCore/QDebug>
@@ -387,7 +383,7 @@ ReturnedValue RegExpPrototype::method_exec(const FunctionObject *b, const Value
}
// fill in result data
- ScopedArrayObject array(scope, scope.engine->newArrayObject(scope.engine->internalClasses[EngineBase::Class_RegExpExecArray], scope.engine->arrayPrototype()));
+ ScopedArrayObject array(scope, scope.engine->newArrayObject(scope.engine->internalClasses(EngineBase::Class_RegExpExecArray)));
int len = r->value()->captureCount();
array->arrayReserve(len);
ScopedValue v(scope);
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 0211ad1011..b14395b507 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -617,7 +617,7 @@ ReturnedValue Runtime::method_loadElement(ExecutionEngine *engine, const Value &
uint idx = 0;
if (index.asArrayIndex(idx)) {
if (Heap::Base *b = object.heapObject()) {
- if (b->vtable()->isObject) {
+ if (b->internalClass->vtable->isObject) {
Heap::Object *o = static_cast<Heap::Object *>(b);
if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) {
Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>();
@@ -661,7 +661,7 @@ bool Runtime::method_storeElement(ExecutionEngine *engine, const Value &object,
uint idx = 0;
if (index.asArrayIndex(idx)) {
if (Heap::Base *b = object.heapObject()) {
- if (b->vtable()->isObject) {
+ if (b->internalClass->vtable->isObject) {
Heap::Object *o = static_cast<Heap::Object *>(b);
if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) {
Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>();
@@ -1217,8 +1217,8 @@ ReturnedValue Runtime::method_arrayLiteral(ExecutionEngine *engine, Value *value
ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4::Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)
{
Scope scope(engine);
- QV4::InternalClass *klass = static_cast<CompiledData::CompilationUnit*>(engine->currentStackFrame->v4Function->compilationUnit)->runtimeClasses[classId];
- ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype()));
+ Scoped<InternalClass> klass(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeClasses[classId]);
+ ScopedObject o(scope, engine->newObject(klass->d()));
{
bool needSparseArray = arrayGetterSetterCountAndFlags >> 30;
@@ -1226,7 +1226,7 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4::
o->initSparseArray();
}
- for (uint i = 0; i < klass->size; ++i)
+ for (uint i = 0; i < klass->d()->size; ++i)
o->setProperty(i, *args++);
if (arrayValueCount > 0) {
@@ -1259,16 +1259,26 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4::
QV4::ReturnedValue Runtime::method_createMappedArgumentsObject(ExecutionEngine *engine)
{
Q_ASSERT(engine->currentContext()->d()->type == Heap::ExecutionContext::Type_CallContext);
- QV4::InternalClass *ic = engine->internalClasses[EngineBase::Class_ArgumentsObject];
- return engine->memoryManager->allocObject<ArgumentsObject>(ic, engine->objectPrototype(), engine->currentStackFrame)->asReturnedValue();
+ Heap::InternalClass *ic = engine->internalClasses(EngineBase::Class_ArgumentsObject);
+ return engine->memoryManager->allocObject<ArgumentsObject>(ic, engine->currentStackFrame)->asReturnedValue();
}
QV4::ReturnedValue Runtime::method_createUnmappedArgumentsObject(ExecutionEngine *engine)
{
- QV4::InternalClass *ic = engine->internalClasses[EngineBase::Class_StrictArgumentsObject];
- return engine->memoryManager->allocObject<StrictArgumentsObject>(ic, engine->objectPrototype(), engine->currentStackFrame)->asReturnedValue();
+ Heap::InternalClass *ic = engine->internalClasses(EngineBase::Class_StrictArgumentsObject);
+ return engine->memoryManager->allocObject<StrictArgumentsObject>(ic, engine->currentStackFrame)->asReturnedValue();
}
+QV4::ReturnedValue Runtime::method_createRestParameter(ExecutionEngine *engine, int argIndex)
+{
+ const Value *values = engine->currentStackFrame->originalArguments + argIndex;
+ int nValues = engine->currentStackFrame->originalArgumentsCount - argIndex;
+ if (nValues <= 0)
+ return engine->newArrayObject(0)->asReturnedValue();
+ return engine->newArrayObject(values, nValues)->asReturnedValue();
+}
+
+
ReturnedValue Runtime::method_loadQmlContext(NoThrowEngine *engine)
{
Heap::QmlContext *ctx = engine->qmlContext();
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index 91232256a9..9bdb41b19e 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -134,6 +134,7 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> {
F(void, declareVar, (ExecutionEngine *engine, bool deletable, int nameIndex)) \
F(ReturnedValue, createMappedArgumentsObject, (ExecutionEngine *engine)) \
F(ReturnedValue, createUnmappedArgumentsObject, (ExecutionEngine *engine)) \
+ F(ReturnedValue, createRestParameter, (ExecutionEngine *engine, int argIndex)) \
\
/* literals */ \
F(ReturnedValue, arrayLiteral, (ExecutionEngine *engine, Value *values, uint length)) \
diff --git a/src/qml/jsruntime/qv4runtimecodegen.cpp b/src/qml/jsruntime/qv4runtimecodegen.cpp
index fe18ddf9ed..93ca666c53 100644
--- a/src/qml/jsruntime/qv4runtimecodegen.cpp
+++ b/src/qml/jsruntime/qv4runtimecodegen.cpp
@@ -58,7 +58,10 @@ void RuntimeCodegen::generateFromFunctionExpression(const QString &fileName,
scan(ast);
scan.leaveEnvironment();
- int index = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : nullptr);
+ if (hasError)
+ return;
+
+ int index = defineFunction(ast->name.toString(), ast, ast->formals, ast->body);
_module->rootContext = _module->functions.at(index);
}
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 7d29d0b517..c0dce2df0d 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -691,7 +691,7 @@ bool SequencePrototype::isSequenceType(int sequenceTypeId)
#define NEW_REFERENCE_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
if (sequenceType == qMetaTypeId<SequenceType>()) { \
- QV4::ScopedObject obj(scope, engine->memoryManager->allocObject<QQml##ElementTypeName##List>(object, propertyIndex)); \
+ QV4::ScopedObject obj(scope, engine->memoryManager->allocate<QQml##ElementTypeName##List>(object, propertyIndex)); \
return obj.asReturnedValue(); \
} else
@@ -709,7 +709,7 @@ ReturnedValue SequencePrototype::newSequence(QV4::ExecutionEngine *engine, int s
#define NEW_COPY_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
if (sequenceType == qMetaTypeId<SequenceType>()) { \
- QV4::ScopedObject obj(scope, engine->memoryManager->allocObject<QQml##ElementTypeName##List>(v.value<SequenceType >())); \
+ QV4::ScopedObject obj(scope, engine->memoryManager->allocate<QQml##ElementTypeName##List>(v.value<SequenceType >())); \
return obj.asReturnedValue(); \
} else
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index e9bef2f604..eab1ffb5d7 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -59,6 +59,8 @@
#include "qv4context_p.h"
#include "qv4string_p.h"
+QT_REQUIRE_CONFIG(qml_sequence_object);
+
QT_BEGIN_NAMESPACE
namespace QV4 {
diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp
index 14def49d0a..31b51cbfe3 100644
--- a/src/qml/jsruntime/qv4serialize.cpp
+++ b/src/qml/jsruntime/qv4serialize.cpp
@@ -40,13 +40,17 @@
#include "qv4serialize_p.h"
#include <private/qv8engine_p.h>
+#if QT_CONFIG(qml_list_model)
#include <private/qqmllistmodel_p.h>
#include <private/qqmllistmodelworkeragent_p.h>
+#endif
#include <private/qv4value_p.h>
#include <private/qv4dateobject_p.h>
#include <private/qv4regexpobject_p.h>
+#if QT_CONFIG(qml_sequence_object)
#include <private/qv4sequenceobject_p.h>
+#endif
#include <private/qv4objectproto_p.h>
#include <private/qv4qobjectwrapper_p.h>
@@ -82,8 +86,12 @@ enum Type {
WorkerNumber,
WorkerDate,
WorkerRegexp,
+#if QT_CONFIG(qml_list_model)
WorkerListModel,
+#endif
+#if QT_CONFIG(qml_sequence_object)
WorkerSequence
+#endif
};
static inline quint32 valueheader(Type type, quint32 size = 0)
@@ -228,6 +236,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
} else if (const QObjectWrapper *qobjectWrapper = v.as<QV4::QObjectWrapper>()) {
// XXX TODO: Generalize passing objects between the main thread and worker scripts so
// that others can trivially plug in their elements.
+#if QT_CONFIG(qml_list_model)
QQmlListModel *lm = qobject_cast<QQmlListModel *>(qobjectWrapper->object());
if (lm && lm->agent()) {
QQmlListModelWorkerAgent *agent = lm->agent();
@@ -236,9 +245,13 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
push(data, (void *)agent);
return;
}
+#else
+ Q_UNUSED(qobjectWrapper);
+#endif
// No other QObject's are allowed to be sent
push(data, valueheader(WorkerUndefined));
} else if (const Object *o = v.as<Object>()) {
+#if QT_CONFIG(qml_sequence_object)
if (o->isListType()) {
// valid sequence. we generate a length (sequence length + 1 for the sequence type)
uint seqLength = ScopedValue(scope, o->get(engine->id_length()))->toUInt32();
@@ -256,6 +269,7 @@ void Serialize::serialize(QByteArray &data, const QV4::Value &v, ExecutionEngine
return;
}
+#endif
// regular object
QV4::ScopedValue val(scope, v);
@@ -353,6 +367,7 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine)
data += ALIGN(length * sizeof(quint16));
return Encode(engine->newRegExpObject(pattern, flags));
}
+#if QT_CONFIG(qml_list_model)
case WorkerListModel:
{
void *ptr = popPtr(data);
@@ -369,6 +384,8 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine)
agent->setEngine(engine);
return rv->asReturnedValue();
}
+#endif
+#if QT_CONFIG(qml_sequence_object)
case WorkerSequence:
{
ScopedValue value(scope);
@@ -387,6 +404,7 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine)
QVariant seqVariant = QV4::SequencePrototype::toVariant(array, sequenceType, &succeeded);
return QV4::SequencePrototype::fromVariant(engine, seqVariant, &succeeded);
}
+#endif
}
Q_ASSERT(!"Unreachable");
return QV4::Encode::undefined();
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 447992ebec..57832a0068 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -54,6 +54,7 @@ using namespace QV4;
void Heap::String::markObjects(Heap::Base *that, MarkStack *markStack)
{
+ Base::markObjects(that, markStack);
String *s = static_cast<String *>(that);
if (s->subtype < StringType_Complex)
return;
@@ -76,7 +77,7 @@ bool String::isEqualTo(Managed *t, Managed *o)
if (t == o)
return true;
- if (!o->d()->vtable()->isString)
+ if (!o->vtable()->isString)
return false;
return static_cast<String *>(t)->isEqualTo(static_cast<String *>(o));
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 5466cc274d..72c4057b20 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -76,6 +76,10 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
};
#ifndef V4_BOOTSTRAP
+ const VTable *vtable() const {
+ return internalClass->vtable;
+ }
+
void init(const QString &text);
void destroy();
void simplifyString() const;
@@ -282,7 +286,7 @@ struct ComplexString : String {
template<>
inline const String *Value::as() const {
- return isManaged() && m()->vtable()->isString ? static_cast<const String *>(this) : nullptr;
+ return isManaged() && m()->internalClass->vtable->isString ? static_cast<const String *>(this) : nullptr;
}
template<>
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index ea1532b8ce..ea931abd1c 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -351,9 +351,9 @@ void Heap::TypedArray::init(Type t)
Heap::TypedArray *TypedArray::create(ExecutionEngine *e, Heap::TypedArray::Type t)
{
- QV4::InternalClass *ic = e->internalClasses[EngineBase::Class_Empty]->changeVTable(staticVTable());
- ic = ic->changePrototype(e->typedArrayPrototype[t].d());
- return e->memoryManager->allocObject<TypedArray>(ic, e->typedArrayPrototype + t, t);
+ Scope scope(e);
+ Scoped<InternalClass> ic(scope, e->newInternalClass(staticVTable(), e->typedArrayPrototype + t));
+ return e->memoryManager->allocObject<TypedArray>(ic->d(), t);
}
ReturnedValue TypedArray::getIndexed(const Managed *m, uint index, bool *hasProperty)
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index 0d4711df3c..c558c27521 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -84,7 +84,7 @@ bool Value::toBooleanImpl(Value val)
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
#else
- if (b->vtable()->isString)
+ if (b->internalClass->vtable->isString)
return static_cast<Heap::String *>(b)->length() > 0;
#endif
return true;
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index a5ee6b5373..42c0370138 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -56,6 +56,7 @@
#include <QtCore/QString>
#include "qv4global_p.h"
#include <private/qv4heap_p.h>
+#include <private/qv4internalclass_p.h>
#include <private/qnumeric_p.h>
@@ -428,11 +429,11 @@ public:
if (!isManaged())
return nullptr;
- Q_ASSERT(m()->vtable());
+ Q_ASSERT(m()->internalClass->vtable);
#if !defined(QT_NO_QOBJECT_CHECK)
static_cast<const T *>(this)->qt_check_for_QMANAGED_macro(static_cast<const T *>(this));
#endif
- const VTable *vt = m()->vtable();
+ const VTable *vt = m()->internalClass->vtable;
while (vt) {
if (vt == T::staticVTable())
return static_cast<const T *>(this);
@@ -500,18 +501,18 @@ inline void Value::mark(MarkStack *markStack)
inline bool Value::isString() const
{
Heap::Base *b = heapObject();
- return b && b->vtable()->isString;
+ return b && b->internalClass->vtable->isString;
}
inline bool Value::isObject() const
{
Heap::Base *b = heapObject();
- return b && b->vtable()->isObject;
+ return b && b->internalClass->vtable->isObject;
}
inline bool Value::isFunctionObject() const
{
Heap::Base *b = heapObject();
- return b && b->vtable()->isFunctionObject;
+ return b && b->internalClass->vtable->isFunctionObject;
}
inline bool Value::isPrimitive() const
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index e73365e9b1..fae917dbb5 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -397,13 +397,13 @@ static bool compareEqual(Value lhs, Value rhs)
Heap::Base *r = rhs.m();
Q_ASSERT(l);
Q_ASSERT(r);
- if (l->vtable()->isString == r->vtable()->isString)
+ if (l->internalClass->vtable->isString == r->internalClass->vtable->isString)
return static_cast<QV4::Managed &>(lhs).isEqualTo(&static_cast<QV4::Managed &>(rhs));
- if (l->vtable()->isString) {
+ if (l->internalClass->vtable->isString) {
rhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(rhs), PREFERREDTYPE_HINT));
break;
} else {
- Q_ASSERT(r->vtable()->isString);
+ Q_ASSERT(r->internalClass->vtable->isString);
lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(lhs), PREFERREDTYPE_HINT));
break;
}
@@ -418,7 +418,7 @@ static bool compareEqual(Value lhs, Value rhs)
rhs = Primitive::fromDouble(rhs.int_32());
// fall through
default: // double
- if (lhs.m()->vtable()->isString)
+ if (lhs.m()->internalClass->vtable->isString)
return RuntimeHelpers::toNumber(lhs) == rhs.doubleValue();
else
lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(lhs), PREFERREDTYPE_HINT));
@@ -462,7 +462,7 @@ static bool compareEqualInt(Value &accumulator, Value lhs, int rhs)
case Value::QT_ManagedOrUndefined2:
case Value::QT_ManagedOrUndefined3:
// LHS: Managed
- if (lhs.m()->vtable()->isString)
+ if (lhs.m()->internalClass->vtable->isString)
return RuntimeHelpers::stringToNumber(static_cast<String &>(lhs).toQString()) == rhs;
accumulator = lhs;
lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(accumulator), PREFERREDTYPE_HINT));
@@ -981,6 +981,10 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
acc = Runtime::method_createUnmappedArgumentsObject(engine);
MOTH_END_INSTR(CreateUnmappedArgumentsObject)
+ MOTH_BEGIN_INSTR(CreateRestParameter)
+ acc = Runtime::method_createRestParameter(engine, argIndex);
+ MOTH_END_INSTR(CreateRestParameter)
+
MOTH_BEGIN_INSTR(ConvertThisToObject)
Value *t = &stack[CallData::This];
if (!t->isObject()) {
@@ -1023,6 +1027,11 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject,
}
MOTH_END_INSTR(JumpFalse)
+ MOTH_BEGIN_INSTR(JumpNotUndefined)
+ if (Q_LIKELY(acc != QV4::Encode::undefined()))
+ code += offset;
+ MOTH_END_INSTR(JumpNotUndefined)
+
MOTH_BEGIN_INSTR(CmpEqNull)
acc = Encode(ACC.isNullOrUndefined());
MOTH_END_INSTR(CmpEqNull)
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index 53933cd090..f327388355 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -54,7 +54,6 @@
#include <private/qv4global_p.h>
#include <private/qv4mmdefs_p.h>
#include <private/qv4writebarrier_p.h>
-#include <private/qv4internalclass_p.h>
#include <QSharedPointer>
// To check if Heap::Base::init is called (meaning, all subclasses did their init and called their
@@ -65,8 +64,6 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-struct InternalClass;
-
struct VTable
{
const VTable * const parent;
@@ -88,17 +85,41 @@ struct VTable
namespace Heap {
+template <typename T, size_t o>
+struct Pointer {
+ static Q_CONSTEXPR size_t offset = o;
+ T operator->() const { return get(); }
+ operator T () const { return get(); }
+
+ Base *base();
+
+ void set(EngineBase *e, T newVal) {
+ WriteBarrier::write(e, base(), &ptr, reinterpret_cast<Base *>(newVal));
+ }
+
+ T get() const { return reinterpret_cast<T>(ptr); }
+
+ template <typename Type>
+ Type *cast() { return static_cast<Type *>(ptr); }
+
+ Base *heapObject() const { return ptr; }
+
+private:
+ Base *ptr;
+};
+typedef Pointer<char *, 0> V4PointerCheck;
+Q_STATIC_ASSERT(std::is_trivial< V4PointerCheck >::value);
+
struct Q_QML_EXPORT Base {
void *operator new(size_t) = delete;
- static void markObjects(Heap::Base *, MarkStack *) {}
+ static void markObjects(Base *, MarkStack *);
- InternalClass *internalClass;
+ Pointer<InternalClass *, 0> internalClass;
inline ReturnedValue asReturnedValue() const;
inline void mark(QV4::MarkStack *markStack);
- const VTable *vtable() const { return internalClass->vtable; }
inline bool isMarked() const {
const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
Chunk *c = h->chunk();
@@ -125,13 +146,9 @@ struct Q_QML_EXPORT Base {
return Chunk::testBit(c->objectBitmap, h - c->realBase());
}
- inline void markChildren(MarkStack *markStack) {
- vtable()->markObjects(this, markStack);
- }
-
void *operator new(size_t, Managed *m) { return m; }
- void *operator new(size_t, Heap::Base *m) { return m; }
- void operator delete(void *, Heap::Base *) {}
+ void *operator new(size_t, Base *m) { return m; }
+ void operator delete(void *, Base *) {}
void init() { _setInitialized(); }
void destroy() { _setDestroyed(); }
@@ -178,10 +195,8 @@ Q_STATIC_ASSERT(std::is_standard_layout<Base>::value);
Q_STATIC_ASSERT(offsetof(Base, internalClass) == 0);
Q_STATIC_ASSERT(sizeof(Base) == QT_POINTER_SIZE);
-}
-
inline
-void Heap::Base::mark(QV4::MarkStack *markStack)
+void Base::mark(QV4::MarkStack *markStack)
{
Q_ASSERT(inUse());
const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
@@ -196,36 +211,12 @@ void Heap::Base::mark(QV4::MarkStack *markStack)
}
}
-namespace Heap {
-
-template <typename T, size_t o>
-struct Pointer {
- static Q_CONSTEXPR size_t offset = o;
- T operator->() const { return get(); }
- operator T () const { return get(); }
-
- Heap::Base *base() {
- Heap::Base *base = reinterpret_cast<Heap::Base *>(this) - (offset/sizeof(Heap::Base));
- Q_ASSERT(base->inUse());
- return base;
- }
-
- void set(EngineBase *e, T newVal) {
- WriteBarrier::write(e, base(), &ptr, reinterpret_cast<Heap::Base *>(newVal));
- }
-
- T get() const { return reinterpret_cast<T>(ptr); }
-
- template <typename Type>
- Type *cast() { return static_cast<Type *>(ptr); }
-
- Heap::Base *heapObject() const { return ptr; }
-
-private:
- Heap::Base *ptr;
-};
-typedef Pointer<char *, 0> V4PointerCheck;
-Q_STATIC_ASSERT(std::is_trivial< V4PointerCheck >::value);
+template<typename T, size_t o>
+Base *Pointer<T, o>::base() {
+ Base *base = reinterpret_cast<Base *>(this) - (offset/sizeof(Base *));
+ Q_ASSERT(base->inUse());
+ return base;
+}
}
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 4e83abebdf..06313c3d30 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -335,7 +335,7 @@ bool Chunk::sweep(ExecutionEngine *engine)
HeapItem *itemToFree = o + index;
Heap::Base *b = *itemToFree;
- const VTable *v = b->vtable();
+ const VTable *v = b->internalClass->vtable;
// if (Q_UNLIKELY(classCountPtr))
// classCountPtr(v->className);
if (v->destroy) {
@@ -389,8 +389,8 @@ void Chunk::freeAll(ExecutionEngine *engine)
HeapItem *itemToFree = o + index;
Heap::Base *b = *itemToFree;
- if (b->vtable()->destroy) {
- b->vtable()->destroy(b);
+ if (b->internalClass->vtable->destroy) {
+ b->internalClass->vtable->destroy(b);
b->_checkIsDestroyed();
}
#ifdef V4_USE_HEAPTRACK
@@ -643,8 +643,9 @@ void BlockAllocator::sweep()
void BlockAllocator::freeAll()
{
- for (auto c : chunks) {
+ for (auto c : chunks)
c->freeAll(engine);
+ for (auto c : chunks) {
Q_V4_PROFILE_DEALLOC(engine, Chunk::DataSize, Profiling::HeapPage);
chunkAllocator->free(c);
}
@@ -691,7 +692,7 @@ static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocato
{
HeapItem *itemToFree = c.chunk->first();
Heap::Base *b = *itemToFree;
- const VTable *v = b->vtable();
+ const VTable *v = b->internalClass->vtable;
if (Q_UNLIKELY(classCountPtr))
classCountPtr(v->className);
@@ -758,6 +759,7 @@ MemoryManager::MemoryManager(ExecutionEngine *engine)
: engine(engine)
, chunkAllocator(new ChunkAllocator)
, blockAllocator(chunkAllocator, engine)
+ , icAllocator(chunkAllocator, engine)
, hugeItemAllocator(chunkAllocator, engine)
, m_persistentValues(new PersistentValueStorage(engine))
, m_weakValues(new PersistentValueStorage(engine))
@@ -884,7 +886,7 @@ Heap::Object *MemoryManager::allocObjectWithMemberData(const QV4::VTable *vtable
Chunk::clearBit(c->extendsBitmap, index);
}
o->memberData.set(engine, m);
- m->internalClass = engine->internalClasses[EngineBase::Class_MemberData];
+ m->internalClass.set(engine, engine->internalClasses(EngineBase::Class_MemberData));
Q_ASSERT(o->memberData->internalClass);
m->values.alloc = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
m->values.size = o->memberData->values.alloc;
@@ -911,7 +913,7 @@ void MarkStack::drain()
Heap::Base *h = pop();
++markStackSize;
Q_ASSERT(h); // at this point we should only have Heap::Base objects in this area on the stack. If not, weird things might happen.
- h->markChildren(this);
+ h->internalClass->vtable->markObjects(h, this);
}
}
@@ -1017,8 +1019,11 @@ void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPt
}
}
- blockAllocator.sweep();
- hugeItemAllocator.sweep(classCountPtr);
+ if (!lastSweep) {
+ blockAllocator.sweep(/*classCountPtr*/);
+ hugeItemAllocator.sweep(classCountPtr);
+ icAllocator.sweep(/*classCountPtr*/);
+ }
}
bool MemoryManager::shouldRunGC() const
@@ -1167,6 +1172,7 @@ void MemoryManager::runGC()
// reset all black bits
blockAllocator.resetBlackBits();
hugeItemAllocator.resetBlackBits();
+ icAllocator.resetBlackBits();
}
size_t MemoryManager::getUsedMem() const
@@ -1193,6 +1199,7 @@ MemoryManager::~MemoryManager()
sweep(/*lastSweep*/true);
blockAllocator.freeAll();
hugeItemAllocator.freeAll();
+ icAllocator.freeAll();
delete m_weakValues;
#ifdef V4_USE_VALGRIND
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index 40670bcdc7..d61655c38a 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -160,224 +160,98 @@ public:
{ return (size + Chunk::SlotSize - 1) & ~(Chunk::SlotSize - 1); }
template<typename ManagedType>
- inline typename ManagedType::Data *allocManaged(std::size_t size)
+ inline typename ManagedType::Data *allocManaged(std::size_t size, Heap::InternalClass *ic)
{
Q_STATIC_ASSERT(std::is_trivial< typename ManagedType::Data >::value);
size = align(size);
- Heap::Base *o = allocData(size);
- InternalClass *ic = ManagedType::defaultInternalClass(engine);
- ic = ic->changeVTable(ManagedType::staticVTable());
- o->internalClass = ic;
- Q_ASSERT(o->internalClass && o->internalClass->vtable);
- return static_cast<typename ManagedType::Data *>(o);
+ typename ManagedType::Data *d = static_cast<typename ManagedType::Data *>(allocData(size));
+ d->internalClass.set(engine, ic);
+ Q_ASSERT(d->internalClass && d->internalClass->vtable);
+ Q_ASSERT(ic->vtable == ManagedType::staticVTable());
+ return d;
}
template<typename ManagedType>
inline typename ManagedType::Data *allocManaged(std::size_t size, InternalClass *ic)
{
- Q_STATIC_ASSERT(std::is_trivial< typename ManagedType::Data >::value);
- size = align(size);
- Heap::Base *o = allocData(size);
- o->internalClass = ic;
- Q_ASSERT(o->internalClass && o->internalClass->vtable);
- Q_ASSERT(ic->vtable == ManagedType::staticVTable());
- return static_cast<typename ManagedType::Data *>(o);
+ return allocManaged<ManagedType>(size, ic->d());
+ }
+
+ template<typename ManagedType>
+ inline typename ManagedType::Data *allocManaged(std::size_t size)
+ {
+ Scope scope(engine);
+ Scoped<InternalClass> ic(scope, ManagedType::defaultInternalClass(engine));
+ return allocManaged<ManagedType>(size, ic);
}
template <typename ObjectType>
- typename ObjectType::Data *allocateObject(InternalClass *ic)
+ typename ObjectType::Data *allocateObject(Heap::InternalClass *ic)
{
Heap::Object *o = allocObjectWithMemberData(ObjectType::staticVTable(), ic->size);
- o->internalClass = ic;
- Q_ASSERT(o->internalClass && o->internalClass->vtable);
- Q_ASSERT(ic->vtable == ObjectType::staticVTable());
+ o->internalClass.set(engine, ic);
+ Q_ASSERT(o->internalClass.get() && o->vtable());
+ Q_ASSERT(o->vtable() == ObjectType::staticVTable());
return static_cast<typename ObjectType::Data *>(o);
}
template <typename ObjectType>
+ typename ObjectType::Data *allocateObject(InternalClass *ic)
+ {
+ return allocateObject<ObjectType>(ic->d());
+ }
+
+ template <typename ObjectType>
typename ObjectType::Data *allocateObject()
{
- InternalClass *ic = ObjectType::defaultInternalClass(engine);
+ Scope scope(engine);
+ Scoped<InternalClass> ic(scope, ObjectType::defaultInternalClass(engine));
ic = ic->changeVTable(ObjectType::staticVTable());
ic = ic->changePrototype(ObjectType::defaultPrototype(engine)->d());
- Heap::Object *o = allocObjectWithMemberData(ObjectType::staticVTable(), ic->size);
- o->internalClass = ic;
- Q_ASSERT(o->internalClass && o->internalClass->vtable);
- Q_ASSERT(o->internalClass->prototype == ObjectType::defaultPrototype(engine)->d());
- return static_cast<typename ObjectType::Data *>(o);
+ return allocateObject<ObjectType>(ic);
}
template <typename ManagedType, typename Arg1>
typename ManagedType::Data *allocWithStringData(std::size_t unmanagedSize, Arg1 arg1)
{
typename ManagedType::Data *o = reinterpret_cast<typename ManagedType::Data *>(allocString(unmanagedSize));
- o->internalClass = ManagedType::defaultInternalClass(engine);
+ o->internalClass.set(engine, ManagedType::defaultInternalClass(engine));
Q_ASSERT(o->internalClass && o->internalClass->vtable);
o->init(arg1);
return o;
}
- template <typename ObjectType>
- typename ObjectType::Data *allocObject(InternalClass *ic)
- {
- Scope scope(engine);
- Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- t->d_unchecked()->init();
- return t->d();
- }
-
- template <typename ObjectType>
- typename ObjectType::Data *allocObject(InternalClass *ic, Object *prototype)
- {
- Scope scope(engine);
- Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : nullptr));
- Q_UNUSED(prototype);
- t->d_unchecked()->init();
- return t->d();
- }
-
- template <typename ObjectType, typename Arg1>
- typename ObjectType::Data *allocObject(InternalClass *ic, Object *prototype, Arg1 arg1)
- {
- Scope scope(engine);
- Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : nullptr));
- Q_UNUSED(prototype);
- t->d_unchecked()->init(arg1);
- return t->d();
- }
-
- template <typename ObjectType, typename Arg1, typename Arg2>
- typename ObjectType::Data *allocObject(InternalClass *ic, Object *prototype, Arg1 arg1, Arg2 arg2)
- {
- Scope scope(engine);
- Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : nullptr));
- Q_UNUSED(prototype);
- t->d_unchecked()->init(arg1, arg2);
- return t->d();
- }
-
- template <typename ObjectType, typename Arg1, typename Arg2, typename Arg3>
- typename ObjectType::Data *allocObject(InternalClass *ic, Object *prototype, Arg1 arg1, Arg2 arg2, Arg3 arg3)
+ template <typename ObjectType, typename... Args>
+ typename ObjectType::Data *allocObject(Heap::InternalClass *ic, Args... args)
{
- Scope scope(engine);
- Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : nullptr));
- Q_UNUSED(prototype);
- t->d_unchecked()->init(arg1, arg2, arg3);
- return t->d();
+ typename ObjectType::Data *d = allocateObject<ObjectType>(ic);
+ d->init(args...);
+ return d;
}
- template <typename ObjectType, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
- typename ObjectType::Data *allocObject(InternalClass *ic, Object *prototype, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
+ template <typename ObjectType, typename... Args>
+ typename ObjectType::Data *allocObject(InternalClass *ic, Args... args)
{
- Scope scope(engine);
- Scoped<ObjectType> t(scope, allocateObject<ObjectType>(ic));
- Q_ASSERT(t->internalClass()->prototype == (prototype ? prototype->d() : nullptr));
- Q_UNUSED(prototype);
- t->d_unchecked()->init(arg1, arg2, arg3, arg4);
- return t->d();
+ typename ObjectType::Data *d = allocateObject<ObjectType>(ic);
+ d->init(args...);
+ return d;
}
- template <typename ObjectType>
- typename ObjectType::Data *allocObject()
+ template <typename ObjectType, typename... Args>
+ typename ObjectType::Data *allocate(Args... args)
{
Scope scope(engine);
Scoped<ObjectType> t(scope, allocateObject<ObjectType>());
- t->d_unchecked()->init();
+ t->d_unchecked()->init(args...);
return t->d();
}
- template <typename ObjectType, typename Arg1>
- typename ObjectType::Data *allocObject(Arg1 arg1)
- {
- Scope scope(engine);
- Scoped<ObjectType> t(scope, allocateObject<ObjectType>());
- t->d_unchecked()->init(arg1);
- return t->d();
- }
-
- template <typename ObjectType, typename Arg1, typename Arg2>
- typename ObjectType::Data *allocObject(Arg1 arg1, Arg2 arg2)
- {
- Scope scope(engine);
- Scoped<ObjectType> t(scope, allocateObject<ObjectType>());
- t->d_unchecked()->init(arg1, arg2);
- return t->d();
- }
-
- template <typename ObjectType, typename Arg1, typename Arg2, typename Arg3>
- typename ObjectType::Data *allocObject(Arg1 arg1, Arg2 arg2, Arg3 arg3)
- {
- Scope scope(engine);
- Scoped<ObjectType> t(scope, allocateObject<ObjectType>());
- t->d_unchecked()->init(arg1, arg2, arg3);
- return t->d();
- }
-
- template <typename ObjectType, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
- typename ObjectType::Data *allocObject(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
- {
- Scope scope(engine);
- Scoped<ObjectType> t(scope, allocateObject<ObjectType>());
- t->d_unchecked()->init(arg1, arg2, arg3, arg4);
- return t->d();
- }
-
-
- template <typename ManagedType>
- typename ManagedType::Data *alloc()
- {
- Scope scope(engine);
- Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
- t->d_unchecked()->init();
- return t->d();
- }
-
- template <typename ManagedType, typename Arg1>
- typename ManagedType::Data *alloc(Arg1 arg1)
+ template <typename ManagedType, typename... Args>
+ typename ManagedType::Data *alloc(Args... args)
{
Scope scope(engine);
Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
- t->d_unchecked()->init(arg1);
- return t->d();
- }
-
- template <typename ManagedType, typename Arg1, typename Arg2>
- typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2)
- {
- Scope scope(engine);
- Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
- t->d_unchecked()->init(arg1, arg2);
- return t->d();
- }
-
- template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3>
- typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3)
- {
- Scope scope(engine);
- Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
- t->d_unchecked()->init(arg1, arg2, arg3);
- return t->d();
- }
-
- template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
- typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
- {
- Scope scope(engine);
- Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
- t->d_unchecked()->init(arg1, arg2, arg3, arg4);
- return t->d();
- }
-
- template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
- typename ManagedType::Data *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
- {
- Scope scope(engine);
- Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data)));
- t->d_unchecked()->init(arg1, arg2, arg3, arg4, arg5);
+ t->d_unchecked()->init(args...);
return t->d();
}
@@ -392,6 +266,14 @@ public:
// called when a JS object grows itself. Specifically: Heap::String::append
void changeUnmanagedHeapSizeUsage(qptrdiff delta) { unmanagedHeapSize += delta; }
+ template<typename ManagedType>
+ typename ManagedType::Data *allocIC()
+ {
+ size_t size = align(sizeof(typename ManagedType::Data));
+ Heap::Base *b = *icAllocator.allocate(size, true);
+ return static_cast<typename ManagedType::Data *>(b);
+ }
+
protected:
/// expects size to be aligned
Heap::Base *allocString(std::size_t unmanagedSize);
@@ -409,6 +291,7 @@ public:
QV4::ExecutionEngine *engine;
ChunkAllocator *chunkAllocator;
BlockAllocator blockAllocator;
+ BlockAllocator icAllocator;
HugeItemAllocator hugeItemAllocator;
PersistentValueStorage *m_persistentValues;
PersistentValueStorage *m_weakValues;
diff --git a/src/qml/parser/parser.pri b/src/qml/parser/parser.pri
index e5b8ae2749..dcdde4f81c 100644
--- a/src/qml/parser/parser.pri
+++ b/src/qml/parser/parser.pri
@@ -3,20 +3,22 @@ HEADERS += \
$$PWD/qqmljsastfwd_p.h \
$$PWD/qqmljsastvisitor_p.h \
$$PWD/qqmljsengine_p.h \
- $$PWD/qqmljsgrammar_p.h \
$$PWD/qqmljslexer_p.h \
$$PWD/qqmljsmemorypool_p.h \
- $$PWD/qqmljsparser_p.h \
$$PWD/qqmljsglobal_p.h \
$$PWD/qqmljskeywords_p.h \
+ $$PWD/qqmljsengine_p.h \
+ $$PWD/qqmljsglobal_p.h
SOURCES += \
$$PWD/qqmljsast.cpp \
$$PWD/qqmljsastvisitor.cpp \
$$PWD/qqmljsengine_p.cpp \
- $$PWD/qqmljsgrammar.cpp \
$$PWD/qqmljslexer.cpp \
- $$PWD/qqmljsparser.cpp \
-OTHER_FILES += \
- $$PWD/qqmljs.g
+CONFIG += qlalr
+QLALRSOURCES = $$PWD/qqmljs.g
+QMAKE_QLALRFLAGS = --no-debug --qt
+
+# make sure we install the headers generated by qlalr
+private_headers.CONFIG += no_check_exist
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index d2d947e55c..fe8e744264 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -40,8 +40,7 @@
%parser QQmlJSGrammar
%decl qqmljsparser_p.h
%impl qqmljsparser.cpp
-%expect 5
-%expect-rr 2
+%expect 1
%token T_AND "&" T_AND_AND "&&" T_AND_EQ "&="
%token T_BREAK "break" T_CASE "case" T_CATCH "catch"
@@ -64,7 +63,7 @@
%token T_RBRACE "}" T_RBRACKET "]" T_REMAINDER "%"
%token T_REMAINDER_EQ "%=" T_RETURN "return" T_RPAREN ")"
%token T_SEMICOLON ";" T_AUTOMATIC_SEMICOLON T_STAR "*"
-%token T_STAR_EQ "*=" T_STRING_LITERAL "string literal"
+%token T_STAR_STAR "**" T_STAR_EQ "*=" T_STRING_LITERAL "string literal"
%token T_PROPERTY "property" T_SIGNAL "signal" T_READONLY "readonly"
%token T_SWITCH "switch" T_THIS "this" T_THROW "throw"
%token T_TILDE "~" T_TRY "try" T_TYPEOF "typeof"
@@ -77,14 +76,29 @@
%token T_MULTILINE_STRING_LITERAL "multiline string literal"
%token T_COMMENT "comment"
%token T_COMPATIBILITY_SEMICOLON
+%token T_ARROW "=>"
%token T_ENUM "enum"
+%token T_ELLIPSIS "..."
+%token T_YIELD "yield"
+%token T_SUPER "super"
+%token T_CLASS "class"
+%token T_EXTENDS "extends"
+%token T_STATIC "static"
+%token T_EXPORT "export"
+%token T_FROM "from"
+
+--- template strings
+%token T_NO_SUBSTITUTION_TEMPLATE"(no subst template)"
+%token T_TEMPLATE_HEAD "(template head)"
+%token T_TEMPLATE_MIDDLE "(template middle)"
+%token T_TEMPLATE_TAIL "(template tail)"
--- context keywords.
%token T_PUBLIC "public"
%token T_IMPORT "import"
%token T_PRAGMA "pragma"
%token T_AS "as"
-%token T_ON "on"
+%token T_OF "of"
%token T_GET "get"
%token T_SET "set"
@@ -95,11 +109,16 @@
%token T_FEED_UI_OBJECT_MEMBER
%token T_FEED_JS_STATEMENT
%token T_FEED_JS_EXPRESSION
-%token T_FEED_JS_SOURCE_ELEMENT
-%token T_FEED_JS_PROGRAM
+%token T_FEED_JS_SCRIPT
+%token T_FEED_JS_MODULE
-%nonassoc SHIFT_THERE
-%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET
+--- Lookahead handling
+%token T_FORCE_DECLARATION "(force decl)"
+%token T_FORCE_BLOCK "(force block)"
+%token T_FOR_LOOKAHEAD_OK "(for lookahead ok)"
+
+--%left T_PLUS T_MINUS
+%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET T_YIELD T_OF T_STATIC T_FROM
%nonassoc REDUCE_HERE
%start TopLevel
@@ -143,10 +162,10 @@
**
****************************************************************************/
-#include "qqmljsengine_p.h"
-#include "qqmljslexer_p.h"
-#include "qqmljsast_p.h"
-#include "qqmljsmemorypool_p.h"
+#include <private/qqmljsengine_p.h>
+#include <private/qqmljslexer_p.h>
+#include <private/qqmljsast_p.h>
+#include <private/qqmljsmemorypool_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qcoreapplication.h>
@@ -221,10 +240,10 @@
#ifndef QQMLJSPARSER_P_H
#define QQMLJSPARSER_P_H
-#include "qqmljsglobal_p.h"
-#include "qqmljsgrammar_p.h"
-#include "qqmljsast_p.h"
-#include "qqmljsengine_p.h"
+#include <private/qqmljsglobal_p.h>
+#include <private/qqmljsgrammar_p.h>
+#include <private/qqmljsast_p.h>
+#include <private/qqmljsengine_p.h>
#include <QtCore/qlist.h>
#include <QtCore/qstring.h>
@@ -250,21 +269,23 @@ public:
AST::ElementList *ElementList;
AST::Elision *Elision;
AST::ExpressionNode *Expression;
+ AST::TemplateLiteral *Template;
AST::Finally *Finally;
AST::FormalParameterList *FormalParameterList;
- AST::FunctionBody *FunctionBody;
AST::FunctionDeclaration *FunctionDeclaration;
AST::Node *Node;
AST::PropertyName *PropertyName;
- AST::PropertyAssignment *PropertyAssignment;
- AST::PropertyAssignmentList *PropertyAssignmentList;
- AST::SourceElement *SourceElement;
- AST::SourceElements *SourceElements;
+ AST::PropertyDefinition *PropertyDefinition;
+ AST::PropertyDefinitionList *PropertyDefinitionList;
AST::Statement *Statement;
AST::StatementList *StatementList;
AST::Block *Block;
AST::VariableDeclaration *VariableDeclaration;
AST::VariableDeclarationList *VariableDeclarationList;
+ AST::BindingPattern *BindingPattern;
+ AST::BindingElement *BindingElement;
+ AST::BindingPropertyList *BindingPropertyList;
+ AST::BindingElementList *BindingElementList;
AST::UiProgram *UiProgram;
AST::UiHeaderItemList *UiHeaderItemList;
@@ -290,12 +311,13 @@ public:
~Parser();
// parse a UI program
- bool parse() { return parse(T_FEED_UI_PROGRAM); }
+ bool parse() { ++functionNestingLevel; bool r = parse(T_FEED_UI_PROGRAM); --functionNestingLevel; return r; }
bool parseStatement() { return parse(T_FEED_JS_STATEMENT); }
bool parseExpression() { return parse(T_FEED_JS_EXPRESSION); }
- bool parseSourceElement() { return parse(T_FEED_JS_SOURCE_ELEMENT); }
- bool parseUiObjectMember() { return parse(T_FEED_UI_OBJECT_MEMBER); }
- bool parseProgram() { return parse(T_FEED_JS_PROGRAM); }
+ bool parseUiObjectMember() { ++functionNestingLevel; bool r = parse(T_FEED_UI_OBJECT_MEMBER); --functionNestingLevel; return r; }
+ bool parseProgram() { return parse(T_FEED_JS_SCRIPT); }
+ bool parseScript() { return parse(T_FEED_JS_SCRIPT); }
+ bool parseModule() { return parse(T_FEED_JS_MODULE); }
AST::UiProgram *ast() const
{ return AST::cast<AST::UiProgram *>(program); }
@@ -366,20 +388,27 @@ protected:
AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr);
AST::UiQualifiedPragmaId *reparseAsQualifiedPragmaId(AST::ExpressionNode *expr);
+ void pushToken(int token);
+ int lookaheadToken(Lexer *lexer);
+
+ void syntaxError(const AST::SourceLocation &location, const char *message) {
+ diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location, QLatin1String(message)));
+ }
+
protected:
Engine *driver;
MemoryPool *pool;
- int tos;
- int stack_size;
- Value *sym_stack;
- int *state_stack;
- AST::SourceLocation *location_stack;
- QStringRef *string_stack;
+ int tos = 0;
+ int stack_size = 0;
+ Value *sym_stack = nullptr;
+ int *state_stack = nullptr;
+ AST::SourceLocation *location_stack = nullptr;
+ QStringRef *string_stack = nullptr;
- AST::Node *program;
+ AST::Node *program = nullptr;
- // error recovery
- enum { TOKEN_BUFFER_SIZE = 3 };
+ // error recovery and lookahead handling
+ enum { TOKEN_BUFFER_SIZE = 5 };
struct SavedToken {
int token;
@@ -388,14 +417,17 @@ protected:
QStringRef spell;
};
- double yylval;
+ int yytoken = -1;
+ double yylval = 0.;
QStringRef yytokenspell;
AST::SourceLocation yylloc;
AST::SourceLocation yyprevlloc;
SavedToken token_buffer[TOKEN_BUFFER_SIZE];
- SavedToken *first_token;
- SavedToken *last_token;
+ SavedToken *first_token = nullptr;
+ SavedToken *last_token = nullptr;
+
+ int functionNestingLevel = 0;
QList<DiagnosticMessage> diagnostic_messages;
};
@@ -424,6 +456,8 @@ protected:
// qlalr --no-debug --no-lines --qt qqmljs.g
//
+#define UNIMPLEMENTED syntaxError(loc(1), "Unimplemented"); return false
+
using namespace QQmlJS;
QT_QML_BEGIN_NAMESPACE
@@ -443,17 +477,7 @@ void Parser::reallocateStack()
Parser::Parser(Engine *engine):
driver(engine),
- pool(engine->pool()),
- tos(0),
- stack_size(0),
- sym_stack(0),
- state_stack(0),
- location_stack(0),
- string_stack(0),
- program(0),
- yylval(0),
- first_token(0),
- last_token(0)
+ pool(engine->pool())
{
}
@@ -517,17 +541,38 @@ AST::UiQualifiedPragmaId *Parser::reparseAsQualifiedPragmaId(AST::ExpressionNode
return 0;
}
+void Parser::pushToken(int token)
+{
+ last_token->token = yytoken;
+ last_token->dval = yylval;
+ last_token->spell = yytokenspell;
+ last_token->loc = yylloc;
+ ++last_token;
+ yytoken = token;
+}
+
+int Parser::lookaheadToken(Lexer *lexer)
+{
+ if (yytoken < 0) {
+ yytoken = lexer->lex();
+ yylval = lexer->tokenValue();
+ yytokenspell = lexer->tokenSpell();
+ yylloc = location(lexer);
+ }
+ return yytoken;
+}
+
bool Parser::parse(int startToken)
{
Lexer *lexer = driver->lexer();
bool hadErrors = false;
- int yytoken = -1;
+ yytoken = -1;
int action = 0;
token_buffer[0].token = startToken;
first_token = &token_buffer[0];
- if (startToken == T_FEED_JS_PROGRAM && !lexer->qmlMode()) {
+ if (startToken == T_FEED_JS_SCRIPT && !lexer->qmlMode()) {
Directives ignoreDirectives;
Directives *directives = driver->directives();
if (!directives)
@@ -570,9 +615,15 @@ bool Parser::parse(int startToken)
yytokenspell = first_token->spell;
yylloc = first_token->loc;
++first_token;
+ if (first_token == last_token)
+ first_token = last_token = &token_buffer[0];
}
}
+#ifdef PARSER_DEBUG
+ qDebug() << " current token" << yytoken << (yytoken >= 0 ? spell[yytoken] : "(null)");
+#endif
+
action = t_action(action, yytoken);
if (action > 0) {
if (action != ACCEPT_STATE) {
@@ -588,6 +639,10 @@ bool Parser::parse(int startToken)
const int r = -action - 1;
tos -= rhs[r];
+#ifdef PARSER_DEBUG
+ qDebug() << " reducing through rule " << r;
+#endif
+
switch (r) {
./
@@ -595,2571 +650,2976 @@ bool Parser::parse(int startToken)
-- Declarative UI
--------------------------------------------------------------------------------------------------------
-TopLevel: T_FEED_UI_PROGRAM UiProgram ;
+TopLevel: T_FEED_UI_PROGRAM UiProgram;
/.
-case $rule_number: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(2).Node;
+ program = sym(1).Node;
+ } break;
./
-TopLevel: T_FEED_JS_STATEMENT Statement ;
+TopLevel: T_FEED_JS_STATEMENT Statement;
/.
-case $rule_number: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(2).Node;
+ program = sym(1).Node;
+ } break;
./
-TopLevel: T_FEED_JS_EXPRESSION Expression ;
+TopLevel: T_FEED_JS_EXPRESSION Expression;
/.
-case $rule_number: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(2).Node;
+ program = sym(1).Node;
+ } break;
./
-TopLevel: T_FEED_JS_SOURCE_ELEMENT SourceElement ;
+TopLevel: T_FEED_UI_OBJECT_MEMBER UiObjectMember;
/.
-case $rule_number: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(2).Node;
+ program = sym(1).Node;
+ } break;
./
-TopLevel: T_FEED_UI_OBJECT_MEMBER UiObjectMember ;
+TopLevel: T_FEED_JS_SCRIPT Script;
/.
-case $rule_number: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(2).Node;
+ program = sym(1).Node;
+ } break;
./
-TopLevel: T_FEED_JS_PROGRAM Program ;
+TopLevel: T_FEED_JS_MODULE Module;
/.
-case $rule_number: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(2).Node;
+ program = sym(1).Node;
+ } break;
./
+
UiProgram: UiHeaderItemListOpt UiRootMember;
/.
-case $rule_number: {
- sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiHeaderItemList,
- sym(2).UiObjectMemberList->finish());
-} break;
+ case $rule_number: {
+ sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiHeaderItemList, sym(2).UiObjectMemberList->finish());
+ } break;
./
-UiHeaderItemListOpt: Empty ;
-UiHeaderItemListOpt: UiHeaderItemList ;
+UiHeaderItemListOpt: Empty;
+UiHeaderItemListOpt: UiHeaderItemList;
/.
-case $rule_number: {
- sym(1).Node = sym(1).UiHeaderItemList->finish();
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(1).UiHeaderItemList->finish();
+ } break;
./
-UiHeaderItemList: UiPragma ;
+UiHeaderItemList: UiPragma;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiPragma);
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiPragma);
+ } break;
./
-UiHeaderItemList: UiImport ;
+UiHeaderItemList: UiImport;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiImport);
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiImport);
+ } break;
./
-UiHeaderItemList: UiHeaderItemList UiPragma ;
+UiHeaderItemList: UiHeaderItemList UiPragma;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiPragma);
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiPragma);
+ } break;
./
-UiHeaderItemList: UiHeaderItemList UiImport ;
+UiHeaderItemList: UiHeaderItemList UiImport;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiImport);
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiImport);
+ } break;
./
-PragmaId: MemberExpression ;
+PragmaId: MemberExpression;
-ImportId: MemberExpression ;
+ImportId: MemberExpression;
-UiPragma: UiPragmaHead T_AUTOMATIC_SEMICOLON ;
-UiPragma: UiPragmaHead T_SEMICOLON ;
+UiPragma: UiPragmaHead T_AUTOMATIC_SEMICOLON;
+UiPragma: UiPragmaHead T_SEMICOLON;
/.
-case $rule_number: {
- sym(1).UiPragma->semicolonToken = loc(2);
-} break;
+ case $rule_number: {
+ sym(1).UiPragma->semicolonToken = loc(2);
+ } break;
./
-UiImport: UiImportHead T_AUTOMATIC_SEMICOLON ;
-UiImport: UiImportHead T_SEMICOLON ;
+UiImport: UiImportHead T_AUTOMATIC_SEMICOLON;
+UiImport: UiImportHead T_SEMICOLON;
/.
-case $rule_number: {
- sym(1).UiImport->semicolonToken = loc(2);
-} break;
+ case $rule_number: {
+ sym(1).UiImport->semicolonToken = loc(2);
+ } break;
./
-UiImport: UiImportHead T_NUMERIC_LITERAL T_AUTOMATIC_SEMICOLON ;
-UiImport: UiImportHead T_NUMERIC_LITERAL T_SEMICOLON ;
+UiImport: UiImportHead T_NUMERIC_LITERAL T_AUTOMATIC_SEMICOLON;
+UiImport: UiImportHead T_NUMERIC_LITERAL T_SEMICOLON;
/.
-case $rule_number: {
- sym(1).UiImport->versionToken = loc(2);
- sym(1).UiImport->semicolonToken = loc(3);
-} break;
+ case $rule_number: {
+ sym(1).UiImport->versionToken = loc(2);
+ sym(1).UiImport->semicolonToken = loc(3);
+ } break;
./
-UiImport: UiImportHead T_NUMERIC_LITERAL T_AS JsIdentifier T_AUTOMATIC_SEMICOLON ;
-UiImport: UiImportHead T_NUMERIC_LITERAL T_AS JsIdentifier T_SEMICOLON ;
+UiImport: UiImportHead T_NUMERIC_LITERAL T_AS QmlIdentifier T_AUTOMATIC_SEMICOLON;
+UiImport: UiImportHead T_NUMERIC_LITERAL T_AS QmlIdentifier T_SEMICOLON;
/.
-case $rule_number: {
- sym(1).UiImport->versionToken = loc(2);
- sym(1).UiImport->asToken = loc(3);
- sym(1).UiImport->importIdToken = loc(4);
- sym(1).UiImport->importId = stringRef(4);
- sym(1).UiImport->semicolonToken = loc(5);
-} break;
+ case $rule_number: {
+ sym(1).UiImport->versionToken = loc(2);
+ sym(1).UiImport->asToken = loc(3);
+ sym(1).UiImport->importIdToken = loc(4);
+ sym(1).UiImport->importId = stringRef(4);
+ sym(1).UiImport->semicolonToken = loc(5);
+ } break;
./
-UiImport: UiImportHead T_AS JsIdentifier T_AUTOMATIC_SEMICOLON ;
-UiImport: UiImportHead T_AS JsIdentifier T_SEMICOLON ;
+UiImport: UiImportHead T_AS QmlIdentifier T_AUTOMATIC_SEMICOLON;
+UiImport: UiImportHead T_AS QmlIdentifier T_SEMICOLON;
/.
-case $rule_number: {
- sym(1).UiImport->asToken = loc(2);
- sym(1).UiImport->importIdToken = loc(3);
- sym(1).UiImport->importId = stringRef(3);
- sym(1).UiImport->semicolonToken = loc(4);
-} break;
+ case $rule_number: {
+ sym(1).UiImport->asToken = loc(2);
+ sym(1).UiImport->importIdToken = loc(3);
+ sym(1).UiImport->importId = stringRef(3);
+ sym(1).UiImport->semicolonToken = loc(4);
+ } break;
./
-UiPragmaHead: T_PRAGMA PragmaId ;
+UiPragmaHead: T_PRAGMA PragmaId;
/.
-case $rule_number: {
- AST::UiPragma *node = 0;
+ case $rule_number: {
+ AST::UiPragma *node = 0;
- if (AST::UiQualifiedPragmaId *qualifiedId = reparseAsQualifiedPragmaId(sym(2).Expression)) {
- node = new (pool) AST::UiPragma(qualifiedId);
- }
+ if (AST::UiQualifiedPragmaId *qualifiedId = reparseAsQualifiedPragmaId(sym(2).Expression))
+ node = new (pool) AST::UiPragma(qualifiedId);
- sym(1).Node = node;
+ 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")));
+ 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;
+ return false; // ### remove me
+ }
+ } break;
./
-UiImportHead: T_IMPORT ImportId ;
+UiImportHead: T_IMPORT ImportId;
/.
-case $rule_number: {
- AST::UiImport *node = 0;
-
- if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) {
- node = new (pool) AST::UiImport(importIdLiteral->value);
- node->fileNameToken = loc(2);
- } else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) {
- node = new (pool) AST::UiImport(qualifiedId);
- node->fileNameToken = loc(2);
- }
+ case $rule_number: {
+ AST::UiImport *node = 0;
- sym(1).Node = node;
+ if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) {
+ node = new (pool) AST::UiImport(importIdLiteral->value);
+ node->fileNameToken = loc(2);
+ } else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) {
+ node = new (pool) AST::UiImport(qualifiedId);
+ node->fileNameToken = loc(2);
+ }
- if (node) {
- node->importToken = loc(1);
- } else {
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1),
- QLatin1String("Expected a qualified name id or a string literal")));
+ sym(1).Node = node;
- return false; // ### remove me
- }
-} break;
+ if (node) {
+ node->importToken = loc(1);
+ } else {
+ diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1),
+ QLatin1String("Expected a qualified name id or a string literal")));
+
+ return false; // ### remove me
+ }
+ } break;
./
Empty: ;
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-UiRootMember: UiObjectDefinition ;
+UiRootMember: UiObjectDefinition;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
+ } break;
./
-UiObjectMemberList: UiObjectMember ;
+UiObjectMemberList: UiObjectMember;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
+ } break;
./
-UiObjectMemberList: UiObjectMemberList UiObjectMember ;
+UiObjectMemberList: UiObjectMemberList UiObjectMember;
/.
-case $rule_number: {
- AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(
- sym(1).UiObjectMemberList, sym(2).UiObjectMember);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(sym(1).UiObjectMemberList, sym(2).UiObjectMember);
+ sym(1).Node = node;
+ } break;
./
-UiArrayMemberList: UiObjectDefinition ;
+UiArrayMemberList: UiObjectDefinition;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember);
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember);
+ } break;
./
-UiArrayMemberList: UiArrayMemberList T_COMMA UiObjectDefinition ;
+UiArrayMemberList: UiArrayMemberList T_COMMA UiObjectDefinition;
/.
-case $rule_number: {
- AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(
- sym(1).UiArrayMemberList, sym(3).UiObjectMember);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(sym(1).UiArrayMemberList, sym(3).UiObjectMember);
+ node->commaToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-UiObjectInitializer: T_LBRACE T_RBRACE ;
+UiObjectInitializer: T_LBRACE T_RBRACE;
/.
-case $rule_number: {
- AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0);
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)0);
+ node->lbraceToken = loc(1);
+ node->rbraceToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-UiObjectInitializer: T_LBRACE UiObjectMemberList T_RBRACE ;
+UiObjectInitializer: T_LBRACE UiObjectMemberList T_RBRACE;
/.
-case $rule_number: {
- AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish());
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish());
+ node->lbraceToken = loc(1);
+ node->rbraceToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-UiObjectDefinition: UiQualifiedId UiObjectInitializer ;
+UiObjectDefinition: UiQualifiedId UiObjectInitializer;
/.
-case $rule_number: {
- AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId,
- sym(2).UiObjectInitializer);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId, sym(2).UiObjectInitializer);
+ sym(1).Node = node;
+ } break;
./
-UiObjectMember: UiObjectDefinition ;
+UiObjectMember: UiObjectDefinition;
-UiObjectMember: UiQualifiedId T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ;
+UiObjectMember: UiQualifiedId T_COLON ExpressionStatementLookahead T_LBRACKET UiArrayMemberList T_RBRACKET;
/.
-case $rule_number: {
- AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding(
- sym(1).UiQualifiedId, sym(4).UiArrayMemberList->finish());
- node->colonToken = loc(2);
- node->lbracketToken = loc(3);
- node->rbracketToken = loc(5);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding(sym(1).UiQualifiedId, sym(5).UiArrayMemberList->finish());
+ node->colonToken = loc(2);
+ node->lbracketToken = loc(4);
+ node->rbracketToken = loc(6);
+ sym(1).Node = node;
+ } break;
./
-UiObjectMember: UiQualifiedId T_COLON UiQualifiedId UiObjectInitializer ;
+UiObjectMember: UiQualifiedId T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer;
/.
-case $rule_number: {
- AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
- sym(1).UiQualifiedId, sym(3).UiQualifiedId, sym(4).UiObjectInitializer);
- node->colonToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
+ sym(1).UiQualifiedId, sym(4).UiQualifiedId, sym(5).UiObjectInitializer);
+ node->colonToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-UiObjectMember: UiQualifiedId T_ON UiQualifiedId UiObjectInitializer ;
+UiObjectMember: UiQualifiedId T_ON UiQualifiedId UiObjectInitializer;
/.
-case $rule_number: {
- AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
- sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer);
- node->colonToken = loc(2);
- node->hasOnToken = true;
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
+ sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer);
+ node->colonToken = loc(2);
+ node->hasOnToken = true;
+ sym(1).Node = node;
+ } break;
./
-UiScriptStatement: Block ;
-UiScriptStatement: EmptyStatement ;
-UiScriptStatement: ExpressionStatement ;
-UiScriptStatement: IfStatement ;
-UiScriptStatement: WithStatement ;
-UiScriptStatement: SwitchStatement ;
-UiScriptStatement: TryStatement ;
-UiObjectMember: UiQualifiedId T_COLON UiScriptStatement ;
+UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_RBRACE;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_COMMA T_RBRACE;
/.
-case $rule_number:
-{
- AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding(
- sym(1).UiQualifiedId, sym(3).Statement);
- node->colonToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ObjectLiteral *l = new (pool) AST::ObjectLiteral(sym(3).PropertyDefinitionList->finish());
+ l->lbraceToken = loc(1);
+ l->rbraceToken = loc(4);
+ AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(l);
+ sym(1).Node = node;
+ } break;
./
-UiPropertyType: T_VAR ;
-/.
-case $rule_number: {
- AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1));
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
-./
-UiPropertyType: T_RESERVED_WORD ;
+UiScriptStatement: ExpressionStatementLookahead T_FORCE_DECLARATION ExpressionStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+UiScriptStatement: ExpressionStatementLookahead T_FORCE_BLOCK Block;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+UiScriptStatement: ExpressionStatementLookahead T_FORCE_BLOCK UiObjectLiteral;
/.
-case $rule_number: {
- AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1));
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(3).Node;
+ } break;
./
-UiPropertyType: T_IDENTIFIER ;
-/.
-case $rule_number: {
- AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1));
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
-./
-UiPropertyType: UiPropertyType T_DOT T_IDENTIFIER ;
+UiScriptStatement: ExpressionStatementLookahead EmptyStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+UiScriptStatement: ExpressionStatementLookahead ExpressionStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+UiScriptStatement: ExpressionStatementLookahead IfStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+UiScriptStatement: ExpressionStatementLookahead WithStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+UiScriptStatement: ExpressionStatementLookahead SwitchStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+UiScriptStatement: ExpressionStatementLookahead TryStatement;
/.
-case $rule_number: {
- AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(sym(1).UiQualifiedId, stringRef(3));
- node->identifierToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(2).Node;
+ } break;
./
-UiParameterListOpt: ;
+UiObjectMember: UiQualifiedId T_COLON UiScriptStatement;
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+case $rule_number:
+{
+ AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding(sym(1).UiQualifiedId, sym(3).Statement);
+ node->colonToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-UiParameterListOpt: UiParameterList ;
+UiPropertyType: T_VAR;
/.
-case $rule_number: {
- sym(1).Node = sym(1).UiParameterList->finish ();
-} break;
+ case $rule_number: {
+ AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1));
+ node->identifierToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UiParameterList: UiPropertyType JsIdentifier ;
+UiPropertyType: T_RESERVED_WORD;
/.
-case $rule_number: {
- AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiQualifiedId->finish(), stringRef(2));
- node->propertyTypeToken = loc(1);
- node->identifierToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1));
+ node->identifierToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UiParameterList: UiParameterList T_COMMA UiPropertyType JsIdentifier ;
+UiPropertyType: T_IDENTIFIER;
/.
-case $rule_number: {
- AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(3).UiQualifiedId->finish(), stringRef(4));
- node->propertyTypeToken = loc(3);
- node->commaToken = loc(2);
- node->identifierToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1));
+ node->identifierToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_AUTOMATIC_SEMICOLON ;
-UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_SEMICOLON ;
+UiPropertyType: UiPropertyType T_DOT T_IDENTIFIER;
/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2));
- node->type = AST::UiPublicMember::Signal;
- node->propertyToken = loc(1);
- node->typeToken = loc(2);
- node->identifierToken = loc(2);
- node->parameters = sym(4).UiParameterList;
- node->semicolonToken = loc(6);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(sym(1).UiQualifiedId, stringRef(3));
+ node->identifierToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-UiObjectMember: T_SIGNAL T_IDENTIFIER T_AUTOMATIC_SEMICOLON ;
-UiObjectMember: T_SIGNAL T_IDENTIFIER T_SEMICOLON ;
+UiParameterListOpt: ;
/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2));
- node->type = AST::UiPublicMember::Signal;
- node->propertyToken = loc(1);
- node->typeToken = loc(2);
- node->identifierToken = loc(2);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_AUTOMATIC_SEMICOLON ;
-UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_SEMICOLON ;
+UiParameterListOpt: UiParameterList;
/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
- node->typeModifier = stringRef(2);
- node->propertyToken = loc(1);
- node->typeModifierToken = loc(2);
- node->typeToken = loc(4);
- node->identifierToken = loc(6);
- node->semicolonToken = loc(7);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(1).UiParameterList->finish();
+ } break;
./
-UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_AUTOMATIC_SEMICOLON ;
-UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_SEMICOLON ;
+UiParameterList: UiPropertyType QmlIdentifier;
/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
- node->propertyToken = loc(1);
- node->typeToken = loc(2);
- node->identifierToken = loc(3);
- node->semicolonToken = loc(4);
- sym(1).Node = node;
-} break;
-./
+ case $rule_number: {
+ AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiQualifiedId->finish(), stringRef(2));
+ node->propertyTypeToken = loc(1);
+ node->identifierToken = loc(2);
+ sym(1).Node = node;
+ } break;
+./
-UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_AUTOMATIC_SEMICOLON ;
-UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_SEMICOLON ;
+UiParameterList: UiParameterList T_COMMA UiPropertyType QmlIdentifier;
/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4));
- node->isDefaultMember = true;
- node->defaultToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->semicolonToken = loc(5);
- sym(1).Node = node;
-} break;
-./
-
-UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_AUTOMATIC_SEMICOLON ;
-UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_SEMICOLON ;
+ case $rule_number: {
+ AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(3).UiQualifiedId->finish(), stringRef(4));
+ node->propertyTypeToken = loc(3);
+ node->commaToken = loc(2);
+ node->identifierToken = loc(4);
+ sym(1).Node = node;
+ } break;
+./
+
+UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_AUTOMATIC_SEMICOLON;
+UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN T_SEMICOLON;
/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7));
- node->isDefaultMember = true;
- node->defaultToken = loc(1);
- node->typeModifier = stringRef(3);
- node->propertyToken = loc(2);
- node->typeModifierToken = loc(2);
- node->typeToken = loc(4);
- node->identifierToken = loc(7);
- node->semicolonToken = loc(8);
- sym(1).Node = node;
-} break;
-./
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2));
+ node->type = AST::UiPublicMember::Signal;
+ node->propertyToken = loc(1);
+ node->typeToken = loc(2);
+ node->identifierToken = loc(2);
+ node->parameters = sym(4).UiParameterList;
+ node->semicolonToken = loc(6);
+ sym(1).Node = node;
+ } break;
+./
+
+UiObjectMember: T_SIGNAL T_IDENTIFIER T_AUTOMATIC_SEMICOLON;
+UiObjectMember: T_SIGNAL T_IDENTIFIER T_SEMICOLON;
+/.
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2));
+ node->type = AST::UiPublicMember::Signal;
+ node->propertyToken = loc(1);
+ node->typeToken = loc(2);
+ node->identifierToken = loc(2);
+ node->semicolonToken = loc(3);
+ sym(1).Node = node;
+ } break;
+./
+
+UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_AUTOMATIC_SEMICOLON;
+UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_SEMICOLON;
+/.
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
+ node->typeModifier = stringRef(2);
+ node->propertyToken = loc(1);
+ node->typeModifierToken = loc(2);
+ node->typeToken = loc(4);
+ node->identifierToken = loc(6);
+ node->semicolonToken = loc(7);
+ sym(1).Node = node;
+ } break;
+./
+
+UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_AUTOMATIC_SEMICOLON;
+UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_SEMICOLON;
+/.
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
+ node->propertyToken = loc(1);
+ node->typeToken = loc(2);
+ node->identifierToken = loc(3);
+ node->semicolonToken = loc(4);
+ sym(1).Node = node;
+ } break;
+./
-UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
-/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3),
- sym(5).Statement);
- node->propertyToken = loc(1);
- node->typeToken = loc(2);
- node->identifierToken = loc(3);
- node->colonToken = loc(4);
- sym(1).Node = node;
-} break;
+UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_AUTOMATIC_SEMICOLON;
+UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_SEMICOLON;
+/.
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4));
+ node->isDefaultMember = true;
+ node->defaultToken = loc(1);
+ node->propertyToken = loc(2);
+ node->typeToken = loc(3);
+ node->identifierToken = loc(4);
+ node->semicolonToken = loc(5);
+ sym(1).Node = node;
+ } break;
+./
+
+UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_AUTOMATIC_SEMICOLON;
+UiObjectMember: T_DEFAULT T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_SEMICOLON;
+/.
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7));
+ node->isDefaultMember = true;
+ node->defaultToken = loc(1);
+ node->typeModifier = stringRef(3);
+ node->propertyToken = loc(2);
+ node->typeModifierToken = loc(2);
+ node->typeToken = loc(4);
+ node->identifierToken = loc(7);
+ node->semicolonToken = loc(8);
+ sym(1).Node = node;
+ } break;
+./
+
+UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement;
+/.
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3), sym(5).Statement);
+ node->propertyToken = loc(1);
+ node->typeToken = loc(2);
+ node->identifierToken = loc(3);
+ node->colonToken = loc(4);
+ sym(1).Node = node;
+ } break;
+./
+
+UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement;
+/.
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), sym(6).Statement);
+ node->isReadonlyMember = true;
+ node->readonlyToken = loc(1);
+ node->propertyToken = loc(2);
+ node->typeToken = loc(3);
+ node->identifierToken = loc(4);
+ node->colonToken = loc(5);
+ sym(1).Node = node;
+ } break;
./
-UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
+UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement;
/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4),
- sym(6).Statement);
- node->isReadonlyMember = true;
- node->readonlyToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->colonToken = loc(5);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4), sym(6).Statement);
+ node->isDefaultMember = true;
+ node->defaultToken = loc(1);
+ node->propertyToken = loc(2);
+ node->typeToken = loc(3);
+ node->identifierToken = loc(4);
+ node->colonToken = loc(5);
+ sym(1).Node = node;
+ } break;
./
-UiObjectMember: T_DEFAULT T_PROPERTY UiPropertyType JsIdentifier T_COLON UiScriptStatement ;
+UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET;
/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4),
- sym(6).Statement);
- node->isDefaultMember = true;
- node->defaultToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->colonToken = loc(5);
- sym(1).Node = node;
-} break;
-./
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
+ node->typeModifier = stringRef(2);
+ node->propertyToken = loc(1);
+ node->typeModifierToken = loc(2);
+ node->typeToken = loc(4);
+ node->identifierToken = loc(6);
+ node->semicolonToken = loc(7); // insert a fake ';' before ':'
-UiObjectMember: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT JsIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET ;
-/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
- node->typeModifier = stringRef(2);
- node->propertyToken = loc(1);
- node->typeModifierToken = loc(2);
- node->typeToken = loc(4);
- node->identifierToken = loc(6);
- node->semicolonToken = loc(7); // insert a fake ';' before ':'
-
- AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6));
- propertyName->identifierToken = loc(6);
- propertyName->next = 0;
-
- AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(
- propertyName, sym(9).UiArrayMemberList->finish());
- binding->colonToken = loc(7);
- binding->lbracketToken = loc(8);
- binding->rbracketToken = loc(10);
-
- node->binding = binding;
+ AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6));
+ propertyName->identifierToken = loc(6);
+ propertyName->next = 0;
- sym(1).Node = node;
-} break;
+ AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(propertyName, sym(9).UiArrayMemberList->finish());
+ binding->colonToken = loc(7);
+ binding->lbracketToken = loc(8);
+ binding->rbracketToken = loc(10);
+
+ node->binding = binding;
+
+ sym(1).Node = node;
+ } break;
./
-UiObjectMember: T_PROPERTY UiPropertyType JsIdentifier T_COLON UiQualifiedId UiObjectInitializer ;
+UiObjectMember: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer;
/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
- node->propertyToken = loc(1);
- node->typeToken = loc(2);
- node->identifierToken = loc(3);
- node->semicolonToken = loc(4); // insert a fake ';' before ':'
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
+ node->propertyToken = loc(1);
+ node->typeToken = loc(2);
+ node->identifierToken = loc(3);
+ node->semicolonToken = loc(4); // insert a fake ';' before ':'
- AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3));
- propertyName->identifierToken = loc(3);
- propertyName->next = 0;
+ AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3));
+ propertyName->identifierToken = loc(3);
+ propertyName->next = 0;
- AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
- propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer);
- binding->colonToken = loc(4);
+ AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
+ propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer);
+ binding->colonToken = loc(4);
- node->binding = binding;
+ node->binding = binding;
- sym(1).Node = node;
-} break;
+ sym(1).Node = node;
+ } break;
./
-UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON UiQualifiedId UiObjectInitializer ;
+UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer;
/.
-case $rule_number: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4));
- node->isReadonlyMember = true;
- node->readonlyToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->semicolonToken = loc(5); // insert a fake ';' before ':'
+ case $rule_number: {
+ AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4));
+ node->isReadonlyMember = true;
+ node->readonlyToken = loc(1);
+ node->propertyToken = loc(2);
+ node->typeToken = loc(3);
+ node->identifierToken = loc(4);
+ node->semicolonToken = loc(5); // insert a fake ';' before ':'
- AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4));
- propertyName->identifierToken = loc(4);
- propertyName->next = 0;
+ AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4));
+ propertyName->identifierToken = loc(4);
+ propertyName->next = 0;
- AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
- propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer);
- binding->colonToken = loc(5);
+ AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
+ propertyName, sym(7).UiQualifiedId, sym(8).UiObjectInitializer);
+ binding->colonToken = loc(5);
- node->binding = binding;
+ node->binding = binding;
- sym(1).Node = node;
-} break;
+ sym(1).Node = node;
+ } break;
./
-UiObjectMember: FunctionDeclaration ;
+UiObjectMember: FunctionDeclaration;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
+ } break;
./
-UiObjectMember: VariableStatement ;
+UiObjectMember: VariableStatement;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
+ } break;
+./
+
+UiQualifiedId: MemberExpression;
+/.
+ case $rule_number: {
+ if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) {
+ diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken,
+ QLatin1String("Ignored annotation")));
+
+ sym(1).Expression = mem->base;
+ }
+
+ if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) {
+ sym(1).UiQualifiedId = qualifiedId;
+ } else {
+ sym(1).UiQualifiedId = 0;
+
+ diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1),
+ QLatin1String("Expected a qualified name id")));
+
+ return false; // ### recover
+ }
+ } break;
./
UiObjectMember: T_ENUM T_IDENTIFIER T_LBRACE EnumMemberList T_RBRACE;
/.
-case $rule_number: {
- AST::UiEnumDeclaration *enumDeclaration = new (pool) AST::UiEnumDeclaration(stringRef(2), sym(4).UiEnumMemberList->finish());
- enumDeclaration->enumToken = loc(1);
- enumDeclaration->rbraceToken = loc(5);
- sym(1).Node = enumDeclaration;
- break;
-}
+ case $rule_number: {
+ AST::UiEnumDeclaration *enumDeclaration = new (pool) AST::UiEnumDeclaration(stringRef(2), sym(4).UiEnumMemberList->finish());
+ enumDeclaration->enumToken = loc(1);
+ enumDeclaration->rbraceToken = loc(5);
+ sym(1).Node = enumDeclaration;
+ break;
+ }
./
EnumMemberList: T_IDENTIFIER;
/.
-case $rule_number: {
- AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1));
- node->memberToken = loc(1);
- sym(1).Node = node;
- break;
-}
+ case $rule_number: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1));
+ node->memberToken = loc(1);
+ sym(1).Node = node;
+ break;
+ }
./
EnumMemberList: T_IDENTIFIER T_EQ T_NUMERIC_LITERAL;
/.
-case $rule_number: {
- AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1), sym(3).dval);
- node->memberToken = loc(1);
- node->valueToken = loc(3);
- sym(1).Node = node;
- break;
-}
+ case $rule_number: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1), sym(3).dval);
+ node->memberToken = loc(1);
+ node->valueToken = loc(3);
+ sym(1).Node = node;
+ break;
+ }
./
EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER;
/.
-case $rule_number: {
- AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3));
- node->memberToken = loc(3);
- sym(1).Node = node;
- break;
-}
+ case $rule_number: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3));
+ node->memberToken = loc(3);
+ sym(1).Node = node;
+ break;
+ }
./
EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER T_EQ T_NUMERIC_LITERAL;
/.
-case $rule_number: {
- AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3), sym(5).dval);
- node->memberToken = loc(3);
- node->valueToken = loc(5);
- sym(1).Node = node;
- break;
-}
+ case $rule_number: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3), sym(5).dval);
+ node->memberToken = loc(3);
+ node->valueToken = loc(5);
+ sym(1).Node = node;
+ break;
+ }
./
-JsIdentifier: T_IDENTIFIER;
+QmlIdentifier: T_IDENTIFIER;
+QmlIdentifier: T_PROPERTY;
+QmlIdentifier: T_SIGNAL;
+QmlIdentifier: T_READONLY;
+QmlIdentifier: T_ON;
+QmlIdentifier: T_GET;
+QmlIdentifier: T_SET;
+QmlIdentifier: T_FROM;
+QmlIdentifier: T_OF;
-JsIdentifier: T_PROPERTY ;
-JsIdentifier: T_SIGNAL ;
-JsIdentifier: T_READONLY ;
-JsIdentifier: T_ON ;
-JsIdentifier: T_GET ;
-JsIdentifier: T_SET ;
+JsIdentifier: T_IDENTIFIER;
+JsIdentifier: T_PROPERTY;
+JsIdentifier: T_SIGNAL;
+JsIdentifier: T_READONLY;
+JsIdentifier: T_ON;
+JsIdentifier: T_GET;
+JsIdentifier: T_SET;
+JsIdentifier: T_FROM;
+JsIdentifier: T_STATIC;
+JsIdentifier: T_OF;
+
+IdentifierReference: JsIdentifier;
+BindingIdentifier: IdentifierReference;
--------------------------------------------------------------------------------------------------------
-- Expressions
--------------------------------------------------------------------------------------------------------
-PrimaryExpression: T_THIS ;
+PrimaryExpression: T_THIS;
/.
-case $rule_number: {
- AST::ThisExpression *node = new (pool) AST::ThisExpression();
- node->thisToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ThisExpression *node = new (pool) AST::ThisExpression();
+ node->thisToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: JsIdentifier ;
+PrimaryExpression: IdentifierReference;
/.
-case $rule_number: {
- AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
+ node->identifierToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: T_NULL ;
+PrimaryExpression: Literal;
+PrimaryExpression: ArrayLiteral;
+PrimaryExpression: ObjectLiteral;
+PrimaryExpression: FunctionExpression;
+PrimaryExpression: ClassExpression;
+PrimaryExpression: GeneratorExpression;
+PrimaryExpression: RegularExpressionLiteral;
+PrimaryExpression: TemplateLiteral;
+
+PrimaryExpression: CoverParenthesizedExpressionAndArrowParameterList;
+
+-- ### Further restricted parsing of the CoverParenthesizedExpressionAndArrowParameterList to the one rule below when this is parsed as a primary expression!
+CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN Expression_In T_RPAREN;
/.
-case $rule_number: {
- AST::NullExpression *node = new (pool) AST::NullExpression();
- node->nullToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression);
+ node->lparenToken = loc(1);
+ node->rparenToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: T_TRUE ;
+CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN T_RPAREN;
+CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN T_ELLIPSIS BindingIdentifier T_RPAREN;
+CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN T_ELLIPSIS BindingPattern T_RPAREN;
+CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN Expression_In T_COMMA T_ELLIPSIS BindingIdentifier T_RPAREN;
+CoverParenthesizedExpressionAndArrowParameterList: T_LPAREN Expression_In T_COMMA T_ELLIPSIS BindingPattern T_RPAREN;
+
+Literal: T_NULL;
/.
-case $rule_number: {
- AST::TrueLiteral *node = new (pool) AST::TrueLiteral();
- node->trueToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::NullExpression *node = new (pool) AST::NullExpression();
+ node->nullToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: T_FALSE ;
+Literal: T_TRUE;
/.
-case $rule_number: {
- AST::FalseLiteral *node = new (pool) AST::FalseLiteral();
- node->falseToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::TrueLiteral *node = new (pool) AST::TrueLiteral();
+ node->trueToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: T_NUMERIC_LITERAL ;
+Literal: T_FALSE;
/.
-case $rule_number: {
- AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval);
- node->literalToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::FalseLiteral *node = new (pool) AST::FalseLiteral();
+ node->falseToken = loc(1);
+ sym(1).Node = node;
+ } break;
+./
+
+Literal: T_NUMERIC_LITERAL;
+/.
+ case $rule_number: {
+ AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval);
+ node->literalToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: T_MULTILINE_STRING_LITERAL ;
-/.case $rule_number:./
+Literal: T_MULTILINE_STRING_LITERAL;
+/. case $rule_number: Q_FALLTHROUGH(); ./
-PrimaryExpression: T_STRING_LITERAL ;
+Literal: T_STRING_LITERAL;
/.
-case $rule_number: {
- AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1));
- node->literalToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1));
+ node->literalToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: T_DIVIDE_ ;
+RegularExpressionLiteral: T_DIVIDE_;
/:
#define J_SCRIPT_REGEXPLITERAL_RULE1 $rule_number
:/
/.
-case $rule_number: {
- bool rx = lexer->scanRegExp(Lexer::NoPrefix);
- if (!rx) {
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
- return false; // ### remove me
- }
-
- loc(1).length = lexer->tokenLength();
- yylloc = loc(1); // adjust the location of the current token
-
- AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
- driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
- node->literalToken = loc(1);
- sym(1).Node = node;
-} break;
+{
+ Lexer::RegExpBodyPrefix prefix;
+ case $rule_number:
+ prefix = Lexer::NoPrefix;
+ goto scan_regexp;
./
-PrimaryExpression: T_DIVIDE_EQ ;
+RegularExpressionLiteral: T_DIVIDE_EQ;
/:
#define J_SCRIPT_REGEXPLITERAL_RULE2 $rule_number
:/
/.
-case $rule_number: {
- bool rx = lexer->scanRegExp(Lexer::EqualPrefix);
- if (!rx) {
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
- return false;
- }
+ case $rule_number:
+ prefix = Lexer::EqualPrefix;
+ goto scan_regexp;
- loc(1).length = lexer->tokenLength();
- yylloc = loc(1); // adjust the location of the current token
+ scan_regexp: {
+ bool rx = lexer->scanRegExp(prefix);
+ if (!rx) {
+ diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
+ return false;
+ }
- AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
- driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
- node->literalToken = loc(1);
- sym(1).Node = node;
-} break;
+ loc(1).length = lexer->tokenLength();
+ yylloc = loc(1); // adjust the location of the current token
+
+ AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
+ node->literalToken = loc(1);
+ sym(1).Node = node;
+ } break;
+}
./
-PrimaryExpression: T_LBRACKET T_RBRACKET ;
+
+ArrayLiteral: T_LBRACKET ElisionOpt T_RBRACKET;
/.
-case $rule_number: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0);
- node->lbracketToken = loc(1);
- node->rbracketToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision);
+ node->lbracketToken = loc(1);
+ node->rbracketToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: T_LBRACKET Elision T_RBRACKET ;
+ArrayLiteral: T_LBRACKET ElementList T_RBRACKET;
/.
-case $rule_number: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish());
- node->lbracketToken = loc(1);
- node->rbracketToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish());
+ node->lbracketToken = loc(1);
+ node->rbracketToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: T_LBRACKET ElementList T_RBRACKET ;
+ArrayLiteral: T_LBRACKET ElementList T_COMMA ElisionOpt T_RBRACKET;
/.
-case $rule_number: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ());
- node->lbracketToken = loc(1);
- node->rbracketToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish(), sym(4).Elision);
+ node->lbracketToken = loc(1);
+ node->commaToken = loc(3);
+ node->rbracketToken = loc(5);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: T_LBRACKET ElementList T_COMMA T_RBRACKET ;
+ElementList: AssignmentExpression_In;
/.
-case $rule_number: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
- (AST::Elision *) 0);
- node->lbracketToken = loc(1);
- node->commaToken = loc(3);
- node->rbracketToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::ElementList(nullptr, sym(1).Expression);
+ } break;
./
-PrimaryExpression: T_LBRACKET ElementList T_COMMA Elision T_RBRACKET ;
+ElementList: Elision AssignmentExpression_In;
/.
-case $rule_number: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
- sym(4).Elision->finish());
- node->lbracketToken = loc(1);
- node->commaToken = loc(3);
- node->rbracketToken = loc(5);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression);
+ } break;
./
--- PrimaryExpression: T_LBRACE T_RBRACE ;
--- /.
--- case $rule_number: {
--- sym(1).Node = new (pool) AST::ObjectLiteral();
--- } break;
--- ./
+ElementList: ElisionOpt SpreadElement;
-PrimaryExpression: T_LBRACE PropertyAssignmentListOpt T_RBRACE ;
+ElementList: ElementList T_COMMA ElisionOpt AssignmentExpression_In;
/.
-case $rule_number: {
- AST::ObjectLiteral *node = 0;
- if (sym(2).Node)
- node = new (pool) AST::ObjectLiteral(
- sym(2).PropertyAssignmentList->finish ());
- else
- node = new (pool) AST::ObjectLiteral();
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision, sym(4).Expression);
+ node->commaToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-PrimaryExpression: T_LBRACE PropertyAssignmentList T_COMMA T_RBRACE ;
-/.
-case $rule_number: {
- AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
- sym(2).PropertyAssignmentList->finish ());
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(4);
- sym(1).Node = node;
-} break;
-./
+ElementList: ElementList T_COMMA ElisionOpt SpreadElement;
-PrimaryExpression: T_LPAREN Expression T_RPAREN ;
+Elision: T_COMMA;
/.
-case $rule_number: {
- AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression);
- node->lparenToken = loc(1);
- node->rparenToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::Elision *node = new (pool) AST::Elision();
+ node->commaToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-
-UiQualifiedId: MemberExpression ;
+Elision: Elision T_COMMA;
/.
-case $rule_number: {
- if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) {
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken,
- QLatin1String("Ignored annotation")));
-
- sym(1).Expression = mem->base;
- }
-
- if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) {
- sym(1).UiQualifiedId = qualifiedId;
- } else {
- sym(1).UiQualifiedId = 0;
-
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1),
- QLatin1String("Expected a qualified name id")));
-
- return false; // ### recover
- }
-} break;
+ case $rule_number: {
+ AST::Elision *node = new (pool) AST::Elision(sym(1).Elision);
+ node->commaToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-ElementList: AssignmentExpression ;
+ElisionOpt: ;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression);
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-ElementList: Elision AssignmentExpression ;
+ElisionOpt: Elision;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression);
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(1).Elision->finish();
+ } break;
./
-ElementList: ElementList T_COMMA AssignmentExpression ;
+SpreadElement: T_ELLIPSIS AssignmentExpression;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+ObjectLiteral: T_LBRACE T_RBRACE;
/.
-case $rule_number: {
- AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList,
- (AST::Elision *) 0, sym(3).Expression);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral();
+ node->lbraceToken = loc(1);
+ node->rbraceToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-ElementList: ElementList T_COMMA Elision AssignmentExpression ;
+ObjectLiteral: T_LBRACE PropertyDefinitionList T_RBRACE;
/.
-case $rule_number: {
- AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(),
- sym(4).Expression);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(sym(2).PropertyDefinitionList->finish());
+ node->lbraceToken = loc(1);
+ node->rbraceToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-Elision: T_COMMA ;
+ObjectLiteral: T_LBRACE PropertyDefinitionList T_COMMA T_RBRACE;
/.
-case $rule_number: {
- AST::Elision *node = new (pool) AST::Elision();
- node->commaToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(sym(2).PropertyDefinitionList->finish());
+ node->lbraceToken = loc(1);
+ node->rbraceToken = loc(4);
+ sym(1).Node = node;
+ } break;
./
-Elision: Elision T_COMMA ;
+
+UiPropertyDefinitionList: UiPropertyDefinition;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+PropertyDefinitionList: PropertyDefinition;
/.
-case $rule_number: {
- AST::Elision *node = new (pool) AST::Elision(sym(1).Elision);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::PropertyDefinitionList(sym(1).PropertyDefinition);
+ } break;
./
-PropertyAssignment: PropertyName T_COLON AssignmentExpression ;
+UiPropertyDefinitionList: UiPropertyDefinitionList T_COMMA UiPropertyDefinition;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+PropertyDefinitionList: PropertyDefinitionList T_COMMA PropertyDefinition;
/.
-case $rule_number: {
- AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue(
- sym(1).PropertyName, sym(3).Expression);
- node->colonToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::PropertyDefinitionList *node = new (pool) AST::PropertyDefinitionList(sym(1).PropertyDefinitionList, sym(3).PropertyDefinition);
+ node->commaToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-PropertyAssignment: T_GET PropertyName T_LPAREN T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
+PropertyDefinition: IdentifierReference;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+PropertyDefinition: CoverInitializedName;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+UiPropertyDefinition: UiPropertyName T_COLON AssignmentExpression_In;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+PropertyDefinition: PropertyName T_COLON AssignmentExpression_In;
/.
-case $rule_number: {
- 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;
+ case $rule_number: {
+ AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue(sym(1).PropertyName, sym(3).Expression);
+ node->colonToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-PropertyAssignment: T_SET PropertyName T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
+PropertyDefinition: MethodDefinition;
+
+PropertyName: LiteralPropertyName;
+PropertyName: ComputedPropertyName;
+
+LiteralPropertyName: IdentifierName;
/.
-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;
+ case $rule_number: {
+ AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
+ node->propertyNameToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-PropertyAssignmentList: PropertyAssignment ;
+UiPropertyName: T_STRING_LITERAL;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+LiteralPropertyName: T_STRING_LITERAL;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment);
-} break;
+ case $rule_number: {
+ AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1));
+ node->propertyNameToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-PropertyAssignmentList: PropertyAssignmentList T_COMMA PropertyAssignment ;
+UiPropertyName: T_NUMERIC_LITERAL;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+LiteralPropertyName: T_NUMERIC_LITERAL;
/.
-case $rule_number: {
- AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList(
- sym(1).PropertyAssignmentList, sym(3).PropertyAssignment);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval);
+ node->propertyNameToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-PropertyName: JsIdentifier %prec SHIFT_THERE ;
+IdentifierName: IdentifierReference;
+IdentifierName: ReservedIdentifier;
+
+ReservedIdentifier: T_BREAK;
+ReservedIdentifier: T_CASE;
+ReservedIdentifier: T_CATCH;
+ReservedIdentifier: T_CONTINUE;
+ReservedIdentifier: T_DEFAULT;
+ReservedIdentifier: T_DELETE;
+ReservedIdentifier: T_DO;
+ReservedIdentifier: T_ELSE;
+ReservedIdentifier: T_ENUM;
+ReservedIdentifier: T_FALSE;
+ReservedIdentifier: T_FINALLY;
+ReservedIdentifier: T_FOR;
+ReservedIdentifier: T_FUNCTION;
+ReservedIdentifier: T_IF;
+ReservedIdentifier: T_IN;
+ReservedIdentifier: T_INSTANCEOF;
+ReservedIdentifier: T_NEW;
+ReservedIdentifier: T_NULL;
+ReservedIdentifier: T_RETURN;
+ReservedIdentifier: T_SWITCH;
+ReservedIdentifier: T_THIS;
+ReservedIdentifier: T_THROW;
+ReservedIdentifier: T_TRUE;
+ReservedIdentifier: T_TRY;
+ReservedIdentifier: T_TYPEOF;
+ReservedIdentifier: T_VAR;
+ReservedIdentifier: T_VOID;
+ReservedIdentifier: T_WHILE;
+ReservedIdentifier: T_CONST;
+ReservedIdentifier: T_LET;
+ReservedIdentifier: T_DEBUGGER;
+ReservedIdentifier: T_RESERVED_WORD;
+ReservedIdentifier: T_SUPER;
+ReservedIdentifier: T_WITH;
+ReservedIdentifier: T_CLASS;
+ReservedIdentifier: T_EXTENDS;
+ReservedIdentifier: T_EXPORT;
+
+ComputedPropertyName: T_LBRACKET AssignmentExpression_In T_RBRACKET;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+
+CoverInitializedName: IdentifierReference Initializer_In;
+
+Initializer: T_EQ AssignmentExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Initializer_In: T_EQ AssignmentExpression_In;
/.
case $rule_number: {
- AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
- node->propertyNameToken = loc(1);
- sym(1).Node = node;
+ sym(1) = sym(2);
} break;
./
-PropertyName: T_STRING_LITERAL ;
+
+InitializerOpt: ;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+InitializerOpt_In: ;
/.
-case $rule_number: {
- AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1));
- node->propertyNameToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-PropertyName: T_NUMERIC_LITERAL ;
+InitializerOpt: Initializer;
+InitializerOpt_In: Initializer_In;
+
+TemplateLiteral: T_NO_SUBSTITUTION_TEMPLATE;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+
+TemplateSpans: T_TEMPLATE_TAIL;
/.
-case $rule_number: {
- AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval);
- node->propertyNameToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), nullptr);
+ node->literalToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-PropertyName: ReservedIdentifier ;
+TemplateSpans: T_TEMPLATE_MIDDLE Expression TemplateSpans;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+
+TemplateLiteral: T_TEMPLATE_HEAD Expression TemplateSpans;
/.
-case $rule_number: {
- AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
- node->propertyNameToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), sym(2).Expression);
+ node->next = sym(3).Template;
+ node->literalToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-ReservedIdentifier: T_BREAK ;
-ReservedIdentifier: T_CASE ;
-ReservedIdentifier: T_CATCH ;
-ReservedIdentifier: T_CONTINUE ;
-ReservedIdentifier: T_DEFAULT ;
-ReservedIdentifier: T_DELETE ;
-ReservedIdentifier: T_DO ;
-ReservedIdentifier: T_ELSE ;
-ReservedIdentifier: T_ENUM ;
-ReservedIdentifier: T_FALSE ;
-ReservedIdentifier: T_FINALLY ;
-ReservedIdentifier: T_FOR ;
-ReservedIdentifier: T_FUNCTION ;
-ReservedIdentifier: T_IF ;
-ReservedIdentifier: T_IN ;
-ReservedIdentifier: T_INSTANCEOF ;
-ReservedIdentifier: T_NEW ;
-ReservedIdentifier: T_NULL ;
-ReservedIdentifier: T_RETURN ;
-ReservedIdentifier: T_SWITCH ;
-ReservedIdentifier: T_THIS ;
-ReservedIdentifier: T_THROW ;
-ReservedIdentifier: T_TRUE ;
-ReservedIdentifier: T_TRY ;
-ReservedIdentifier: T_TYPEOF ;
-ReservedIdentifier: T_VAR ;
-ReservedIdentifier: T_VOID ;
-ReservedIdentifier: T_WHILE ;
-ReservedIdentifier: T_CONST ;
-ReservedIdentifier: T_LET ;
-ReservedIdentifier: T_DEBUGGER ;
-ReservedIdentifier: T_RESERVED_WORD ;
-ReservedIdentifier: T_WITH ;
-
-PropertyIdentifier: JsIdentifier ;
-PropertyIdentifier: ReservedIdentifier ;
-
-MemberExpression: PrimaryExpression ;
-MemberExpression: FunctionExpression ;
-
-MemberExpression: MemberExpression T_LBRACKET Expression T_RBRACKET ;
+
+MemberExpression: PrimaryExpression;
+
+MemberExpression: MemberExpression T_LBRACKET Expression_In T_RBRACKET;
/.
-case $rule_number: {
- AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
- node->lbracketToken = loc(2);
- node->rbracketToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
+ node->lbracketToken = loc(2);
+ node->rbracketToken = loc(4);
+ sym(1).Node = node;
+ } break;
./
-MemberExpression: MemberExpression T_DOT PropertyIdentifier ;
+MemberExpression: MemberExpression T_DOT IdentifierName;
/.
-case $rule_number: {
- AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
- node->dotToken = loc(2);
- node->identifierToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
+ node->dotToken = loc(2);
+ node->identifierToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-MemberExpression: T_NEW MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ;
+MemberExpression: SuperProperty;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+MemberExpression: MetaProperty;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+MemberExpression: T_NEW MemberExpression T_LPAREN Arguments T_RPAREN;
/.
-case $rule_number: {
- AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList);
- node->newToken = loc(1);
- node->lparenToken = loc(3);
- node->rparenToken = loc(5);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList);
+ node->newToken = loc(1);
+ node->lparenToken = loc(3);
+ node->rparenToken = loc(5);
+ sym(1).Node = node;
+ } break;
./
-NewExpression: MemberExpression ;
+SuperProperty: T_SUPER T_LBRACKET Expression_In T_RBRACKET;
-NewExpression: T_NEW NewExpression ;
+SuperProperty: T_SUPER T_DOT IdentifierName;
+
+MetaProperty: NewTarget;
+
+NewTarget: T_NEW T_DOT T_IDENTIFIER; -- ### the identifier has to be "target";
+
+NewExpression: MemberExpression;
+
+NewExpression: T_NEW NewExpression;
/.
-case $rule_number: {
+ case $rule_number: {
AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
node->newToken = loc(1);
sym(1).Node = node;
-} break;
+ } break;
./
-CallExpression: MemberExpression T_LPAREN ArgumentListOpt T_RPAREN ;
+
+CallExpression: CallExpression TemplateLiteral;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+MemberExpression: MemberExpression TemplateLiteral;
/.
-case $rule_number: {
- AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::TaggedTemplate *node = new (pool) AST::TaggedTemplate(sym(1).Expression, sym(2).Template);
+ sym(1).Node = node;
+ } break;
./
-CallExpression: CallExpression T_LPAREN ArgumentListOpt T_RPAREN ;
+CallExpression: MemberExpression T_LPAREN Arguments T_RPAREN;
/.
-case $rule_number: {
- AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ sym(1).Node = node;
+ } break;
./
-CallExpression: CallExpression T_LBRACKET Expression T_RBRACKET ;
+CallExpression: SuperCall;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+CallExpression: CallExpression T_LPAREN Arguments T_RPAREN;
/.
-case $rule_number: {
- AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
- node->lbracketToken = loc(2);
- node->rbracketToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ sym(1).Node = node;
+ } break;
./
-CallExpression: CallExpression T_DOT PropertyIdentifier ;
+CallExpression: CallExpression T_LBRACKET Expression_In T_RBRACKET;
/.
-case $rule_number: {
- AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
- node->dotToken = loc(2);
- node->identifierToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
+ node->lbracketToken = loc(2);
+ node->rbracketToken = loc(4);
+ sym(1).Node = node;
+ } break;
./
-ArgumentListOpt: ;
+CallExpression: CallExpression T_DOT IdentifierName;
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
+ node->dotToken = loc(2);
+ node->identifierToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-ArgumentListOpt: ArgumentList ;
+SuperCall: T_SUPER T_LPAREN Arguments T_RPAREN;
+
+Arguments: ;
/.
-case $rule_number: {
- sym(1).Node = sym(1).ArgumentList->finish();
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-ArgumentList: AssignmentExpression ;
+Arguments: ArgumentList;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Arguments: ArgumentList T_COMMA;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression);
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(1).ArgumentList->finish();
+ } break;
./
-ArgumentList: ArgumentList T_COMMA AssignmentExpression ;
+ArgumentList: AssignmentExpression_In;
/.
-case $rule_number: {
- AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression);
+ } break;
./
-LeftHandSideExpression: NewExpression ;
-LeftHandSideExpression: CallExpression ;
-PostfixExpression: LeftHandSideExpression ;
+ArgumentList: T_ELLIPSIS AssignmentExpression_In;
+/. case $rule_number: { UNIMPLEMENTED; } ./
-PostfixExpression: LeftHandSideExpression T_PLUS_PLUS ;
+ArgumentList: ArgumentList T_COMMA AssignmentExpression_In;
/.
-case $rule_number: {
- AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression);
- node->incrementToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression);
+ node->commaToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-PostfixExpression: LeftHandSideExpression T_MINUS_MINUS ;
+ArgumentList: ArgumentList T_COMMA T_ELLIPSIS AssignmentExpression_In;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+LeftHandSideExpression: NewExpression;
+LeftHandSideExpression: CallExpression;
+
+UpdateExpression: LeftHandSideExpression;
+
+UpdateExpression: LeftHandSideExpression T_PLUS_PLUS;
/.
-case $rule_number: {
- AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression);
- node->decrementToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression);
+ node->incrementToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-UnaryExpression: PostfixExpression ;
+UpdateExpression: LeftHandSideExpression T_MINUS_MINUS;
+/.
+ case $rule_number: {
+ AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression);
+ node->decrementToken = loc(2);
+ sym(1).Node = node;
+ } break;
+./
-UnaryExpression: T_DELETE UnaryExpression ;
+UpdateExpression: T_PLUS_PLUS UnaryExpression;
/.
-case $rule_number: {
- AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression);
- node->deleteToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression);
+ node->incrementToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UnaryExpression: T_VOID UnaryExpression ;
+UpdateExpression: T_MINUS_MINUS UnaryExpression;
/.
-case $rule_number: {
- AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression);
- node->voidToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression);
+ node->decrementToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UnaryExpression: T_TYPEOF UnaryExpression ;
+UnaryExpression: UpdateExpression;
+
+UnaryExpression: T_DELETE UnaryExpression;
/.
-case $rule_number: {
- AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression);
- node->typeofToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression);
+ node->deleteToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UnaryExpression: T_PLUS_PLUS UnaryExpression ;
+UnaryExpression: T_VOID UnaryExpression;
/.
-case $rule_number: {
- AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression);
- node->incrementToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression);
+ node->voidToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UnaryExpression: T_MINUS_MINUS UnaryExpression ;
+UnaryExpression: T_TYPEOF UnaryExpression;
/.
-case $rule_number: {
- AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression);
- node->decrementToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression);
+ node->typeofToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UnaryExpression: T_PLUS UnaryExpression ;
+UnaryExpression: T_PLUS UnaryExpression;
/.
-case $rule_number: {
- AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression);
- node->plusToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression);
+ node->plusToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UnaryExpression: T_MINUS UnaryExpression ;
+UnaryExpression: T_MINUS UnaryExpression;
/.
-case $rule_number: {
- AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression);
- node->minusToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression);
+ node->minusToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UnaryExpression: T_TILDE UnaryExpression ;
+UnaryExpression: T_TILDE UnaryExpression;
/.
-case $rule_number: {
- AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression);
- node->tildeToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression);
+ node->tildeToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-UnaryExpression: T_NOT UnaryExpression ;
+UnaryExpression: T_NOT UnaryExpression;
/.
-case $rule_number: {
- AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression);
- node->notToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression);
+ node->notToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-MultiplicativeExpression: UnaryExpression ;
+ExponentiationExpression: UnaryExpression;
-MultiplicativeExpression: MultiplicativeExpression T_STAR UnaryExpression ;
+ExponentiationExpression: UpdateExpression T_STAR_STAR ExponentiationExpression;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+MultiplicativeExpression: ExponentiationExpression;
+
+MultiplicativeExpression: MultiplicativeExpression MultiplicativeOperator ExponentiationExpression;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Mul, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-MultiplicativeExpression: MultiplicativeExpression T_DIVIDE_ UnaryExpression ;
+MultiplicativeOperator: T_STAR;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Div, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::Mul;
+ } break;
./
-MultiplicativeExpression: MultiplicativeExpression T_REMAINDER UnaryExpression ;
+MultiplicativeOperator: T_DIVIDE_;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Mod, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::Div;
+ } break;
+./
+
+MultiplicativeOperator: T_REMAINDER;
+/.
+ case $rule_number: {
+ sym(1).ival = QSOperator::Mod;
+ } break;
./
-AdditiveExpression: MultiplicativeExpression ;
+AdditiveExpression: MultiplicativeExpression;
-AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression ;
+AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Add, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Add, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression ;
+AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Sub, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Sub, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-ShiftExpression: AdditiveExpression ;
+ShiftExpression: AdditiveExpression;
-ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression ;
+ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::LShift, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::LShift, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression ;
+ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::RShift, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::RShift, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression ;
+ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::URShift, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::URShift, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-RelationalExpression: ShiftExpression ;
+RelationalExpression_In: ShiftExpression;
+RelationalExpression: ShiftExpression;
-RelationalExpression: RelationalExpression T_LT ShiftExpression ;
+RelationalExpression_In: RelationalExpression_In RelationalOperator ShiftExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+RelationalExpression: RelationalExpression RelationalOperator ShiftExpression;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Lt, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-RelationalExpression: RelationalExpression T_GT ShiftExpression ;
+RelationalOperator: T_LT;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Gt, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::Lt;
+ } break;
./
-
-RelationalExpression: RelationalExpression T_LE ShiftExpression ;
+RelationalOperator: T_GT;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Le, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::Gt;
+ } break;
./
-
-RelationalExpression: RelationalExpression T_GE ShiftExpression ;
+RelationalOperator: T_LE;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Ge, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::Le;
+ } break;
./
-
-RelationalExpression: RelationalExpression T_INSTANCEOF ShiftExpression ;
+RelationalOperator: T_GE;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::InstanceOf, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::Ge;
+ } break;
+./
+RelationalOperator: T_INSTANCEOF;
+/.
+ case $rule_number: {
+ sym(1).ival = QSOperator::InstanceOf;
+ } break;
./
-RelationalExpression: RelationalExpression T_IN ShiftExpression ;
+RelationalExpression_In: RelationalExpression_In T_IN ShiftExpression;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::In, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::In, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-RelationalExpressionNotIn: ShiftExpression ;
+EqualityExpression_In: RelationalExpression_In;
+EqualityExpression: RelationalExpression;
-RelationalExpressionNotIn: RelationalExpressionNotIn T_LT ShiftExpression ;
+EqualityExpression_In: EqualityExpression_In EqualityOperator RelationalExpression_In;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+EqualityExpression: EqualityExpression EqualityOperator RelationalExpression;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Lt, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-RelationalExpressionNotIn: RelationalExpressionNotIn T_GT ShiftExpression ;
+EqualityOperator: T_EQ_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Gt, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::Equal;
+ } break;
./
-
-RelationalExpressionNotIn: RelationalExpressionNotIn T_LE ShiftExpression ;
+EqualityOperator: T_NOT_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Le, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::NotEqual;
+ } break;
./
-
-RelationalExpressionNotIn: RelationalExpressionNotIn T_GE ShiftExpression ;
+EqualityOperator: T_EQ_EQ_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Ge, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::StrictEqual;
+ } break;
./
-
-RelationalExpressionNotIn: RelationalExpressionNotIn T_INSTANCEOF ShiftExpression ;
+EqualityOperator: T_NOT_EQ_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::InstanceOf, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::StrictNotEqual;
+ } break;
./
-EqualityExpression: RelationalExpression ;
-EqualityExpression: EqualityExpression T_EQ_EQ RelationalExpression ;
+BitwiseANDExpression: EqualityExpression;
+XitwiseANDExpression_In: EqualityExpression_In;
+
+BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+XitwiseANDExpression_In: XitwiseANDExpression_In T_AND EqualityExpression_In;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Equal, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitAnd, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-EqualityExpression: EqualityExpression T_NOT_EQ RelationalExpression ;
+
+BitwiseXORExpression: BitwiseANDExpression;
+BitwiseXORExpression_In: XitwiseANDExpression_In;
+
+BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+BitwiseXORExpression_In: BitwiseXORExpression_In T_XOR XitwiseANDExpression_In;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::NotEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitXor, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-EqualityExpression: EqualityExpression T_EQ_EQ_EQ RelationalExpression ;
+BitwiseORExpression: BitwiseXORExpression;
+BitwiseORExpression_In: BitwiseXORExpression_In;
+
+BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+BitwiseORExpression_In: BitwiseORExpression_In T_OR BitwiseXORExpression_In;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::StrictEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitOr, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-EqualityExpression: EqualityExpression T_NOT_EQ_EQ RelationalExpression ;
+LogicalANDExpression: BitwiseORExpression;
+LogicalANDExpression_In: BitwiseORExpression_In;
+
+LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+LogicalANDExpression_In: LogicalANDExpression_In T_AND_AND BitwiseORExpression_In;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::StrictNotEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::And, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-EqualityExpressionNotIn: RelationalExpressionNotIn ;
+LogicalORExpression: LogicalANDExpression;
+LogicalORExpression_In: LogicalANDExpression_In;
-EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ RelationalExpressionNotIn ;
+LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+LogicalORExpression_In: LogicalORExpression_In T_OR_OR LogicalANDExpression_In;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Equal, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Or, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ RelationalExpressionNotIn;
+
+ConditionalExpression: LogicalORExpression;
+ConditionalExpression_In: LogicalORExpression_In;
+
+ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression T_COLON AssignmentExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+ConditionalExpression_In: LogicalORExpression_In T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression_In;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::NotEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, sym(3).Expression, sym(5).Expression);
+ node->questionToken = loc(2);
+ node->colonToken = loc(4);
+ sym(1).Node = node;
+ } break;
./
-EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ_EQ RelationalExpressionNotIn ;
+AssignmentExpression: ConditionalExpression;
+AssignmentExpression_In: ConditionalExpression_In;
+
+AssignmentExpression: YieldExpression;
+AssignmentExpression_In: YieldExpression_In;
+
+AssignmentExpression: ArrowFunction;
+AssignmentExpression_In: ArrowFunction_In;
+
+-- ### Use AssignmentPattern in some cases for LHSexpression
+AssignmentExpression: LeftHandSideExpression T_EQ AssignmentExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+AssignmentExpression_In: LeftHandSideExpression T_EQ AssignmentExpression_In;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::StrictEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Assign, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ_EQ RelationalExpressionNotIn ;
+AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+AssignmentExpression_In: LeftHandSideExpression AssignmentOperator AssignmentExpression_In;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::StrictNotEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression);
+ node->operatorToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-BitwiseANDExpression: EqualityExpression ;
-
-BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression ;
+AssignmentOperator: T_STAR_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitAnd, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceMul;
+ } break;
./
-BitwiseANDExpressionNotIn: EqualityExpressionNotIn ;
-
-BitwiseANDExpressionNotIn: BitwiseANDExpressionNotIn T_AND EqualityExpressionNotIn ;
+AssignmentOperator: T_DIVIDE_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitAnd, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceDiv;
+ } break;
./
-BitwiseXORExpression: BitwiseANDExpression ;
-
-BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression ;
+AssignmentOperator: T_REMAINDER_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitXor, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceMod;
+ } break;
./
-BitwiseXORExpressionNotIn: BitwiseANDExpressionNotIn ;
-
-BitwiseXORExpressionNotIn: BitwiseXORExpressionNotIn T_XOR BitwiseANDExpressionNotIn ;
+AssignmentOperator: T_PLUS_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitXor, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceAdd;
+ } break;
./
-BitwiseORExpression: BitwiseXORExpression ;
-
-BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression ;
+AssignmentOperator: T_MINUS_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitOr, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceSub;
+ } break;
./
-BitwiseORExpressionNotIn: BitwiseXORExpressionNotIn ;
-
-BitwiseORExpressionNotIn: BitwiseORExpressionNotIn T_OR BitwiseXORExpressionNotIn ;
+AssignmentOperator: T_LT_LT_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitOr, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceLeftShift;
+ } break;
./
-LogicalANDExpression: BitwiseORExpression ;
-
-LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression ;
+AssignmentOperator: T_GT_GT_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::And, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceRightShift;
+ } break;
./
-LogicalANDExpressionNotIn: BitwiseORExpressionNotIn ;
+AssignmentOperator: T_GT_GT_GT_EQ;
+/.
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceURightShift;
+ } break;
+./
-LogicalANDExpressionNotIn: LogicalANDExpressionNotIn T_AND_AND BitwiseORExpressionNotIn ;
+AssignmentOperator: T_AND_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::And, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceAnd;
+ } break;
./
-LogicalORExpression: LogicalANDExpression ;
+AssignmentOperator: T_XOR_EQ;
+/.
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceXor;
+ } break;
+./
-LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression ;
+AssignmentOperator: T_OR_EQ;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Or, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).ival = QSOperator::InplaceOr;
+ } break;
./
-LogicalORExpressionNotIn: LogicalANDExpressionNotIn ;
+Expression: AssignmentExpression;
+Expression_In: AssignmentExpression_In;
-LogicalORExpressionNotIn: LogicalORExpressionNotIn T_OR_OR LogicalANDExpressionNotIn ;
+Expression: Expression T_COMMA AssignmentExpression;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Expression_In: Expression_In T_COMMA AssignmentExpression_In;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Or, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
+ node->commaToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-ConditionalExpression: LogicalORExpression ;
-
-ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression T_COLON AssignmentExpression ;
+ExpressionOpt: ;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+ExpressionOpt_In: ;
/.
-case $rule_number: {
- AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
- sym(3).Expression, sym(5).Expression);
- node->questionToken = loc(2);
- node->colonToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-ConditionalExpressionNotIn: LogicalORExpressionNotIn ;
+ExpressionOpt: Expression;
+ExpressionOpt_In: Expression_In;
+
+-- Statements
-ConditionalExpressionNotIn: LogicalORExpressionNotIn T_QUESTION AssignmentExpressionNotIn T_COLON AssignmentExpressionNotIn ;
+Statement: ExpressionStatementLookahead T_FORCE_BLOCK BlockStatement;
/.
-case $rule_number: {
- AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
- sym(3).Expression, sym(5).Expression);
- node->questionToken = loc(2);
- node->colonToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(3).Node;
+ } break;
./
-AssignmentExpression: ConditionalExpression ;
-
-AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression ;
+Statement: ExpressionStatementLookahead VariableStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead EmptyStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead ExpressionStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead IfStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead BreakableStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead ContinueStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead BreakStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead ReturnStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead WithStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead LabelledStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead ThrowStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead TryStatement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+Statement: ExpressionStatementLookahead DebuggerStatement;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- sym(2).ival, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(2).Node;
+ } break;
./
-AssignmentExpressionNotIn: ConditionalExpressionNotIn ;
+Declaration: HoistableDeclaration;
+Declaration: ClassDeclaration;
+Declaration: LexicalDeclaration_In;
+
+HoistableDeclaration: FunctionDeclaration;
+HoistableDeclaration: GeneratorDeclaration;
-AssignmentExpressionNotIn: LeftHandSideExpression AssignmentOperator AssignmentExpressionNotIn ;
+HoistableDeclaration_Default: FunctionDeclaration_Default;
+HoistableDeclaration_Default: GeneratorDeclaration_Default;
+
+BreakableStatement: IterationStatement;
+BreakableStatement: SwitchStatement;
+
+BlockStatement: Block;
+
+Block: T_LBRACE StatementListOpt T_RBRACE;
/.
-case $rule_number: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- sym(2).ival, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::Block *node = new (pool) AST::Block(sym(2).StatementList);
+ node->lbraceToken = loc(1);
+ node->rbraceToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-AssignmentOperator: T_EQ ;
+StatementList: StatementListItem;
+
+StatementList: StatementList StatementListItem;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::Assign;
-} break;
+ case $rule_number: {
+ sym(1).StatementList = sym(1).StatementList->append(sym(2).StatementList);
+ } break;
./
-AssignmentOperator: T_STAR_EQ ;
+StatementListItem: Statement;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceMul;
-} break;
+ case $rule_number: {
+ sym(1).StatementList = new (pool) AST::StatementList(sym(1).Statement);
+ } break;
./
-AssignmentOperator: T_DIVIDE_EQ ;
+StatementListItem: ExpressionStatementLookahead T_FORCE_DECLARATION Declaration T_AUTOMATIC_SEMICOLON;
+StatementListItem: ExpressionStatementLookahead T_FORCE_DECLARATION Declaration T_SEMICOLON;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceDiv;
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::StatementList(sym(3).FunctionDeclaration);
+ } break;
./
-AssignmentOperator: T_REMAINDER_EQ ;
+StatementListOpt: ;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceMod;
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-AssignmentOperator: T_PLUS_EQ ;
+StatementListOpt: StatementList;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceAdd;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(1).StatementList->finish();
+ } break;
./
-AssignmentOperator: T_MINUS_EQ ;
+LetOrConst: T_LET;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceSub;
-} break;
+ case $rule_number: {
+ sym(1).ival = AST::VariableDeclaration::BlockScope;
+ } break;
./
-
-AssignmentOperator: T_LT_LT_EQ ;
+LetOrConst: T_CONST;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceLeftShift;
-} break;
+ case $rule_number: {
+ sym(1).ival = AST::VariableDeclaration::ReadOnlyBlockScope;
+ } break;
./
-AssignmentOperator: T_GT_GT_EQ ;
+Var: T_VAR;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceRightShift;
-} break;
+ case $rule_number: {
+ sym(1).ival = AST::VariableDeclaration::FunctionScope;
+ } break;
./
-AssignmentOperator: T_GT_GT_GT_EQ ;
+LexicalDeclaration: LetOrConst BindingList;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+LexicalDeclaration_In: LetOrConst BindingList_In;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+VarDeclaration: Var VariableDeclarationList;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+VarDeclaration_In: Var VariableDeclarationList_In;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceURightShift;
-} break;
+ case $rule_number: {
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::VariableScope(sym(1).ival);
+ AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(s));
+ node->declarationKindToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-AssignmentOperator: T_AND_EQ ;
+VariableStatement: VarDeclaration_In T_AUTOMATIC_SEMICOLON;
+VariableStatement: VarDeclaration_In T_SEMICOLON;
+
+BindingList: LexicalBinding_In;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+BindingList_In: LexicalBinding_In;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+VariableDeclarationList: VariableDeclaration;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+VariableDeclarationList_In: VariableDeclaration_In;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceAnd;
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
+ } break;
./
-AssignmentOperator: T_XOR_EQ ;
+BindingList: BindingList T_COMMA LexicalBinding;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+BindingList_In: BindingList_In T_COMMA LexicalBinding_In;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+VariableDeclarationList_In: VariableDeclarationList_In T_COMMA VariableDeclaration_In;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceXor;
-} break;
+ case $rule_number: {
+ AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
+ node->commaToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-AssignmentOperator: T_OR_EQ ;
+LexicalBinding: BindingIdentifier InitializerOpt;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+LexicalBinding_In: BindingIdentifier InitializerOpt_In;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+VariableDeclaration: BindingIdentifier InitializerOpt;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+VariableDeclaration_In: BindingIdentifier InitializerOpt_In;
/.
-case $rule_number: {
- sym(1).ival = QSOperator::InplaceOr;
-} break;
+ case $rule_number: {
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
+ AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s);
+ node->identifierToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-Expression: AssignmentExpression ;
+LexicalBinding: BindingPattern Initializer;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+LexicalBinding_In: BindingPattern Initializer_In;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+VariableDeclaration: BindingPattern InitializerOpt;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+VariableDeclaration_In: BindingPattern Initializer_In;
+/. case $rule_number: { UNIMPLEMENTED; } ./
-Expression: Expression T_COMMA AssignmentExpression ;
+BindingPattern: T_LBRACE ObjectBindingPattern T_RBRACE;
/.
-case $rule_number: {
- AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ auto *node = new (pool) AST::ObjectBindingPattern(sym(2).BindingPropertyList);
+ node->first = loc(1);
+ node->last = loc(3);
+ sym(1).Node = node;
+ } break;
./
-ExpressionOpt: ;
+BindingPattern: T_LBRACKET ArrayBindingPattern T_RBRACKET;
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ auto *node = new (pool) AST::ArrayBindingPattern(sym(2).BindingElementList);
+ node->first = loc(1);
+ node->last = loc(3);
+ sym(1).Node = node;
+ } break;
./
-ExpressionOpt: Expression ;
-
-ExpressionNotIn: AssignmentExpressionNotIn ;
-
-ExpressionNotIn: ExpressionNotIn T_COMMA AssignmentExpressionNotIn ;
+ObjectBindingPattern: ;
/.
-case $rule_number: {
- AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-ExpressionNotInOpt: ;
+ObjectBindingPattern: BindingPropertyList;
+/. case $rule_number: ./
+ObjectBindingPattern: BindingPropertyList T_COMMA;
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(1).BindingPropertyList->finish();
+ } break;
./
-ExpressionNotInOpt: ExpressionNotIn ;
-
-Statement: Block ;
-Statement: VariableStatement ;
-Statement: EmptyStatement ;
-Statement: ExpressionStatement ;
-Statement: IfStatement ;
-Statement: IterationStatement ;
-Statement: ContinueStatement ;
-Statement: BreakStatement ;
-Statement: ReturnStatement ;
-Statement: WithStatement ;
-Statement: LabelledStatement ;
-Statement: SwitchStatement ;
-Statement: ThrowStatement ;
-Statement: TryStatement ;
-Statement: DebuggerStatement ;
-
-
-Block: T_LBRACE StatementListOpt T_RBRACE ;
+ArrayBindingPattern: ElisionOpt BindingRestElementOpt;
/.
-case $rule_number: {
- AST::Block *node = new (pool) AST::Block(sym(2).StatementList);
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ if (sym(3).Elision || sym(4).Node) {
+ auto *l = new (pool) AST::BindingElementList(sym(1).Elision, sym(2).Node);
+ sym(1).Node = l->finish();
+ } else {
+ sym(1).Node = nullptr;
+ }
+ } break;
./
-StatementList: Statement ;
+ArrayBindingPattern: BindingElementList;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::StatementList(sym(1).Statement);
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(1).BindingElementList->finish();
+ } break;
./
-StatementList: StatementList Statement ;
+ArrayBindingPattern: BindingElementList T_COMMA ElisionOpt BindingRestElementOpt;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement);
-} break;
+ case $rule_number: {
+ if (sym(3).Elision || sym(4).Node) {
+ auto *l = new (pool) AST::BindingElementList(sym(3).Elision, sym(4).Node);
+ l = sym(1).BindingElementList->append(l);
+ sym(1).Node = l;
+ }
+ sym(1).Node = sym(1).BindingElementList->finish();
+ } break;
./
-StatementListOpt: ;
+BindingPropertyList: BindingProperty;
+
+BindingPropertyList: BindingPropertyList T_COMMA BindingProperty;
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(1).BindingPropertyList->append(sym(3).BindingPropertyList);
+ } break;
./
-StatementListOpt: StatementList ;
+BindingElementList: BindingElisionElement;
+
+BindingElementList: BindingElementList T_COMMA BindingElisionElement;
/.
-case $rule_number: {
- sym(1).Node = sym(1).StatementList->finish ();
-} break;
+ case $rule_number: {
+ sym(1).BindingElementList->append(sym(3).BindingElementList);
+ } break;
./
-VariableStatement: VariableDeclarationKind VariableDeclarationList T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
-VariableStatement: VariableDeclarationKind VariableDeclarationList T_SEMICOLON ;
+BindingElisionElement: ElisionOpt BindingElement;
/.
-case $rule_number: {
- AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
- if (sym(1).ival == T_LET)
- s = AST::VariableDeclaration::BlockScope;
- else if (sym(1).ival == T_CONST)
- s = AST::VariableDeclaration::ReadOnlyBlockScope;
-
- AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(s));
- node->declarationKindToken = loc(1);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::BindingElementList(sym(1).Elision, sym(2).BindingElement);
+ } break;
./
-VariableDeclarationKind: T_LET ;
+
+BindingProperty: BindingIdentifier InitializerOpt_In;
/.
-case $rule_number: {
- sym(1).ival = T_LET;
-} break;
+ case $rule_number: {
+ AST::StringLiteralPropertyName *name = new (pool) AST::StringLiteralPropertyName(stringRef(1));
+ AST::BindingElement *e = new (pool) AST::BindingElement(stringRef(1), sym(2).Expression);
+ AST::BindingPropertyList *node = new (pool) AST::BindingPropertyList(name, e);
+ sym(1).Node = node;
+ } break;
./
-VariableDeclarationKind: T_CONST ;
+BindingProperty: PropertyName T_COLON BindingElement;
/.
-case $rule_number: {
- sym(1).ival = T_CONST;
-} break;
+ case $rule_number: {
+ AST::BindingPropertyList *node = new (pool) AST::BindingPropertyList(sym(1).PropertyName, sym(3).BindingElement);
+ sym(1).Node = node;
+ } break;
./
-VariableDeclarationKind: T_VAR ;
+BindingElement: BindingIdentifier InitializerOpt_In;
/.
-case $rule_number: {
- sym(1).ival = T_VAR;
-} break;
+ case $rule_number: {
+ AST::BindingElement *node = new (pool) AST::BindingElement(stringRef(1), sym(2).Expression);
+ node->identifierToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-VariableDeclarationList: VariableDeclaration ;
+BindingElement: BindingPattern InitializerOpt_In;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
-} break;
+ case $rule_number: {
+ AST::BindingElement *node = new (pool) AST::BindingElement(sym(1).BindingPattern, sym(2).Expression);
+ node->identifierToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration ;
+BindingRestElement: T_ELLIPSIS BindingIdentifier;
/.
-case $rule_number: {
- AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(
- sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BindingRestElement *node = new (pool) AST::BindingRestElement(stringRef(2));
+ node->identifierToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-VariableDeclarationListNotIn: VariableDeclarationNotIn ;
+BindingRestElement: T_ELLIPSIS BindingPattern;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+BindingRestElementOpt: ;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-VariableDeclarationListNotIn: VariableDeclarationListNotIn T_COMMA VariableDeclarationNotIn ;
+BindingRestElementOpt: BindingRestElement;
+
+
+EmptyStatement: T_SEMICOLON;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
-} break;
+ case $rule_number: {
+ AST::EmptyStatement *node = new (pool) AST::EmptyStatement();
+ node->semicolonToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-VariableDeclaration: JsIdentifier InitialiserOpt ;
+-- Spec says it should have a "[lookahead ∉ { {, function, class, let [ }]" before the Expression statement.
+-- This is implemented with the rule below that is run before any statement and inserts a T_EXPRESSION_STATEMENT_OK
+-- token if it's ok to parse as an expression statement.
+ExpressionStatementLookahead: ;
+/:
+#define J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE $rule_number
+:/
/.
-case $rule_number: {
- AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
- AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s);
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ int token = lookaheadToken(lexer);
+ if (token == T_LBRACE)
+ pushToken(T_FORCE_BLOCK);
+ else if (token == T_FUNCTION || token == T_CLASS || token == T_LET || token == T_CONST)
+ pushToken(T_FORCE_DECLARATION);
+ } break;
+./
+
+ExpressionStatement: Expression_In T_AUTOMATIC_SEMICOLON;
+ExpressionStatement: Expression_In T_SEMICOLON;
+/.
+ case $rule_number: {
+ AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression);
+ node->semicolonToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-
-VariableDeclarationNotIn: JsIdentifier InitialiserNotInOpt ;
+
+IfStatement: T_IF T_LPAREN Expression_In T_RPAREN Statement T_ELSE Statement;
+/.
+ case $rule_number: {
+ AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement);
+ node->ifToken = loc(1);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ node->elseToken = loc(6);
+ sym(1).Node = node;
+ } break;
+./
+
+IfStatement: T_IF T_LPAREN Expression_In T_RPAREN Statement;
/.
-case $rule_number: {
- AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
- AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s);
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement);
+ node->ifToken = loc(1);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ sym(1).Node = node;
+ } break;
+./
+
+
+IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression_In T_RPAREN T_AUTOMATIC_SEMICOLON;
+IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression_In T_RPAREN T_COMPATIBILITY_SEMICOLON; -- for JSC/V8 compatibility
+IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression_In T_RPAREN T_SEMICOLON;
+/.
+ case $rule_number: {
+ AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression);
+ node->doToken = loc(1);
+ node->whileToken = loc(3);
+ node->lparenToken = loc(4);
+ node->rparenToken = loc(6);
+ node->semicolonToken = loc(7);
+ sym(1).Node = node;
+ } break;
./
-Initialiser: T_EQ AssignmentExpression ;
+IterationStatement: T_WHILE T_LPAREN Expression_In T_RPAREN Statement;
/.
-case $rule_number: {
- // ### TODO: AST for initializer
- sym(1) = sym(2);
-} break;
+ case $rule_number: {
+ AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement);
+ node->whileToken = loc(1);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ sym(1).Node = node;
+ } break;
./
-InitialiserOpt: ;
+IterationStatement: T_FOR T_LPAREN ExpressionOpt T_SEMICOLON ExpressionOpt_In T_SEMICOLON ExpressionOpt_In T_RPAREN Statement; -- [lookahead != { let [ }]
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression, sym(5).Expression, sym(7).Expression, sym(9).Statement);
+ node->forToken = loc(1);
+ node->lparenToken = loc(2);
+ node->firstSemicolonToken = loc(4);
+ node->secondSemicolonToken = loc(6);
+ node->rparenToken = loc(8);
+ sym(1).Node = node;
+ } break;
./
-InitialiserOpt: Initialiser ;
+IterationStatement: T_FOR T_LPAREN VarDeclaration T_SEMICOLON ExpressionOpt_In T_SEMICOLON ExpressionOpt_In T_RPAREN Statement;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+IterationStatement: T_FOR T_LPAREN LexicalDeclaration T_SEMICOLON ExpressionOpt_In T_SEMICOLON ExpressionOpt_In T_RPAREN Statement;
+/.
+ case $rule_number: {
+ // ### get rid of the static_cast!
+ AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
+ static_cast<AST::VariableStatement *>(sym(3).Node)->declarations, sym(5).Expression,
+ sym(7).Expression, sym(9).Statement);
+ node->forToken = loc(1);
+ node->lparenToken = loc(2);
+ node->varToken = loc(3);
+ node->firstSemicolonToken = loc(4);
+ node->secondSemicolonToken = loc(6);
+ node->rparenToken = loc(8);
+ sym(1).Node = node;
+ } break;
+./
-InitialiserNotIn: T_EQ AssignmentExpressionNotIn ;
+IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression_In T_RPAREN Statement;
/.
-case $rule_number: {
- // ### TODO: AST for initializer
- sym(1) = sym(2);
-} break;
+ case $rule_number: {
+ AST::ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression, sym(5).Expression, sym(7).Statement);
+ node->forToken = loc(1);
+ node->lparenToken = loc(2);
+ node->inToken = loc(4);
+ node->rparenToken = loc(6);
+ sym(1).Node = node;
+ } break;
./
-InitialiserNotInOpt: ;
+IterationStatement: T_FOR T_LPAREN ForDeclaration T_IN Expression_In T_RPAREN Statement;
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(sym(3).VariableDeclaration, sym(5).Expression, sym(7).Statement);
+ node->forToken = loc(1);
+ node->lparenToken = loc(2);
+ node->varToken = loc(3);
+ node->inToken = loc(4);
+ node->rparenToken = loc(6);
+ sym(1).Node = node;
+ } break;
./
-InitialiserNotInOpt: InitialiserNotIn ;
-EmptyStatement: T_SEMICOLON ;
+IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_OF AssignmentExpression_In T_RPAREN Statement; -- [lookahead ≠ let]
+/. case $rule_number: { UNIMPLEMENTED; } ./
+IterationStatement: T_FOR T_LPAREN ForDeclaration T_OF Expression_In T_RPAREN Statement;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+ForDeclaration: LetOrConst ForBinding;
+/. case $rule_number: Q_FALLTHROUGH(); ./
+ForDeclaration: Var ForBinding;
/.
-case $rule_number: {
- AST::EmptyStatement *node = new (pool) AST::EmptyStatement();
- node->semicolonToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::VariableScope(sym(1).ival);
+ auto *node = new (pool) AST::VariableDeclaration(stringRef(2), nullptr, s);
+ node->identifierToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-
-ExpressionStatement: Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
-ExpressionStatement: Expression T_SEMICOLON ;
+
+ForBinding: BindingIdentifier;
+
+ForBinding: BindingPattern;
+/. case $rule_number: UNIMPLEMENTED; ./
+
+ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON;
+ContinueStatement: T_CONTINUE T_SEMICOLON;
/.
-case $rule_number: {
- AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression);
- node->semicolonToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ContinueStatement *node = new (pool) AST::ContinueStatement();
+ node->continueToken = loc(1);
+ node->semicolonToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement T_ELSE Statement ;
+ContinueStatement: T_CONTINUE IdentifierReference T_AUTOMATIC_SEMICOLON;
+ContinueStatement: T_CONTINUE IdentifierReference T_SEMICOLON;
/.
-case $rule_number: {
- AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement);
- node->ifToken = loc(1);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- node->elseToken = loc(6);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2));
+ node->continueToken = loc(1);
+ node->identifierToken = loc(2);
+ node->semicolonToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-
-IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement ;
+
+BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON;
+BreakStatement: T_BREAK T_SEMICOLON;
/.
-case $rule_number: {
- AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement);
- node->ifToken = loc(1);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef());
+ node->breakToken = loc(1);
+ node->semicolonToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-
-IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
-IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_COMPATIBILITY_SEMICOLON ; -- for JSC/V8 compatibility
-IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_SEMICOLON ;
+BreakStatement: T_BREAK IdentifierReference T_AUTOMATIC_SEMICOLON;
+BreakStatement: T_BREAK IdentifierReference T_SEMICOLON;
/.
-case $rule_number: {
- AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression);
- node->doToken = loc(1);
- node->whileToken = loc(3);
- node->lparenToken = loc(4);
- node->rparenToken = loc(6);
- node->semicolonToken = loc(7);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2));
+ node->breakToken = loc(1);
+ node->identifierToken = loc(2);
+ node->semicolonToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-IterationStatement: T_WHILE T_LPAREN Expression T_RPAREN Statement ;
+ReturnStatement: T_RETURN ExpressionOpt_In T_AUTOMATIC_SEMICOLON;
+ReturnStatement: T_RETURN ExpressionOpt_In T_SEMICOLON;
/.
-case $rule_number: {
- AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement);
- node->whileToken = loc(1);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ if (!functionNestingLevel) {
+ syntaxError(loc(1), "Return statement not allowed outside of Function declaration.");
+ return false;
+ }
+ AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression);
+ node->returnToken = loc(1);
+ node->semicolonToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-IterationStatement: T_FOR T_LPAREN ExpressionNotInOpt T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
+WithStatement: T_WITH T_LPAREN Expression_In T_RPAREN Statement;
/.
-case $rule_number: {
- AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression,
- sym(5).Expression, sym(7).Expression, sym(9).Statement);
- node->forToken = loc(1);
- node->lparenToken = loc(2);
- node->firstSemicolonToken = loc(4);
- node->secondSemicolonToken = loc(6);
- node->rparenToken = loc(8);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement);
+ node->withToken = loc(1);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ sym(1).Node = node;
+ } break;
./
-IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationListNotIn T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
+SwitchStatement: T_SWITCH T_LPAREN Expression_In T_RPAREN CaseBlock;
/.
-case $rule_number: {
- AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
- AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
- sym(4).VariableDeclarationList->finish(s), sym(6).Expression,
- sym(8).Expression, sym(10).Statement);
- node->forToken = loc(1);
- node->lparenToken = loc(2);
- node->varToken = loc(3);
- node->firstSemicolonToken = loc(5);
- node->secondSemicolonToken = loc(7);
- node->rparenToken = loc(9);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock);
+ node->switchToken = loc(1);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ sym(1).Node = node;
+ } break;
./
-IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression T_RPAREN Statement ;
+CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE;
/.
-case $rule_number: {
- AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression,
- sym(5).Expression, sym(7).Statement);
- node->forToken = loc(1);
- node->lparenToken = loc(2);
- node->inToken = loc(4);
- node->rparenToken = loc(6);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses);
+ node->lbraceToken = loc(1);
+ node->rbraceToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationNotIn T_IN Expression T_RPAREN Statement ;
+CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE;
/.
-case $rule_number: {
- AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(
- sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
- node->forToken = loc(1);
- node->lparenToken = loc(2);
- node->varToken = loc(3);
- node->inToken = loc(5);
- node->rparenToken = loc(7);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
+ node->lbraceToken = loc(1);
+ node->rbraceToken = loc(5);
+ sym(1).Node = node;
+ } break;
./
-ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
-ContinueStatement: T_CONTINUE T_SEMICOLON ;
+CaseClauses: CaseClause;
/.
-case $rule_number: {
- AST::ContinueStatement *node = new (pool) AST::ContinueStatement();
- node->continueToken = loc(1);
- node->semicolonToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause);
+ } break;
./
-ContinueStatement: T_CONTINUE JsIdentifier T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
-ContinueStatement: T_CONTINUE JsIdentifier T_SEMICOLON ;
+CaseClauses: CaseClauses CaseClause;
/.
-case $rule_number: {
- AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2));
- node->continueToken = loc(1);
- node->identifierToken = loc(2);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause);
+ } break;
./
-BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
-BreakStatement: T_BREAK T_SEMICOLON ;
+CaseClausesOpt: ;
/.
-case $rule_number: {
- AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef());
- node->breakToken = loc(1);
- node->semicolonToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-BreakStatement: T_BREAK JsIdentifier T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
-BreakStatement: T_BREAK JsIdentifier T_SEMICOLON ;
+CaseClausesOpt: CaseClauses;
/.
-case $rule_number: {
- AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2));
- node->breakToken = loc(1);
- node->identifierToken = loc(2);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(1).CaseClauses->finish();
+ } break;
./
-ReturnStatement: T_RETURN ExpressionOpt T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
-ReturnStatement: T_RETURN ExpressionOpt T_SEMICOLON ;
+CaseClause: T_CASE Expression_In T_COLON StatementListOpt;
/.
-case $rule_number: {
- AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression);
- node->returnToken = loc(1);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList);
+ node->caseToken = loc(1);
+ node->colonToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-WithStatement: T_WITH T_LPAREN Expression T_RPAREN Statement ;
+DefaultClause: T_DEFAULT T_COLON StatementListOpt;
/.
-case $rule_number: {
- AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement);
- node->withToken = loc(1);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList);
+ node->defaultToken = loc(1);
+ node->colonToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-SwitchStatement: T_SWITCH T_LPAREN Expression T_RPAREN CaseBlock ;
+LabelledStatement: IdentifierReference T_COLON LabelledItem;
/.
-case $rule_number: {
- AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock);
- node->switchToken = loc(1);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
+ 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;
./
-CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE ;
+LabelledItem: Statement;
+
+LabelledItem: ExpressionStatementLookahead T_FORCE_DECLARATION FunctionDeclaration;
/.
-case $rule_number: {
- AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses);
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ syntaxError(loc(3), "FunctionDeclarations are not allowed after a label.");
+ return false;
+ } break;
./
-CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE ;
+ThrowStatement: T_THROW Expression_In T_AUTOMATIC_SEMICOLON;
+ThrowStatement: T_THROW Expression_In T_SEMICOLON;
/.
-case $rule_number: {
- AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(5);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression);
+ node->throwToken = loc(1);
+ node->semicolonToken = loc(3);
+ sym(1).Node = node;
+ } break;
./
-CaseClauses: CaseClause ;
+TryStatement: T_TRY Block Catch;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause);
-} break;
+ case $rule_number: {
+ AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch);
+ node->tryToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-CaseClauses: CaseClauses CaseClause ;
+TryStatement: T_TRY Block Finally;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause);
-} break;
+ case $rule_number: {
+ AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally);
+ node->tryToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-CaseClausesOpt: ;
+TryStatement: T_TRY Block Catch Finally;
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally);
+ node->tryToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-CaseClausesOpt: CaseClauses ;
+Catch: T_CATCH T_LPAREN CatchParameter T_RPAREN Block;
/.
-case $rule_number: {
- sym(1).Node = sym(1).CaseClauses->finish ();
-} break;
+ case $rule_number: {
+ AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block);
+ node->catchToken = loc(1);
+ node->lparenToken = loc(2);
+ node->identifierToken = loc(3);
+ node->rparenToken = loc(4);
+ sym(1).Node = node;
+ } break;
./
-CaseClause: T_CASE Expression T_COLON StatementListOpt ;
+Finally: T_FINALLY Block;
/.
-case $rule_number: {
- AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList);
- node->caseToken = loc(1);
- node->colonToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::Finally *node = new (pool) AST::Finally(sym(2).Block);
+ node->finallyToken = loc(1);
+ sym(1).Node = node;
+ } break;
./
-DefaultClause: T_DEFAULT T_COLON StatementListOpt ;
+CatchParameter: BindingIdentifier;
+CatchParameter: BindingPattern;
+
+DebuggerStatement: T_DEBUGGER T_AUTOMATIC_SEMICOLON; -- automatic semicolon
+DebuggerStatement: T_DEBUGGER T_SEMICOLON;
/.
-case $rule_number: {
- AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList);
- node->defaultToken = loc(1);
- node->colonToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement();
+ node->debuggerToken = loc(1);
+ node->semicolonToken = loc(2);
+ sym(1).Node = node;
+ } break;
./
-LabelledStatement: JsIdentifier T_COLON Statement ;
+-- 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.
+-- This is still required for parsing QML, where MemberExpression and FunctionDeclaration would
+-- otherwise conflict.
+Function: T_FUNCTION %prec REDUCE_HERE;
+
+FunctionDeclaration: Function BindingIdentifier T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
/.
-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;
+ case $rule_number: {
+ AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList);
+ node->functionToken = loc(1);
+ node->identifierToken = loc(2);
+ node->lparenToken = loc(3);
+ node->rparenToken = loc(5);
+ node->lbraceToken = loc(6);
+ node->rbraceToken = loc(8);
+ sym(1).Node = node;
+ } break;
./
-ThrowStatement: T_THROW Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
-ThrowStatement: T_THROW Expression T_SEMICOLON ;
+
+FunctionDeclaration_Default: FunctionDeclaration;
+FunctionDeclaration_Default: T_FUNCTION T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
/.
-case $rule_number: {
- AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression);
- node->throwToken = loc(1);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(1), sym(3).FormalParameterList, sym(6).StatementList);
+ node->functionToken = loc(1);
+ node->identifierToken = loc(1);
+ node->lparenToken = loc(2);
+ node->rparenToken = loc(4);
+ node->lbraceToken = loc(5);
+ node->rbraceToken = loc(7);
+ sym(1).Node = node;
+ } break;
./
-TryStatement: T_TRY Block Catch ;
+FunctionExpression: T_FUNCTION BindingIdentifier T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
/.
-case $rule_number: {
- AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch);
- node->tryToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList);
+ node->functionToken = loc(1);
+ if (! stringRef(2).isNull())
+ node->identifierToken = loc(2);
+ node->lparenToken = loc(3);
+ node->rparenToken = loc(5);
+ node->lbraceToken = loc(6);
+ node->rbraceToken = loc(8);
+ sym(1).Node = node;
+ } break;
./
-TryStatement: T_TRY Block Finally ;
+FunctionExpression: T_FUNCTION T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
/.
-case $rule_number: {
- AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally);
- node->tryToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(1), sym(3).FormalParameterList, sym(6).StatementList);
+ 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;
./
-TryStatement: T_TRY Block Catch Finally ;
+StrictFormalParameters: FormalParameters;
+
+FormalParameters: ;
/.
-case $rule_number: {
- AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally);
- node->tryToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-Catch: T_CATCH T_LPAREN JsIdentifier T_RPAREN Block ;
+FormalParameters: FormalParameterList;
/.
-case $rule_number: {
- AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block);
- node->catchToken = loc(1);
- node->lparenToken = loc(2);
- node->identifierToken = loc(3);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ sym(1).Node = sym(1).FormalParameterList->finish();
+ } break;
./
-Finally: T_FINALLY Block ;
+FormalsList: BindingElement;
+/. case $rule_number: ./
+
+FormalParameterList: BindingRestElement;
/.
-case $rule_number: {
- AST::Finally *node = new (pool) AST::Finally(sym(2).Block);
- node->finallyToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::FormalParameterList *node = new (pool) AST::FormalParameterList(nullptr, sym(1).Node);
+ sym(1).Node = node;
+ } break;
./
-DebuggerStatement: T_DEBUGGER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
-DebuggerStatement: T_DEBUGGER T_SEMICOLON ;
+FormalParameterList: FormalsList;
+
+FormalParameterList: FormalsList T_COMMA BindingRestElement;
+/. case $rule_number: ./
+
+FormalsList: FormalsList T_COMMA BindingElement;
/.
-case $rule_number: {
- AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement();
- node->debuggerToken = loc(1);
- node->semicolonToken = loc(2);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, sym(3).Node);
+ sym(1).Node = node;
+ } break;
./
--- 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 ;
+FormalParameter: BindingElement;
-FunctionDeclaration: Function JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
+FunctionLBrace: T_LBRACE;
/.
-case $rule_number: {
- AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
- node->functionToken = loc(1);
- node->identifierToken = loc(2);
- node->lparenToken = loc(3);
- node->rparenToken = loc(5);
- node->lbraceToken = loc(6);
- node->rbraceToken = loc(8);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ ++functionNestingLevel;
+ } break;
./
-FunctionExpression: T_FUNCTION JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
+FunctionRBrace: T_RBRACE;
/.
-case $rule_number: {
- AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
- node->functionToken = loc(1);
- if (! stringRef(2).isNull())
- node->identifierToken = loc(2);
- node->lparenToken = loc(3);
- node->rparenToken = loc(5);
- node->lbraceToken = loc(6);
- node->rbraceToken = loc(8);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ --functionNestingLevel;
+ } break;
./
-FunctionExpression: T_FUNCTION T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
+
+FunctionBody: FunctionStatementList;
+FunctionStatementList: StatementListOpt;
+
+ArrowFunction: ArrowParameters T_ARROW ConciseBody;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+ArrowFunction_In: ArrowParameters T_ARROW ConciseBody_In;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+ArrowParameters: BindingIdentifier;
+
+ArrowParameters: CoverParenthesizedExpressionAndArrowParameterList;
+
+-- ### CoverParenthesizedExpressionAndArrowParameterList for ArrowParameters refined to:
+-- ArrowFormalParameters[Yield]: (StrictFormalParameters[?Yield])
+
+ConciseBodyLookahead: ;
+/:
+#define J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE $rule_number
+:/
/.
-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;
+ case $rule_number: {
+ if (lookaheadToken(lexer) == T_LBRACE)
+ pushToken(T_FORCE_BLOCK);
+ } break;
./
-FormalParameterList: JsIdentifier ;
+ConciseBody: ConciseBodyLookahead AssignmentExpression; -- [lookahead ≠ {]
+ConciseBody_In: ConciseBodyLookahead AssignmentExpression_In; -- [lookahead ≠ {]
+ConciseBody: ConciseBodyLookahead T_FORCE_BLOCK FunctionLBrace FunctionBody FunctionRBrace;
+ConciseBody_In: ConciseBodyLookahead T_FORCE_BLOCK FunctionLBrace FunctionBody FunctionRBrace;
+
+MethodDefinition: PropertyName T_LPAREN StrictFormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+MethodDefinition: GeneratorMethod;
+
+MethodDefinition: T_GET PropertyName T_LPAREN T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
/.
-case $rule_number: {
- AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1));
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(sym(2).PropertyName, sym(6).StatementList);
+ 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;
./
-FormalParameterList: FormalParameterList T_COMMA JsIdentifier ;
+MethodDefinition: T_SET PropertyName T_LPAREN PropertySetParameterList T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
/.
-case $rule_number: {
- AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3));
- node->commaToken = loc(2);
- node->identifierToken = loc(3);
- sym(1).Node = node;
-} break;
+ case $rule_number: {
+ AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
+ sym(2).PropertyName, sym(4).FormalParameterList, sym(7).StatementList);
+ 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;
./
-FormalParameterListOpt: ;
+
+PropertySetParameterList: FormalParameter;
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ AST::FormalParameterList *node = (new (pool) AST::FormalParameterList(nullptr, sym(1).Node))->finish();
+ sym(1).Node = node;
+ } break;
./
-FormalParameterListOpt: FormalParameterList ;
+GeneratorLBrace: T_LBRACE;
/.
-case $rule_number: {
- sym(1).Node = sym(1).FormalParameterList->finish ();
-} break;
+ case $rule_number: {
+ ++functionNestingLevel;
+ lexer->enterGeneratorBody();
+ } break;
./
-FunctionBodyOpt: ;
+GeneratorRBrace: T_RBRACE;
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ --functionNestingLevel;
+ lexer->leaveGeneratorBody();
+ } break;
./
-FunctionBodyOpt: FunctionBody ;
+GeneratorMethod: T_STAR PropertyName T_LPAREN StrictFormalParameters T_RPAREN GeneratorLBrace GeneratorBody GeneratorRBrace;
+/. case $rule_number: { UNIMPLEMENTED; } ./
-FunctionBody: SourceElements ;
-/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ());
-} break;
-./
+GeneratorDeclaration: T_FUNCTION T_STAR BindingIdentifier T_LPAREN FormalParameters T_RPAREN GeneratorLBrace GeneratorBody GeneratorRBrace;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+GeneratorDeclaration_Default: GeneratorDeclaration;
+GeneratorDeclaration_Default: T_FUNCTION T_STAR T_LPAREN FormalParameters T_RPAREN GeneratorLBrace GeneratorBody GeneratorRBrace;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+GeneratorExpression: T_FUNCTION T_STAR BindingIdentifier T_LPAREN FormalParameters T_RPAREN GeneratorLBrace GeneratorBody GeneratorRBrace;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+GeneratorExpression: T_FUNCTION T_STAR T_LPAREN FormalParameters T_RPAREN GeneratorLBrace GeneratorBody GeneratorRBrace;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+GeneratorBody: FunctionBody;
-Program: Empty ;
+YieldExpression: T_YIELD T_STAR AssignmentExpression;
+YieldExpression_In: T_YIELD T_STAR AssignmentExpression_In;
+YieldExpression: T_YIELD AssignmentExpression;
+YieldExpression_In: T_YIELD AssignmentExpression_In;
-Program: SourceElements ;
+
+ClassDeclaration: T_CLASS BindingIdentifier ClassTail;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+ClassDeclaration_Default: ClassDeclaration;
+ClassDeclaration_Default: T_CLASS ClassTail;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+ClassExpression: T_CLASS BindingIdentifier ClassTail;
+
+ClassExpression: T_CLASS ClassTail;
+
+ClassLBrace: T_LBRACE;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ());
-} break;
+ case $rule_number: {
+ lexer->setStaticIsKeyword(true);
+ } break;
./
-SourceElements: SourceElement ;
+ClassRBrace: T_RBRACE;
+/. case $rule_number: ./
+ClassStaticQualifier: T_STATIC;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement);
-} break;
+ case $rule_number: {
+ lexer->setStaticIsKeyword(false);
+ } break;
./
-SourceElements: SourceElements SourceElement ;
+ClassTail: ClassLBrace ClassBodyOpt ClassRBrace;
+ClassTail: ClassHeritage ClassLBrace ClassBodyOpt ClassRBrace;
+
+ClassHeritage: T_EXTENDS LeftHandSideExpression;
+
+ClassBody: ClassElementList;
+
+ClassBodyOpt: ;
+
+ClassBodyOpt: ClassBody;
+
+ClassElementList: ClassElement;
+ClassElementList: ClassElementList ClassElement;
+
+ClassElement: MethodDefinition;
+
+ClassElement: ClassStaticQualifier MethodDefinition;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement);
-} break;
+ case $rule_number: {
+ lexer->setStaticIsKeyword(true);
+ } break;
./
-SourceElement: Statement ;
+ClassElement: T_SEMICOLON;
+
+-- Scripts and Modules
+
+Script: ;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement);
-} break;
+ case $rule_number: {
+ sym(1).Node = nullptr;
+ } break;
./
-SourceElement: FunctionDeclaration ;
+Script: ScriptBody;
+
+ScriptBody: StatementList;
/.
-case $rule_number: {
- sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration);
-} break;
+ case $rule_number: {
+ sym(1).Node = new (pool) AST::Program(sym(1).StatementList->finish());
+ } break;
./
-PropertyAssignmentListOpt: ;
+Module: ModuleBodyOpt;
+/. case $rule_number: { UNIMPLEMENTED; } ./
+
+ModuleBody: ModuleItemList;
+
+ModuleBodyOpt: ;
+ModuleBodyOpt: ModuleBody;
+
+ModuleItemList: ModuleItem;
+ModuleItemList: ModuleItemList ModuleItem;
+
+ModuleItem: ImportDeclaration T_AUTOMATIC_SEMICOLON;
+ModuleItem: ImportDeclaration T_SEMICOLON;
+ModuleItem: ExportDeclaration T_AUTOMATIC_SEMICOLON;
+ModuleItem: ExportDeclaration T_SEMICOLON;
+ModuleItem: StatementListItem;
+
+ImportDeclaration: T_IMPORT ImportClause FromClause;
+ImportDeclaration: T_IMPORT ModuleSpecifier;
+
+ImportClause: ImportedDefaultBinding;
+ImportClause: NameSpaceImport;
+ImportClause: NamedImports;
+ImportClause: ImportedDefaultBinding T_COMMA NameSpaceImport;
+ImportClause: ImportedDefaultBinding T_COMMA NamedImports;
+
+ImportedDefaultBinding: ImportedBinding;
+
+NameSpaceImport: T_STAR T_AS ImportedBinding;
+
+NamedImports: T_LBRACE T_RBRACE;
+NamedImports: T_LBRACE ImportsList T_RBRACE;
+NamedImports: T_LBRACE ImportsList T_COMMA T_RBRACE;
+
+FromClause: T_FROM ModuleSpecifier;
+
+ImportsList: ImportSpecifier;
+ImportsList: ImportsList T_COMMA ImportSpecifier;
+
+ImportSpecifier: ImportedBinding;
+ImportSpecifier: IdentifierName T_AS ImportedBinding;
+
+ModuleSpecifier: T_STRING_LITERAL;
+
+ImportedBinding: BindingIdentifier;
+
+ExportDeclarationLookahead: ;
+/:
+#define J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE $rule_number
+:/
/.
-case $rule_number: {
- sym(1).Node = 0;
-} break;
+ case $rule_number: {
+ int token = lookaheadToken(lexer);
+ if (token == T_FUNCTION || token == T_CLASS)
+ pushToken(T_FORCE_DECLARATION);
+ } break;
./
-PropertyAssignmentListOpt: PropertyAssignmentList ;
+ExportDeclaration: T_EXPORT T_STAR FromClause;
+ExportDeclaration: T_EXPORT ExportClause FromClause;
+ExportDeclaration: T_EXPORT ExportClause;
+ExportDeclaration: T_EXPORT VariableStatement;
+ExportDeclaration: T_EXPORT Declaration;
+ExportDeclaration: T_EXPORT T_DEFAULT ExportDeclarationLookahead T_FORCE_DECLARATION HoistableDeclaration_Default;
+ExportDeclaration: T_EXPORT T_DEFAULT ExportDeclarationLookahead T_FORCE_DECLARATION ClassDeclaration_Default;
+ExportDeclaration: T_EXPORT T_DEFAULT ExportDeclarationLookahead AssignmentExpression_In; -- [lookahead ∉ { function, class }]
+
+ExportClause: T_LBRACE T_RBRACE;
+ExportClause: T_LBRACE ExportsList T_RBRACE;
+ExportClause: T_LBRACE ExportsList T_COMMA T_RBRACE;
+
+ExportsList: ExportSpecifier;
+ExportsList: ExportsList T_COMMA ExportSpecifier;
+
+ExportSpecifier: IdentifierName;
+ExportSpecifier: IdentifierName T_AS IdentifierName;
+
+-- Old top level code
/.
+ // ------------ end of switch statement
} // switch
action = nt_action(state_stack[tos], lhs[r] - TERMINAL_COUNT);
} // if
@@ -3260,8 +3720,7 @@ PropertyAssignmentListOpt: PropertyAssignmentList ;
for (int tk = 1; tk < TERMINAL_COUNT; ++tk) {
if (tk == T_AUTOMATIC_SEMICOLON || tk == T_FEED_UI_PROGRAM ||
- tk == T_FEED_JS_STATEMENT || tk == T_FEED_JS_EXPRESSION ||
- tk == T_FEED_JS_SOURCE_ELEMENT)
+ tk == T_FEED_JS_STATEMENT || tk == T_FEED_JS_EXPRESSION)
continue;
int a = t_action(errorState, tk);
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 34657a7d48..f78e48e66a 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -155,6 +155,16 @@ void StringLiteral::accept0(Visitor *visitor)
visitor->endVisit(this);
}
+void TemplateLiteral::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ if (next)
+ accept(next, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
void NumericLiteral::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
@@ -232,10 +242,10 @@ void PropertyGetterSetter::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void PropertyAssignmentList::accept0(Visitor *visitor)
+void PropertyDefinitionList::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
- for (PropertyAssignmentList *it = this; it; it = it->next) {
+ for (PropertyDefinitionList *it = this; it; it = it->next) {
accept(it->assignment, visitor);
}
}
@@ -752,57 +762,71 @@ void FunctionExpression::accept0(Visitor *visitor)
visitor->endVisit(this);
}
-void FormalParameterList::accept0(Visitor *visitor)
+QStringList FormalParameterList::formals() const
{
- if (visitor->visit(this)) {
- // ###
+ QStringList formals;
+ int i = 0;
+ for (const FormalParameterList *it = this; it; it = it->next) {
+ QString name;
+ if (QQmlJS::AST::BindingElement *b = it->bindingElement()) {
+ name = b->name;
+ } else if (QQmlJS::AST::BindingRestElement *r = it->bindingRestElement()) {
+ name = r->name.toString();
+ }
+ int duplicateIndex = formals.indexOf(name);
+ if (duplicateIndex >= 0) {
+ // change the name of the earlier argument to enforce the lookup semantics from the spec
+ formals[duplicateIndex] += QLatin1String("#") + QString::number(i);
+ }
+ formals += name;
+ ++i;
}
-
- visitor->endVisit(this);
+ return formals;
}
-void FunctionBody::accept0(Visitor *visitor)
+QStringList FormalParameterList::boundNames() const
{
- if (visitor->visit(this)) {
- accept(elements, visitor);
+ QStringList names;
+ for (const FormalParameterList *it = this; it; it = it->next) {
+ if (QQmlJS::AST::BindingElement *b = it->bindingElement()) {
+ b->boundNames(&names);
+ } else if (QQmlJS::AST::BindingRestElement *r = it->bindingRestElement()) {
+ names += r->name.toString();
+ }
}
-
- visitor->endVisit(this);
+ return names;
}
-void Program::accept0(Visitor *visitor)
+void FormalParameterList::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
- accept(elements, visitor);
+ // ###
}
visitor->endVisit(this);
}
-void SourceElements::accept0(Visitor *visitor)
+FormalParameterList *FormalParameterList::finish()
{
- if (visitor->visit(this)) {
- for (SourceElements *it = this; it; it = it->next) {
- accept(it->element, visitor);
- }
- }
-
- visitor->endVisit(this);
-}
+ FormalParameterList *front = next;
+ next = nullptr;
-void FunctionSourceElement::accept0(Visitor *visitor)
-{
- if (visitor->visit(this)) {
- accept(declaration, visitor);
+ int i = 0;
+ for (const FormalParameterList *it = this; it; it = it->next) {
+ QString name;
+ if (QQmlJS::AST::BindingElement *b = it->bindingElement()) {
+ if (b->name.isEmpty())
+ name = QLatin1String("arg#") + QString::number(i);
+ }
+ ++i;
}
-
- visitor->endVisit(this);
+ return front;
}
-void StatementSourceElement::accept0(Visitor *visitor)
+void Program::accept0(Visitor *visitor)
{
if (visitor->visit(this)) {
- accept(statement, visitor);
+ accept(statements, visitor);
}
visitor->endVisit(this);
@@ -984,6 +1008,93 @@ void UiEnumMemberList::accept0(Visitor *visitor)
visitor->endVisit(this);
}
+void TaggedTemplate::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(templateLiteral, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void BindingRestElement::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ }
+
+ visitor->endVisit(this);
+}
+
+void BindingElement::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(initializer, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void BindingElement::boundNames(QStringList *names)
+{
+ if (binding) {
+ if (BindingElementList *e = elementList())
+ e->boundNames(names);
+ else if (BindingPropertyList *p = propertyList())
+ p->boundNames(names);
+ } else
+ names->append(name);
+}
+
+void BindingElementList::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ }
+
+ visitor->endVisit(this);
+}
+
+void BindingElementList::boundNames(QStringList *names)
+{
+ for (BindingElementList *it = this; it; it = it->next) {
+ if (BindingElement *e = it->bindingElement())
+ e->boundNames(names);
+ else if (BindingRestElement *r = it->bindingRestElement())
+ names->append(r->name.toString());
+ }
+}
+
+void BindingPropertyList::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ }
+
+ visitor->endVisit(this);
+}
+
+void BindingPropertyList::boundNames(QStringList *names)
+{
+ for (BindingPropertyList *it = this; it; it = it->next)
+ it->binding->boundNames(names);
+}
+
+void ObjectBindingPattern::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(properties, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void ArrayBindingPattern::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(elements, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
} } // namespace QQmlJS::AST
QT_QML_END_NAMESPACE
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index ed3c83badf..6c8a5c7af6 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -156,7 +156,6 @@ public:
Kind_FunctionBody,
Kind_FunctionDeclaration,
Kind_FunctionExpression,
- Kind_FunctionSourceElement,
Kind_IdentifierExpression,
Kind_IdentifierPropertyName,
Kind_IfStatement,
@@ -175,19 +174,18 @@ public:
Kind_PreDecrementExpression,
Kind_PreIncrementExpression,
Kind_Program,
- Kind_PropertyAssignmentList,
+ Kind_PropertyDefinitionList,
Kind_PropertyGetterSetter,
Kind_PropertyName,
Kind_PropertyNameAndValue,
Kind_RegExpLiteral,
Kind_ReturnStatement,
- Kind_SourceElement,
- Kind_SourceElements,
Kind_StatementList,
- Kind_StatementSourceElement,
Kind_StringLiteral,
Kind_StringLiteralPropertyName,
Kind_SwitchStatement,
+ Kind_TemplateLiteral,
+ Kind_TaggedTemplate,
Kind_ThisExpression,
Kind_ThrowStatement,
Kind_TildeExpression,
@@ -203,6 +201,12 @@ public:
Kind_WhileStatement,
Kind_WithStatement,
Kind_NestedExpression,
+ Kind_ArrayBindingPattern,
+ Kind_ObjectBindingPattern,
+ Kind_BindingElement,
+ Kind_BindingElementList,
+ Kind_BindingPropertyList,
+ Kind_BindingRestElement,
Kind_UiArrayBinding,
Kind_UiImport,
@@ -428,6 +432,29 @@ public:
SourceLocation literalToken;
};
+class QML_PARSER_EXPORT TemplateLiteral : public ExpressionNode
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(TemplateLiteral)
+
+ TemplateLiteral(const QStringRef &str, ExpressionNode *e)
+ : value(str), expression(e), next(nullptr)
+ { kind = K; }
+
+ SourceLocation firstSourceLocation() const override
+ { return literalToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return next ? next->lastSourceLocation() : (expression ? expression->lastSourceLocation() : literalToken); }
+
+ void accept0(Visitor *visitor) override;
+
+ QStringRef value;
+ ExpressionNode *expression;
+ TemplateLiteral *next;
+ SourceLocation literalToken;
+};
+
class QML_PARSER_EXPORT RegExpLiteral: public ExpressionNode
{
public:
@@ -491,7 +518,7 @@ public:
ObjectLiteral()
{ kind = K; }
- ObjectLiteral(PropertyAssignmentList *plist):
+ ObjectLiteral(PropertyDefinitionList *plist):
properties (plist) { kind = K; }
void accept0(Visitor *visitor) override;
@@ -503,7 +530,7 @@ public:
{ return rbraceToken; }
// attributes
- PropertyAssignmentList *properties = nullptr;
+ PropertyDefinitionList *properties = nullptr;
SourceLocation lbraceToken;
SourceLocation rbraceToken;
};
@@ -609,27 +636,34 @@ public:
SourceLocation propertyNameToken;
};
-class QML_PARSER_EXPORT PropertyAssignment: public Node
+class QML_PARSER_EXPORT PropertyDefinition: public Node
{
public:
- PropertyAssignment(PropertyName *n)
+ PropertyDefinition(PropertyName *n)
: name(n)
{}
+
+ SourceLocation firstSourceLocation() const override
+ { return name->firstSourceLocation(); }
+
+ SourceLocation lastSourceLocation() const override
+ { return name->lastSourceLocation(); }
+
// attributes
PropertyName *name;
};
-class QML_PARSER_EXPORT PropertyAssignmentList: public Node
+class QML_PARSER_EXPORT PropertyDefinitionList: public Node
{
public:
- QQMLJS_DECLARE_AST_NODE(PropertyAssignmentList)
+ QQMLJS_DECLARE_AST_NODE(PropertyDefinitionList)
- PropertyAssignmentList(PropertyAssignment *assignment)
+ PropertyDefinitionList(PropertyDefinition *assignment)
: assignment(assignment)
, next(this)
{ kind = K; }
- PropertyAssignmentList(PropertyAssignmentList *previous, PropertyAssignment *assignment)
+ PropertyDefinitionList(PropertyDefinitionList *previous, PropertyDefinition *assignment)
: assignment(assignment)
{
kind = K;
@@ -637,9 +671,9 @@ public:
previous->next = this;
}
- inline PropertyAssignmentList *finish ()
+ inline PropertyDefinitionList *finish ()
{
- PropertyAssignmentList *front = next;
+ PropertyDefinitionList *front = next;
next = nullptr;
return front;
}
@@ -653,18 +687,18 @@ public:
{ return next ? next->lastSourceLocation() : assignment->lastSourceLocation(); }
// attributes
- PropertyAssignment *assignment;
- PropertyAssignmentList *next;
+ PropertyDefinition *assignment;
+ PropertyDefinitionList *next;
SourceLocation commaToken;
};
-class QML_PARSER_EXPORT PropertyNameAndValue: public PropertyAssignment
+class QML_PARSER_EXPORT PropertyNameAndValue: public PropertyDefinition
{
public:
QQMLJS_DECLARE_AST_NODE(PropertyNameAndValue)
PropertyNameAndValue(PropertyName *n, ExpressionNode *v)
- : PropertyAssignment(n), value(v)
+ : PropertyDefinition(n), value(v)
{ kind = K; }
void accept0(Visitor *visitor) override;
@@ -681,7 +715,7 @@ public:
SourceLocation commaToken;
};
-class QML_PARSER_EXPORT PropertyGetterSetter: public PropertyAssignment
+class QML_PARSER_EXPORT PropertyGetterSetter: public PropertyDefinition
{
public:
QQMLJS_DECLARE_AST_NODE(PropertyGetterSetter)
@@ -691,12 +725,12 @@ public:
Setter
};
- PropertyGetterSetter(PropertyName *n, FunctionBody *b)
- : PropertyAssignment(n), type(Getter), formals(nullptr), functionBody (b)
+ PropertyGetterSetter(PropertyName *n, StatementList *b)
+ : PropertyDefinition(n), type(Getter), formals(nullptr), functionBody(b)
{ kind = K; }
- PropertyGetterSetter(PropertyName *n, FormalParameterList *f, FunctionBody *b)
- : PropertyAssignment(n), type(Setter), formals(f), functionBody (b)
+ PropertyGetterSetter(PropertyName *n, FormalParameterList *f, StatementList *b)
+ : PropertyDefinition(n), type(Setter), formals(f), functionBody(b)
{ kind = K; }
void accept0(Visitor *visitor) override;
@@ -714,7 +748,7 @@ public:
FormalParameterList *formals;
SourceLocation rparenToken;
SourceLocation lbraceToken;
- FunctionBody *functionBody;
+ StatementList *functionBody;
SourceLocation rbraceToken;
};
@@ -814,6 +848,28 @@ public:
SourceLocation identifierToken;
};
+class QML_PARSER_EXPORT TaggedTemplate : public ExpressionNode
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(TaggedTemplate)
+
+ TaggedTemplate(ExpressionNode *b, TemplateLiteral *t)
+ : base (b), templateLiteral(t)
+ { kind = K; }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return base->firstSourceLocation(); }
+
+ SourceLocation lastSourceLocation() const override
+ { return templateLiteral->lastSourceLocation(); }
+
+ // attributes
+ ExpressionNode *base;
+ TemplateLiteral *templateLiteral;
+};
+
class QML_PARSER_EXPORT NewMemberExpression: public ExpressionNode
{
public:
@@ -1257,22 +1313,21 @@ class QML_PARSER_EXPORT StatementList: public Node
public:
QQMLJS_DECLARE_AST_NODE(StatementList)
- StatementList(Statement *stmt):
- statement (stmt), next (this)
- { kind = K; }
+ // ### This should be a Statement, but FunctionDeclaration currently doesn't inherit it.
+ StatementList(Node *stmt)
+ : statement(stmt), next (this)
+ { kind = K; }
- StatementList(StatementList *previous, Statement *stmt):
- statement (stmt)
- {
- kind = K;
- next = previous->next;
- previous->next = this;
+ StatementList *append(StatementList *n) {
+ n->next = next;
+ next = n;
+ return n;
}
void accept0(Visitor *visitor) override;
SourceLocation firstSourceLocation() const override
- { return statement->firstSourceLocation(); }
+ { return statement ? statement->firstSourceLocation() : statement->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
{ return next ? next->lastSourceLocation() : statement->lastSourceLocation(); }
@@ -1285,33 +1340,10 @@ public:
}
// attributes
- Statement *statement;
+ Node *statement = nullptr;
StatementList *next;
};
-class QML_PARSER_EXPORT VariableStatement: public Statement
-{
-public:
- QQMLJS_DECLARE_AST_NODE(VariableStatement)
-
- VariableStatement(VariableDeclarationList *vlist):
- declarations (vlist)
- { kind = K; }
-
- void accept0(Visitor *visitor) override;
-
- SourceLocation firstSourceLocation() const override
- { return declarationKindToken; }
-
- SourceLocation lastSourceLocation() const override
- { return semicolonToken; }
-
-// attributes
- VariableDeclarationList *declarations;
- SourceLocation declarationKindToken;
- SourceLocation semicolonToken;
-};
-
class QML_PARSER_EXPORT VariableDeclaration: public Node
{
public:
@@ -1390,6 +1422,28 @@ public:
SourceLocation commaToken;
};
+class QML_PARSER_EXPORT VariableStatement: public Statement
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(VariableStatement)
+
+ VariableStatement(VariableDeclarationList *vlist):
+ declarations (vlist)
+ { kind = K; }
+
+ void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return declarationKindToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return declarations->lastSourceLocation(); }
+
+// attributes
+ VariableDeclarationList *declarations;
+ SourceLocation declarationKindToken;
+};
+
class QML_PARSER_EXPORT EmptyStatement: public Statement
{
public:
@@ -1423,7 +1477,7 @@ public:
{ return expression->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return semicolonToken; }
+ { return expression->lastSourceLocation(); }
// attributes
ExpressionNode *expression;
@@ -1993,7 +2047,7 @@ class QML_PARSER_EXPORT FunctionExpression: public ExpressionNode
public:
QQMLJS_DECLARE_AST_NODE(FunctionExpression)
- FunctionExpression(const QStringRef &n, FormalParameterList *f, FunctionBody *b):
+ FunctionExpression(const QStringRef &n, FormalParameterList *f, StatementList *b):
name (n), formals (f), body (b)
{ kind = K; }
@@ -2008,7 +2062,7 @@ public:
// attributes
QStringRef name;
FormalParameterList *formals;
- FunctionBody *body;
+ StatementList *body;
SourceLocation functionToken;
SourceLocation identifierToken;
SourceLocation lparenToken;
@@ -2017,185 +2071,301 @@ public:
SourceLocation rbraceToken;
};
-class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression
+class QML_PARSER_EXPORT BindingRestElement : public Node
{
public:
- QQMLJS_DECLARE_AST_NODE(FunctionDeclaration)
+ QQMLJS_DECLARE_AST_NODE(BindingRestElement)
- FunctionDeclaration(const QStringRef &n, FormalParameterList *f, FunctionBody *b):
- FunctionExpression(n, f, b)
- { kind = K; }
+ BindingRestElement(const QStringRef &n)
+ : name(n)
+ { kind = K; }
void accept0(Visitor *visitor) override;
+
+ SourceLocation firstSourceLocation() const override
+ { return identifierToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return identifierToken; }
+
+// attributes
+ SourceLocation identifierToken;
+ QStringRef name;
};
-class QML_PARSER_EXPORT FormalParameterList: public Node
+class QML_PARSER_EXPORT BindingPattern : public Node
{
public:
- QQMLJS_DECLARE_AST_NODE(FormalParameterList)
- FormalParameterList(const QStringRef &n):
- name (n), next (this)
- { kind = K; }
+ SourceLocation firstSourceLocation() const override
+ { return first; }
- FormalParameterList(FormalParameterList *previous, const QStringRef &n):
- name (n)
- {
- kind = K;
- next = previous->next;
- previous->next = this;
- }
+ SourceLocation lastSourceLocation() const override
+ { return last; }
- void accept0(Visitor *visitor) override;
+ SourceLocation first;
+ SourceLocation last;
+};
- SourceLocation firstSourceLocation() const override
- { return identifierToken; }
+class QML_PARSER_EXPORT ObjectBindingPattern : public BindingPattern
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(ObjectBindingPattern)
- SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : identifierToken; }
+ ObjectBindingPattern(BindingPropertyList *p)
+ : properties(p)
+ { kind = K; }
- inline FormalParameterList *finish ()
- {
- FormalParameterList *front = next;
- next = nullptr;
- return front;
- }
+ void accept0(Visitor *visitor) override;
-// attributes
- QStringRef name;
- FormalParameterList *next;
- SourceLocation commaToken;
- SourceLocation identifierToken;
+ BindingPropertyList *properties;
};
-class QML_PARSER_EXPORT SourceElement: public Node
+class QML_PARSER_EXPORT ArrayBindingPattern : public BindingPattern
{
public:
- QQMLJS_DECLARE_AST_NODE(SourceElement)
+ QQMLJS_DECLARE_AST_NODE(ArrayBindingPattern)
- inline SourceElement()
- { kind = K; }
+ ArrayBindingPattern(BindingElementList *e)
+ : elements(e)
+ { kind = K; }
+
+ void accept0(Visitor *visitor) override;
+
+ BindingElementList *elements;
};
-class QML_PARSER_EXPORT SourceElements: public Node
+class QML_PARSER_EXPORT BindingElement : public Node
{
public:
- QQMLJS_DECLARE_AST_NODE(SourceElements)
+ QQMLJS_DECLARE_AST_NODE(BindingElement)
- SourceElements(SourceElement *elt):
- element (elt), next (this)
- { kind = K; }
+ BindingElement(const QStringRef &n, ExpressionNode *i = nullptr)
+ : name(n.toString()), initializer(i)
+ { kind = K; }
- SourceElements(SourceElements *previous, SourceElement *elt):
- element (elt)
- {
- kind = K;
- next = previous->next;
- previous->next = this;
- }
+ BindingElement(BindingPattern *binding, ExpressionNode *i = nullptr)
+ : binding(binding), initializer(i)
+ { kind = K; }
void accept0(Visitor *visitor) override;
SourceLocation firstSourceLocation() const override
- { return element->firstSourceLocation(); }
+ { return identifierToken; }
SourceLocation lastSourceLocation() const override
- { return next ? next->lastSourceLocation() : element->lastSourceLocation(); }
+ { return initializer ? initializer->lastSourceLocation() : (binding ? binding->lastSourceLocation() : identifierToken); }
- inline SourceElements *finish ()
- {
- SourceElements *front = next;
- next = nullptr;
- return front;
+ BindingElementList *elementList() const {
+ ArrayBindingPattern *p = cast<ArrayBindingPattern *>(binding);
+ return p ? p->elements : nullptr;
+ }
+ BindingPropertyList *propertyList() const {
+ ObjectBindingPattern *p = cast<ObjectBindingPattern *>(binding);
+ return p ? p->properties : nullptr;
}
+ void boundNames(QStringList *names);
+
// attributes
- SourceElement *element;
- SourceElements *next;
+ SourceLocation identifierToken;
+ BindingPattern *binding = nullptr;
+ QString name;
+ ExpressionNode *initializer = nullptr;
};
-class QML_PARSER_EXPORT FunctionBody: public Node
+class QML_PARSER_EXPORT BindingElementList : public Node
{
public:
- QQMLJS_DECLARE_AST_NODE(FunctionBody)
+ QQMLJS_DECLARE_AST_NODE(BindingElementList)
- FunctionBody(SourceElements *elts):
- elements (elts)
- { kind = K; }
+ BindingElementList(Elision *e, Node *p)
+ : elision(e), param(p), next(this)
+ { kind = K; }
+
+ BindingElementList *append(BindingElementList *n) {
+ n->next = next;
+ next = n;
+ return n;
+ }
+
+ inline BindingElementList *finish ()
+ {
+ BindingElementList *front = next;
+ next = 0;
+ return front;
+ }
+
+ BindingRestElement *bindingRestElement() const {
+ return cast<BindingRestElement *>(param);
+ }
+
+ BindingElement *bindingElement() const {
+ return cast<BindingElement *>(param);
+ }
void accept0(Visitor *visitor) override;
+ void boundNames(QStringList *names);
+
SourceLocation firstSourceLocation() const override
- { return elements ? elements->firstSourceLocation() : SourceLocation(); }
+ { return elision ? elision->firstSourceLocation() : param->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return elements ? elements->lastSourceLocation() : SourceLocation(); }
+ { return next ? next->lastSourceLocation() : (param ? param->lastSourceLocation() : elision->lastSourceLocation()); }
-// attributes
- SourceElements *elements;
+ Elision *elision = nullptr;
+ Node *param = nullptr;
+ BindingElementList *next;
};
-class QML_PARSER_EXPORT Program: public Node
+class QML_PARSER_EXPORT BindingPropertyList : public Node
{
public:
- QQMLJS_DECLARE_AST_NODE(Program)
+ QQMLJS_DECLARE_AST_NODE(BindingPropertyList)
- Program(SourceElements *elts):
- elements (elts)
- { kind = K; }
+ BindingPropertyList(PropertyName *n, BindingElement *e)
+ : propertyName(n), binding(e), next(this)
+ { kind = K; }
void accept0(Visitor *visitor) override;
+ void boundNames(QStringList *names);
+
+ BindingPropertyList *append(BindingPropertyList *n) {
+ n->next = next;
+ next = n;
+ return n;
+ }
+
+ inline BindingPropertyList *finish ()
+ {
+ BindingPropertyList *front = next;
+ next = 0;
+ return front;
+ }
+
SourceLocation firstSourceLocation() const override
- { return elements ? elements->firstSourceLocation() : SourceLocation(); }
+ { return propertyName->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return elements ? elements->lastSourceLocation() : SourceLocation(); }
+ { return next ? next->lastSourceLocation() : binding->lastSourceLocation(); }
-// attributes
- SourceElements *elements;
+ PropertyName *propertyName;
+ BindingElement *binding;
+ BindingPropertyList *next;
};
-class QML_PARSER_EXPORT FunctionSourceElement: public SourceElement
+class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression
{
public:
- QQMLJS_DECLARE_AST_NODE(FunctionSourceElement)
+ QQMLJS_DECLARE_AST_NODE(FunctionDeclaration)
- FunctionSourceElement(FunctionDeclaration *f):
- declaration (f)
+ FunctionDeclaration(const QStringRef &n, FormalParameterList *f, StatementList *b):
+ FunctionExpression(n, f, b)
{ kind = K; }
void accept0(Visitor *visitor) override;
+};
+
+class QML_PARSER_EXPORT FormalParameterList: public Node
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(FormalParameterList)
+
+ FormalParameterList(FormalParameterList *previous, Node *p)
+ : param(p)
+ {
+ kind = K;
+ if (previous) {
+ next = previous->next;
+ previous->next = this;
+ } else {
+ next = this;
+ }
+ }
+
+ FormalParameterList *append(FormalParameterList *n) {
+ n->next = next;
+ next = n;
+ return n;
+ }
+
+ BindingRestElement *bindingRestElement() const {
+ return cast<BindingRestElement *>(param);
+ }
+
+ BindingElement *bindingElement() const {
+ return cast<BindingElement *>(param);
+ }
+
+ bool isSimpleParameterList()
+ {
+ AST::FormalParameterList *formals = this;
+ while (formals) {
+ if (formals->bindingRestElement())
+ return false;
+ BindingElement *e = formals->bindingElement();
+ Q_ASSERT(e);
+ if (e->initializer || e->binding)
+ return false;
+ formals = formals->next;
+ }
+ return true;
+ }
+
+ bool containsName(const QString &name) const {
+ for (const FormalParameterList *it = this; it; it = it->next) {
+ if (QQmlJS::AST::BindingElement *b = it->bindingElement()) {
+ // ### handle binding patterns
+ if (b->name == name)
+ return true;
+ } else if (QQmlJS::AST::BindingRestElement *r = it->bindingRestElement()) {
+ if (r->name == name)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ QStringList formals() const;
+
+ QStringList boundNames() const;
+
+ void accept0(Visitor *visitor) override;
SourceLocation firstSourceLocation() const override
- { return declaration->firstSourceLocation(); }
+ { return param->firstSourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return declaration->lastSourceLocation(); }
+ { return next ? next->lastSourceLocation() : param->lastSourceLocation(); }
+
+ FormalParameterList *finish();
// attributes
- FunctionDeclaration *declaration;
+ Node *param = nullptr;
+ FormalParameterList *next;
};
-class QML_PARSER_EXPORT StatementSourceElement: public SourceElement
+class QML_PARSER_EXPORT Program: public Node
{
public:
- QQMLJS_DECLARE_AST_NODE(StatementSourceElement)
+ QQMLJS_DECLARE_AST_NODE(Program)
- StatementSourceElement(Statement *stmt):
- statement (stmt)
- { kind = K; }
+ Program(StatementList *statements)
+ : statements(statements)
+ { kind = K; }
void accept0(Visitor *visitor) override;
SourceLocation firstSourceLocation() const override
- { return statement->firstSourceLocation(); }
+ { return statements ? statements->firstSourceLocation() : SourceLocation(); }
SourceLocation lastSourceLocation() const override
- { return statement->lastSourceLocation(); }
+ { return statements ? statements->lastSourceLocation() : SourceLocation(); }
// attributes
- Statement *statement;
+ StatementList *statements;
};
class QML_PARSER_EXPORT DebuggerStatement: public Statement
diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h
index 140a757e51..89245f4884 100644
--- a/src/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/parser/qqmljsastfwd_p.h
@@ -91,12 +91,13 @@ class TrueLiteral;
class FalseLiteral;
class NumericLiteral;
class StringLiteral;
+class TemplateLiteral;
class RegExpLiteral;
class ArrayLiteral;
class ObjectLiteral;
class ElementList;
class Elision;
-class PropertyAssignmentList;
+class PropertyDefinitionList;
class PropertyGetterSetter;
class PropertyNameAndValue;
class PropertyName;
@@ -105,6 +106,7 @@ class StringLiteralPropertyName;
class NumericLiteralPropertyName;
class ArrayMemberExpression;
class FieldMemberExpression;
+class TaggedTemplate;
class NewMemberExpression;
class NewExpression;
class CallExpression;
@@ -154,14 +156,17 @@ class Finally;
class FunctionDeclaration;
class FunctionExpression;
class FormalParameterList;
-class FunctionBody;
class Program;
-class SourceElements;
-class SourceElement;
-class FunctionSourceElement;
-class StatementSourceElement;
class DebuggerStatement;
class NestedExpression;
+class BindingPattern;
+class ArrayBindingPattern;
+class ObjectBindingPattern;
+class BindingElement;
+class BindingElementList;
+class BindingPropertyList;
+class BindingElement;
+class BindingRestElement;
// ui elements
class UiProgram;
diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h
index 13218f0e98..1c11ee9c02 100644
--- a/src/qml/parser/qqmljsastvisitor_p.h
+++ b/src/qml/parser/qqmljsastvisitor_p.h
@@ -125,6 +125,9 @@ public:
virtual bool visit(StringLiteral *) { return true; }
virtual void endVisit(StringLiteral *) {}
+ virtual bool visit(TemplateLiteral *) { return true; }
+ virtual void endVisit(TemplateLiteral *) {}
+
virtual bool visit(NumericLiteral *) { return true; }
virtual void endVisit(NumericLiteral *) {}
@@ -143,8 +146,8 @@ public:
virtual bool visit(Elision *) { return true; }
virtual void endVisit(Elision *) {}
- virtual bool visit(PropertyAssignmentList *) { return true; }
- virtual void endVisit(PropertyAssignmentList *) {}
+ virtual bool visit(PropertyDefinitionList *) { return true; }
+ virtual void endVisit(PropertyDefinitionList *) {}
virtual bool visit(PropertyNameAndValue *) { return true; }
virtual void endVisit(PropertyNameAndValue *) {}
@@ -170,6 +173,9 @@ public:
virtual bool visit(FieldMemberExpression *) { return true; }
virtual void endVisit(FieldMemberExpression *) {}
+ virtual bool visit(TaggedTemplate *) { return true; }
+ virtual void endVisit(TaggedTemplate *) {}
+
virtual bool visit(NewMemberExpression *) { return true; }
virtual void endVisit(NewMemberExpression *) {}
@@ -314,23 +320,29 @@ public:
virtual bool visit(FunctionExpression *) { return true; }
virtual void endVisit(FunctionExpression *) {}
- virtual bool visit(FormalParameterList *) { return true; }
- virtual void endVisit(FormalParameterList *) {}
+ virtual bool visit(ObjectBindingPattern *) { return true; }
+ virtual void endVisit(ObjectBindingPattern *) {}
- virtual bool visit(FunctionBody *) { return true; }
- virtual void endVisit(FunctionBody *) {}
+ virtual bool visit(ArrayBindingPattern *) { return true; }
+ virtual void endVisit(ArrayBindingPattern *) {}
- virtual bool visit(Program *) { return true; }
- virtual void endVisit(Program *) {}
+ virtual bool visit(BindingElement *) { return true; }
+ virtual void endVisit(BindingElement *) {}
- virtual bool visit(SourceElements *) { return true; }
- virtual void endVisit(SourceElements *) {}
+ virtual bool visit(BindingElementList *) { return true; }
+ virtual void endVisit(BindingElementList *) {}
- virtual bool visit(FunctionSourceElement *) { return true; }
- virtual void endVisit(FunctionSourceElement *) {}
+ virtual bool visit(BindingPropertyList *) { return true; }
+ virtual void endVisit(BindingPropertyList *) {}
- virtual bool visit(StatementSourceElement *) { return true; }
- virtual void endVisit(StatementSourceElement *) {}
+ virtual bool visit(BindingRestElement *) { return true; }
+ virtual void endVisit(BindingRestElement *) {}
+
+ virtual bool visit(FormalParameterList *) { return true; }
+ virtual void endVisit(FormalParameterList *) {}
+
+ virtual bool visit(Program *) { return true; }
+ virtual void endVisit(Program *) {}
virtual bool visit(DebuggerStatement *) { return true; }
virtual void endVisit(DebuggerStatement *) {}
diff --git a/src/qml/parser/qqmljsengine_p.cpp b/src/qml/parser/qqmljsengine_p.cpp
index b4f0debf85..97ce6ebea3 100644
--- a/src/qml/parser/qqmljsengine_p.cpp
+++ b/src/qml/parser/qqmljsengine_p.cpp
@@ -112,13 +112,6 @@ double integerFromString(const char *buf, int size, int radix)
return result;
}
-double integerFromString(const QString &str, int radix)
-{
- QByteArray ba = QStringRef(&str).trimmed().toLatin1();
- return integerFromString(ba.constData(), ba.size(), radix);
-}
-
-
Engine::Engine()
: _lexer(nullptr), _directives(nullptr)
{ }
diff --git a/src/qml/parser/qqmljsengine_p.h b/src/qml/parser/qqmljsengine_p.h
index af26bac0ff..1de907d296 100644
--- a/src/qml/parser/qqmljsengine_p.h
+++ b/src/qml/parser/qqmljsengine_p.h
@@ -63,9 +63,35 @@ QT_QML_BEGIN_NAMESPACE
namespace QQmlJS {
class Lexer;
-class Directives;
class MemoryPool;
+class QML_PARSER_EXPORT Directives {
+public:
+ virtual ~Directives() {}
+
+ virtual void pragmaLibrary()
+ {
+ }
+
+ virtual void importFile(const QString &jsfile, const QString &module, int line, int column)
+ {
+ Q_UNUSED(jsfile);
+ Q_UNUSED(module);
+ Q_UNUSED(line);
+ Q_UNUSED(column);
+ }
+
+ virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column)
+ {
+ Q_UNUSED(uri);
+ Q_UNUSED(version);
+ Q_UNUSED(module);
+ Q_UNUSED(line);
+ Q_UNUSED(column);
+ }
+};
+
+
class QML_PARSER_EXPORT DiagnosticMessage
{
public:
diff --git a/src/qml/parser/qqmljsgrammar.cpp b/src/qml/parser/qqmljsgrammar.cpp
deleted file mode 100644
index 2aaeb385e3..0000000000
--- a/src/qml/parser/qqmljsgrammar.cpp
+++ /dev/null
@@ -1,1167 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// This file was generated by qlalr - DO NOT EDIT!
-#include "qqmljsgrammar_p.h"
-
-QT_BEGIN_NAMESPACE
-
-const char *const QQmlJSGrammar::spell [] = {
- "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ",", "continue",
- "default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===",
- "finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier",
- "if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=",
- "-", "-=", "--", "new", "!", "!=", "!==", "numeric literal", "|", "|=",
- "||", "+", "+=", "++", "?", "}", "]", "%", "%=", "return",
- ")", ";", nullptr, "*", "*=", "string literal", "property", "signal", "readonly", "switch",
- "this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^",
- "^=", "null", "true", "false", "const", "let", "debugger", "reserved word", "multiline string literal", "comment",
- nullptr, "enum", "public", "import", "pragma", "as", "on", "get", "set", nullptr,
- nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
-};
-
-const short QQmlJSGrammar::lhs [] = {
- 108, 108, 108, 108, 108, 108, 109, 115, 115, 118,
- 118, 118, 118, 121, 123, 119, 119, 120, 120, 120,
- 120, 120, 120, 120, 120, 124, 125, 117, 116, 128,
- 128, 129, 129, 130, 130, 127, 113, 113, 113, 113,
- 132, 132, 132, 132, 132, 132, 132, 113, 140, 140,
- 140, 140, 141, 141, 142, 142, 113, 113, 113, 113,
- 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
- 113, 113, 113, 113, 113, 113, 113, 145, 145, 145,
- 145, 126, 126, 126, 126, 126, 126, 126, 146, 146,
- 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
- 146, 146, 146, 146, 146, 146, 131, 148, 148, 148,
- 148, 147, 147, 152, 152, 152, 150, 150, 153, 153,
- 153, 153, 156, 156, 156, 156, 156, 156, 156, 156,
- 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
- 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
- 156, 156, 156, 156, 156, 157, 157, 122, 122, 122,
- 122, 122, 160, 160, 161, 161, 161, 161, 159, 159,
- 162, 162, 163, 163, 164, 164, 164, 165, 165, 165,
- 165, 165, 165, 165, 165, 165, 165, 166, 166, 166,
- 166, 167, 167, 167, 168, 168, 168, 168, 169, 169,
- 169, 169, 169, 169, 169, 170, 170, 170, 170, 170,
- 170, 171, 171, 171, 171, 171, 172, 172, 172, 172,
- 172, 173, 173, 174, 174, 175, 175, 176, 176, 177,
- 177, 178, 178, 179, 179, 180, 180, 181, 181, 182,
- 182, 183, 183, 184, 184, 151, 151, 185, 185, 186,
- 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
- 186, 111, 111, 187, 187, 188, 188, 189, 189, 110,
- 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
- 110, 110, 110, 110, 133, 198, 198, 197, 197, 144,
- 144, 199, 199, 199, 200, 200, 202, 202, 201, 203,
- 206, 204, 204, 207, 205, 205, 134, 135, 135, 136,
- 136, 190, 190, 190, 190, 190, 190, 190, 190, 191,
- 191, 191, 191, 192, 192, 192, 192, 193, 193, 137,
- 138, 208, 208, 211, 211, 209, 209, 212, 210, 194,
- 195, 195, 139, 139, 139, 213, 214, 196, 196, 215,
- 143, 158, 158, 216, 216, 155, 155, 154, 154, 217,
- 114, 114, 218, 218, 112, 112, 149, 149, 219
-};
-
-const short QQmlJSGrammar::rhs [] = {
- 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
- 1, 2, 2, 1, 1, 2, 2, 2, 2, 3,
- 3, 5, 5, 4, 4, 2, 2, 0, 1, 1,
- 2, 1, 3, 2, 3, 2, 1, 5, 4, 4,
- 1, 1, 1, 1, 1, 1, 1, 3, 1, 1,
- 1, 3, 0, 1, 2, 4, 6, 6, 3, 3,
- 7, 7, 4, 4, 5, 5, 8, 8, 5, 6,
- 6, 10, 6, 7, 1, 1, 5, 1, 3, 3,
- 5, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 3, 4, 5, 3, 4, 3, 1, 1, 2, 3,
- 4, 1, 2, 3, 7, 8, 1, 3, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
- 3, 5, 1, 2, 4, 4, 4, 3, 0, 1,
- 1, 3, 1, 1, 1, 2, 2, 1, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 1, 3, 3,
- 3, 1, 3, 3, 1, 3, 3, 3, 1, 3,
- 3, 3, 3, 3, 3, 1, 3, 3, 3, 3,
- 3, 1, 3, 3, 3, 3, 1, 3, 3, 3,
- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
- 3, 1, 5, 1, 5, 1, 3, 1, 3, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 3, 0, 1, 1, 3, 0, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 3, 1, 2, 0, 1, 3,
- 3, 1, 1, 1, 1, 3, 1, 3, 2, 2,
- 2, 0, 1, 2, 0, 1, 1, 2, 2, 7,
- 5, 7, 7, 7, 5, 9, 10, 7, 8, 2,
- 2, 3, 3, 2, 2, 3, 3, 3, 3, 5,
- 5, 3, 5, 1, 2, 0, 1, 4, 3, 3,
- 3, 3, 3, 3, 4, 5, 2, 2, 2, 1,
- 8, 8, 7, 1, 3, 0, 1, 0, 1, 1,
- 1, 1, 1, 2, 1, 1, 0, 1, 2
-};
-
-const short QQmlJSGrammar::action_default [] = {
- 0, 0, 28, 0, 0, 0, 28, 0, 195, 262,
- 226, 234, 230, 174, 246, 222, 3, 159, 90, 175,
- 238, 242, 163, 192, 173, 178, 158, 212, 199, 0,
- 97, 98, 93, 0, 87, 82, 367, 0, 0, 0,
- 0, 95, 0, 0, 91, 94, 86, 0, 0, 83,
- 85, 88, 84, 96, 89, 0, 92, 0, 0, 188,
- 0, 0, 175, 194, 177, 176, 0, 0, 0, 190,
- 191, 189, 193, 0, 223, 0, 0, 0, 0, 213,
- 0, 0, 0, 0, 0, 0, 203, 0, 0, 0,
- 197, 198, 196, 201, 205, 204, 202, 200, 215, 214,
- 216, 0, 231, 0, 227, 0, 0, 169, 156, 168,
- 157, 123, 124, 125, 151, 126, 153, 127, 128, 129,
- 130, 131, 132, 133, 134, 135, 136, 137, 138, 152,
- 139, 140, 154, 141, 142, 143, 144, 145, 146, 147,
- 148, 149, 150, 155, 0, 0, 167, 263, 170, 0,
- 171, 0, 172, 166, 0, 259, 252, 250, 257, 258,
- 256, 255, 261, 254, 253, 251, 260, 247, 0, 235,
- 0, 0, 239, 0, 0, 243, 0, 0, 169, 161,
- 0, 160, 0, 165, 179, 0, 356, 356, 357, 0,
- 354, 0, 355, 0, 358, 270, 277, 276, 284, 272,
- 0, 273, 0, 359, 0, 366, 274, 275, 90, 280,
- 278, 363, 360, 365, 281, 0, 293, 0, 0, 0,
- 0, 350, 0, 367, 292, 264, 307, 0, 0, 0,
- 294, 0, 0, 282, 283, 0, 271, 279, 308, 309,
- 0, 356, 0, 0, 358, 0, 351, 352, 0, 340,
- 364, 0, 324, 325, 326, 327, 0, 320, 321, 322,
- 323, 348, 349, 0, 0, 0, 0, 0, 312, 313,
- 314, 268, 266, 228, 236, 232, 248, 224, 269, 0,
- 175, 240, 244, 217, 206, 0, 0, 225, 0, 0,
- 0, 0, 218, 0, 0, 0, 0, 0, 210, 208,
- 211, 209, 207, 220, 219, 221, 0, 233, 0, 229,
- 0, 267, 175, 0, 249, 264, 265, 0, 264, 0,
- 0, 316, 0, 0, 0, 318, 0, 237, 0, 0,
- 241, 0, 0, 245, 305, 0, 297, 306, 300, 0,
- 304, 0, 264, 298, 0, 264, 0, 0, 317, 0,
- 0, 0, 319, 0, 0, 0, 311, 0, 310, 90,
- 117, 368, 0, 0, 122, 286, 289, 0, 123, 293,
- 126, 153, 128, 129, 93, 134, 135, 87, 136, 292,
- 139, 91, 94, 264, 88, 96, 142, 89, 144, 92,
- 146, 147, 294, 149, 150, 155, 0, 119, 118, 121,
- 105, 120, 104, 0, 114, 287, 285, 0, 0, 0,
- 358, 0, 115, 163, 164, 169, 0, 162, 0, 328,
- 329, 0, 356, 0, 0, 358, 0, 116, 0, 0,
- 0, 331, 336, 334, 337, 0, 0, 335, 336, 0,
- 332, 0, 333, 288, 339, 0, 288, 338, 0, 341,
- 342, 0, 288, 343, 344, 0, 0, 345, 0, 0,
- 0, 346, 347, 181, 180, 0, 0, 0, 315, 0,
- 0, 0, 330, 302, 295, 0, 303, 299, 0, 301,
- 290, 0, 291, 296, 0, 0, 358, 0, 353, 108,
- 0, 0, 112, 99, 0, 101, 110, 0, 102, 111,
- 113, 103, 109, 100, 0, 106, 185, 183, 187, 184,
- 182, 186, 361, 6, 362, 4, 2, 75, 107, 0,
- 0, 0, 83, 85, 84, 37, 5, 0, 76, 0,
- 51, 50, 49, 0, 0, 51, 0, 0, 0, 52,
- 0, 67, 68, 0, 65, 0, 66, 41, 42, 43,
- 44, 46, 47, 71, 45, 0, 0, 0, 78, 0,
- 77, 80, 0, 81, 0, 79, 0, 51, 0, 0,
- 0, 0, 0, 61, 0, 62, 0, 0, 32, 0,
- 0, 72, 33, 0, 36, 34, 30, 0, 35, 31,
- 0, 63, 0, 64, 163, 0, 69, 73, 0, 0,
- 0, 0, 163, 288, 0, 70, 90, 123, 293, 126,
- 153, 128, 129, 93, 134, 135, 136, 292, 139, 91,
- 94, 264, 96, 142, 89, 144, 92, 146, 147, 294,
- 149, 150, 155, 74, 0, 59, 53, 60, 54, 0,
- 0, 0, 0, 56, 0, 57, 58, 55, 0, 0,
- 0, 0, 48, 0, 38, 39, 0, 40, 8, 0,
- 0, 9, 0, 11, 0, 10, 0, 1, 27, 15,
- 14, 26, 13, 12, 29, 7, 0, 18, 0, 19,
- 0, 24, 25, 0, 20, 21, 0, 22, 23, 16,
- 17, 369
-};
-
-const short QQmlJSGrammar::goto_default [] = {
- 7, 667, 213, 200, 211, 526, 513, 662, 675, 512,
- 661, 665, 663, 671, 22, 668, 666, 664, 18, 525,
- 587, 577, 584, 579, 553, 195, 199, 201, 206, 237,
- 214, 234, 568, 639, 638, 205, 236, 557, 26, 491,
- 490, 362, 361, 9, 360, 363, 204, 484, 364, 109,
- 17, 149, 24, 13, 148, 19, 25, 59, 23, 8,
- 28, 27, 283, 15, 277, 10, 273, 12, 275, 11,
- 274, 20, 281, 21, 282, 14, 276, 272, 313, 418,
- 278, 279, 207, 197, 196, 210, 209, 233, 198, 367,
- 366, 235, 475, 474, 335, 336, 477, 338, 476, 337,
- 431, 435, 438, 434, 433, 453, 454, 202, 188, 203,
- 212, 0
-};
-
-const short QQmlJSGrammar::action_index [] = {
- 350, 1528, 3041, 3041, 2937, 1235, 115, 105, 239, -108,
- 102, 93, 95, 205, -108, 422, 110, -108, -108, 727,
- 92, 118, 265, 256, -108, -108, -108, 507, 247, 1528,
- -108, -108, -108, 665, -108, -108, 2729, 1826, 1528, 1528,
- 1528, -108, 1041, 1528, -108, -108, -108, 1528, 1528, -108,
- -108, -108, -108, -108, -108, 1528, -108, 1528, 1528, -108,
- 1528, 1528, 174, 221, -108, -108, 1528, 1528, 1528, -108,
- -108, -108, 177, 1528, 422, 1528, 1528, 1528, 1528, 411,
- 1528, 1528, 1528, 1528, 1528, 1528, 211, 1528, 1528, 1528,
- 142, 148, 154, 217, 223, 226, 227, 231, 507, 385,
- 395, 1528, 57, 1528, 83, 2521, 1528, 1528, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, 179, 1528, -108, -108, 77, 36,
- -108, 1528, -108, -108, 1528, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, -108, -108, -108, 1528, 56,
- 1528, 1528, 80, 74, 1528, -108, 2521, 1528, 1528, -108,
- 125, -108, 55, -108, -108, 53, 410, 418, 72, 52,
- -108, 392, -108, 46, 3041, -108, -108, -108, -108, -108,
- 273, -108, 396, -108, 44, -108, -108, -108, 76, -108,
- -108, -108, 3041, -108, -108, 744, -108, 589, 98, 2937,
- 91, 90, 88, 3249, -108, 1528, -108, 86, 1528, 81,
- -108, 75, 73, -108, -108, 586, -108, -108, -108, -108,
- 71, 491, 69, 65, 3041, 64, -108, -108, 2937, -108,
- -108, 139, -108, -108, -108, -108, 134, -108, -108, -108,
- -108, -108, -108, 63, 66, 1528, 147, 264, -108, -108,
- -108, 1726, -108, 87, 68, 70, -108, 334, 82, 78,
- 796, 89, 121, 349, 318, 469, 1528, 330, 1528, 1528,
- 1528, 1528, 359, 1528, 1528, 1528, 1528, 1528, 284, 289,
- 303, 306, 313, 365, 369, 375, 1528, 58, 1528, 85,
- 1528, -108, 849, 1528, -108, 1528, 79, 59, 1528, 61,
- 2937, -108, 1528, 146, 2937, -108, 1528, 62, 1528, 1528,
- 106, 99, 1528, -108, 96, 176, 171, -108, -108, 1528,
- -108, 407, 1528, -108, 97, 1528, -52, 2937, -108, 1528,
- 120, 2937, -108, 1528, 123, 2937, 101, 2937, -108, 116,
- -108, 84, 45, 0, -108, -108, 2937, -39, 641, -3,
- 652, 156, 1528, 2937, -7, -11, 567, 2625, -21, 5,
- 945, 2, 94, 1629, 2625, -1, -26, 6, 1528, 10,
- -15, 1528, 14, 1528, -25, -12, 2833, -108, -108, -108,
- -108, -108, -108, 1528, -108, -108, -108, -14, -58, -13,
- 3041, -36, -108, 287, -108, 1528, -46, -108, 153, -108,
- -108, -31, 586, -57, -32, 3041, 11, -108, 1528, 168,
- 29, -108, 47, -108, 48, 169, 1528, -108, 49, 50,
- -108, 9, -108, 2937, -108, 136, 2937, -108, 275, -108,
- -108, 126, 2937, 35, -108, 33, 37, -108, 466, -4,
- 38, -108, -108, -108, -108, 1528, 130, 2937, -108, 1528,
- 117, 2937, -108, 34, -108, 296, -108, -108, 1528, -108,
- -108, 404, -108, -108, 12, 40, 3041, 13, -108, -108,
- 155, 1926, -108, -108, 2026, -108, -108, 2126, -108, -108,
- -108, -108, -108, -108, 144, -108, -108, -108, -108, -108,
- -108, -108, -108, -108, 3041, -108, -108, -108, 132, -27,
- 15, 1137, 218, -23, 17, -108, -108, 196, -108, 242,
- 8, -108, -108, 579, 237, -108, 127, 18, 415, -108,
- 103, -108, -108, 236, -108, 2223, -108, -108, -108, -108,
- -108, -108, -108, -108, -108, 27, 21, 137, 31, 20,
- -108, 23, -5, -108, -9, -108, 332, -10, 571, 201,
- 195, 586, 225, -108, 7, -108, 1137, 165, -108, 4,
- 1137, -108, -108, 1333, -108, -108, -108, 1431, -108, -108,
- 184, -108, 2223, -108, 331, 3, -108, -108, 202, 531,
- 26, 2417, 327, 3145, 1, -108, 25, 629, 24, 649,
- 124, 1528, 2937, 22, -6, 514, -8, 19, 1041, 16,
- 94, 1629, 28, 42, 67, 1528, 60, 43, 1528, 54,
- 1528, 41, 39, -108, 234, -108, 228, -108, 51, -2,
- 564, 233, 575, -108, 100, -108, -108, -108, 2320, 1137,
- 1826, 32, -108, 122, -108, -108, 30, -108, -108, 1137,
- 1137, 104, 903, -108, 308, -108, 108, -108, -108, 133,
- 119, -108, -108, -108, -108, -108, 451, -108, 164, -108,
- 161, -108, -108, 458, -108, -108, 151, -108, -108, -108,
- -108, -108,
-
- -112, 18, 86, 97, 69, 316, 7, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -64,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, 66,
- -112, -112, -112, -17, -112, -112, -10, -36, 3, 90,
- 95, -112, 149, 74, -112, -112, -112, 67, 13, -112,
- -112, -112, -112, -112, -112, 178, -112, 181, 185, -112,
- 189, 190, -112, -112, -112, -112, 198, 208, 212, -112,
- -112, -112, -112, 209, -112, 201, 164, 111, 113, -112,
- 116, 130, 131, 132, 134, 142, -112, 118, 124, 144,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, 154, -112, 155, -112, 268, 28, -8, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, 42, -112, -112, -112, -112,
- -112, 47, -112, -112, 50, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, 159, -112,
- 158, 56, -112, -112, 57, -112, 362, 60, 157, -112,
- -112, -112, -112, -112, -112, -112, 20, 151, -112, -112,
- -112, 25, -112, -112, 30, -112, -112, -112, -112, -112,
- -112, -112, 31, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, 233, -112, -112, 34, -112, 35, -112, 225,
- -112, 36, -112, 216, -112, 55, -112, -112, 53, 39,
- -112, -112, -112, -112, -112, 19, -112, -112, -112, -112,
- -112, 94, -112, -112, 92, -112, -112, -112, 117, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, 33, -112, -112, -112, -112,
- -112, 88, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, 51, 220, -112, 227, 235,
- 236, 244, -112, 21, 17, 102, 91, 89, -112, -112,
- -112, -112, -112, -112, -112, -112, 211, -112, 247, -112,
- 257, -112, -112, 264, -112, 75, -112, -112, 103, -112,
- 112, -112, 29, -112, 73, -112, 263, -112, 255, 254,
- -112, -112, 245, -112, -112, -112, -112, -112, -112, 248,
- -112, 65, 105, -112, -112, 99, -112, 162, -112, 37,
- -112, 115, -112, 44, -112, 135, -112, 137, -112, -112,
- -112, -112, -112, -112, -112, -112, 138, -112, 24, -112,
- 26, -112, 104, 140, -112, -112, 32, 64, -112, -112,
- 174, -112, -112, 48, 87, -112, -112, -112, 54, -112,
- 40, 71, -112, 150, -112, -112, 197, -112, -112, -112,
- -112, -112, -112, 12, -112, -112, -112, -112, -112, -112,
- 206, -112, -112, -112, -112, 207, -112, -112, -112, -112,
- -112, -112, 231, -112, -112, 239, -112, -112, 43, -112,
- -112, -112, -112, -112, -59, -112, 38, -112, -62, -112,
- -112, -112, -112, 258, -112, -112, 259, -112, -112, -112,
- -112, -112, 163, -72, -112, -112, 41, -112, 62, -112,
- 61, -112, -112, -112, -112, 59, -112, 193, -112, 58,
- -112, 204, -112, -112, -112, -112, -112, -112, 52, -112,
- -112, 175, -112, -112, -112, -112, 186, -112, -112, -112,
- -112, 49, -112, -112, 173, -112, -112, 45, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, 213, -112, -112, -112, -112, -112,
- -112, 46, -112, -112, -112, -112, -112, -112, -112, 27,
- -112, -112, -112, -18, -9, -112, -112, -112, 15, -112,
- -112, -112, -112, -112, -112, 331, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -112, -112, 11, -6,
- -112, 10, -112, -112, -112, -112, 156, -112, -112, -112,
- 240, -112, -112, 330, -112, -112, -112, 332, -112, -112,
- -112, -112, 376, -112, -112, 8, -112, -112, -7, 76,
- -112, 358, -112, 228, 5, -112, -112, 6, -112, 4,
- -112, 79, 221, -112, -112, 2, -112, -112, 174, -112,
- -112, 16, -112, -112, -112, 14, -112, -16, 70, -112,
- 63, -112, -112, -112, -112, -112, -30, -112, -112, -112,
- -15, -28, -13, -112, -112, -112, -112, -112, 460, 93,
- 307, -12, -112, -112, -112, -112, -11, -112, -112, -2,
- -1, 85, 84, -112, -112, -112, -112, -112, -112, -112,
- -112, -112, -112, -112, -112, -112, -3, -112, -112, -112,
- -112, -112, -112, 0, -112, -112, -112, -112, -112, -112,
- -112, -112
-};
-
-const short QQmlJSGrammar::action_info [] = {
- -132, 425, 409, 424, -151, 422, -120, 403, 347, -140,
- 428, 465, -152, -143, 417, 353, 406, -145, 452, 412,
- 410, -148, 408, -140, 469, 271, -152, 569, 353, -132,
- 271, -151, 248, 601, 583, -120, 583, 583, 565, 529,
- 562, 576, 563, 598, 555, 534, 634, 539, 564, 561,
- 558, 478, 436, 436, 436, 456, 460, 443, 644, 641,
- 556, -148, 432, 583, 442, 583, 427, -145, 488, 458,
- 452, 452, 485, 486, -143, 469, 452, 465, 428, 194,
- 191, 174, 168, 248, 73, 151, 286, 145, 286, 187,
- 310, 326, 396, 0, 168, 0, 153, 0, 244, 247,
- 402, -121, 265, 73, 101, 691, 332, 241, 326, 469,
- 306, 465, 193, 339, 452, 183, 306, 357, 145, 246,
- 318, 320, 428, 248, 353, 145, 186, 271, 145, 243,
- 580, 145, 455, 145, 176, 0, 103, 308, 145, 315,
- 264, 101, 537, 446, 145, 559, 456, 176, 176, 308,
- 0, 538, 145, 177, 145, 145, 0, 0, 345, 262,
- 261, 646, 645, 494, 542, 541, 177, 177, 170, 690,
- 689, 328, 171, 580, 103, 329, 145, 471, 654, 439,
- 351, 181, 60, 355, 341, 262, 261, 145, 60, 66,
- 467, 592, 560, 61, 60, 260, 259, 659, 660, 61,
- 255, 254, 349, 648, 505, 61, 324, 267, 659, 660,
- 537, 495, 688, 687, 420, 419, 64, 262, 261, 571,
- 105, 581, 682, 681, 440, 685, 684, 65, 430, 583,
- 535, 535, 574, 66, 67, 146, 87, 342, 88, 106,
- 68, 107, 87, 545, 88, 593, 591, 567, 87, 89,
- 88, 87, 87, 88, 88, 89, 87, 535, 88, 683,
- 0, 89, 535, 0, 89, 89, 535, 0, 66, 89,
- 636, 530, 87, 0, 88, 0, 532, 532, 67, 60,
- 176, 145, 0, 145, 68, 89, 575, 573, 531, 531,
- 61, 0, 649, 532, 0, 637, 635, 546, 544, 177,
- 0, 178, 176, 532, 481, 531, 0, 0, 532, 87,
- 0, 88, 532, 67, 87, 531, 88, 532, 0, 68,
- 531, 177, 89, 415, 531, 270, 268, 89, 87, 531,
- 88, 87, 0, 88, 239, 238, 450, 449, 87, 0,
- 88, 89, 176, 87, 89, 88, 176, 176, 288, 289,
- 0, 89, 288, 289, 269, 678, 89, 482, 480, 0,
- -107, 177, 0, 178, -107, 177, 177, 178, 415, 679,
- 677, 0, 293, 294, 0, 290, 291, 0, 0, 290,
- 291, 295, 293, 294, 296, 0, 297, 0, 293, 294,
- 0, 295, 293, 294, 296, 0, 297, 295, 293, 294,
- 296, 295, 297, 676, 296, 0, 297, 295, 80, 81,
- 296, 0, 297, 0, 0, 0, 82, 83, 80, 81,
- 84, 35, 85, 0, 0, 35, 82, 83, 0, 0,
- 84, 0, 85, 35, 80, 81, 35, 0, 0, 35,
- 75, 76, 82, 83, 35, 0, 84, 35, 85, 0,
- 6, 5, 4, 1, 3, 2, 0, 0, 49, 52,
- 50, 0, 49, 52, 50, 0, 0, 77, 78, 0,
- 49, 52, 50, 49, 52, 50, 49, 52, 50, 0,
- 35, 49, 52, 50, 49, 52, 50, 35, 46, 34,
- 51, 0, 46, 34, 51, 35, 0, 0, 35, 0,
- 46, 34, 51, 46, 34, 51, 46, 34, 51, 0,
- 0, 46, 34, 51, 46, 34, 51, 49, 52, 50,
- 35, 0, 0, 0, 49, 52, 50, 0, 0, 0,
- 80, 81, 49, 52, 50, 49, 52, 50, 82, 83,
- 0, 0, 84, 35, 85, 0, 537, 46, 34, 51,
- 186, 0, 0, 0, 46, 34, 51, 49, 52, 50,
- 35, 0, 46, 34, 51, 46, 34, 51, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 537,
- 49, 52, 50, 0, 0, 0, 537, 46, 34, 51,
- 537, 0, 0, 35, 537, 0, 35, 49, 52, 50,
- 35, 0, 0, 186, 35, 0, 0, 0, 35, 0,
- 46, 34, 51, 0, 0, 35, 0, 0, 35, 0,
- 0, 0, 0, 0, 0, 0, 0, 46, 34, 51,
- 49, 52, 50, 49, 52, 50, 0, 49, 52, 50,
- 0, 49, 52, 50, 0, 49, 52, 50, 0, 0,
- 258, 257, 49, 52, 50, 49, 52, 50, 35, 0,
- 46, 34, 51, 46, 34, 51, 0, 46, 34, 51,
- 35, 46, 34, 51, 0, 46, 34, 51, 35, 0,
- 0, 35, 46, 34, 51, 46, 34, 51, 0, 0,
- 253, 252, 0, 0, 35, 49, 52, 50, 0, 0,
- 0, 186, 253, 252, 0, 0, 0, 49, 52, 50,
- 258, 257, 0, 258, 257, 49, 52, 50, 49, 52,
- 50, 0, 0, 0, 0, 46, 34, 51, 0, 0,
- 155, 49, 52, 50, 0, 0, 0, 46, 34, 51,
- 156, 0, 0, 0, 157, 46, 34, 51, 46, 34,
- 51, 0, 0, 158, 0, 159, 0, 0, 0, 0,
- 0, 46, 34, 51, 0, 0, 160, 0, 161, 64,
- 0, 0, 0, 35, 0, 0, 162, 0, 0, 163,
- 65, 0, 0, 0, 0, 164, 0, 0, 0, 0,
- 0, 165, 0, 0, 0, 0, 0, 0, 0, 155,
- 0, 0, 0, 0, 0, 253, 252, 166, 0, 156,
- 49, 52, 50, 157, 0, 0, 0, 0, 0, 0,
- 0, 0, 158, 0, 159, 0, 0, 322, 0, 0,
- 0, 0, 0, 0, 0, 160, 0, 161, 64, 0,
- 46, 34, 51, 0, 0, 162, 0, 0, 163, 65,
- 0, 0, 155, 0, 164, 0, 0, 0, 0, 0,
- 165, 0, 156, 0, 0, 0, 157, 0, 0, 0,
- 0, 0, 0, 0, 0, 158, 166, 159, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 160, 0,
- 161, 64, 0, 0, 0, 0, 0, 0, 162, 0,
- 0, 163, 65, 0, 0, 0, 0, 164, 0, 0,
- 0, 0, 0, 165, 0, 30, 31, 0, 0, 0,
- 0, 0, 0, 0, 0, 33, 0, 0, 0, 166,
- 0, 0, 35, 0, 0, 0, 36, 37, 0, 38,
- 0, 0, 0, 0, 0, 0, 521, 0, 0, 0,
- 45, 0, 0, 0, 0, 0, 0, 30, 31, 0,
- 0, 0, 0, 0, 0, 0, 0, 33, 53, 49,
- 52, 50, 0, 54, 35, 0, 0, 0, 36, 37,
- 0, 38, 0, 0, 44, 56, 32, 0, 42, 0,
- 0, 41, 45, 0, 0, 0, 0, 0, 0, 46,
- 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
- 53, 49, 52, 50, 0, 54, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 44, 56, 32, 0,
- 0, 0, 0, 41, 0, 0, 0, 0, 0, 0,
- 0, 46, 34, 51, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 30, 31, 0, 0, 0, 0, 0,
- 0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
- 35, 0, 0, 0, 36, 37, 0, 38, 0, 0,
- 0, 0, 0, 0, 42, 0, 0, 0, 45, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 53, 49, 52, 50,
- 0, 54, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 44, 56, 32, 0, 0, 0, 0, 41,
- 0, 0, 0, 0, 0, 0, 0, 46, 34, 51,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,
- 31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
- 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,
- 36, 37, 0, 38, 0, 0, 0, 0, 0, 0,
- 521, 0, 0, 0, 45, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 53, 49, 52, 50, 0, 54, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 44, 56,
- 32, 0, 0, 0, 0, 41, 0, 0, 0, 0,
- 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 519, 0, 30, 31, 0,
- 0, 0, 0, 0, 0, 0, 0, 221, 0, 0,
- 0, 0, 0, 0, 35, 0, 0, 0, 36, 37,
- 0, 38, 0, 0, 0, 0, 0, 0, 521, 0,
- 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 53, 522, 524, 523, 0, 54, 0, 0, 0, 0,
- 230, 0, 0, 0, 0, 0, 44, 56, 32, 216,
- 224, 0, 0, 41, 0, 0, 520, 0, 0, 0,
- 0, 46, 34, 51, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 519, 0, 30, 31, 0, 0, 0,
- 0, 0, 0, 0, 0, 221, 0, 0, 0, 0,
- 0, 0, 35, 0, 0, 0, 36, 37, 0, 38,
- 0, 0, 0, 0, 0, 0, 521, 0, 0, 0,
- 45, 0, 0, 0, 0, 0, 0, 0, 585, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 53, 522,
- 524, 523, 0, 54, 0, 0, 0, 0, 230, 0,
- 0, 0, 0, 0, 44, 56, 32, 216, 224, 0,
- 0, 41, 0, 0, 520, 0, 0, 0, 0, 46,
- 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 519, 0, 30, 31, 0, 0, 0, 0, 0,
- 0, 0, 0, 221, 0, 0, 0, 0, 0, 0,
- 35, 0, 0, 0, 36, 37, 0, 38, 0, 0,
- 0, 0, 0, 0, 521, 0, 0, 0, 45, 0,
- 0, 0, 0, 0, 0, 0, 588, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 53, 522, 524, 523,
- 0, 54, 0, 0, 0, 0, 230, 0, 0, 0,
- 0, 0, 44, 56, 32, 216, 224, 0, 0, 41,
- 0, 0, 520, 0, 0, 0, 0, 46, 34, 51,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 29,
- 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 33, 0, 0, 0, 0, 0, 0, 35, 0, 0,
- 0, 36, 37, 0, 38, 0, 0, 0, 39, 0,
- 40, 42, 43, 0, 0, 45, 0, 0, 0, 47,
- 0, 48, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 53, 49, 52, 50, 0, 54, 0,
- 55, 0, 57, 0, 58, 0, 0, 0, 0, 44,
- 56, 32, 0, 0, 0, 0, 41, 0, 0, 0,
- 0, 0, 0, 0, 46, 34, 51, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, -141, 0, 0, 0,
- 29, 30, 31, 0, 0, 0, 0, 0, 0, 0,
- 0, 33, 0, 0, 0, 0, 0, 0, 35, 0,
- 0, 0, 36, 37, 0, 38, 0, 0, 0, 39,
- 0, 40, 42, 43, 0, 0, 45, 0, 0, 0,
- 47, 0, 48, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 53, 49, 52, 50, 0, 54,
- 0, 55, 0, 57, 0, 58, 0, 0, 0, 0,
- 44, 56, 32, 0, 0, 0, 0, 41, 0, 0,
- 0, 0, 0, 0, 0, 46, 34, 51, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 29, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
- 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
- 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
- 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
- 57, 285, 58, 0, 0, 0, 0, 44, 56, 32,
- 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 492, 0, 0, 29, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
- 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
- 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
- 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
- 0, 0, 493, 0, 0, 0, 0, 0, 0, 0,
- 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
- 57, 0, 58, 0, 0, 0, 0, 44, 56, 32,
- 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 500, 0, 0, 29, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
- 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
- 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
- 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
- 0, 0, 503, 0, 0, 0, 0, 0, 0, 0,
- 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
- 57, 0, 58, 0, 0, 0, 0, 44, 56, 32,
- 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 492, 0, 0, 29, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
- 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
- 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
- 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
- 0, 0, 498, 0, 0, 0, 0, 0, 0, 0,
- 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
- 57, 0, 58, 0, 0, 0, 0, 44, 56, 32,
- 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 500, 0, 0, 29, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
- 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
- 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
- 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
- 0, 0, 501, 0, 0, 0, 0, 0, 0, 0,
- 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
- 57, 0, 58, 0, 0, 0, 0, 44, 56, 32,
- 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 29, 30, 31, 0, 0, 0,
- 0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
- 0, 0, 35, 222, 0, 0, 223, 37, 0, 38,
- 0, 0, 0, 39, 0, 40, 42, 43, 0, 0,
- 45, 0, 0, 0, 47, 0, 48, 0, 0, 0,
- 0, 0, 0, 0, 226, 0, 0, 0, 53, 49,
- 52, 50, 227, 54, 0, 55, 229, 57, 0, 58,
- 0, 232, 0, 0, 44, 56, 32, 0, 0, 0,
- 0, 41, 0, 0, 0, 0, 0, 0, 0, 46,
- 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 29, 30, 31, 0, 0, 0, 0, 0, 0,
- 0, 0, 33, 0, 0, 0, 0, 0, 0, 35,
- 222, 0, 0, 603, 650, 0, 38, 0, 0, 0,
- 39, 0, 40, 42, 43, 0, 0, 45, 0, 0,
- 0, 47, 0, 48, 0, 0, 0, 0, 0, 0,
- 0, 226, 0, 0, 0, 53, 49, 52, 50, 227,
- 54, 0, 55, 229, 57, 0, 58, 0, 232, 0,
- 0, 44, 56, 32, 0, 0, 0, 0, 41, 0,
- 0, 0, 0, 0, 0, 0, 46, 34, 51, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 29, 30,
- 31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
- 0, 0, 0, 0, 0, 0, 35, 222, 0, 0,
- 603, 37, 0, 38, 0, 0, 0, 39, 0, 40,
- 42, 43, 0, 0, 45, 0, 0, 0, 47, 0,
- 48, 0, 0, 0, 0, 0, 0, 0, 226, 0,
- 0, 0, 53, 49, 52, 50, 227, 54, 0, 55,
- 229, 57, 0, 58, 0, 232, 0, 0, 44, 56,
- 32, 0, 0, 0, 0, 41, 0, 0, 0, 0,
- 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 111, 112, 113, 0, 0,
- 115, 117, 118, 0, 0, 119, 0, 120, 0, 0,
- 0, 123, 124, 125, 0, 0, 0, 0, 0, 0,
- 35, 126, 127, 128, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 130, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 133, 0, 0, 0, 0, 0, 0, 49, 52, 50,
- 134, 135, 136, 0, 138, 139, 140, 141, 142, 143,
- 0, 0, 131, 137, 122, 114, 129, 116, 132, 0,
- 0, 0, 121, 0, 0, 0, 0, 46, 34, 51,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 111,
- 112, 113, 0, 0, 115, 117, 118, 0, 0, 119,
- 0, 120, 0, 0, 0, 123, 124, 125, 0, 0,
- 0, 0, 0, 0, 35, 126, 127, 128, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 130, 0,
- 0, 0, 399, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 133, 0, 0, 0, 0, 0,
- 401, 49, 52, 50, 134, 135, 136, 0, 138, 139,
- 140, 141, 142, 143, 0, 0, 131, 137, 122, 114,
- 129, 116, 132, 0, 0, 0, 121, 0, 0, 0,
- 0, 46, 34, 51, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 111, 112, 113, 0, 0, 115, 117,
- 118, 0, 0, 119, 0, 120, 0, 0, 0, 123,
- 124, 125, 0, 0, 0, 0, 0, 0, 35, 126,
- 127, 128, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 130, 0, 0, 0, 399, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 133, 0,
- 0, 0, 0, 0, 401, 49, 52, 50, 134, 135,
- 136, 0, 138, 139, 140, 141, 142, 143, 0, 0,
- 131, 137, 122, 114, 129, 116, 132, 0, 0, 0,
- 121, 0, 0, 0, 0, 46, 377, 384, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 111, 112, 113,
- 0, 0, 115, 117, 118, 0, 0, 119, 0, 120,
- 0, 0, 0, 123, 124, 125, 0, 0, 0, 0,
- 0, 0, 35, 126, 127, 128, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 130, 0, 0, 0,
- 399, 0, 0, 0, 0, 0, 0, 0, 400, 0,
- 0, 0, 133, 0, 0, 0, 0, 0, 401, 49,
- 52, 50, 134, 135, 136, 0, 138, 139, 140, 141,
- 142, 143, 0, 0, 131, 137, 122, 114, 129, 116,
- 132, 0, 0, 0, 121, 0, 0, 0, 0, 46,
- 377, 384, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 215, 0, 0, 0, 0, 217, 0, 29, 30,
- 31, 219, 0, 0, 0, 0, 0, 0, 220, 33,
- 0, 0, 0, 0, 0, 0, 35, 222, 0, 0,
- 223, 37, 0, 38, 0, 0, 0, 39, 0, 40,
- 42, 43, 0, 0, 45, 0, 0, 0, 47, 0,
- 48, 0, 0, 0, 0, 0, 225, 0, 226, 0,
- 0, 0, 53, 49, 52, 50, 227, 54, 228, 55,
- 229, 57, 230, 58, 231, 232, 0, 0, 44, 56,
- 32, 216, 224, 218, 0, 41, 0, 0, 0, 0,
- 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 215, 0, 0, 0, 0,
- 217, 0, 29, 30, 31, 219, 0, 0, 0, 0,
- 0, 0, 220, 221, 0, 0, 0, 0, 0, 0,
- 35, 222, 0, 0, 223, 37, 0, 38, 0, 0,
- 0, 39, 0, 40, 42, 43, 0, 0, 45, 0,
- 0, 0, 47, 0, 48, 0, 0, 0, 0, 0,
- 225, 0, 226, 0, 0, 0, 53, 49, 52, 50,
- 227, 54, 228, 55, 229, 57, 230, 58, 231, 232,
- 0, 0, 44, 56, 32, 216, 224, 218, 0, 41,
- 0, 0, 0, 0, 0, 0, 0, 46, 34, 51,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 607,
- 112, 113, 0, 0, 609, 117, 611, 30, 31, 612,
- 0, 120, 0, 0, 0, 123, 614, 615, 0, 0,
- 0, 0, 0, 0, 35, 616, 127, 128, 223, 37,
- 0, 38, 0, 0, 0, 39, 0, 40, 618, 43,
- 0, 0, 620, 0, 0, 0, 47, 0, 48, 0,
- 0, 0, 0, 0, 621, 0, 226, 0, 0, 0,
- 622, 49, 52, 50, 623, 624, 625, 55, 627, 628,
- 629, 630, 631, 632, 0, 0, 619, 626, 613, 608,
- 617, 610, 132, 41, 0, 0, 121, 0, 0, 0,
- 0, 46, 377, 384, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 368, 112, 113, 0, 0, 370, 117,
- 372, 30, 31, 373, 0, 120, 0, 0, 0, 123,
- 375, 376, 0, 0, 0, 0, 0, 0, 35, 378,
- 127, 128, 223, 37, 0, 38, 0, 0, 0, 39,
- 0, 40, 380, 43, 0, 0, 382, 0, 0, 0,
- 47, 0, 48, 0, -288, 0, 0, 0, 383, 0,
- 226, 0, 0, 0, 385, 49, 52, 50, 386, 387,
- 388, 55, 390, 391, 392, 393, 394, 395, 0, 0,
- 381, 389, 374, 369, 379, 371, 132, 41, 0, 0,
- 121, 0, 0, 0, 0, 46, 377, 384, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
-
- 543, 185, 640, 647, 642, 643, 504, 489, 397, 451,
- 655, 657, 669, 670, 154, 680, 658, 448, 686, 316,
- 185, 16, 256, 536, 251, 599, 570, 633, 572, 590,
- 597, 144, 323, 540, 457, 150, 266, 473, 190, 441,
- 350, 445, 251, 192, 256, 437, 429, 354, 208, 240,
- 185, 316, 251, 256, 185, 404, 448, 448, 316, 533,
- 566, 470, 466, 180, 451, 451, 462, 0, 62, 334,
- 510, 516, 62, 0, 0, 325, 62, 299, 316, 0,
- 459, 298, 397, 334, 0, 147, 461, 208, 499, 0,
- 152, 208, 502, 167, 600, 479, 673, 672, 518, 173,
- 175, 515, 316, 674, 208, 397, 316, 518, 316, 407,
- 208, 0, 190, 0, 321, 208, 656, 352, 62, 249,
- 464, 62, 62, 184, 509, 62, 62, 463, 463, 62,
- 208, 508, 421, 208, 62, 208, 184, 356, 245, 358,
- 405, 242, 263, 280, 62, 62, 62, 506, 284, 302,
- 62, 301, 507, 208, 317, 208, 208, 62, 208, 62,
- 343, 184, 300, 413, 348, 365, 62, 0, 62, 190,
- 518, 62, 99, 62, 100, 578, 86, 90, 346, 62,
- 208, 208, 319, 91, 344, 62, 62, 62, 413, 62,
- 93, 94, 95, 473, 96, 468, 514, 62, 189, 62,
- 150, 414, 97, 92, 208, 62, 472, 464, 182, 62,
- 62, 208, 497, 62, 62, 397, 496, 250, 365, 62,
- 104, 102, 208, 263, 208, 98, 414, 263, 169, 172,
- 365, 208, 487, 62, 359, 511, 62, 250, 463, 208,
- 62, 398, 464, 208, 62, 62, 606, 63, 72, 190,
- 150, 208, 411, 62, 518, 69, 62, 208, 416, 582,
- 365, 365, 79, 62, 62, 70, 62, 62, 483, 71,
- 0, 284, 74, 0, 0, 62, 208, 208, 423, 307,
- 284, 0, 62, 0, 287, 426, 108, 284, 0, 292,
- 62, 62, 0, 0, 0, 284, 284, 303, 304, 62,
- 312, 0, 62, 312, 284, 284, 305, 284, 284, 312,
- 62, 0, 312, 309, 284, 284, 110, 284, 62, 312,
- 0, 594, 333, 284, 284, 340, 578, 330, 653, 0,
- 518, 331, 0, 327, 311, 586, 0, 589, 0, 527,
- 0, 314, 0, 0, 518, 0, 518, 444, 447, 0,
- 489, 517, 528, 527, 0, 527, 547, 548, 549, 550,
- 554, 551, 552, 0, 0, 517, 528, 517, 528, 0,
- 0, 0, 602, 0, 0, 0, 0, 0, 0, 0,
- 108, 604, 605, 547, 548, 549, 550, 554, 551, 552,
- 594, 0, 0, 0, 0, 0, 0, 0, 0, 595,
- 596, 547, 548, 549, 550, 554, 551, 552, 0, 0,
- 110, 179, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 602, 0, 0, 0, 0, 0,
- 0, 0, 0, 651, 652, 547, 548, 549, 550, 554,
- 551, 552, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0
-};
-
-const short QQmlJSGrammar::action_check [] = {
- 7, 33, 60, 60, 7, 36, 7, 7, 60, 7,
- 36, 36, 7, 7, 60, 36, 55, 7, 33, 55,
- 33, 7, 36, 7, 36, 36, 7, 37, 36, 7,
- 36, 7, 7, 7, 33, 7, 33, 33, 47, 66,
- 17, 34, 47, 66, 29, 37, 29, 29, 17, 29,
- 29, 17, 5, 5, 5, 20, 60, 7, 60, 8,
- 33, 7, 33, 33, 55, 33, 55, 7, 55, 36,
- 33, 33, 60, 33, 7, 36, 33, 36, 36, 33,
- 8, 7, 2, 7, 1, 8, 1, 8, 1, 36,
- 8, 2, 8, -1, 2, -1, 60, -1, 33, 55,
- 55, 7, 36, 1, 48, 0, 7, 36, 2, 36,
- 48, 36, 60, 17, 33, 60, 48, 16, 8, 55,
- 61, 60, 36, 7, 36, 8, 36, 36, 8, 60,
- 8, 8, 6, 8, 15, -1, 79, 79, 8, 61,
- 77, 48, 15, 7, 8, 8, 20, 15, 15, 79,
- -1, 24, 8, 34, 8, 8, -1, -1, 61, 61,
- 62, 61, 62, 8, 61, 62, 34, 34, 50, 61,
- 62, 50, 54, 8, 79, 54, 8, 60, 56, 10,
- 60, 56, 40, 60, 8, 61, 62, 8, 40, 12,
- 60, 7, 55, 51, 40, 61, 62, 93, 94, 51,
- 61, 62, 31, 7, 60, 51, 60, 60, 93, 94,
- 15, 56, 61, 62, 61, 62, 42, 61, 62, 24,
- 15, 56, 61, 62, 55, 61, 62, 53, 60, 33,
- 29, 29, 7, 12, 57, 56, 25, 61, 27, 34,
- 63, 36, 25, 7, 27, 61, 62, 29, 25, 38,
- 27, 25, 25, 27, 27, 38, 25, 29, 27, 95,
- -1, 38, 29, -1, 38, 38, 29, -1, 12, 38,
- 36, 29, 25, -1, 27, -1, 75, 75, 57, 40,
- 15, 8, -1, 8, 63, 38, 61, 62, 87, 87,
- 51, -1, 96, 75, -1, 61, 62, 61, 62, 34,
- -1, 36, 15, 75, 8, 87, -1, -1, 75, 25,
- -1, 27, 75, 57, 25, 87, 27, 75, -1, 63,
- 87, 34, 38, 36, 87, 61, 62, 38, 25, 87,
- 27, 25, -1, 27, 61, 62, 61, 62, 25, -1,
- 27, 38, 15, 25, 38, 27, 15, 15, 18, 19,
- -1, 38, 18, 19, 90, 47, 38, 61, 62, -1,
- 33, 34, -1, 36, 33, 34, 34, 36, 36, 61,
- 62, -1, 23, 24, -1, 45, 46, -1, -1, 45,
- 46, 32, 23, 24, 35, -1, 37, -1, 23, 24,
- -1, 32, 23, 24, 35, -1, 37, 32, 23, 24,
- 35, 32, 37, 95, 35, -1, 37, 32, 23, 24,
- 35, -1, 37, -1, -1, -1, 31, 32, 23, 24,
- 35, 29, 37, -1, -1, 29, 31, 32, -1, -1,
- 35, -1, 37, 29, 23, 24, 29, -1, -1, 29,
- 18, 19, 31, 32, 29, -1, 35, 29, 37, -1,
- 100, 101, 102, 103, 104, 105, -1, -1, 66, 67,
- 68, -1, 66, 67, 68, -1, -1, 45, 46, -1,
- 66, 67, 68, 66, 67, 68, 66, 67, 68, -1,
- 29, 66, 67, 68, 66, 67, 68, 29, 96, 97,
- 98, -1, 96, 97, 98, 29, -1, -1, 29, -1,
- 96, 97, 98, 96, 97, 98, 96, 97, 98, -1,
- -1, 96, 97, 98, 96, 97, 98, 66, 67, 68,
- 29, -1, -1, -1, 66, 67, 68, -1, -1, -1,
- 23, 24, 66, 67, 68, 66, 67, 68, 31, 32,
- -1, -1, 35, 29, 37, -1, 15, 96, 97, 98,
- 36, -1, -1, -1, 96, 97, 98, 66, 67, 68,
- 29, -1, 96, 97, 98, 96, 97, 98, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 15,
- 66, 67, 68, -1, -1, -1, 15, 96, 97, 98,
- 15, -1, -1, 29, 15, -1, 29, 66, 67, 68,
- 29, -1, -1, 36, 29, -1, -1, -1, 29, -1,
- 96, 97, 98, -1, -1, 29, -1, -1, 29, -1,
- -1, -1, -1, -1, -1, -1, -1, 96, 97, 98,
- 66, 67, 68, 66, 67, 68, -1, 66, 67, 68,
- -1, 66, 67, 68, -1, 66, 67, 68, -1, -1,
- 61, 62, 66, 67, 68, 66, 67, 68, 29, -1,
- 96, 97, 98, 96, 97, 98, -1, 96, 97, 98,
- 29, 96, 97, 98, -1, 96, 97, 98, 29, -1,
- -1, 29, 96, 97, 98, 96, 97, 98, -1, -1,
- 61, 62, -1, -1, 29, 66, 67, 68, -1, -1,
- -1, 36, 61, 62, -1, -1, -1, 66, 67, 68,
- 61, 62, -1, 61, 62, 66, 67, 68, 66, 67,
- 68, -1, -1, -1, -1, 96, 97, 98, -1, -1,
- 3, 66, 67, 68, -1, -1, -1, 96, 97, 98,
- 13, -1, -1, -1, 17, 96, 97, 98, 96, 97,
- 98, -1, -1, 26, -1, 28, -1, -1, -1, -1,
- -1, 96, 97, 98, -1, -1, 39, -1, 41, 42,
- -1, -1, -1, 29, -1, -1, 49, -1, -1, 52,
- 53, -1, -1, -1, -1, 58, -1, -1, -1, -1,
- -1, 64, -1, -1, -1, -1, -1, -1, -1, 3,
- -1, -1, -1, -1, -1, 61, 62, 80, -1, 13,
- 66, 67, 68, 17, -1, -1, -1, -1, -1, -1,
- -1, -1, 26, -1, 28, -1, -1, 31, -1, -1,
- -1, -1, -1, -1, -1, 39, -1, 41, 42, -1,
- 96, 97, 98, -1, -1, 49, -1, -1, 52, 53,
- -1, -1, 3, -1, 58, -1, -1, -1, -1, -1,
- 64, -1, 13, -1, -1, -1, 17, -1, -1, -1,
- -1, -1, -1, -1, -1, 26, 80, 28, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 39, -1,
- 41, 42, -1, -1, -1, -1, -1, -1, 49, -1,
- -1, 52, 53, -1, -1, -1, -1, 58, -1, -1,
- -1, -1, -1, 64, -1, 12, 13, -1, -1, -1,
- -1, -1, -1, -1, -1, 22, -1, -1, -1, 80,
- -1, -1, 29, -1, -1, -1, 33, 34, -1, 36,
- -1, -1, -1, -1, -1, -1, 43, -1, -1, -1,
- 47, -1, -1, -1, -1, -1, -1, 12, 13, -1,
- -1, -1, -1, -1, -1, -1, -1, 22, 65, 66,
- 67, 68, -1, 70, 29, -1, -1, -1, 33, 34,
- -1, 36, -1, -1, 81, 82, 83, -1, 43, -1,
- -1, 88, 47, -1, -1, -1, -1, -1, -1, 96,
- 97, 98, -1, -1, -1, -1, -1, -1, -1, -1,
- 65, 66, 67, 68, -1, 70, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 81, 82, 83, -1,
- -1, -1, -1, 88, -1, -1, -1, -1, -1, -1,
- -1, 96, 97, 98, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 12, 13, -1, -1, -1, -1, -1,
- -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
- 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
- -1, -1, -1, -1, 43, -1, -1, -1, 47, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
- -1, 70, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 81, 82, 83, -1, -1, -1, -1, 88,
- -1, -1, -1, -1, -1, -1, -1, 96, 97, 98,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 12,
- 13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
- -1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
- 33, 34, -1, 36, -1, -1, -1, -1, -1, -1,
- 43, -1, -1, -1, 47, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 65, 66, 67, 68, -1, 70, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 81, 82,
- 83, -1, -1, -1, -1, 88, -1, -1, -1, -1,
- -1, -1, -1, 96, 97, 98, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 10, -1, 12, 13, -1,
- -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
- -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
- -1, 36, -1, -1, -1, -1, -1, -1, 43, -1,
- -1, -1, 47, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 65, 66, 67, 68, -1, 70, -1, -1, -1, -1,
- 75, -1, -1, -1, -1, -1, 81, 82, 83, 84,
- 85, -1, -1, 88, -1, -1, 91, -1, -1, -1,
- -1, 96, 97, 98, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 10, -1, 12, 13, -1, -1, -1,
- -1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
- -1, -1, 29, -1, -1, -1, 33, 34, -1, 36,
- -1, -1, -1, -1, -1, -1, 43, -1, -1, -1,
- 47, -1, -1, -1, -1, -1, -1, -1, 55, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 65, 66,
- 67, 68, -1, 70, -1, -1, -1, -1, 75, -1,
- -1, -1, -1, -1, 81, 82, 83, 84, 85, -1,
- -1, 88, -1, -1, 91, -1, -1, -1, -1, 96,
- 97, 98, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 10, -1, 12, 13, -1, -1, -1, -1, -1,
- -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
- 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
- -1, -1, -1, -1, 43, -1, -1, -1, 47, -1,
- -1, -1, -1, -1, -1, -1, 55, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
- -1, 70, -1, -1, -1, -1, 75, -1, -1, -1,
- -1, -1, 81, 82, 83, 84, 85, -1, -1, 88,
- -1, -1, 91, -1, -1, -1, -1, 96, 97, 98,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 11,
- 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
- 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
- -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
- 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
- -1, 53, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- 72, -1, 74, -1, 76, -1, -1, -1, -1, 81,
- 82, 83, -1, -1, -1, -1, 88, -1, -1, -1,
- -1, -1, -1, -1, 96, 97, 98, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 7, -1, -1, -1,
- 11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
- -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
- -1, -1, 33, 34, -1, 36, -1, -1, -1, 40,
- -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
- 51, -1, 53, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
- -1, 72, -1, 74, -1, 76, -1, -1, -1, -1,
- 81, 82, 83, -1, -1, -1, -1, 88, -1, -1,
- -1, -1, -1, -1, -1, 96, 97, 98, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
- 74, 75, 76, -1, -1, -1, -1, 81, 82, 83,
- -1, -1, -1, -1, 88, -1, -1, -1, -1, -1,
- -1, -1, 96, 97, 98, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 8, -1, -1, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, -1, 56, -1, -1, -1, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
- 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
- -1, -1, -1, -1, 88, -1, -1, -1, -1, -1,
- -1, -1, 96, 97, 98, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 8, -1, -1, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, -1, 56, -1, -1, -1, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
- 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
- -1, -1, -1, -1, 88, -1, -1, -1, -1, -1,
- -1, -1, 96, 97, 98, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 8, -1, -1, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, -1, 56, -1, -1, -1, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
- 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
- -1, -1, -1, -1, 88, -1, -1, -1, -1, -1,
- -1, -1, 96, 97, 98, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 8, -1, -1, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, -1, 56, -1, -1, -1, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
- 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
- -1, -1, -1, -1, 88, -1, -1, -1, -1, -1,
- -1, -1, 96, 97, 98, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 11, 12, 13, -1, -1, -1,
- -1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
- -1, -1, 29, 30, -1, -1, 33, 34, -1, 36,
- -1, -1, -1, 40, -1, 42, 43, 44, -1, -1,
- 47, -1, -1, -1, 51, -1, 53, -1, -1, -1,
- -1, -1, -1, -1, 61, -1, -1, -1, 65, 66,
- 67, 68, 69, 70, -1, 72, 73, 74, -1, 76,
- -1, 78, -1, -1, 81, 82, 83, -1, -1, -1,
- -1, 88, -1, -1, -1, -1, -1, -1, -1, 96,
- 97, 98, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 11, 12, 13, -1, -1, -1, -1, -1, -1,
- -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
- 30, -1, -1, 33, 34, -1, 36, -1, -1, -1,
- 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
- -1, 51, -1, 53, -1, -1, -1, -1, -1, -1,
- -1, 61, -1, -1, -1, 65, 66, 67, 68, 69,
- 70, -1, 72, 73, 74, -1, 76, -1, 78, -1,
- -1, 81, 82, 83, -1, -1, -1, -1, 88, -1,
- -1, -1, -1, -1, -1, -1, 96, 97, 98, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 11, 12,
- 13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
- -1, -1, -1, -1, -1, -1, 29, 30, -1, -1,
- 33, 34, -1, 36, -1, -1, -1, 40, -1, 42,
- 43, 44, -1, -1, 47, -1, -1, -1, 51, -1,
- 53, -1, -1, -1, -1, -1, -1, -1, 61, -1,
- -1, -1, 65, 66, 67, 68, 69, 70, -1, 72,
- 73, 74, -1, 76, -1, 78, -1, -1, 81, 82,
- 83, -1, -1, -1, -1, 88, -1, -1, -1, -1,
- -1, -1, -1, 96, 97, 98, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 4, 5, 6, -1, -1,
- 9, 10, 11, -1, -1, 14, -1, 16, -1, -1,
- -1, 20, 21, 22, -1, -1, -1, -1, -1, -1,
- 29, 30, 31, 32, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 43, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 59, -1, -1, -1, -1, -1, -1, 66, 67, 68,
- 69, 70, 71, -1, 73, 74, 75, 76, 77, 78,
- -1, -1, 81, 82, 83, 84, 85, 86, 87, -1,
- -1, -1, 91, -1, -1, -1, -1, 96, 97, 98,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 4,
- 5, 6, -1, -1, 9, 10, 11, -1, -1, 14,
- -1, 16, -1, -1, -1, 20, 21, 22, -1, -1,
- -1, -1, -1, -1, 29, 30, 31, 32, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 43, -1,
- -1, -1, 47, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 59, -1, -1, -1, -1, -1,
- 65, 66, 67, 68, 69, 70, 71, -1, 73, 74,
- 75, 76, 77, 78, -1, -1, 81, 82, 83, 84,
- 85, 86, 87, -1, -1, -1, 91, -1, -1, -1,
- -1, 96, 97, 98, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 4, 5, 6, -1, -1, 9, 10,
- 11, -1, -1, 14, -1, 16, -1, -1, -1, 20,
- 21, 22, -1, -1, -1, -1, -1, -1, 29, 30,
- 31, 32, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 59, -1,
- -1, -1, -1, -1, 65, 66, 67, 68, 69, 70,
- 71, -1, 73, 74, 75, 76, 77, 78, -1, -1,
- 81, 82, 83, 84, 85, 86, 87, -1, -1, -1,
- 91, -1, -1, -1, -1, 96, 97, 98, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 4, 5, 6,
- -1, -1, 9, 10, 11, -1, -1, 14, -1, 16,
- -1, -1, -1, 20, 21, 22, -1, -1, -1, -1,
- -1, -1, 29, 30, 31, 32, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 43, -1, -1, -1,
- 47, -1, -1, -1, -1, -1, -1, -1, 55, -1,
- -1, -1, 59, -1, -1, -1, -1, -1, 65, 66,
- 67, 68, 69, 70, 71, -1, 73, 74, 75, 76,
- 77, 78, -1, -1, 81, 82, 83, 84, 85, 86,
- 87, -1, -1, -1, 91, -1, -1, -1, -1, 96,
- 97, 98, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 4, -1, -1, -1, -1, 9, -1, 11, 12,
- 13, 14, -1, -1, -1, -1, -1, -1, 21, 22,
- -1, -1, -1, -1, -1, -1, 29, 30, -1, -1,
- 33, 34, -1, 36, -1, -1, -1, 40, -1, 42,
- 43, 44, -1, -1, 47, -1, -1, -1, 51, -1,
- 53, -1, -1, -1, -1, -1, 59, -1, 61, -1,
- -1, -1, 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 76, 77, 78, -1, -1, 81, 82,
- 83, 84, 85, 86, -1, 88, -1, -1, -1, -1,
- -1, -1, -1, 96, 97, 98, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 4, -1, -1, -1, -1,
- 9, -1, 11, 12, 13, 14, -1, -1, -1, -1,
- -1, -1, 21, 22, -1, -1, -1, -1, -1, -1,
- 29, 30, -1, -1, 33, 34, -1, 36, -1, -1,
- -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
- -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
- 59, -1, 61, -1, -1, -1, 65, 66, 67, 68,
- 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- -1, -1, 81, 82, 83, 84, 85, 86, -1, 88,
- -1, -1, -1, -1, -1, -1, -1, 96, 97, 98,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 4,
- 5, 6, -1, -1, 9, 10, 11, 12, 13, 14,
- -1, 16, -1, -1, -1, 20, 21, 22, -1, -1,
- -1, -1, -1, -1, 29, 30, 31, 32, 33, 34,
- -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
- -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
- -1, -1, -1, -1, 59, -1, 61, -1, -1, -1,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, -1, -1, 81, 82, 83, 84,
- 85, 86, 87, 88, -1, -1, 91, -1, -1, -1,
- -1, 96, 97, 98, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 4, 5, 6, -1, -1, 9, 10,
- 11, 12, 13, 14, -1, 16, -1, -1, -1, 20,
- 21, 22, -1, -1, -1, -1, -1, -1, 29, 30,
- 31, 32, 33, 34, -1, 36, -1, -1, -1, 40,
- -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
- 51, -1, 53, -1, 55, -1, -1, -1, 59, -1,
- 61, -1, -1, -1, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 75, 76, 77, 78, -1, -1,
- 81, 82, 83, 84, 85, 86, 87, 88, -1, -1,
- 91, -1, -1, -1, -1, 96, 97, 98, -1, -1,
- -1, -1, -1, -1, -1, -1, -1,
-
- 18, 18, 32, 18, 32, 18, 3, 43, 18, 25,
- 22, 22, 14, 14, 78, 18, 9, 3, 18, 3,
- 18, 3, 18, 32, 18, 32, 32, 22, 18, 18,
- 22, 3, 3, 18, 106, 43, 3, 18, 18, 101,
- 3, 3, 18, 18, 18, 104, 3, 3, 18, 18,
- 18, 3, 18, 18, 18, 43, 3, 3, 3, 32,
- 14, 3, 3, 3, 25, 25, 25, -1, 55, 18,
- 57, 2, 55, -1, -1, 2, 55, 60, 3, -1,
- 18, 60, 18, 18, -1, 43, 25, 18, 43, -1,
- 43, 18, 43, 43, 18, 43, 11, 12, 14, 43,
- 43, 4, 3, 19, 18, 18, 3, 14, 3, 45,
- 18, -1, 18, -1, 2, 18, 23, 2, 55, 2,
- 57, 55, 55, 57, 57, 55, 55, 57, 57, 55,
- 18, 57, 45, 18, 55, 18, 57, 2, 46, 2,
- 2, 47, 2, 55, 55, 55, 55, 57, 60, 60,
- 55, 60, 57, 18, 79, 18, 18, 55, 18, 55,
- 95, 57, 60, 14, 2, 2, 55, -1, 55, 18,
- 14, 55, 61, 55, 61, 19, 60, 59, 79, 55,
- 18, 18, 79, 59, 79, 55, 55, 55, 14, 55,
- 60, 60, 60, 18, 60, 2, 110, 55, 47, 55,
- 43, 52, 60, 59, 18, 55, 2, 57, 51, 55,
- 55, 18, 39, 55, 55, 18, 43, 4, 2, 55,
- 65, 67, 18, 2, 18, 61, 52, 2, 69, 71,
- 2, 18, 46, 55, 18, 57, 55, 4, 57, 18,
- 55, 44, 57, 18, 55, 55, 18, 58, 58, 18,
- 43, 18, 46, 55, 14, 57, 55, 18, 51, 19,
- 2, 2, 61, 55, 55, 57, 55, 55, 93, 57,
- -1, 60, 63, -1, -1, 55, 18, 18, 47, 68,
- 60, -1, 55, -1, 64, 46, 18, 60, -1, 62,
- 55, 55, -1, -1, -1, 60, 60, 62, 62, 55,
- 55, -1, 55, 55, 60, 60, 62, 60, 60, 55,
- 55, -1, 55, 66, 60, 60, 48, 60, 55, 55,
- -1, 14, 77, 60, 60, 77, 19, 72, 21, -1,
- 14, 77, -1, 70, 77, 5, -1, 5, -1, 23,
- -1, 77, -1, -1, 14, -1, 14, 89, 89, -1,
- 43, 35, 36, 23, -1, 23, 25, 26, 27, 28,
- 29, 30, 31, -1, -1, 35, 36, 35, 36, -1,
- -1, -1, 14, -1, -1, -1, -1, -1, -1, -1,
- 18, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 14, -1, -1, -1, -1, -1, -1, -1, -1, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, -1, -1,
- 48, 49, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 14, -1, -1, -1, -1, -1,
- -1, -1, -1, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1
-};
-
-QT_END_NAMESPACE
diff --git a/src/qml/parser/qqmljsgrammar_p.h b/src/qml/parser/qqmljsgrammar_p.h
deleted file mode 100644
index 9d028f2191..0000000000
--- a/src/qml/parser/qqmljsgrammar_p.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-// This file was generated by qlalr - DO NOT EDIT!
-#ifndef QQMLJSGRAMMAR_P_H
-#define QQMLJSGRAMMAR_P_H
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlJSGrammar
-{
-public:
- enum VariousConstants {
- EOF_SYMBOL = 0,
- REDUCE_HERE = 107,
- SHIFT_THERE = 106,
- T_AND = 1,
- T_AND_AND = 2,
- T_AND_EQ = 3,
- T_AS = 95,
- T_AUTOMATIC_SEMICOLON = 62,
- T_BREAK = 4,
- T_CASE = 5,
- T_CATCH = 6,
- T_COLON = 7,
- T_COMMA = 8,
- T_COMMENT = 89,
- T_COMPATIBILITY_SEMICOLON = 90,
- T_CONST = 84,
- T_CONTINUE = 9,
- T_DEBUGGER = 86,
- T_DEFAULT = 10,
- T_DELETE = 11,
- T_DIVIDE_ = 12,
- T_DIVIDE_EQ = 13,
- T_DO = 14,
- T_DOT = 15,
- T_ELSE = 16,
- T_ENUM = 91,
- T_EQ = 17,
- T_EQ_EQ = 18,
- T_EQ_EQ_EQ = 19,
- T_ERROR = 99,
- T_FALSE = 83,
- T_FEED_JS_EXPRESSION = 103,
- T_FEED_JS_PROGRAM = 105,
- T_FEED_JS_SOURCE_ELEMENT = 104,
- T_FEED_JS_STATEMENT = 102,
- T_FEED_UI_OBJECT_MEMBER = 101,
- T_FEED_UI_PROGRAM = 100,
- T_FINALLY = 20,
- T_FOR = 21,
- T_FUNCTION = 22,
- T_GE = 23,
- T_GET = 97,
- T_GT = 24,
- T_GT_GT = 25,
- T_GT_GT_EQ = 26,
- T_GT_GT_GT = 27,
- T_GT_GT_GT_EQ = 28,
- T_IDENTIFIER = 29,
- T_IF = 30,
- T_IMPORT = 93,
- T_IN = 31,
- T_INSTANCEOF = 32,
- T_LBRACE = 33,
- T_LBRACKET = 34,
- T_LE = 35,
- T_LET = 85,
- T_LPAREN = 36,
- T_LT = 37,
- T_LT_LT = 38,
- T_LT_LT_EQ = 39,
- T_MINUS = 40,
- T_MINUS_EQ = 41,
- T_MINUS_MINUS = 42,
- T_MULTILINE_STRING_LITERAL = 88,
- T_NEW = 43,
- T_NOT = 44,
- T_NOT_EQ = 45,
- T_NOT_EQ_EQ = 46,
- T_NULL = 81,
- T_NUMERIC_LITERAL = 47,
- T_ON = 96,
- T_OR = 48,
- T_OR_EQ = 49,
- T_OR_OR = 50,
- T_PLUS = 51,
- T_PLUS_EQ = 52,
- T_PLUS_PLUS = 53,
- T_PRAGMA = 94,
- T_PROPERTY = 66,
- T_PUBLIC = 92,
- T_QUESTION = 54,
- T_RBRACE = 55,
- T_RBRACKET = 56,
- T_READONLY = 68,
- T_REMAINDER = 57,
- T_REMAINDER_EQ = 58,
- T_RESERVED_WORD = 87,
- T_RETURN = 59,
- T_RPAREN = 60,
- T_SEMICOLON = 61,
- T_SET = 98,
- T_SIGNAL = 67,
- T_STAR = 63,
- T_STAR_EQ = 64,
- T_STRING_LITERAL = 65,
- T_SWITCH = 69,
- T_THIS = 70,
- T_THROW = 71,
- T_TILDE = 72,
- T_TRUE = 82,
- T_TRY = 73,
- T_TYPEOF = 74,
- T_VAR = 75,
- T_VOID = 76,
- T_WHILE = 77,
- T_WITH = 78,
- T_XOR = 79,
- T_XOR_EQ = 80,
-
- ACCEPT_STATE = 691,
- RULE_COUNT = 369,
- STATE_COUNT = 692,
- TERMINAL_COUNT = 108,
- NON_TERMINAL_COUNT = 112,
-
- GOTO_INDEX_OFFSET = 692,
- GOTO_INFO_OFFSET = 3357,
- GOTO_CHECK_OFFSET = 3357
- };
-
- static const char *const spell[];
- static const short lhs[];
- static const short rhs[];
- static const short goto_default[];
- static const short action_default[];
- static const short action_index[];
- static const short action_info[];
- static const short action_check[];
-
- static inline int nt_action (int state, int nt)
- {
- const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;
- if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)
- return goto_default [nt];
-
- return action_info [GOTO_INFO_OFFSET + yyn];
- }
-
- static inline int t_action (int state, int token)
- {
- const int yyn = action_index [state] + token;
-
- if (yyn < 0 || action_check [yyn] != token)
- return - action_default [state];
-
- return action_info [yyn];
- }
-};
-
-
-QT_END_NAMESPACE
-#endif // QQMLJSGRAMMAR_P_H
-
diff --git a/src/qml/parser/qqmljskeywords_p.h b/src/qml/parser/qqmljskeywords_p.h
index 20daf545a9..9cc47469e5 100644
--- a/src/qml/parser/qqmljskeywords_p.h
+++ b/src/qml/parser/qqmljskeywords_p.h
@@ -57,10 +57,10 @@ QT_QML_BEGIN_NAMESPACE
namespace QQmlJS {
-static inline int classify2(const QChar *s, bool qmlMode) {
+static inline int classify2(const QChar *s, int parseModeFlags) {
if (s[0].unicode() == 'a') {
if (s[1].unicode() == 's') {
- return qmlMode ? Lexer::T_AS : Lexer::T_IDENTIFIER;
+ return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_AS : Lexer::T_IDENTIFIER;
}
}
else if (s[0].unicode() == 'd') {
@@ -76,15 +76,15 @@ static inline int classify2(const QChar *s, bool qmlMode) {
return Lexer::T_IN;
}
}
- else if (qmlMode && s[0].unicode() == 'o') {
+ else if ((parseModeFlags & Lexer::QmlMode) && s[0].unicode() == 'o') {
if (s[1].unicode() == 'n') {
- return qmlMode ? Lexer::T_ON : Lexer::T_IDENTIFIER;
+ return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_ON : Lexer::T_IDENTIFIER;
}
}
return Lexer::T_IDENTIFIER;
}
-static inline int classify3(const QChar *s, bool qmlMode) {
+static inline int classify3(const QChar *s, int parseModeFlags) {
if (s[0].unicode() == 'f') {
if (s[1].unicode() == 'o') {
if (s[2].unicode() == 'r') {
@@ -102,7 +102,7 @@ static inline int classify3(const QChar *s, bool qmlMode) {
else if (s[0].unicode() == 'i') {
if (s[1].unicode() == 'n') {
if (s[2].unicode() == 't') {
- return qmlMode ? int(Lexer::T_INT) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_INT) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -144,12 +144,12 @@ static inline int classify3(const QChar *s, bool qmlMode) {
return Lexer::T_IDENTIFIER;
}
-static inline int classify4(const QChar *s, bool qmlMode) {
+static inline int classify4(const QChar *s, int parseModeFlags) {
if (s[0].unicode() == 'b') {
if (s[1].unicode() == 'y') {
if (s[2].unicode() == 't') {
if (s[3].unicode() == 'e') {
- return qmlMode ? int(Lexer::T_BYTE) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_BYTE) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -165,7 +165,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
else if (s[1].unicode() == 'h') {
if (s[2].unicode() == 'a') {
if (s[3].unicode() == 'r') {
- return qmlMode ? int(Lexer::T_CHAR) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_CHAR) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -181,7 +181,16 @@ static inline int classify4(const QChar *s, bool qmlMode) {
else if (s[1].unicode() == 'n') {
if (s[2].unicode() == 'u') {
if (s[3].unicode() == 'm') {
- return qmlMode ? int(Lexer::T_ENUM) : int(Lexer::T_RESERVED_WORD);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_ENUM) : int(Lexer::T_RESERVED_WORD);
+ }
+ }
+ }
+ }
+ else if (s[0].unicode() == 'f') {
+ if (s[1].unicode() == 'r') {
+ if (s[2].unicode() == 'o') {
+ if (s[3].unicode() == 'm') {
+ return int(Lexer::T_FROM);
}
}
}
@@ -190,7 +199,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
if (s[1].unicode() == 'o') {
if (s[2].unicode() == 't') {
if (s[3].unicode() == 'o') {
- return qmlMode ? int(Lexer::T_GOTO) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_GOTO) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -199,7 +208,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
if (s[1].unicode() == 'o') {
if (s[2].unicode() == 'n') {
if (s[3].unicode() == 'g') {
- return qmlMode ? int(Lexer::T_LONG) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_LONG) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -250,7 +259,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
return Lexer::T_IDENTIFIER;
}
-static inline int classify5(const QChar *s, bool qmlMode) {
+static inline int classify5(const QChar *s, int parseModeFlags) {
if (s[0].unicode() == 'b') {
if (s[1].unicode() == 'r') {
if (s[2].unicode() == 'e') {
@@ -305,7 +314,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
if (s[2].unicode() == 'n') {
if (s[3].unicode() == 'a') {
if (s[4].unicode() == 'l') {
- return qmlMode ? int(Lexer::T_FINAL) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_FINAL) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -314,7 +323,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
if (s[2].unicode() == 'o') {
if (s[3].unicode() == 'a') {
if (s[4].unicode() == 't') {
- return qmlMode ? int(Lexer::T_FLOAT) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_FLOAT) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -325,7 +334,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
if (s[2].unicode() == 'o') {
if (s[3].unicode() == 'r') {
if (s[4].unicode() == 't') {
- return qmlMode ? int(Lexer::T_SHORT) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_SHORT) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -334,7 +343,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
if (s[2].unicode() == 'p') {
if (s[3].unicode() == 'e') {
if (s[4].unicode() == 'r') {
- return qmlMode ? int(Lexer::T_SUPER) : int(Lexer::T_RESERVED_WORD);
+ return int(Lexer::T_SUPER);
}
}
}
@@ -362,10 +371,21 @@ static inline int classify5(const QChar *s, bool qmlMode) {
}
}
}
+ else if (s[0].unicode() == 'y') {
+ if (s[1].unicode() == 'i') {
+ if (s[2].unicode() == 'e') {
+ if (s[3].unicode() == 'l') {
+ if (s[4].unicode() == 'd') {
+ return (parseModeFlags & Lexer::YieldIsKeyword) ? Lexer::T_YIELD : Lexer::T_IDENTIFIER;
+ }
+ }
+ }
+ }
+ }
return Lexer::T_IDENTIFIER;
}
-static inline int classify6(const QChar *s, bool qmlMode) {
+static inline int classify6(const QChar *s, int parseModeFlags) {
if (s[0].unicode() == 'd') {
if (s[1].unicode() == 'e') {
if (s[2].unicode() == 'l') {
@@ -383,7 +403,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
if (s[3].unicode() == 'b') {
if (s[4].unicode() == 'l') {
if (s[5].unicode() == 'e') {
- return qmlMode ? int(Lexer::T_DOUBLE) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_DOUBLE) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -409,7 +429,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
if (s[3].unicode() == 'o') {
if (s[4].unicode() == 'r') {
if (s[5].unicode() == 't') {
- return qmlMode ? int(Lexer::T_IMPORT) : int(Lexer::T_RESERVED_WORD);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_IMPORT) : int(Lexer::T_RESERVED_WORD);
}
}
}
@@ -422,7 +442,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
if (s[3].unicode() == 'i') {
if (s[4].unicode() == 'v') {
if (s[5].unicode() == 'e') {
- return qmlMode ? int(Lexer::T_NATIVE) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_NATIVE) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -435,7 +455,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
if (s[3].unicode() == 'l') {
if (s[4].unicode() == 'i') {
if (s[5].unicode() == 'c') {
- return qmlMode ? Lexer::T_PUBLIC : Lexer::T_IDENTIFIER;
+ return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_PUBLIC : Lexer::T_IDENTIFIER;
}
}
}
@@ -446,7 +466,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
if (s[3].unicode() == 'g') {
if (s[4].unicode() == 'm') {
if (s[5].unicode() == 'a') {
- return qmlMode ? Lexer::T_PRAGMA : Lexer::T_IDENTIFIER;
+ return (parseModeFlags & Lexer::QmlMode) ? Lexer::T_PRAGMA : Lexer::T_IDENTIFIER;
}
}
}
@@ -467,7 +487,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
}
}
else if (s[0].unicode() == 's') {
- if (qmlMode && s[1].unicode() == 'i') {
+ if ((parseModeFlags & Lexer::QmlMode) && s[1].unicode() == 'i') {
if (s[2].unicode() == 'g') {
if (s[3].unicode() == 'n') {
if (s[4].unicode() == 'a') {
@@ -483,7 +503,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
if (s[3].unicode() == 't') {
if (s[4].unicode() == 'i') {
if (s[5].unicode() == 'c') {
- return qmlMode ? int(Lexer::T_STATIC) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::StaticIsKeyword) ? int(Lexer::T_STATIC) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -507,7 +527,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
if (s[3].unicode() == 'o') {
if (s[4].unicode() == 'w') {
if (s[5].unicode() == 's') {
- return qmlMode ? int(Lexer::T_THROWS) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_THROWS) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -528,7 +548,7 @@ static inline int classify6(const QChar *s, bool qmlMode) {
return Lexer::T_IDENTIFIER;
}
-static inline int classify7(const QChar *s, bool qmlMode) {
+static inline int classify7(const QChar *s, int parseModeFlags) {
if (s[0].unicode() == 'b') {
if (s[1].unicode() == 'o') {
if (s[2].unicode() == 'o') {
@@ -536,7 +556,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
if (s[4].unicode() == 'e') {
if (s[5].unicode() == 'a') {
if (s[6].unicode() == 'n') {
- return qmlMode ? int(Lexer::T_BOOLEAN) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_BOOLEAN) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -596,7 +616,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
if (s[4].unicode() == 'a') {
if (s[5].unicode() == 'g') {
if (s[6].unicode() == 'e') {
- return qmlMode ? int(Lexer::T_PACKAGE) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_PACKAGE) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -609,7 +629,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
if (s[4].unicode() == 'a') {
if (s[5].unicode() == 't') {
if (s[6].unicode() == 'e') {
- return qmlMode ? int(Lexer::T_PRIVATE) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_PRIVATE) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -620,7 +640,7 @@ static inline int classify7(const QChar *s, bool qmlMode) {
return Lexer::T_IDENTIFIER;
}
-static inline int classify8(const QChar *s, bool qmlMode) {
+static inline int classify8(const QChar *s, int parseModeFlags) {
if (s[0].unicode() == 'a') {
if (s[1].unicode() == 'b') {
if (s[2].unicode() == 's') {
@@ -629,7 +649,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
if (s[5].unicode() == 'a') {
if (s[6].unicode() == 'c') {
if (s[7].unicode() == 't') {
- return qmlMode ? int(Lexer::T_ABSTRACT) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_ABSTRACT) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -689,7 +709,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
}
}
}
- else if (qmlMode && s[0].unicode() == 'p') {
+ else if ((parseModeFlags & Lexer::QmlMode) && s[0].unicode() == 'p') {
if (s[1].unicode() == 'r') {
if (s[2].unicode() == 'o') {
if (s[3].unicode() == 'p') {
@@ -706,7 +726,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
}
}
}
- else if (qmlMode && s[0].unicode() == 'r') {
+ else if ((parseModeFlags & Lexer::QmlMode) && s[0].unicode() == 'r') {
if (s[1].unicode() == 'e') {
if (s[2].unicode() == 'a') {
if (s[3].unicode() == 'd') {
@@ -731,7 +751,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
if (s[5].unicode() == 'i') {
if (s[6].unicode() == 'l') {
if (s[7].unicode() == 'e') {
- return qmlMode ? int(Lexer::T_VOLATILE) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_VOLATILE) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -743,7 +763,7 @@ static inline int classify8(const QChar *s, bool qmlMode) {
return Lexer::T_IDENTIFIER;
}
-static inline int classify9(const QChar *s, bool qmlMode) {
+static inline int classify9(const QChar *s, int parseModeFlags) {
if (s[0].unicode() == 'i') {
if (s[1].unicode() == 'n') {
if (s[2].unicode() == 't') {
@@ -753,7 +773,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
if (s[6].unicode() == 'a') {
if (s[7].unicode() == 'c') {
if (s[8].unicode() == 'e') {
- return qmlMode ? int(Lexer::T_INTERFACE) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_INTERFACE) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -772,7 +792,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
if (s[6].unicode() == 't') {
if (s[7].unicode() == 'e') {
if (s[8].unicode() == 'd') {
- return qmlMode ? int(Lexer::T_PROTECTED) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_PROTECTED) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -791,7 +811,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
if (s[6].unicode() == 'e') {
if (s[7].unicode() == 'n') {
if (s[8].unicode() == 't') {
- return qmlMode ? int(Lexer::T_TRANSIENT) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_TRANSIENT) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -804,7 +824,7 @@ static inline int classify9(const QChar *s, bool qmlMode) {
return Lexer::T_IDENTIFIER;
}
-static inline int classify10(const QChar *s, bool qmlMode) {
+static inline int classify10(const QChar *s, int parseModeFlags) {
if (s[0].unicode() == 'i') {
if (s[1].unicode() == 'm') {
if (s[2].unicode() == 'p') {
@@ -815,7 +835,7 @@ static inline int classify10(const QChar *s, bool qmlMode) {
if (s[7].unicode() == 'n') {
if (s[8].unicode() == 't') {
if (s[9].unicode() == 's') {
- return qmlMode ? int(Lexer::T_IMPLEMENTS) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_IMPLEMENTS) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -848,7 +868,7 @@ static inline int classify10(const QChar *s, bool qmlMode) {
return Lexer::T_IDENTIFIER;
}
-static inline int classify12(const QChar *s, bool qmlMode) {
+static inline int classify12(const QChar *s, int parseModeFlags) {
if (s[0].unicode() == 's') {
if (s[1].unicode() == 'y') {
if (s[2].unicode() == 'n') {
@@ -861,7 +881,7 @@ static inline int classify12(const QChar *s, bool qmlMode) {
if (s[9].unicode() == 'z') {
if (s[10].unicode() == 'e') {
if (s[11].unicode() == 'd') {
- return qmlMode ? int(Lexer::T_SYNCHRONIZED) : int(Lexer::T_IDENTIFIER);
+ return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_SYNCHRONIZED) : int(Lexer::T_IDENTIFIER);
}
}
}
@@ -877,18 +897,18 @@ static inline int classify12(const QChar *s, bool qmlMode) {
return Lexer::T_IDENTIFIER;
}
-int Lexer::classify(const QChar *s, int n, bool qmlMode) {
+int Lexer::classify(const QChar *s, int n, int parseModeFlags) {
switch (n) {
- case 2: return classify2(s, qmlMode);
- case 3: return classify3(s, qmlMode);
- case 4: return classify4(s, qmlMode);
- case 5: return classify5(s, qmlMode);
- case 6: return classify6(s, qmlMode);
- case 7: return classify7(s, qmlMode);
- case 8: return classify8(s, qmlMode);
- case 9: return classify9(s, qmlMode);
- case 10: return classify10(s, qmlMode);
- case 12: return classify12(s, qmlMode);
+ case 2: return classify2(s, parseModeFlags);
+ case 3: return classify3(s, parseModeFlags);
+ case 4: return classify4(s, parseModeFlags);
+ case 5: return classify5(s, parseModeFlags);
+ case 6: return classify6(s, parseModeFlags);
+ case 7: return classify7(s, parseModeFlags);
+ case 8: return classify8(s, parseModeFlags);
+ case 9: return classify9(s, parseModeFlags);
+ case 10: return classify10(s, parseModeFlags);
+ case 12: return classify12(s, parseModeFlags);
default: return Lexer::T_IDENTIFIER;
} // switch
}
diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp
index aab9025a08..1165183483 100644
--- a/src/qml/parser/qqmljslexer.cpp
+++ b/src/qml/parser/qqmljslexer.cpp
@@ -77,22 +77,15 @@ static inline QChar convertHex(QChar c1, QChar c2)
return QChar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
}
-static inline QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
-{
- return QChar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode()),
- (convertHex(c1.unicode()) << 4) + convertHex(c2.unicode()));
-}
-
Lexer::Lexer(Engine *engine)
: _engine(engine)
, _codePtr(nullptr)
, _endPtr(nullptr)
- , _lastLinePtr(nullptr)
- , _tokenLinePtr(nullptr)
, _tokenStartPtr(nullptr)
, _char(QLatin1Char('\n'))
, _errorCode(NoError)
, _currentLineNumber(0)
+ , _currentColumnNumber(0)
, _tokenValue(0)
, _parenthesesState(IgnoreParentheses)
, _parenthesesCount(0)
@@ -101,6 +94,7 @@ Lexer::Lexer(Engine *engine)
, _tokenKind(0)
, _tokenLength(0)
, _tokenLine(0)
+ , _tokenColumn(0)
, _validTokenText(false)
, _prohibitAutomaticSemicolon(false)
, _restrictedKeyword(false)
@@ -137,14 +131,13 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
_codePtr = code.unicode();
_endPtr = _codePtr + code.length();
- _lastLinePtr = _codePtr;
- _tokenLinePtr = _codePtr;
_tokenStartPtr = _codePtr;
_char = QLatin1Char('\n');
_errorCode = NoError;
_currentLineNumber = lineno;
+ _currentColumnNumber = 0;
_tokenValue = 0;
// parentheses state
@@ -156,6 +149,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode)
_patternFlags = 0;
_tokenLength = 0;
_tokenLine = lineno;
+ _tokenColumn = 0;
_validTokenText = false;
_prohibitAutomaticSemicolon = false;
@@ -172,9 +166,10 @@ void Lexer::scanChar()
if (sequenceLength == 2)
_char = *_codePtr++;
- if (unsigned sequenceLength = isLineTerminatorSequence()) {
- _lastLinePtr = _codePtr + sequenceLength - 1; // points to the first character after the newline
+ ++_currentColumnNumber;
+ if (isLineTerminator()) {
++_currentLineNumber;
+ _currentColumnNumber = 0;
}
}
@@ -222,12 +217,32 @@ inline bool isBinop(int tok)
return false;
}
}
+
+int hexDigit(QChar c)
+{
+ if (c >= QLatin1Char('0') && c <= QLatin1Char('9'))
+ return c.unicode() - '0';
+ if (c >= QLatin1Char('a') && c <= QLatin1Char('f'))
+ return c.unicode() - 'a' + 10;
+ if (c >= QLatin1Char('A') && c <= QLatin1Char('F'))
+ return c.unicode() - 'A' + 10;
+ return -1;
+}
+
+int octalDigit(QChar c)
+{
+ if (c >= QLatin1Char('0') && c <= QLatin1Char('7'))
+ return c.unicode() - '0';
+ return -1;
+}
+
} // anonymous namespace
int Lexer::lex()
{
const int previousTokenKind = _tokenKind;
+ again:
_tokenSpell = QStringRef();
_tokenKind = scanToken();
_tokenLength = _codePtr - _tokenStartPtr - 1;
@@ -239,6 +254,9 @@ int Lexer::lex()
// update the flags
switch (_tokenKind) {
case T_LBRACE:
+ if (_bracesCount > 0)
+ ++_bracesCount;
+ Q_FALLTHROUGH();
case T_SEMICOLON:
case T_QUESTION:
case T_COLON:
@@ -269,6 +287,11 @@ int Lexer::lex()
case T_THROW:
_restrictedKeyword = true;
break;
+ case T_RBRACE:
+ if (_bracesCount > 0)
+ --_bracesCount;
+ if (_bracesCount == 0)
+ goto again;
} // switch
// update the parentheses state
@@ -295,39 +318,57 @@ int Lexer::lex()
return _tokenKind;
}
-bool Lexer::isUnicodeEscapeSequence(const QChar *chars)
-{
- if (isHexDigit(chars[0]) && isHexDigit(chars[1]) && isHexDigit(chars[2]) && isHexDigit(chars[3]))
- return true;
-
- return false;
-}
-
-QChar Lexer::decodeUnicodeEscapeCharacter(bool *ok)
+uint Lexer::decodeUnicodeEscapeCharacter(bool *ok)
{
- if (_char == QLatin1Char('u') && isUnicodeEscapeSequence(&_codePtr[0])) {
- scanChar(); // skip u
+ Q_ASSERT(_char == QLatin1Char('u'));
+ scanChar(); // skip u
+ if (_codePtr + 4 <= _endPtr && isHexDigit(_char)) {
+ uint codePoint = 0;
+ for (int i = 0; i < 4; ++i) {
+ int digit = hexDigit(_char);
+ if (digit < 0)
+ goto error;
+ codePoint *= 16;
+ codePoint += digit;
+ scanChar();
+ }
- const QChar c1 = _char;
- scanChar();
+ *ok = true;
+ return codePoint;
+ } else if (_codePtr < _endPtr && _char == QLatin1Char('{')) {
+ scanChar(); // skip '{'
+ uint codePoint = 0;
+ if (!isHexDigit(_char))
+ // need at least one hex digit
+ goto error;
- const QChar c2 = _char;
- scanChar();
+ while (_codePtr <= _endPtr) {
+ int digit = hexDigit(_char);
+ if (digit < 0)
+ break;
+ codePoint *= 16;
+ codePoint += digit;
+ if (codePoint > 0x10ffff)
+ goto error;
+ scanChar();
+ }
- const QChar c3 = _char;
- scanChar();
+ if (_char != QLatin1Char('}'))
+ goto error;
- const QChar c4 = _char;
- scanChar();
+ scanChar(); // skip '}'
- if (ok)
- *ok = true;
- return convertUnicode(c1, c2, c3, c4);
+ *ok = true;
+ return codePoint;
}
+ error:
+ _errorCode = IllegalUnicodeEscapeSequence;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence");
+
*ok = false;
- return QChar();
+ return 0;
}
QChar Lexer::decodeHexEscapeCharacter(bool *ok)
@@ -351,15 +392,15 @@ QChar Lexer::decodeHexEscapeCharacter(bool *ok)
return QChar();
}
-static inline bool isIdentifierStart(QChar ch)
+static inline bool isIdentifierStart(uint ch)
{
// fast path for ascii
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
- (ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
+ if ((ch >= 'a' && ch <= 'z') ||
+ (ch >= 'A' && ch <= 'Z') ||
ch == '$' || ch == '_')
return true;
- switch (ch.category()) {
+ switch (QChar::category(ch)) {
case QChar::Number_Letter:
case QChar::Letter_Uppercase:
case QChar::Letter_Lowercase:
@@ -373,17 +414,17 @@ static inline bool isIdentifierStart(QChar ch)
return false;
}
-static bool isIdentifierPart(QChar ch)
+static bool isIdentifierPart(uint ch)
{
// fast path for ascii
- if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
- (ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
- (ch.unicode() >= '0' && ch.unicode() <= '9') ||
+ if ((ch >= 'a' && ch <= 'z') ||
+ (ch >= 'A' && ch <= 'Z') ||
+ (ch >= '0' && ch <= '9') ||
ch == '$' || ch == '_' ||
- ch.unicode() == 0x200c /* ZWNJ */ || ch.unicode() == 0x200d /* ZWJ */)
+ ch == 0x200c /* ZWNJ */ || ch == 0x200d /* ZWJ */)
return true;
- switch (ch.category()) {
+ switch (QChar::category(ch)) {
case QChar::Mark_NonSpacing:
case QChar::Mark_SpacingCombining:
@@ -412,19 +453,23 @@ int Lexer::scanToken()
return tk;
}
+ if (_bracesCount == 0) {
+ // we're inside a Template string
+ return scanString(TemplateContinuation);
+ }
+
+
_terminator = false;
again:
_validTokenText = false;
- _tokenLinePtr = _lastLinePtr;
while (_char.isSpace()) {
- if (unsigned sequenceLength = isLineTerminatorSequence()) {
- _tokenLinePtr = _codePtr + sequenceLength - 1;
-
+ if (isLineTerminator()) {
if (_restrictedKeyword) {
// automatic semicolon insertion
_tokenLine = _currentLineNumber;
+ _tokenColumn = _currentColumnNumber;
_tokenStartPtr = _codePtr - 1;
return T_SEMICOLON;
} else {
@@ -438,6 +483,7 @@ again:
_tokenStartPtr = _codePtr - 1;
_tokenLine = _currentLineNumber;
+ _tokenColumn = _currentColumnNumber;
if (_codePtr > _endPtr)
return EOF_SYMBOL;
@@ -501,6 +547,9 @@ again:
return T_EQ_EQ_EQ;
}
return T_EQ_EQ;
+ } else if (_char == QLatin1Char('>')) {
+ scanChar();
+ return T_ARROW;
}
return T_EQ;
@@ -557,50 +606,18 @@ again:
return T_DIVIDE_;
case '.':
- if (_char.isDigit()) {
- QVarLengthArray<char,32> chars;
-
- chars.append(ch.unicode()); // append the `.'
-
- while (_char.isDigit()) {
- chars.append(_char.unicode());
+ if (isDecimalDigit(_char.unicode()))
+ return scanNumber(ch);
+ if (_char == QLatin1Char('.')) {
+ scanChar();
+ if (_char == QLatin1Char('.')) {
scanChar();
- }
-
- if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
- if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
- _codePtr[1].isDigit())) {
-
- chars.append(_char.unicode());
- scanChar(); // consume `e'
-
- if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
- chars.append(_char.unicode());
- scanChar(); // consume the sign
- }
-
- while (_char.isDigit()) {
- chars.append(_char.unicode());
- scanChar();
- }
- }
- }
-
- chars.append('\0');
-
- const char *begin = chars.constData();
- const char *end = nullptr;
- bool ok = false;
-
- _tokenValue = qstrtod(begin, &end, &ok);
-
- if (end - begin != chars.size() - 1) {
- _errorCode = IllegalExponentIndicator;
- _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal syntax for exponential number");
+ return T_ELLIPSIS;
+ } else {
+ _errorCode = IllegalCharacter;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Unexpected token '.'");
return T_ERROR;
}
-
- return T_NUMERIC_LITERAL;
}
return T_DOT;
@@ -642,6 +659,9 @@ again:
if (_char == QLatin1Char('=')) {
scanChar();
return T_STAR_EQ;
+ } else if (_char == QLatin1Char('*')) {
+ scanChar();
+ return T_STAR_STAR;
}
return T_STAR;
@@ -676,141 +696,12 @@ again:
}
return T_NOT;
+ case '`':
+ _outerTemplateBraceCount.push(_bracesCount);
+ Q_FALLTHROUGH();
case '\'':
- case '"': {
- const QChar quote = ch;
- bool multilineStringLiteral = false;
-
- const QChar *startCode = _codePtr;
-
- if (_engine) {
- while (_codePtr <= _endPtr) {
- if (isLineTerminator()) {
- if (qmlMode())
- break;
- _errorCode = IllegalCharacter;
- _errorMessage = QCoreApplication::translate("QQmlParser", "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);
- scanChar();
-
- return T_STRING_LITERAL;
- }
- scanChar();
- }
- }
-
- _validTokenText = true;
- _tokenText.resize(0);
- startCode--;
- while (startCode != _codePtr - 1)
- _tokenText += *startCode++;
-
- while (_codePtr <= _endPtr) {
- if (unsigned sequenceLength = isLineTerminatorSequence()) {
- multilineStringLiteral = true;
- _tokenText += _char;
- if (sequenceLength == 2)
- _tokenText += *_codePtr;
- scanChar();
- } else if (_char == quote) {
- scanChar();
-
- if (_engine)
- _tokenSpell = _engine->newStringRef(_tokenText);
-
- return multilineStringLiteral ? T_MULTILINE_STRING_LITERAL : T_STRING_LITERAL;
- } else if (_char == QLatin1Char('\\')) {
- scanChar();
- if (_codePtr > _endPtr) {
- _errorCode = IllegalEscapeSequence;
- _errorMessage = QCoreApplication::translate("QQmlParser", "End of file reached at escape sequence");
- return T_ERROR;
- }
-
- QChar u;
-
- switch (_char.unicode()) {
- // unicode escape sequence
- case 'u': {
- bool ok = false;
- u = decodeUnicodeEscapeCharacter(&ok);
- if (! ok) {
- _errorCode = IllegalUnicodeEscapeSequence;
- _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence");
- return T_ERROR;
- }
- } break;
-
- // hex escape sequence
- case 'x': {
- bool ok = false;
- u = decodeHexEscapeCharacter(&ok);
- if (!ok) {
- _errorCode = IllegalHexadecimalEscapeSequence;
- _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal hexadecimal escape sequence");
- return T_ERROR;
- }
- } break;
-
- // single character escape sequence
- case '\\': u = QLatin1Char('\\'); scanChar(); break;
- case '\'': u = QLatin1Char('\''); scanChar(); break;
- case '\"': u = QLatin1Char('\"'); scanChar(); break;
- case 'b': u = QLatin1Char('\b'); scanChar(); break;
- case 'f': u = QLatin1Char('\f'); scanChar(); break;
- case 'n': u = QLatin1Char('\n'); scanChar(); break;
- case 'r': u = QLatin1Char('\r'); scanChar(); break;
- case 't': u = QLatin1Char('\t'); scanChar(); break;
- case 'v': u = QLatin1Char('\v'); scanChar(); break;
-
- case '0':
- if (! _codePtr->isDigit()) {
- scanChar();
- u = QLatin1Char('\0');
- break;
- }
- Q_FALLTHROUGH();
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- _errorCode = IllegalEscapeSequence;
- _errorMessage = QCoreApplication::translate("QQmlParser", "Octal escape sequences are not allowed");
- return T_ERROR;
-
- case '\r':
- case '\n':
- case 0x2028u:
- case 0x2029u:
- scanChar();
- continue;
-
- default:
- // non escape character
- u = _char;
- scanChar();
- }
-
- _tokenText += u;
- } else {
- _tokenText += _char;
- scanChar();
- }
- }
-
- _errorCode = UnclosedStringLiteral;
- _errorMessage = QCoreApplication::translate("QQmlParser", "Unclosed string at end of line");
- return T_ERROR;
- }
+ case '"':
+ return scanString(ScanStringMode(ch.unicode()));
case '0':
case '1':
case '2':
@@ -824,28 +715,36 @@ again:
return scanNumber(ch);
default: {
- QChar c = ch;
+ uint c = ch.unicode();
bool identifierWithEscapeChars = false;
- if (c == QLatin1Char('\\') && _char == QLatin1Char('u')) {
+ if (QChar::isHighSurrogate(c) && QChar::isLowSurrogate(_char.unicode())) {
+ c = QChar::surrogateToUcs4(ushort(c), _char.unicode());
+ scanChar();
+ } else if (c == '\\' && _char == QLatin1Char('u')) {
identifierWithEscapeChars = true;
bool ok = false;
c = decodeUnicodeEscapeCharacter(&ok);
- if (! ok) {
- _errorCode = IllegalUnicodeEscapeSequence;
- _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence");
+ if (!ok)
return T_ERROR;
- }
}
if (isIdentifierStart(c)) {
if (identifierWithEscapeChars) {
_tokenText.resize(0);
- _tokenText += c;
+ if (QChar::requiresSurrogates(c)) {
+ _tokenText += QChar(QChar::highSurrogate(c));
+ _tokenText += QChar(QChar::lowSurrogate(c));
+ } else {
+ _tokenText += QChar(c);
+ }
_validTokenText = true;
}
- while (true) {
- c = _char;
- if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
- if (! identifierWithEscapeChars) {
+ while (_codePtr <= _endPtr) {
+ c = _char.unicode();
+ if (QChar::isHighSurrogate(c) && QChar::isLowSurrogate(_codePtr->unicode())) {
+ scanChar();
+ c = QChar::surrogateToUcs4(ushort(c), _char.unicode());
+ } else if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
+ if (!identifierWithEscapeChars) {
identifierWithEscapeChars = true;
_tokenText.resize(0);
_tokenText.insert(0, _tokenStartPtr, _codePtr - _tokenStartPtr - 1);
@@ -855,38 +754,52 @@ again:
scanChar(); // skip '\\'
bool ok = false;
c = decodeUnicodeEscapeCharacter(&ok);
- if (! ok) {
- _errorCode = IllegalUnicodeEscapeSequence;
- _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence");
+ if (!ok)
return T_ERROR;
- }
- if (isIdentifierPart(c))
- _tokenText += c;
- continue;
- } else if (isIdentifierPart(c)) {
- if (identifierWithEscapeChars)
- _tokenText += c;
- scanChar();
+ if (!isIdentifierPart(c))
+ break;
+
+ if (identifierWithEscapeChars) {
+ if (QChar::requiresSurrogates(c)) {
+ _tokenText += QChar(QChar::highSurrogate(c));
+ _tokenText += QChar(QChar::lowSurrogate(c));
+ } else {
+ _tokenText += QChar(c);
+ }
+ }
continue;
}
- _tokenLength = _codePtr - _tokenStartPtr - 1;
+ if (!isIdentifierPart(c))
+ break;
- int kind = T_IDENTIFIER;
+ if (identifierWithEscapeChars) {
+ if (QChar::requiresSurrogates(c)) {
+ _tokenText += QChar(QChar::highSurrogate(c));
+ _tokenText += QChar(QChar::lowSurrogate(c));
+ } else {
+ _tokenText += QChar(c);
+ }
+ }
+ scanChar();
+ }
- if (! identifierWithEscapeChars)
- kind = classify(_tokenStartPtr, _tokenLength, _qmlMode);
+ _tokenLength = _codePtr - _tokenStartPtr - 1;
- if (_engine) {
- if (kind == T_IDENTIFIER && identifierWithEscapeChars)
- _tokenSpell = _engine->newStringRef(_tokenText);
- else
- _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
- }
+ int kind = T_IDENTIFIER;
- return kind;
+ if (!identifierWithEscapeChars)
+ kind = classify(_tokenStartPtr, _tokenLength, parseModeFlags());
+
+ if (_engine) {
+ if (kind == T_IDENTIFIER && identifierWithEscapeChars)
+ _tokenSpell = _engine->newStringRef(_tokenText);
+ else
+ _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength);
}
+
+ return kind;
}
}
@@ -896,93 +809,278 @@ again:
return T_ERROR;
}
-int Lexer::scanNumber(QChar ch)
+int Lexer::scanString(ScanStringMode mode)
{
- if (ch != QLatin1Char('0')) {
- QVarLengthArray<char, 64> buf;
- buf += ch.toLatin1();
-
- QChar n = _char;
- const QChar *code = _codePtr;
- while (n.isDigit()) {
- buf += n.toLatin1();
- n = *code++;
- }
+ QChar quote = (mode == TemplateContinuation) ? QChar(TemplateHead) : QChar(mode);
+ bool multilineStringLiteral = false;
+
+ const QChar *startCode = _codePtr;
- if (n != QLatin1Char('.') && n != QLatin1Char('e') && n != QLatin1Char('E')) {
- if (code != _codePtr) {
- _codePtr = code - 1;
+ if (_engine) {
+ while (_codePtr <= _endPtr) {
+ if (isLineTerminator()) {
+ if (qmlMode())
+ break;
+ _errorCode = IllegalCharacter;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Stray newline in string literal");
+ return T_ERROR;
+ } else if (_char == QLatin1Char('\\')) {
+ break;
+ } else if (_char == '$' && quote == QLatin1Char('`')) {
+ break;
+ } else if (_char == quote) {
+ _tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode);
scanChar();
+
+ if (quote == QLatin1Char('`'))
+ _bracesCount = _outerTemplateBraceCount.pop();
+
+ if (mode == TemplateHead)
+ return T_NO_SUBSTITUTION_TEMPLATE;
+ else if (mode == TemplateContinuation)
+ return T_TEMPLATE_TAIL;
+ else
+ return T_STRING_LITERAL;
}
- buf.append('\0');
- _tokenValue = strtod(buf.constData(), nullptr);
- return T_NUMERIC_LITERAL;
+ scanChar();
}
- } else if (_char.isDigit() && !qmlMode()) {
- _errorCode = IllegalCharacter;
- _errorMessage = QCoreApplication::translate("QQmlParser", "Decimal numbers can't start with '0'");
- return T_ERROR;
}
- QVarLengthArray<char,32> chars;
- chars.append(ch.unicode());
+ _validTokenText = true;
+ _tokenText.resize(0);
+ startCode--;
+ while (startCode != _codePtr - 1)
+ _tokenText += *startCode++;
+
+ while (_codePtr <= _endPtr) {
+ if (unsigned sequenceLength = isLineTerminatorSequence()) {
+ multilineStringLiteral = true;
+ _tokenText += _char;
+ if (sequenceLength == 2)
+ _tokenText += *_codePtr;
+ scanChar();
+ } else if (_char == mode) {
+ scanChar();
- if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) {
- ch = _char; // remember the x or X to use it in the error message below.
+ if (_engine)
+ _tokenSpell = _engine->newStringRef(_tokenText);
- // parse hex integer literal
- chars.append(_char.unicode());
- scanChar(); // consume `x'
+ if (quote == QLatin1Char('`'))
+ _bracesCount = _outerTemplateBraceCount.pop();
- while (isHexDigit(_char)) {
- chars.append(_char.unicode());
+ if (mode == TemplateContinuation)
+ return T_TEMPLATE_TAIL;
+ else if (mode == TemplateHead)
+ return T_NO_SUBSTITUTION_TEMPLATE;
+
+ return multilineStringLiteral ? T_MULTILINE_STRING_LITERAL : T_STRING_LITERAL;
+ } else if (quote == QLatin1Char('`') && _char == QLatin1Char('$') && *_codePtr == '{') {
+ scanChar();
+ scanChar();
+ _bracesCount = 1;
+ if (_engine)
+ _tokenSpell = _engine->newStringRef(_tokenText);
+
+ return (mode == TemplateHead ? T_TEMPLATE_HEAD : T_TEMPLATE_MIDDLE);
+ } else if (_char == QLatin1Char('\\')) {
+ scanChar();
+ if (_codePtr > _endPtr) {
+ _errorCode = IllegalEscapeSequence;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "End of file reached at escape sequence");
+ return T_ERROR;
+ }
+
+ QChar u;
+
+ switch (_char.unicode()) {
+ // unicode escape sequence
+ case 'u': {
+ bool ok = false;
+ uint codePoint = decodeUnicodeEscapeCharacter(&ok);
+ if (!ok)
+ return T_ERROR;
+ if (QChar::requiresSurrogates(codePoint)) {
+ // need to use a surrogate pair
+ _tokenText += QChar(QChar::highSurrogate(codePoint));
+ u = QChar::lowSurrogate(codePoint);
+ } else {
+ u = codePoint;
+ }
+ } break;
+
+ // hex escape sequence
+ case 'x': {
+ bool ok = false;
+ u = decodeHexEscapeCharacter(&ok);
+ if (!ok) {
+ _errorCode = IllegalHexadecimalEscapeSequence;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal hexadecimal escape sequence");
+ return T_ERROR;
+ }
+ } break;
+
+ // single character escape sequence
+ case '\\': u = QLatin1Char('\\'); scanChar(); break;
+ case '\'': u = QLatin1Char('\''); scanChar(); break;
+ case '\"': u = QLatin1Char('\"'); scanChar(); break;
+ case 'b': u = QLatin1Char('\b'); scanChar(); break;
+ case 'f': u = QLatin1Char('\f'); scanChar(); break;
+ case 'n': u = QLatin1Char('\n'); scanChar(); break;
+ case 'r': u = QLatin1Char('\r'); scanChar(); break;
+ case 't': u = QLatin1Char('\t'); scanChar(); break;
+ case 'v': u = QLatin1Char('\v'); scanChar(); break;
+
+ case '0':
+ if (! _codePtr->isDigit()) {
+ scanChar();
+ u = QLatin1Char('\0');
+ break;
+ }
+ Q_FALLTHROUGH();
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ _errorCode = IllegalEscapeSequence;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Octal escape sequences are not allowed");
+ return T_ERROR;
+
+ case '\r':
+ case '\n':
+ case 0x2028u:
+ case 0x2029u:
+ scanChar();
+ continue;
+
+ default:
+ // non escape character
+ u = _char;
+ scanChar();
+ }
+
+ _tokenText += u;
+ } else {
+ _tokenText += _char;
scanChar();
}
+ }
- if (chars.size() < 3) {
- _errorCode = IllegalHexNumber;
- _errorMessage = QCoreApplication::translate("QQmlParser", "At least one hexadecimal digit is required after '0%1'").arg(ch);
+ _errorCode = UnclosedStringLiteral;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Unclosed string at end of line");
+ return T_ERROR;
+}
+
+int Lexer::scanNumber(QChar ch)
+{
+ if (ch == QLatin1Char('0')) {
+ if (_char == QLatin1Char('x') || _char == QLatin1Char('X')) {
+ ch = _char; // remember the x or X to use it in the error message below.
+
+ // parse hex integer literal
+ scanChar(); // consume 'x'
+
+ if (!isHexDigit(_char)) {
+ _errorCode = IllegalNumber;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "At least one hexadecimal digit is required after '0%1'").arg(ch);
+ return T_ERROR;
+ }
+
+ double d = 0.;
+ while (1) {
+ int digit = ::hexDigit(_char);
+ if (digit < 0)
+ break;
+ d *= 16;
+ d += digit;
+ scanChar();
+ }
+
+ _tokenValue = d;
+ return T_NUMERIC_LITERAL;
+ } else if (_char == QLatin1Char('o') || _char == QLatin1Char('O')) {
+ ch = _char; // remember the o or O to use it in the error message below.
+
+ // parse octal integer literal
+ scanChar(); // consume 'o'
+
+ if (!isOctalDigit(_char.unicode())) {
+ _errorCode = IllegalNumber;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "At least one octal digit is required after '0%1'").arg(ch);
+ return T_ERROR;
+ }
+
+ double d = 0.;
+ while (1) {
+ int digit = ::octalDigit(_char);
+ if (digit < 0)
+ break;
+ d *= 8;
+ d += digit;
+ scanChar();
+ }
+
+ _tokenValue = d;
+ return T_NUMERIC_LITERAL;
+ } else if (_char == QLatin1Char('b') || _char == QLatin1Char('B')) {
+ ch = _char; // remember the b or B to use it in the error message below.
+
+ // parse binary integer literal
+ scanChar(); // consume 'b'
+
+ if (_char.unicode() != '0' && _char.unicode() != '1') {
+ _errorCode = IllegalNumber;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "At least one binary digit is required after '0%1'").arg(ch);
+ return T_ERROR;
+ }
+
+ double d = 0.;
+ while (1) {
+ int digit = 0;
+ if (_char.unicode() == '1')
+ digit = 1;
+ else if (_char.unicode() != '0')
+ break;
+ d *= 2;
+ d += digit;
+ scanChar();
+ }
+
+ _tokenValue = d;
+ return T_NUMERIC_LITERAL;
+ } else if (_char.isDigit() && !qmlMode()) {
+ _errorCode = IllegalCharacter;
+ _errorMessage = QCoreApplication::translate("QQmlParser", "Decimal numbers can't start with '0'");
return T_ERROR;
}
-
- _tokenValue = integerFromString(chars.constData(), chars.size(), 16);
- return T_NUMERIC_LITERAL;
}
// decimal integer literal
- while (_char.isDigit()) {
- chars.append(_char.unicode());
- scanChar(); // consume the digit
- }
-
- if (_char == QLatin1Char('.')) {
- chars.append(_char.unicode());
- scanChar(); // consume `.'
+ QVarLengthArray<char,32> chars;
+ chars.append(ch.unicode());
+ if (ch != QLatin1Char('.')) {
while (_char.isDigit()) {
chars.append(_char.unicode());
- scanChar();
+ scanChar(); // consume the digit
}
- if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
- if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
- _codePtr[1].isDigit())) {
-
- chars.append(_char.unicode());
- scanChar(); // consume `e'
+ if (_char == QLatin1Char('.')) {
+ chars.append(_char.unicode());
+ scanChar(); // consume `.'
+ }
+ }
- if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
- chars.append(_char.unicode());
- scanChar(); // consume the sign
- }
+ while (_char.isDigit()) {
+ chars.append(_char.unicode());
+ scanChar();
+ }
- while (_char.isDigit()) {
- chars.append(_char.unicode());
- scanChar();
- }
- }
- }
- } else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+ if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
_codePtr[1].isDigit())) {
@@ -1001,12 +1099,6 @@ int Lexer::scanNumber(QChar ch)
}
}
- if (chars.length() == 1) {
- // if we ended up with a single digit, then it was a '0'
- _tokenValue = 0;
- return T_NUMERIC_LITERAL;
- }
-
chars.append('\0');
const char *begin = chars.constData();
@@ -1174,16 +1266,6 @@ bool Lexer::isOctalDigit(ushort c)
return (c >= '0' && c <= '7');
}
-int Lexer::tokenEndLine() const
-{
- return _currentLineNumber;
-}
-
-int Lexer::tokenEndColumn() const
-{
- return _codePtr - _lastLinePtr;
-}
-
QString Lexer::tokenText() const
{
if (_validTokenText)
diff --git a/src/qml/parser/qqmljslexer_p.h b/src/qml/parser/qqmljslexer_p.h
index 11d8081713..a6ac8cb354 100644
--- a/src/qml/parser/qqmljslexer_p.h
+++ b/src/qml/parser/qqmljslexer_p.h
@@ -51,10 +51,11 @@
// We mean it.
//
-#include "qqmljsglobal_p.h"
-#include "qqmljsgrammar_p.h"
+#include <private/qqmljsglobal_p.h>
+#include <private/qqmljsgrammar_p.h>
#include <QtCore/qstring.h>
+#include <QtCore/qstack.h>
QT_QML_BEGIN_NAMESPACE
@@ -62,32 +63,7 @@ namespace QQmlJS {
class Engine;
class DiagnosticMessage;
-
-class QML_PARSER_EXPORT Directives {
-public:
- virtual ~Directives() {}
-
- virtual void pragmaLibrary()
- {
- }
-
- virtual void importFile(const QString &jsfile, const QString &module, int line, int column)
- {
- Q_UNUSED(jsfile);
- Q_UNUSED(module);
- Q_UNUSED(line);
- Q_UNUSED(column);
- }
-
- virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column)
- {
- Q_UNUSED(uri);
- Q_UNUSED(version);
- Q_UNUSED(module);
- Q_UNUSED(line);
- Q_UNUSED(column);
- }
-};
+class Directives;
class QML_PARSER_EXPORT Lexer: public QQmlJSGrammar
{
@@ -97,10 +73,7 @@ public:
T_BOOLEAN = T_RESERVED_WORD,
T_BYTE = T_RESERVED_WORD,
T_CHAR = T_RESERVED_WORD,
- T_CLASS = T_RESERVED_WORD,
T_DOUBLE = T_RESERVED_WORD,
- T_EXPORT = T_RESERVED_WORD,
- T_EXTENDS = T_RESERVED_WORD,
T_FINAL = T_RESERVED_WORD,
T_FLOAT = T_RESERVED_WORD,
T_GOTO = T_RESERVED_WORD,
@@ -113,8 +86,6 @@ public:
T_PRIVATE = T_RESERVED_WORD,
T_PROTECTED = T_RESERVED_WORD,
T_SHORT = T_RESERVED_WORD,
- T_STATIC = T_RESERVED_WORD,
- T_SUPER = T_RESERVED_WORD,
T_SYNCHRONIZED = T_RESERVED_WORD,
T_THROWS = T_RESERVED_WORD,
T_TRANSIENT = T_RESERVED_WORD,
@@ -124,7 +95,7 @@ public:
enum Error {
NoError,
IllegalCharacter,
- IllegalHexNumber,
+ IllegalNumber,
UnclosedStringLiteral,
IllegalEscapeSequence,
IllegalUnicodeEscapeSequence,
@@ -145,10 +116,29 @@ public:
RegExp_Multiline = 0x04
};
+ enum ParseModeFlags {
+ QmlMode = 0x1,
+ YieldIsKeyword = 0x2,
+ StaticIsKeyword = 0x4
+ };
+
public:
Lexer(Engine *engine);
+ int parseModeFlags() const {
+ int flags = 0;
+ if (qmlMode())
+ flags |= QmlMode|StaticIsKeyword;
+ if (yieldIsKeyWord())
+ flags |= YieldIsKeyword;
+ if (_staticIsKeyword)
+ flags |= StaticIsKeyword;
+ return flags;
+ }
+
bool qmlMode() const;
+ bool yieldIsKeyWord() const { return _generatorLevel != 0; }
+ void setStaticIsKeyword(bool b) { _staticIsKeyword = b; }
QString code() const;
void setCode(const QString &code, int lineno, bool qmlMode = true);
@@ -166,10 +156,7 @@ public:
int tokenLength() const { return _tokenLength; }
int tokenStartLine() const { return _tokenLine; }
- int tokenStartColumn() const { return _tokenStartPtr - _tokenLinePtr + 1; }
-
- int tokenEndLine() const;
- int tokenEndColumn() const;
+ int tokenStartColumn() const { return _tokenColumn; }
inline QStringRef tokenSpell() const { return _tokenSpell; }
double tokenValue() const { return _tokenValue; }
@@ -188,13 +175,23 @@ public:
BalancedParentheses
};
+ void enterGeneratorBody() { ++_generatorLevel; }
+ void leaveGeneratorBody() { --_generatorLevel; }
+
protected:
- int classify(const QChar *s, int n, bool qmlMode);
+ static int classify(const QChar *s, int n, int parseModeFlags);
private:
inline void scanChar();
int scanToken();
int scanNumber(QChar ch);
+ enum ScanStringMode {
+ SingleQuote = '\'',
+ DoubleQuote = '"',
+ TemplateHead = '`',
+ TemplateContinuation = 0
+ };
+ int scanString(ScanStringMode mode);
bool isLineTerminator() const;
unsigned isLineTerminatorSequence() const;
@@ -202,10 +199,9 @@ private:
static bool isDecimalDigit(ushort c);
static bool isHexDigit(QChar c);
static bool isOctalDigit(ushort c);
- static bool isUnicodeEscapeSequence(const QChar *chars);
void syncProhibitAutomaticSemicolon();
- QChar decodeUnicodeEscapeCharacter(bool *ok);
+ uint decodeUnicodeEscapeCharacter(bool *ok);
QChar decodeHexEscapeCharacter(bool *ok);
private:
@@ -218,26 +214,30 @@ private:
const QChar *_codePtr;
const QChar *_endPtr;
- const QChar *_lastLinePtr;
- const QChar *_tokenLinePtr;
const QChar *_tokenStartPtr;
QChar _char;
Error _errorCode;
int _currentLineNumber;
+ int _currentColumnNumber;
double _tokenValue;
// parentheses state
ParenthesesState _parenthesesState;
int _parenthesesCount;
+ // template string stack
+ QStack<int> _outerTemplateBraceCount;
+ int _bracesCount = -1;
+
int _stackToken;
int _patternFlags;
int _tokenKind;
int _tokenLength;
int _tokenLine;
+ int _tokenColumn;
bool _validTokenText;
bool _prohibitAutomaticSemicolon;
@@ -246,6 +246,8 @@ private:
bool _followsClosingBrace;
bool _delimited;
bool _qmlMode;
+ int _generatorLevel = 0;
+ bool _staticIsKeyword = false;
};
} // end of namespace QQmlJS
diff --git a/src/qml/parser/qqmljsparser.cpp b/src/qml/parser/qqmljsparser.cpp
deleted file mode 100644
index 24b04b02f9..0000000000
--- a/src/qml/parser/qqmljsparser.cpp
+++ /dev/null
@@ -1,2010 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmljsengine_p.h"
-#include "qqmljslexer_p.h"
-#include "qqmljsast_p.h"
-#include "qqmljsmemorypool_p.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qcoreapplication.h>
-
-#include <string.h>
-
-
-
-#include "qqmljsparser_p.h"
-
-#include <QtCore/qvarlengtharray.h>
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is automatically generated from qqmljs.g.
-// Changes should be made to that file, not here. Any change to this file will
-// be lost!
-//
-// To regenerate this file, run:
-// qlalr --no-debug --no-lines --qt qqmljs.g
-//
-
-using namespace QQmlJS;
-
-QT_QML_BEGIN_NAMESPACE
-
-void Parser::reallocateStack()
-{
- if (! stack_size)
- stack_size = 128;
- else
- stack_size <<= 1;
-
- sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value)));
- state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int)));
- location_stack = reinterpret_cast<AST::SourceLocation*> (realloc(location_stack, stack_size * sizeof(AST::SourceLocation)));
- string_stack = reinterpret_cast<QStringRef*> (realloc(static_cast<void *>(string_stack), stack_size * sizeof(QStringRef)));
-}
-
-Parser::Parser(Engine *engine):
- driver(engine),
- pool(engine->pool()),
- tos(0),
- stack_size(0),
- sym_stack(nullptr),
- state_stack(nullptr),
- location_stack(nullptr),
- string_stack(nullptr),
- program(nullptr),
- yylval(0),
- first_token(nullptr),
- last_token(nullptr)
-{
-}
-
-Parser::~Parser()
-{
- if (stack_size) {
- free(sym_stack);
- free(state_stack);
- free(location_stack);
- free(string_stack);
- }
-}
-
-static inline AST::SourceLocation location(Lexer *lexer)
-{
- AST::SourceLocation loc;
- loc.offset = lexer->tokenOffset();
- loc.length = lexer->tokenLength();
- loc.startLine = lexer->tokenStartLine();
- loc.startColumn = lexer->tokenStartColumn();
- return loc;
-}
-
-AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
-{
- QVarLengthArray<QStringRef, 4> nameIds;
- QVarLengthArray<AST::SourceLocation, 4> locations;
-
- AST::ExpressionNode *it = expr;
- while (AST::FieldMemberExpression *m = AST::cast<AST::FieldMemberExpression *>(it)) {
- nameIds.append(m->name);
- locations.append(m->identifierToken);
- it = m->base;
- }
-
- if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(it)) {
- AST::UiQualifiedId *q = new (pool) AST::UiQualifiedId(idExpr->name);
- q->identifierToken = idExpr->identifierToken;
-
- AST::UiQualifiedId *currentId = q;
- for (int i = nameIds.size() - 1; i != -1; --i) {
- currentId = new (pool) AST::UiQualifiedId(currentId, nameIds[i]);
- currentId->identifierToken = locations[i];
- }
-
- return currentId->finish();
- }
-
- return nullptr;
-}
-
-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 nullptr;
-}
-
-
-bool Parser::parse(int startToken)
-{
- Lexer *lexer = driver->lexer();
- bool hadErrors = false;
- int yytoken = -1;
- int action = 0;
-
- token_buffer[0].token = startToken;
- first_token = &token_buffer[0];
- if (startToken == T_FEED_JS_PROGRAM && !lexer->qmlMode()) {
- Directives ignoreDirectives;
- Directives *directives = driver->directives();
- if (!directives)
- directives = &ignoreDirectives;
- DiagnosticMessage error;
- if (!lexer->scanDirectives(directives, &error)) {
- diagnostic_messages.append(error);
- return false;
- }
- token_buffer[1].token = lexer->tokenKind();
- token_buffer[1].dval = lexer->tokenValue();
- token_buffer[1].loc = location(lexer);
- token_buffer[1].spell = lexer->tokenSpell();
- last_token = &token_buffer[2];
- } else {
- last_token = &token_buffer[1];
- }
-
- tos = -1;
- program = nullptr;
-
- do {
- if (++tos == stack_size)
- reallocateStack();
-
- state_stack[tos] = action;
-
- _Lcheck_token:
- if (yytoken == -1 && -TERMINAL_COUNT != action_index[action]) {
- yyprevlloc = yylloc;
-
- if (first_token == last_token) {
- yytoken = lexer->lex();
- yylval = lexer->tokenValue();
- yytokenspell = lexer->tokenSpell();
- yylloc = location(lexer);
- } else {
- yytoken = first_token->token;
- yylval = first_token->dval;
- yytokenspell = first_token->spell;
- yylloc = first_token->loc;
- ++first_token;
- }
- }
-
- action = t_action(action, yytoken);
- if (action > 0) {
- if (action != ACCEPT_STATE) {
- yytoken = -1;
- sym(1).dval = yylval;
- stringRef(1) = yytokenspell;
- loc(1) = yylloc;
- } else {
- --tos;
- return ! hadErrors;
- }
- } else if (action < 0) {
- const int r = -action - 1;
- tos -= rhs[r];
-
- switch (r) {
-
-case 0: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
-
-case 1: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
-
-case 2: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
-
-case 3: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
-
-case 4: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
-
-case 5: {
- sym(1).Node = sym(2).Node;
- program = sym(1).Node;
-} break;
-
-case 6: {
- sym(1).UiProgram = new (pool) AST::UiProgram(sym(1).UiHeaderItemList,
- sym(2).UiObjectMemberList->finish());
-} break;
-
-case 8: {
- sym(1).Node = sym(1).UiHeaderItemList->finish();
-} break;
-
-case 9: {
- sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiPragma);
-} break;
-
-case 10: {
- sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiImport);
-} break;
-
-case 11: {
- sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiPragma);
-} break;
-
-case 12: {
- sym(1).Node = new (pool) AST::UiHeaderItemList(sym(1).UiHeaderItemList, sym(2).UiImport);
-} break;
-
-case 16: {
- sym(1).UiPragma->semicolonToken = loc(2);
-} break;
-
-case 18: {
- sym(1).UiImport->semicolonToken = loc(2);
-} break;
-
-case 20: {
- sym(1).UiImport->versionToken = loc(2);
- sym(1).UiImport->semicolonToken = loc(3);
-} break;
-
-case 22: {
- sym(1).UiImport->versionToken = loc(2);
- sym(1).UiImport->asToken = loc(3);
- sym(1).UiImport->importIdToken = loc(4);
- sym(1).UiImport->importId = stringRef(4);
- sym(1).UiImport->semicolonToken = loc(5);
-} break;
-
-case 24: {
- sym(1).UiImport->asToken = loc(2);
- sym(1).UiImport->importIdToken = loc(3);
- sym(1).UiImport->importId = stringRef(3);
- sym(1).UiImport->semicolonToken = loc(4);
-} break;
-
-case 25: {
- AST::UiPragma *node = nullptr;
-
- 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;
-
-case 26: {
- AST::UiImport *node = nullptr;
-
- if (AST::StringLiteral *importIdLiteral = AST::cast<AST::StringLiteral *>(sym(2).Expression)) {
- node = new (pool) AST::UiImport(importIdLiteral->value);
- node->fileNameToken = loc(2);
- } else if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(2).Expression)) {
- node = new (pool) AST::UiImport(qualifiedId);
- node->fileNameToken = loc(2);
- }
-
- sym(1).Node = node;
-
- if (node) {
- node->importToken = loc(1);
- } else {
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1),
- QLatin1String("Expected a qualified name id or a string literal")));
-
- return false; // ### remove me
- }
-} break;
-
-case 27: {
- sym(1).Node = nullptr;
-} break;
-
-case 28: {
- sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
-} break;
-
-case 29: {
- sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
-} break;
-
-case 30: {
- AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(
- sym(1).UiObjectMemberList, sym(2).UiObjectMember);
- sym(1).Node = node;
-} break;
-
-case 31: {
- sym(1).Node = new (pool) AST::UiArrayMemberList(sym(1).UiObjectMember);
-} break;
-
-case 32: {
- AST::UiArrayMemberList *node = new (pool) AST::UiArrayMemberList(
- sym(1).UiArrayMemberList, sym(3).UiObjectMember);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 33: {
- AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer((AST::UiObjectMemberList*)nullptr);
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 34: {
- AST::UiObjectInitializer *node = new (pool) AST::UiObjectInitializer(sym(2).UiObjectMemberList->finish());
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 35: {
- AST::UiObjectDefinition *node = new (pool) AST::UiObjectDefinition(sym(1).UiQualifiedId,
- sym(2).UiObjectInitializer);
- sym(1).Node = node;
-} break;
-
-case 37: {
- AST::UiArrayBinding *node = new (pool) AST::UiArrayBinding(
- sym(1).UiQualifiedId, sym(4).UiArrayMemberList->finish());
- node->colonToken = loc(2);
- node->lbracketToken = loc(3);
- node->rbracketToken = loc(5);
- sym(1).Node = node;
-} break;
-
-case 38: {
- AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
- sym(1).UiQualifiedId, sym(3).UiQualifiedId, sym(4).UiObjectInitializer);
- node->colonToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 39: {
- AST::UiObjectBinding *node = new (pool) AST::UiObjectBinding(
- sym(3).UiQualifiedId, sym(1).UiQualifiedId, sym(4).UiObjectInitializer);
- node->colonToken = loc(2);
- node->hasOnToken = true;
- sym(1).Node = node;
-} break;
-
-case 47:
-{
- AST::UiScriptBinding *node = new (pool) AST::UiScriptBinding(
- sym(1).UiQualifiedId, sym(3).Statement);
- node->colonToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 48: {
- AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1));
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 49: {
- AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1));
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 50: {
- AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(stringRef(1));
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 51: {
- AST::UiQualifiedId *node = new (pool) AST::UiQualifiedId(sym(1).UiQualifiedId, stringRef(3));
- node->identifierToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 52: {
- sym(1).Node = nullptr;
-} break;
-
-case 53: {
- sym(1).Node = sym(1).UiParameterList->finish ();
-} break;
-
-case 54: {
- AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiQualifiedId->finish(), stringRef(2));
- node->propertyTypeToken = loc(1);
- node->identifierToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 55: {
- AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(3).UiQualifiedId->finish(), stringRef(4));
- node->propertyTypeToken = loc(3);
- node->commaToken = loc(2);
- node->identifierToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 57: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2));
- node->type = AST::UiPublicMember::Signal;
- node->propertyToken = loc(1);
- node->typeToken = loc(2);
- node->identifierToken = loc(2);
- node->parameters = sym(4).UiParameterList;
- node->semicolonToken = loc(6);
- sym(1).Node = node;
-} break;
-
-case 59: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2));
- node->type = AST::UiPublicMember::Signal;
- node->propertyToken = loc(1);
- node->typeToken = loc(2);
- node->identifierToken = loc(2);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 61: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
- node->typeModifier = stringRef(2);
- node->propertyToken = loc(1);
- node->typeModifierToken = loc(2);
- node->typeToken = loc(4);
- node->identifierToken = loc(6);
- node->semicolonToken = loc(7);
- sym(1).Node = node;
-} break;
-
-case 63: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
- node->propertyToken = loc(1);
- node->typeToken = loc(2);
- node->identifierToken = loc(3);
- node->semicolonToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 65: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4));
- node->isDefaultMember = true;
- node->defaultToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->semicolonToken = loc(5);
- sym(1).Node = node;
-} break;
-
-case 67: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(5).UiQualifiedId->finish(), stringRef(7));
- node->isDefaultMember = true;
- node->defaultToken = loc(1);
- node->typeModifier = stringRef(3);
- node->propertyToken = loc(2);
- node->typeModifierToken = loc(2);
- node->typeToken = loc(4);
- node->identifierToken = loc(7);
- node->semicolonToken = loc(8);
- sym(1).Node = node;
-} break;
-
-case 68: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3),
- sym(5).Statement);
- node->propertyToken = loc(1);
- node->typeToken = loc(2);
- node->identifierToken = loc(3);
- node->colonToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 69: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4),
- sym(6).Statement);
- node->isReadonlyMember = true;
- node->readonlyToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->colonToken = loc(5);
- sym(1).Node = node;
-} break;
-
-case 70: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4),
- sym(6).Statement);
- node->isDefaultMember = true;
- node->defaultToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->colonToken = loc(5);
- sym(1).Node = node;
-} break;
-
-case 71: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
- node->typeModifier = stringRef(2);
- node->propertyToken = loc(1);
- node->typeModifierToken = loc(2);
- node->typeToken = loc(4);
- node->identifierToken = loc(6);
- node->semicolonToken = loc(7); // insert a fake ';' before ':'
-
- AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6));
- propertyName->identifierToken = loc(6);
- propertyName->next = nullptr;
-
- AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(
- propertyName, sym(9).UiArrayMemberList->finish());
- binding->colonToken = loc(7);
- binding->lbracketToken = loc(8);
- binding->rbracketToken = loc(10);
-
- node->binding = binding;
-
- sym(1).Node = node;
-} break;
-
-case 72: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
- node->propertyToken = loc(1);
- node->typeToken = loc(2);
- node->identifierToken = loc(3);
- node->semicolonToken = loc(4); // insert a fake ';' before ':'
-
- AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3));
- propertyName->identifierToken = loc(3);
- propertyName->next = nullptr;
-
- AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
- propertyName, sym(5).UiQualifiedId, sym(6).UiObjectInitializer);
- binding->colonToken = loc(4);
-
- node->binding = binding;
-
- sym(1).Node = node;
-} break;
-
-case 73: {
- AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(3).UiQualifiedId->finish(), stringRef(4));
- node->isReadonlyMember = true;
- node->readonlyToken = loc(1);
- node->propertyToken = loc(2);
- node->typeToken = loc(3);
- node->identifierToken = loc(4);
- node->semicolonToken = loc(5); // insert a fake ';' before ':'
-
- AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4));
- propertyName->identifierToken = loc(4);
- propertyName->next = nullptr;
-
- AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
- propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer);
- binding->colonToken = loc(5);
-
- node->binding = binding;
-
- sym(1).Node = node;
-} break;
-
-case 74: {
- sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
-} break;
-
-case 75: {
- sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
-} break;
-
-case 76: {
- AST::UiEnumDeclaration *enumDeclaration = new (pool) AST::UiEnumDeclaration(stringRef(2), sym(4).UiEnumMemberList->finish());
- enumDeclaration->enumToken = loc(1);
- enumDeclaration->rbraceToken = loc(5);
- sym(1).Node = enumDeclaration;
- break;
-}
-
-case 77: {
- AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1));
- node->memberToken = loc(1);
- sym(1).Node = node;
- break;
-}
-
-case 78: {
- AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1), sym(3).dval);
- node->memberToken = loc(1);
- node->valueToken = loc(3);
- sym(1).Node = node;
- break;
-}
-
-case 79: {
- AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3));
- node->memberToken = loc(3);
- sym(1).Node = node;
- break;
-}
-
-case 80: {
- AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3), sym(5).dval);
- node->memberToken = loc(3);
- node->valueToken = loc(5);
- sym(1).Node = node;
- break;
-}
-
-case 88: {
- AST::ThisExpression *node = new (pool) AST::ThisExpression();
- node->thisToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 89: {
- AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 90: {
- AST::NullExpression *node = new (pool) AST::NullExpression();
- node->nullToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 91: {
- AST::TrueLiteral *node = new (pool) AST::TrueLiteral();
- node->trueToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 92: {
- AST::FalseLiteral *node = new (pool) AST::FalseLiteral();
- node->falseToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 93: {
- AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval);
- node->literalToken = loc(1);
- sym(1).Node = node;
-} break;
-case 94:
-case 95: {
- AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1));
- node->literalToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 96: {
- bool rx = lexer->scanRegExp(Lexer::NoPrefix);
- if (!rx) {
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
- return false; // ### remove me
- }
-
- loc(1).length = lexer->tokenLength();
- yylloc = loc(1); // adjust the location of the current token
-
- AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
- driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
- node->literalToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 97: {
- bool rx = lexer->scanRegExp(Lexer::EqualPrefix);
- if (!rx) {
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
- return false;
- }
-
- loc(1).length = lexer->tokenLength();
- yylloc = loc(1); // adjust the location of the current token
-
- AST::RegExpLiteral *node = new (pool) AST::RegExpLiteral(
- driver->newStringRef(lexer->regExpPattern()), lexer->regExpFlags());
- node->literalToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 98: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) nullptr);
- node->lbracketToken = loc(1);
- node->rbracketToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 99: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish());
- node->lbracketToken = loc(1);
- node->rbracketToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 100: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ());
- node->lbracketToken = loc(1);
- node->rbracketToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 101: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
- (AST::Elision *) nullptr);
- node->lbracketToken = loc(1);
- node->commaToken = loc(3);
- node->rbracketToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 102: {
- AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
- sym(4).Elision->finish());
- node->lbracketToken = loc(1);
- node->commaToken = loc(3);
- node->rbracketToken = loc(5);
- sym(1).Node = node;
-} break;
-
-case 103: {
- AST::ObjectLiteral *node = nullptr;
- if (sym(2).Node)
- node = new (pool) AST::ObjectLiteral(
- sym(2).PropertyAssignmentList->finish ());
- else
- node = new (pool) AST::ObjectLiteral();
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 104: {
- AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
- sym(2).PropertyAssignmentList->finish ());
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 105: {
- AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression);
- node->lparenToken = loc(1);
- node->rparenToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 106: {
- if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) {
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken,
- QLatin1String("Ignored annotation")));
-
- sym(1).Expression = mem->base;
- }
-
- if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) {
- sym(1).UiQualifiedId = qualifiedId;
- } else {
- sym(1).UiQualifiedId = nullptr;
-
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, loc(1),
- QLatin1String("Expected a qualified name id")));
-
- return false; // ### recover
- }
-} break;
-
-case 107: {
- sym(1).Node = new (pool) AST::ElementList((AST::Elision *) nullptr, sym(1).Expression);
-} break;
-
-case 108: {
- sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression);
-} break;
-
-case 109: {
- AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList,
- (AST::Elision *) nullptr, sym(3).Expression);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 110: {
- AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(),
- sym(4).Expression);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 111: {
- AST::Elision *node = new (pool) AST::Elision();
- node->commaToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 112: {
- AST::Elision *node = new (pool) AST::Elision(sym(1).Elision);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 113: {
- AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue(
- sym(1).PropertyName, sym(3).Expression);
- node->colonToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 114: {
- 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;
-
-case 115: {
- 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;
-
-case 116: {
- sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment);
-} break;
-
-case 117: {
- AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList(
- sym(1).PropertyAssignmentList, sym(3).PropertyAssignment);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 118: {
- AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
- node->propertyNameToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 119: {
- AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1));
- node->propertyNameToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 120: {
- AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval);
- node->propertyNameToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 121: {
- AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
- node->propertyNameToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 159: {
- AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
- node->lbracketToken = loc(2);
- node->rbracketToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 160: {
- AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
- node->dotToken = loc(2);
- node->identifierToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 161: {
- AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList);
- node->newToken = loc(1);
- node->lparenToken = loc(3);
- node->rparenToken = loc(5);
- sym(1).Node = node;
-} break;
-
-case 163: {
- AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
- node->newToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 164: {
- AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 165: {
- AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 166: {
- AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
- node->lbracketToken = loc(2);
- node->rbracketToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 167: {
- AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
- node->dotToken = loc(2);
- node->identifierToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 168: {
- sym(1).Node = nullptr;
-} break;
-
-case 169: {
- sym(1).Node = sym(1).ArgumentList->finish();
-} break;
-
-case 170: {
- sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression);
-} break;
-
-case 171: {
- AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 175: {
- AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression);
- node->incrementToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 176: {
- AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression);
- node->decrementToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 178: {
- AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression);
- node->deleteToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 179: {
- AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression);
- node->voidToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 180: {
- AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression);
- node->typeofToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 181: {
- AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression);
- node->incrementToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 182: {
- AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression);
- node->decrementToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 183: {
- AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression);
- node->plusToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 184: {
- AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression);
- node->minusToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 185: {
- AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression);
- node->tildeToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 186: {
- AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression);
- node->notToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 188: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Mul, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 189: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Div, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 190: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Mod, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 192: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Add, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 193: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Sub, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 195: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::LShift, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 196: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::RShift, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 197: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::URShift, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 199: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Lt, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 200: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Gt, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 201: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Le, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 202: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Ge, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 203: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::InstanceOf, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 204: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::In, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 206: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Lt, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 207: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Gt, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 208: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Le, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 209: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Ge, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 210: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::InstanceOf, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 212: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Equal, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 213: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::NotEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 214: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::StrictEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 215: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::StrictNotEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 217: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Equal, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 218: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::NotEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 219: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::StrictEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 220: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::StrictNotEqual, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 222: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitAnd, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 224: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitAnd, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 226: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitXor, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 228: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitXor, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 230: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitOr, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 232: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::BitOr, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 234: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::And, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 236: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::And, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 238: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Or, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 240: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- QSOperator::Or, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 242: {
- AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
- sym(3).Expression, sym(5).Expression);
- node->questionToken = loc(2);
- node->colonToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 244: {
- AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
- sym(3).Expression, sym(5).Expression);
- node->questionToken = loc(2);
- node->colonToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 246: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- sym(2).ival, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 248: {
- AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
- sym(2).ival, sym(3).Expression);
- node->operatorToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 249: {
- sym(1).ival = QSOperator::Assign;
-} break;
-
-case 250: {
- sym(1).ival = QSOperator::InplaceMul;
-} break;
-
-case 251: {
- sym(1).ival = QSOperator::InplaceDiv;
-} break;
-
-case 252: {
- sym(1).ival = QSOperator::InplaceMod;
-} break;
-
-case 253: {
- sym(1).ival = QSOperator::InplaceAdd;
-} break;
-
-case 254: {
- sym(1).ival = QSOperator::InplaceSub;
-} break;
-
-case 255: {
- sym(1).ival = QSOperator::InplaceLeftShift;
-} break;
-
-case 256: {
- sym(1).ival = QSOperator::InplaceRightShift;
-} break;
-
-case 257: {
- sym(1).ival = QSOperator::InplaceURightShift;
-} break;
-
-case 258: {
- sym(1).ival = QSOperator::InplaceAnd;
-} break;
-
-case 259: {
- sym(1).ival = QSOperator::InplaceXor;
-} break;
-
-case 260: {
- sym(1).ival = QSOperator::InplaceOr;
-} break;
-
-case 262: {
- AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 263: {
- sym(1).Node = nullptr;
-} break;
-
-case 266: {
- AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 267: {
- sym(1).Node = nullptr;
-} break;
-
-case 284: {
- AST::Block *node = new (pool) AST::Block(sym(2).StatementList);
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 285: {
- sym(1).Node = new (pool) AST::StatementList(sym(1).Statement);
-} break;
-
-case 286: {
- sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement);
-} break;
-
-case 287: {
- sym(1).Node = nullptr;
-} break;
-
-case 288: {
- sym(1).Node = sym(1).StatementList->finish ();
-} break;
-
-case 290: {
- AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
- if (sym(1).ival == T_LET)
- s = AST::VariableDeclaration::BlockScope;
- else if (sym(1).ival == T_CONST)
- s = AST::VariableDeclaration::ReadOnlyBlockScope;
-
- AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(s));
- node->declarationKindToken = loc(1);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 291: {
- sym(1).ival = T_LET;
-} break;
-
-case 292: {
- sym(1).ival = T_CONST;
-} break;
-
-case 293: {
- sym(1).ival = T_VAR;
-} break;
-
-case 294: {
- sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
-} break;
-
-case 295: {
- AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(
- sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
- node->commaToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 296: {
- sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
-} break;
-
-case 297: {
- sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
-} break;
-
-case 298: {
- AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
- AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s);
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 299: {
- AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
- AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s);
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 300: {
- // ### TODO: AST for initializer
- sym(1) = sym(2);
-} break;
-
-case 301: {
- sym(1).Node = nullptr;
-} break;
-
-case 303: {
- // ### TODO: AST for initializer
- sym(1) = sym(2);
-} break;
-
-case 304: {
- sym(1).Node = nullptr;
-} break;
-
-case 306: {
- AST::EmptyStatement *node = new (pool) AST::EmptyStatement();
- node->semicolonToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 308: {
- AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression);
- node->semicolonToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 309: {
- AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement);
- node->ifToken = loc(1);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- node->elseToken = loc(6);
- sym(1).Node = node;
-} break;
-
-case 310: {
- AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement);
- node->ifToken = loc(1);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 313: {
- AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression);
- node->doToken = loc(1);
- node->whileToken = loc(3);
- node->lparenToken = loc(4);
- node->rparenToken = loc(6);
- node->semicolonToken = loc(7);
- sym(1).Node = node;
-} break;
-
-case 314: {
- AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement);
- node->whileToken = loc(1);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 315: {
- AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression,
- sym(5).Expression, sym(7).Expression, sym(9).Statement);
- node->forToken = loc(1);
- node->lparenToken = loc(2);
- node->firstSemicolonToken = loc(4);
- node->secondSemicolonToken = loc(6);
- node->rparenToken = loc(8);
- sym(1).Node = node;
-} break;
-
-case 316: {
- AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
- AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
- sym(4).VariableDeclarationList->finish(s), sym(6).Expression,
- sym(8).Expression, sym(10).Statement);
- node->forToken = loc(1);
- node->lparenToken = loc(2);
- node->varToken = loc(3);
- node->firstSemicolonToken = loc(5);
- node->secondSemicolonToken = loc(7);
- node->rparenToken = loc(9);
- sym(1).Node = node;
-} break;
-
-case 317: {
- AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression,
- sym(5).Expression, sym(7).Statement);
- node->forToken = loc(1);
- node->lparenToken = loc(2);
- node->inToken = loc(4);
- node->rparenToken = loc(6);
- sym(1).Node = node;
-} break;
-
-case 318: {
- AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(
- sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
- node->forToken = loc(1);
- node->lparenToken = loc(2);
- node->varToken = loc(3);
- node->inToken = loc(5);
- node->rparenToken = loc(7);
- sym(1).Node = node;
-} break;
-
-case 320: {
- AST::ContinueStatement *node = new (pool) AST::ContinueStatement();
- node->continueToken = loc(1);
- node->semicolonToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 322: {
- AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2));
- node->continueToken = loc(1);
- node->identifierToken = loc(2);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 324: {
- AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef());
- node->breakToken = loc(1);
- node->semicolonToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 326: {
- AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2));
- node->breakToken = loc(1);
- node->identifierToken = loc(2);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 328: {
- AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression);
- node->returnToken = loc(1);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 329: {
- AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement);
- node->withToken = loc(1);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 330: {
- AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock);
- node->switchToken = loc(1);
- node->lparenToken = loc(2);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 331: {
- AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses);
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 332: {
- AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
- node->lbraceToken = loc(1);
- node->rbraceToken = loc(5);
- sym(1).Node = node;
-} break;
-
-case 333: {
- sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause);
-} break;
-
-case 334: {
- sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause);
-} break;
-
-case 335: {
- sym(1).Node = nullptr;
-} break;
-
-case 336: {
- sym(1).Node = sym(1).CaseClauses->finish ();
-} break;
-
-case 337: {
- AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList);
- node->caseToken = loc(1);
- node->colonToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 338: {
- AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList);
- node->defaultToken = loc(1);
- node->colonToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 339: {
- 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;
-
-case 341: {
- AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression);
- node->throwToken = loc(1);
- node->semicolonToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 342: {
- AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch);
- node->tryToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 343: {
- AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally);
- node->tryToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 344: {
- AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally);
- node->tryToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 345: {
- AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block);
- node->catchToken = loc(1);
- node->lparenToken = loc(2);
- node->identifierToken = loc(3);
- node->rparenToken = loc(4);
- sym(1).Node = node;
-} break;
-
-case 346: {
- AST::Finally *node = new (pool) AST::Finally(sym(2).Block);
- node->finallyToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 348: {
- AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement();
- node->debuggerToken = loc(1);
- node->semicolonToken = loc(2);
- sym(1).Node = node;
-} break;
-
-case 350: {
- AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
- node->functionToken = loc(1);
- node->identifierToken = loc(2);
- node->lparenToken = loc(3);
- node->rparenToken = loc(5);
- node->lbraceToken = loc(6);
- node->rbraceToken = loc(8);
- sym(1).Node = node;
-} break;
-
-case 351: {
- AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
- node->functionToken = loc(1);
- if (! stringRef(2).isNull())
- node->identifierToken = loc(2);
- node->lparenToken = loc(3);
- node->rparenToken = loc(5);
- node->lbraceToken = loc(6);
- node->rbraceToken = loc(8);
- sym(1).Node = node;
-} break;
-
-case 352: {
- 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;
-
-case 353: {
- AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1));
- node->identifierToken = loc(1);
- sym(1).Node = node;
-} break;
-
-case 354: {
- AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3));
- node->commaToken = loc(2);
- node->identifierToken = loc(3);
- sym(1).Node = node;
-} break;
-
-case 355: {
- sym(1).Node = nullptr;
-} break;
-
-case 356: {
- sym(1).Node = sym(1).FormalParameterList->finish ();
-} break;
-
-case 357: {
- sym(1).Node = nullptr;
-} break;
-
-case 359: {
- sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ());
-} break;
-
-case 361: {
- sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ());
-} break;
-
-case 362: {
- sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement);
-} break;
-
-case 363: {
- sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement);
-} break;
-
-case 364: {
- sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement);
-} break;
-
-case 365: {
- sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration);
-} break;
-
-case 366: {
- sym(1).Node = nullptr;
-} break;
-
- } // switch
- action = nt_action(state_stack[tos], lhs[r] - TERMINAL_COUNT);
- } // if
- } while (action != 0);
-
- if (first_token == last_token) {
- const int errorState = state_stack[tos];
-
- // automatic insertion of `;'
- if (yytoken != -1 && ((t_action(errorState, T_AUTOMATIC_SEMICOLON) && lexer->canInsertAutomaticSemicolon(yytoken))
- || t_action(errorState, T_COMPATIBILITY_SEMICOLON))) {
- SavedToken &tk = token_buffer[0];
- tk.token = yytoken;
- tk.dval = yylval;
- tk.spell = yytokenspell;
- tk.loc = yylloc;
-
- yylloc = yyprevlloc;
- yylloc.offset += yylloc.length;
- yylloc.startColumn += yylloc.length;
- yylloc.length = 0;
-
- //const QString msg = QCoreApplication::translate("QQmlParser", "Missing `;'");
- //diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, yylloc, msg));
-
- first_token = &token_buffer[0];
- last_token = &token_buffer[1];
-
- yytoken = T_SEMICOLON;
- yylval = 0;
-
- action = errorState;
-
- goto _Lcheck_token;
- }
-
- hadErrors = true;
-
- token_buffer[0].token = yytoken;
- token_buffer[0].dval = yylval;
- token_buffer[0].spell = yytokenspell;
- token_buffer[0].loc = yylloc;
-
- token_buffer[1].token = yytoken = lexer->lex();
- token_buffer[1].dval = yylval = lexer->tokenValue();
- token_buffer[1].spell = yytokenspell = lexer->tokenSpell();
- token_buffer[1].loc = yylloc = location(lexer);
-
- if (t_action(errorState, yytoken)) {
- QString msg;
- int token = token_buffer[0].token;
- if (token < 0 || token >= TERMINAL_COUNT)
- msg = QCoreApplication::translate("QQmlParser", "Syntax error");
- else
- msg = QCoreApplication::translate("QQmlParser", "Unexpected token `%1'").arg(QLatin1String(spell[token]));
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
-
- action = errorState;
- goto _Lcheck_token;
- }
-
- static int tokens[] = {
- T_PLUS,
- T_EQ,
-
- T_COMMA,
- T_COLON,
- T_SEMICOLON,
-
- T_RPAREN, T_RBRACKET, T_RBRACE,
-
- T_NUMERIC_LITERAL,
- T_IDENTIFIER,
-
- T_LPAREN, T_LBRACKET, T_LBRACE,
-
- EOF_SYMBOL
- };
-
- for (int *tk = tokens; *tk != EOF_SYMBOL; ++tk) {
- int a = t_action(errorState, *tk);
- if (a > 0 && t_action(a, yytoken)) {
- const QString msg = QCoreApplication::translate("QQmlParser", "Expected token `%1'").arg(QLatin1String(spell[*tk]));
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
-
- yytoken = *tk;
- yylval = 0;
- yylloc = token_buffer[0].loc;
- yylloc.length = 0;
-
- first_token = &token_buffer[0];
- last_token = &token_buffer[2];
-
- action = errorState;
- goto _Lcheck_token;
- }
- }
-
- for (int tk = 1; tk < TERMINAL_COUNT; ++tk) {
- if (tk == T_AUTOMATIC_SEMICOLON || tk == T_FEED_UI_PROGRAM ||
- tk == T_FEED_JS_STATEMENT || tk == T_FEED_JS_EXPRESSION ||
- tk == T_FEED_JS_SOURCE_ELEMENT)
- continue;
-
- int a = t_action(errorState, tk);
- if (a > 0 && t_action(a, yytoken)) {
- const QString msg = QCoreApplication::translate("QQmlParser", "Expected token `%1'").arg(QLatin1String(spell[tk]));
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
-
- yytoken = tk;
- yylval = 0;
- yylloc = token_buffer[0].loc;
- yylloc.length = 0;
-
- action = errorState;
- goto _Lcheck_token;
- }
- }
-
- const QString msg = QCoreApplication::translate("QQmlParser", "Syntax error");
- diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
- }
-
- return false;
-}
-
-QT_QML_END_NAMESPACE
-
-
diff --git a/src/qml/parser/qqmljsparser_p.h b/src/qml/parser/qqmljsparser_p.h
deleted file mode 100644
index b4aecd2f08..0000000000
--- a/src/qml/parser/qqmljsparser_p.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is automatically generated from qqmljs.g.
-// Changes should be made to that file, not here. Any change to this file will
-// be lost!
-//
-// To regenerate this file, run:
-// qlalr --no-debug --no-lines --qt qqmljs.g
-//
-
-#ifndef QQMLJSPARSER_P_H
-#define QQMLJSPARSER_P_H
-
-#include "qqmljsglobal_p.h"
-#include "qqmljsgrammar_p.h"
-#include "qqmljsast_p.h"
-#include "qqmljsengine_p.h"
-
-#include <QtCore/qlist.h>
-#include <QtCore/qstring.h>
-
-QT_QML_BEGIN_NAMESPACE
-
-namespace QQmlJS {
-
-class Engine;
-
-class QML_PARSER_EXPORT Parser: protected QQmlJSGrammar
-{
-public:
- union Value {
- int ival;
- double dval;
- AST::ArgumentList *ArgumentList;
- AST::CaseBlock *CaseBlock;
- AST::CaseClause *CaseClause;
- AST::CaseClauses *CaseClauses;
- AST::Catch *Catch;
- AST::DefaultClause *DefaultClause;
- AST::ElementList *ElementList;
- AST::Elision *Elision;
- AST::ExpressionNode *Expression;
- AST::Finally *Finally;
- AST::FormalParameterList *FormalParameterList;
- AST::FunctionBody *FunctionBody;
- AST::FunctionDeclaration *FunctionDeclaration;
- AST::Node *Node;
- AST::PropertyName *PropertyName;
- AST::PropertyAssignment *PropertyAssignment;
- AST::PropertyAssignmentList *PropertyAssignmentList;
- AST::SourceElement *SourceElement;
- AST::SourceElements *SourceElements;
- AST::Statement *Statement;
- AST::StatementList *StatementList;
- AST::Block *Block;
- AST::VariableDeclaration *VariableDeclaration;
- AST::VariableDeclarationList *VariableDeclarationList;
-
- AST::UiProgram *UiProgram;
- AST::UiHeaderItemList *UiHeaderItemList;
- AST::UiPragma *UiPragma;
- AST::UiImport *UiImport;
- AST::UiParameterList *UiParameterList;
- AST::UiPublicMember *UiPublicMember;
- AST::UiObjectDefinition *UiObjectDefinition;
- AST::UiObjectInitializer *UiObjectInitializer;
- AST::UiObjectBinding *UiObjectBinding;
- AST::UiScriptBinding *UiScriptBinding;
- AST::UiArrayBinding *UiArrayBinding;
- AST::UiObjectMember *UiObjectMember;
- AST::UiObjectMemberList *UiObjectMemberList;
- AST::UiArrayMemberList *UiArrayMemberList;
- AST::UiQualifiedId *UiQualifiedId;
- AST::UiQualifiedPragmaId *UiQualifiedPragmaId;
- AST::UiEnumMemberList *UiEnumMemberList;
- };
-
-public:
- Parser(Engine *engine);
- ~Parser();
-
- // parse a UI program
- bool parse() { return parse(T_FEED_UI_PROGRAM); }
- bool parseStatement() { return parse(T_FEED_JS_STATEMENT); }
- bool parseExpression() { return parse(T_FEED_JS_EXPRESSION); }
- bool parseSourceElement() { return parse(T_FEED_JS_SOURCE_ELEMENT); }
- bool parseUiObjectMember() { return parse(T_FEED_UI_OBJECT_MEMBER); }
- bool parseProgram() { return parse(T_FEED_JS_PROGRAM); }
-
- AST::UiProgram *ast() const
- { return AST::cast<AST::UiProgram *>(program); }
-
- AST::Statement *statement() const
- {
- if (! program)
- return nullptr;
-
- return program->statementCast();
- }
-
- AST::ExpressionNode *expression() const
- {
- if (! program)
- return nullptr;
-
- return program->expressionCast();
- }
-
- AST::UiObjectMember *uiObjectMember() const
- {
- if (! program)
- return nullptr;
-
- return program->uiObjectMemberCast();
- }
-
- AST::Node *rootNode() const
- { return program; }
-
- QList<DiagnosticMessage> diagnosticMessages() const
- { return diagnostic_messages; }
-
- inline DiagnosticMessage diagnosticMessage() const
- {
- for (const DiagnosticMessage &d : diagnostic_messages) {
- if (d.kind != DiagnosticMessage::Warning)
- return d;
- }
-
- return DiagnosticMessage();
- }
-
- inline QString errorMessage() const
- { return diagnosticMessage().message; }
-
- inline int errorLineNumber() const
- { return diagnosticMessage().loc.startLine; }
-
- inline int errorColumnNumber() const
- { return diagnosticMessage().loc.startColumn; }
-
-protected:
- bool parse(int startToken);
-
- void reallocateStack();
-
- inline Value &sym(int index)
- { return sym_stack [tos + index - 1]; }
-
- inline QStringRef &stringRef(int index)
- { return string_stack [tos + index - 1]; }
-
- inline AST::SourceLocation &loc(int index)
- { return location_stack [tos + index - 1]; }
-
- AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr);
- AST::UiQualifiedPragmaId *reparseAsQualifiedPragmaId(AST::ExpressionNode *expr);
-
-protected:
- Engine *driver;
- MemoryPool *pool;
- int tos;
- int stack_size;
- Value *sym_stack;
- int *state_stack;
- AST::SourceLocation *location_stack;
- QStringRef *string_stack;
-
- AST::Node *program;
-
- // error recovery
- enum { TOKEN_BUFFER_SIZE = 3 };
-
- struct SavedToken {
- int token;
- double dval;
- AST::SourceLocation loc;
- QStringRef spell;
- };
-
- double yylval;
- QStringRef yytokenspell;
- AST::SourceLocation yylloc;
- AST::SourceLocation yyprevlloc;
-
- SavedToken token_buffer[TOKEN_BUFFER_SIZE];
- SavedToken *first_token;
- SavedToken *last_token;
-
- QList<DiagnosticMessage> diagnostic_messages;
-};
-
-} // end of namespace QQmlJS
-
-
-
-#define J_SCRIPT_REGEXPLITERAL_RULE1 96
-
-#define J_SCRIPT_REGEXPLITERAL_RULE2 97
-
-QT_QML_END_NAMESPACE
-
-
-
-#endif // QQMLJSPARSER_P_H
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index 2137877427..940ebb3257 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -73,7 +73,7 @@ include(jsruntime/jsruntime.pri)
include(jit/jit.pri)
include(qml/qml.pri)
include(debugger/debugger.pri)
-qtConfig(animation) {
+qtConfig(qml-animation) {
include(animations/animations.pri)
}
include(types/types.pri)
diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri
index 412dc6cba2..6d69294c17 100644
--- a/src/qml/qml/qml.pri
+++ b/src/qml/qml/qml.pri
@@ -20,7 +20,6 @@ SOURCES += \
$$PWD/qqmlinfo.cpp \
$$PWD/qqmlerror.cpp \
$$PWD/qqmlvaluetype.cpp \
- $$PWD/qqmlxmlhttprequest.cpp \
$$PWD/qqmlcleanup.cpp \
$$PWD/qqmlpropertycache.cpp \
$$PWD/qqmlnotifier.cpp \
@@ -31,7 +30,6 @@ SOURCES += \
$$PWD/qqmlextensionplugin.cpp \
$$PWD/qqmlimport.cpp \
$$PWD/qqmllist.cpp \
- $$PWD/qqmllocale.cpp \
$$PWD/qqmljavascriptexpression.cpp \
$$PWD/qqmlabstractbinding.cpp \
$$PWD/qqmlvaluetypeproxybinding.cpp \
@@ -85,7 +83,6 @@ HEADERS += \
$$PWD/qqmldata_p.h \
$$PWD/qqmlerror.h \
$$PWD/qqmlvaluetype_p.h \
- $$PWD/qqmlxmlhttprequest_p.h \
$$PWD/qqmlcleanup_p.h \
$$PWD/qqmlpropertycache_p.h \
$$PWD/qqmlpropertyindex_p.h \
@@ -99,7 +96,6 @@ HEADERS += \
$$PWD/qqmlimport_p.h \
$$PWD/qqmlextensionplugin.h \
$$PWD/qqmlscriptstring_p.h \
- $$PWD/qqmllocale_p.h \
$$PWD/qqmlcomponentattached_p.h \
$$PWD/qqmljavascriptexpression_p.h \
$$PWD/qqmlabstractbinding_p.h \
@@ -120,5 +116,22 @@ HEADERS += \
$$PWD/qqmldelayedcallqueue_p.h \
$$PWD/qqmlloggingcategory_p.h
+qtConfig(qml-xml-http-request) {
+ HEADERS += \
+ $$PWD/qqmlxmlhttprequest_p.h
+
+ SOURCES += \
+ $$PWD/qqmlxmlhttprequest.cpp
+
+}
+
+qtConfig(qml-locale) {
+ HEADERS += \
+ $$PWD/qqmllocale_p.h
+
+ SOURCES += \
+ $$PWD/qqmllocale.cpp
+}
+
include(ftw/ftw.pri)
include(v8/v8.pri)
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index fe4768db15..517c216873 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1421,7 +1421,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
QQmlComponentExtension *e = componentExtension(args->v4engine());
- QV4::Scoped<QV4::QmlIncubatorObject> r(scope, v4->memoryManager->allocObject<QV4::QmlIncubatorObject>(mode));
+ QV4::Scoped<QV4::QmlIncubatorObject> r(scope, v4->memoryManager->allocate<QV4::QmlIncubatorObject>(mode));
QV4::ScopedObject p(scope, e->incubationProto.value());
r->setPrototype(p);
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 7e11177caa..b72e07d97b 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -48,7 +48,6 @@
#include "qqmlcomponent.h"
#include "qqmlvme_p.h"
#include "qqmlstringconverters_p.h"
-#include "qqmlxmlhttprequest_p.h"
#include "qqmlscriptstring.h"
#include "qqmlglobal_p.h"
#include "qqmlcomponent_p.h"
@@ -79,13 +78,17 @@
#include <private/qobject_p.h>
#include <private/qmetaobject_p.h>
+#if QT_CONFIG(qml_locale)
#include <private/qqmllocale_p.h>
+#endif
#include <private/qqmlbind_p.h>
#include <private/qqmlconnections_p.h>
-#if QT_CONFIG(animation)
+#if QT_CONFIG(qml_animation)
#include <private/qqmltimer_p.h>
#endif
+#if QT_CONFIG(qml_list_model)
#include <private/qqmllistmodel_p.h>
+#endif
#include <private/qqmlplatform_p.h>
#include <private/qquickpackage_p.h>
#if QT_CONFIG(qml_delegate_model)
@@ -219,7 +222,7 @@ void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int
qmlRegisterType<QQmlBind,8>(uri, versionMajor, (versionMinor < 8 ? 8 : versionMinor), "Binding"); //Only available in >=2.8
qmlRegisterType<QQmlConnections,1>(uri, versionMajor, (versionMinor < 3 ? 3 : versionMinor), "Connections"); //Only available in >=2.3
qmlRegisterType<QQmlConnections>(uri, versionMajor, versionMinor,"Connections");
-#if QT_CONFIG(animation)
+#if QT_CONFIG(qml_animation)
qmlRegisterType<QQmlTimer>(uri, versionMajor, versionMinor,"Timer");
#endif
qmlRegisterType<QQmlInstantiator>(uri, versionMajor, (versionMinor < 1 ? 1 : versionMinor), "Instantiator"); //Only available in >=2.1
@@ -232,8 +235,10 @@ void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int
// These QtQuick types' implementation resides in the QtQml module
void QQmlEnginePrivate::registerQtQuick2Types(const char *uri, int versionMajor, int versionMinor)
{
+#if QT_CONFIG(qml_list_model)
qmlRegisterType<QQmlListElement>(uri, versionMajor, versionMinor, "ListElement"); // Now in QtQml.Models, here for compatibility
qmlRegisterCustomType<QQmlListModel>(uri, versionMajor, versionMinor, "ListModel", new QQmlListModelParser); // Now in QtQml.Models, here for compatibility
+#endif
qmlRegisterType<QQuickWorkerScript>(uri, versionMajor, versionMinor, "WorkerScript");
qmlRegisterType<QQuickPackage>(uri, versionMajor, versionMinor, "Package");
#if QT_CONFIG(qml_delegate_model)
@@ -250,7 +255,9 @@ void QQmlEnginePrivate::defineQtQuick2Module()
// register the QtQuick2 types which are implemented in the QtQml module.
registerQtQuick2Types("QtQuick",2,0);
+#if QT_CONFIG(qml_locale)
qmlRegisterUncreatableType<QQmlLocale>("QtQuick", 2, 0, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
+#endif
// Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
qmlRegisterModule("QtQuick", 2, QT_VERSION_MINOR);
@@ -951,7 +958,9 @@ void QQmlEnginePrivate::init()
if (baseModulesUninitialized) {
qmlRegisterType<QQmlComponent>("QML", 1, 0, "Component"); // required for the Compiler.
registerBaseTypes("QtQml", 2, 0); // import which provides language building blocks.
+#if QT_CONFIG(qml_locale)
qmlRegisterUncreatableType<QQmlLocale>("QtQml", 2, 2, "Locale", QQmlEngine::tr("Locale cannot be instantiated. Use Qt.locale()"));
+#endif
// Auto-increment the import to stay in sync with ALL future QtQml minor versions from 5.11 onward
qmlRegisterModule("QtQml", 2, QT_VERSION_MINOR);
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index 3fbe3df2ab..62ad9988d5 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -74,7 +74,7 @@ ReturnedValue QmlListWrapper::create(ExecutionEngine *engine, QObject *object, i
Scope scope(engine);
- Scoped<QmlListWrapper> r(scope, engine->memoryManager->allocObject<QmlListWrapper>());
+ Scoped<QmlListWrapper> r(scope, engine->memoryManager->allocate<QmlListWrapper>());
r->d()->object = object;
r->d()->propertyType = propType;
void *args[] = { &r->d()->property(), nullptr };
@@ -86,7 +86,7 @@ ReturnedValue QmlListWrapper::create(ExecutionEngine *engine, const QQmlListProp
{
Scope scope(engine);
- Scoped<QmlListWrapper> r(scope, engine->memoryManager->allocObject<QmlListWrapper>());
+ Scoped<QmlListWrapper> r(scope, engine->memoryManager->allocate<QmlListWrapper>());
r->d()->object = prop.object;
r->d()->property() = prop;
r->d()->propertyType = propType;
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 2a5c58b47b..cea0790280 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -825,7 +825,7 @@ QV4::ReturnedValue QQmlLocale::wrap(ExecutionEngine *v4, const QLocale &locale)
{
QV4::Scope scope(v4);
QV4LocaleDataDeletable *d = localeV4Data(scope.engine);
- QV4::Scoped<QQmlLocaleData> wrapper(scope, v4->memoryManager->allocObject<QQmlLocaleData>());
+ QV4::Scoped<QQmlLocaleData> wrapper(scope, v4->memoryManager->allocate<QQmlLocaleData>());
*wrapper->d()->locale = locale;
QV4::ScopedObject p(scope, d->prototype.value());
wrapper->setPrototype(p);
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 8341b1f555..859c36e11b 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -58,6 +58,8 @@
#include <private/qqmlglobal_p.h>
#include <private/qv4object_p.h>
+QT_REQUIRE_CONFIG(qml_locale);
+
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index ce35e966aa..de077b6d38 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -111,7 +111,7 @@ ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o,
Q_ASSERT(t.isValid());
Scope scope(engine);
- Scoped<QQmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QQmlTypeWrapper>());
+ Scoped<QQmlTypeWrapper> w(scope, engine->memoryManager->allocate<QQmlTypeWrapper>());
w->d()->mode = mode; w->d()->object = o;
w->d()->typePrivate = t.priv();
QQmlType::refHandle(w->d()->typePrivate);
@@ -127,7 +127,7 @@ ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o,
Q_ASSERT(importNamespace);
Scope scope(engine);
- Scoped<QQmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QQmlTypeWrapper>());
+ Scoped<QQmlTypeWrapper> w(scope, engine->memoryManager->allocate<QQmlTypeWrapper>());
w->d()->mode = mode; w->d()->object = o; w->d()->typeNamespace = t; w->d()->importNamespace = importNamespace;
t->addref();
return w.asReturnedValue();
@@ -232,7 +232,7 @@ ReturnedValue QQmlTypeWrapper::get(const Managed *m, String *name, bool *hasProp
value = type.scopedEnumIndex(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok);
if (ok) {
- Scoped<QQmlScopedEnumWrapper> enumWrapper(scope, v4->memoryManager->allocObject<QQmlScopedEnumWrapper>());
+ Scoped<QQmlScopedEnumWrapper> enumWrapper(scope, v4->memoryManager->allocate<QQmlScopedEnumWrapper>());
enumWrapper->d()->typePrivate = type.priv();
QQmlType::refHandle(enumWrapper->d()->typePrivate);
enumWrapper->d()->scopeEnumIndex = value;
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 6196a09d94..c4c4b0b776 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -186,7 +186,7 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *obj
Scope scope(engine);
initProto(engine);
- Scoped<QQmlValueTypeReference> r(scope, engine->memoryManager->allocObject<QQmlValueTypeReference>());
+ Scoped<QQmlValueTypeReference> r(scope, engine->memoryManager->allocate<QQmlValueTypeReference>());
r->d()->object = object;
r->d()->property = property;
r->d()->setPropertyCache(QJSEnginePrivate::get(engine)->cache(metaObject));
@@ -200,7 +200,7 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, const QVaria
Scope scope(engine);
initProto(engine);
- Scoped<QQmlValueTypeWrapper> r(scope, engine->memoryManager->allocObject<QQmlValueTypeWrapper>());
+ Scoped<QQmlValueTypeWrapper> r(scope, engine->memoryManager->allocate<QQmlValueTypeWrapper>());
r->d()->setPropertyCache(QJSEnginePrivate::get(engine)->cache(metaObject));
r->d()->valueType = QQmlValueTypeFactory::valueType(typeId);
r->d()->gadgetPtr = nullptr;
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 567d83f3ee..9d3388c2f2 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -595,7 +595,7 @@ ReturnedValue NodePrototype::getProto(ExecutionEngine *v4)
Scope scope(v4);
QQmlXMLHttpRequestData *d = xhrdata(v4);
if (d->nodePrototype.isUndefined()) {
- ScopedObject p(scope, v4->memoryManager->allocObject<NodePrototype>());
+ ScopedObject p(scope, v4->memoryManager->allocate<NodePrototype>());
d->nodePrototype.set(v4, p);
v4->v8Engine->freezeObject(p);
}
@@ -606,7 +606,7 @@ ReturnedValue Node::create(ExecutionEngine *v4, NodeImpl *data)
{
Scope scope(v4);
- Scoped<Node> instance(scope, v4->memoryManager->allocObject<Node>(data));
+ Scoped<Node> instance(scope, v4->memoryManager->allocate<Node>(data));
ScopedObject p(scope);
switch (data->type) {
@@ -876,7 +876,7 @@ ReturnedValue Document::load(ExecutionEngine *v4, const QByteArray &data)
return Encode::null();
}
- ScopedObject instance(scope, v4->memoryManager->allocObject<Node>(document));
+ ScopedObject instance(scope, v4->memoryManager->allocate<Node>(document));
document->release(); // the GC should own the NodeImpl via Node now
ScopedObject p(scope);
instance->setPrototype((p = Document::prototype(v4)));
@@ -930,7 +930,7 @@ ReturnedValue NamedNodeMap::get(const Managed *m, String *name, bool *hasPropert
ReturnedValue NamedNodeMap::create(ExecutionEngine *v4, NodeImpl *data, const QList<NodeImpl *> &list)
{
- return (v4->memoryManager->allocObject<NamedNodeMap>(data, list))->asReturnedValue();
+ return (v4->memoryManager->allocate<NamedNodeMap>(data, list))->asReturnedValue();
}
ReturnedValue NodeList::getIndexed(const Managed *m, uint index, bool *hasProperty)
@@ -964,7 +964,7 @@ ReturnedValue NodeList::get(const Managed *m, String *name, bool *hasProperty)
ReturnedValue NodeList::create(ExecutionEngine *v4, NodeImpl *data)
{
- return (v4->memoryManager->allocObject<NodeList>(data))->asReturnedValue();
+ return (v4->memoryManager->allocate<NodeList>(data))->asReturnedValue();
}
ReturnedValue Document::method_documentElement(const FunctionObject *b, const Value *thisObject, const Value *, int)
@@ -1643,7 +1643,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
const QQmlXMLHttpRequestCtor *ctor = static_cast<const QQmlXMLHttpRequestCtor *>(f);
QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->v8Engine->networkAccessManager(), scope.engine);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, scope.engine->memoryManager->allocObject<QQmlXMLHttpRequestWrapper>(r));
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, scope.engine->memoryManager->allocate<QQmlXMLHttpRequestWrapper>(r));
ScopedObject proto(scope, ctor->d()->proto);
w->setPrototype(proto);
return w.asReturnedValue();
@@ -2049,7 +2049,7 @@ void *qt_add_qmlxmlhttprequest(ExecutionEngine *v4)
{
Scope scope(v4);
- Scoped<QQmlXMLHttpRequestCtor> ctor(scope, v4->memoryManager->allocObject<QQmlXMLHttpRequestCtor>(v4));
+ Scoped<QQmlXMLHttpRequestCtor> ctor(scope, v4->memoryManager->allocate<QQmlXMLHttpRequestCtor>(v4));
ScopedString s(scope, v4->newString(QStringLiteral("XMLHttpRequest")));
v4->globalObject->defineReadonlyProperty(s, ctor);
diff --git a/src/qml/qml/qqmlxmlhttprequest_p.h b/src/qml/qml/qqmlxmlhttprequest_p.h
index f2836d8301..7515ef8dcc 100644
--- a/src/qml/qml/qqmlxmlhttprequest_p.h
+++ b/src/qml/qml/qqmlxmlhttprequest_p.h
@@ -55,7 +55,7 @@
#include <QtCore/qglobal.h>
#include <private/qqmlglobal_p.h>
-#if QT_CONFIG(xmlstreamreader) && QT_CONFIG(qml_network)
+QT_REQUIRE_CONFIG(qml_xml_http_request);
QT_BEGIN_NAMESPACE
@@ -64,7 +64,5 @@ void qt_rem_qmlxmlhttprequest(QV4::ExecutionEngine *engine, void *);
QT_END_NAMESPACE
-#endif // xmlstreamreader && qml_network
-
#endif // QQMLXMLHTTPREQUEST_P_H
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 9e7c84011b..2ec1d7e87b 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -44,7 +44,9 @@
#include <private/qqmlcomponent_p.h>
#include <private/qqmlloggingcategory_p.h>
#include <private/qqmlstringconverters_p.h>
+#if QT_CONFIG(qml_locale)
#include <private/qqmllocale_p.h>
+#endif
#include <private/qv8engine_p.h>
#include <private/qqmldelayedcallqueue_p.h>
#include <QFileInfo>
@@ -138,7 +140,9 @@ void Heap::QtObject::init(QQmlEngine *qmlEngine)
o->defineDefaultProperty(QStringLiteral("btoa"), QV4::QtObject::method_btoa);
o->defineDefaultProperty(QStringLiteral("atob"), QV4::QtObject::method_atob);
o->defineDefaultProperty(QStringLiteral("resolvedUrl"), QV4::QtObject::method_resolvedUrl);
+#if QT_CONFIG(qml_locale)
o->defineDefaultProperty(QStringLiteral("locale"), QV4::QtObject::method_locale);
+#endif
o->defineDefaultProperty(QStringLiteral("binding"), QV4::QtObject::method_binding);
if (qmlEngine) {
@@ -1309,6 +1313,7 @@ ReturnedValue QtObject::method_createComponent(const FunctionObject *b, const Va
return QV4::QObjectWrapper::wrap(scope.engine, c);
}
+#if QT_CONFIG(qml_locale)
/*!
\qmlmethod Qt::locale(name)
@@ -1343,6 +1348,7 @@ ReturnedValue QtObject::method_locale(const FunctionObject *b, const Value *, co
return QQmlLocale::locale(scope.engine, code);
}
+#endif
void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *bindingFunction)
{
@@ -1413,7 +1419,7 @@ ReturnedValue QtObject::method_binding(const FunctionObject *b, const Value *, c
if (!f)
THROW_TYPE_ERROR_WITH_MESSAGE("binding(): argument (binding expression) must be a function");
- return Encode(scope.engine->memoryManager->allocObject<QQmlBindingFunction>(f));
+ return Encode(scope.engine->memoryManager->allocate<QQmlBindingFunction>(f));
}
@@ -1792,7 +1798,7 @@ void QV4::GlobalExtensions::init(Object *globalObject, QJSEngine::Extensions ext
globalObject->defineDefaultProperty(QStringLiteral("print"), QV4::ConsoleObject::method_log);
- QV4::ScopedObject console(scope, globalObject->engine()->memoryManager->allocObject<QV4::ConsoleObject>());
+ QV4::ScopedObject console(scope, globalObject->engine()->memoryManager->allocate<QV4::ConsoleObject>());
globalObject->defineDefaultProperty(QStringLiteral("console"), console);
}
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index ee3b5f7d6e..e1f82df390 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -126,7 +126,9 @@ struct QtObject : Object
static ReturnedValue method_resolvedUrl(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_createQmlObject(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_createComponent(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+#if QT_CONFIG(qml_locale)
static ReturnedValue method_locale(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+#endif
static ReturnedValue method_binding(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue method_get_platform(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 038a75d50a..8a786e76cf 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -39,14 +39,21 @@
#include "qv8engine_p.h"
+#if QT_CONFIG(qml_sequence_object)
#include "qv4sequenceobject_p.h"
+#endif
+
#include "private/qjsengine_p.h"
#include <private/qqmlbuiltinfunctions_p.h>
#include <private/qqmllist_p.h>
#include <private/qqmlengine_p.h>
+#if QT_CONFIG(qml_xml_http_request)
#include <private/qqmlxmlhttprequest_p.h>
+#endif
+#if QT_CONFIG(qml_locale)
#include <private/qqmllocale_p.h>
+#endif
#include <private/qqmlglobal_p.h>
#include <private/qqmlmemoryprofiler_p.h>
#include <private/qqmlplatform_p.h>
@@ -123,11 +130,12 @@ static void restoreJSValue(QDataStream &stream, void *data)
}
}
-QV8Engine::QV8Engine(QJSEngine *qq, QV4::ExecutionEngine *v4)
- : q(qq)
- , m_engine(nullptr)
+QV8Engine::QV8Engine(QV4::ExecutionEngine *v4)
+ : m_engine(nullptr)
, m_v4Engine(v4)
+#if QT_CONFIG(qml_xml_http_request)
, m_xmlHttpRequestData(nullptr)
+#endif
{
#ifdef Q_PROCESSOR_X86_32
if (!qCpuHasFeature(SSE2)) {
@@ -157,7 +165,7 @@ QV8Engine::~QV8Engine()
qDeleteAll(m_extensionData);
m_extensionData.clear();
-#if QT_CONFIG(xmlstreamreader) && QT_CONFIG(qml_network)
+#if QT_CONFIG(qml_xml_http_request)
qt_rem_qmlxmlhttprequest(m_v4Engine, m_xmlHttpRequestData);
m_xmlHttpRequestData = nullptr;
#endif
@@ -180,14 +188,16 @@ void QV8Engine::initializeGlobal()
QV4::Scope scope(m_v4Engine);
QV4::GlobalExtensions::init(m_v4Engine->globalObject, QJSEngine::AllExtensions);
- QV4::ScopedObject qt(scope, m_v4Engine->memoryManager->allocObject<QV4::QtObject>(m_engine));
+ QV4::ScopedObject qt(scope, m_v4Engine->memoryManager->allocate<QV4::QtObject>(m_engine));
m_v4Engine->globalObject->defineDefaultProperty(QStringLiteral("Qt"), qt);
+#if QT_CONFIG(qml_locale)
QQmlLocale::registerStringLocaleCompare(m_v4Engine);
QQmlDateExtension::registerExtension(m_v4Engine);
QQmlNumberExtension::registerExtension(m_v4Engine);
+#endif
-#if QT_CONFIG(xmlstreamreader) && QT_CONFIG(qml_network)
+#if QT_CONFIG(qml_xml_http_request)
qt_add_domexceptions(m_v4Engine);
m_xmlHttpRequestData = qt_add_qmlxmlhttprequest(m_v4Engine);
#endif
@@ -221,7 +231,7 @@ static void freeze_recursive(QV4::ExecutionEngine *v4, QV4::Object *object)
if (!instanceOfObject)
return;
- QV4::InternalClass *frozen = object->internalClass()->propertiesFrozen();
+ QV4::Heap::InternalClass *frozen = object->internalClass()->propertiesFrozen();
if (object->internalClass() == frozen)
return;
object->setInternalClass(frozen);
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index b6a378667e..d90f1827fe 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -154,10 +154,9 @@ class Q_QML_PRIVATE_EXPORT QV8Engine
friend class QJSEngine;
public:
// static QJSEngine* get(QV8Engine* d) { Q_ASSERT(d); return d->q; }
- static QV4::ExecutionEngine *getV4(QJSEngine *q) { return q->handle(); }
static QV4::ExecutionEngine *getV4(QV8Engine *d) { return d->m_v4Engine; }
- QV8Engine(QJSEngine* qq, QV4::ExecutionEngine *v4);
+ QV8Engine(QV4::ExecutionEngine *v4);
virtual ~QV8Engine();
// This enum should be in sync with QQmlEngine::ObjectOwnership
@@ -170,10 +169,11 @@ public:
void initQmlGlobalObject();
void setEngine(QQmlEngine *engine);
QQmlEngine *engine() { return m_engine; }
- QJSEngine *publicEngine() { return q; }
QQmlDelayedCallQueue *delayedCallQueue() { return &m_delayedCallQueue; }
+#if QT_CONFIG(qml_xml_http_request)
void *xmlHttpRequestData() const { return m_xmlHttpRequestData; }
+#endif
void freezeObject(const QV4::Value &value);
@@ -202,13 +202,14 @@ public:
int consoleCountHelper(const QString &file, quint16 line, quint16 column);
protected:
- QJSEngine* q;
QQmlEngine *m_engine;
QQmlDelayedCallQueue m_delayedCallQueue;
QV4::ExecutionEngine *m_v4Engine;
+#if QT_CONFIG(qml_xml_http_request)
void *m_xmlHttpRequestData;
+#endif
QVector<Deletable *> m_extensionData;
diff --git a/src/qml/qtqmlglobal.h b/src/qml/qtqmlglobal.h
index 6e92867cf5..e02dfa5ed4 100644
--- a/src/qml/qtqmlglobal.h
+++ b/src/qml/qtqmlglobal.h
@@ -52,6 +52,7 @@
# endif
#else
# define QT_FEATURE_qml_debug -1
+# define QT_FEATURE_qml_sequence_object 1
#endif
QT_BEGIN_NAMESPACE
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 44166e4aa8..6915ab6e89 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -93,7 +93,7 @@ struct DelegateModelGroupFunction : QV4::FunctionObject
static Heap::DelegateModelGroupFunction *create(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::Value &arg))
{
- return scope->engine()->memoryManager->allocObject<DelegateModelGroupFunction>(scope, flag, code);
+ return scope->engine()->memoryManager->allocate<DelegateModelGroupFunction>(scope, flag, code);
}
static ReturnedValue call(const QV4::FunctionObject *that, const Value *thisObject, const Value *argv, int argc)
@@ -487,6 +487,35 @@ void QQmlDelegateModel::setRootIndex(const QVariant &root)
}
/*!
+ \qmlproperty int QtQml.Models::DelegateModel::rows
+
+ Contains the number of rows in the model. If the model
+ is a list of items, it will be equal to the number of items
+ in the list.
+
+ \since QtQml.Models 2.12
+*/
+int QQmlDelegateModel::rows() const
+{
+ Q_D(const QQmlDelegateModel);
+ return d->m_adaptorModel.rowCount();
+}
+
+/*!
+ \qmlproperty int QtQml.Models::DelegateModel::columns
+
+ Contains the number of columns in the model. If the model
+ is a list of items, it will be equal to \c 1.
+
+ \since QtQml.Models 2.12
+*/
+int QQmlDelegateModel::columns() const
+{
+ Q_D(const QQmlDelegateModel);
+ return d->m_adaptorModel.columnCount();
+}
+
+/*!
\qmlmethod QModelIndex QtQml.Models::DelegateModel::modelIndex(int index)
QAbstractItemModel provides a hierarchical tree of data, whereas
@@ -1045,7 +1074,10 @@ QQmlIncubator::Status QQmlDelegateModel::incubationStatus(int index)
if (!it->inCache())
return QQmlIncubator::Null;
- return d->m_cache.at(it.cacheIndex)->incubationTask->status();
+ if (auto incubationTask = d->m_cache.at(it.cacheIndex)->incubationTask)
+ return incubationTask->status();
+
+ return QQmlIncubator::Ready;
}
QString QQmlDelegateModelPrivate::stringValue(Compositor::Group group, int index, const QString &name)
@@ -1587,8 +1619,15 @@ void QQmlDelegateModel::_q_rowsMoved(
void QQmlDelegateModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles)
{
Q_D(QQmlDelegateModel);
- if (begin.parent() == d->m_adaptorModel.rootIndex)
- _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, roles);
+ if (begin.parent() != d->m_adaptorModel.rootIndex)
+ return;
+
+ int rowCount = end.row() - begin.row() + 1;
+
+ for (int col = begin.column(); col <= end.column(); ++col) {
+ int startIndex = d->m_adaptorModel.indexAt(begin.row(), col);
+ _q_itemsChanged(startIndex, rowCount, roles);
+ }
}
bool QQmlDelegateModel::isDescendantOf(const QPersistentModelIndex& desc, const QList< QPersistentModelIndex >& parents) const
@@ -2482,7 +2521,7 @@ QQmlV4Handle QQmlDelegateModelGroup::get(int index)
model->m_cacheMetaType->initializePrototype();
QV4::ExecutionEngine *v4 = model->m_cacheMetaType->v4Engine;
QV4::Scope scope(v4);
- QV4::ScopedObject o(scope, v4->memoryManager->allocObject<QQmlDelegateModelItemObject>(cacheItem));
+ QV4::ScopedObject o(scope, v4->memoryManager->allocate<QQmlDelegateModelItemObject>(cacheItem));
QV4::ScopedObject p(scope, model->m_cacheMetaType->modelItemProto.value());
o->setPrototype(p);
++cacheItem->scriptRef;
@@ -3193,7 +3232,10 @@ QQmlIncubator::Status QQmlPartsModel::incubationStatus(int index)
if (!it->inCache())
return QQmlIncubator::Null;
- return model->m_cache.at(it.cacheIndex)->incubationTask->status();
+ if (auto incubationTask = model->m_cache.at(it.cacheIndex)->incubationTask)
+ return incubationTask->status();
+
+ return QQmlIncubator::Ready;
}
int QQmlPartsModel::indexOf(QObject *item, QObject *) const
@@ -3237,7 +3279,7 @@ struct QQmlDelegateModelGroupChange : QV4::Object
V4_OBJECT2(QQmlDelegateModelGroupChange, QV4::Object)
static QV4::Heap::QQmlDelegateModelGroupChange *create(QV4::ExecutionEngine *e) {
- return e->memoryManager->allocObject<QQmlDelegateModelGroupChange>();
+ return e->memoryManager->allocate<QQmlDelegateModelGroupChange>();
}
static QV4::ReturnedValue method_get_index(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
@@ -3274,7 +3316,7 @@ struct QQmlDelegateModelGroupChangeArray : public QV4::Object
public:
static QV4::Heap::QQmlDelegateModelGroupChangeArray *create(QV4::ExecutionEngine *engine, const QVector<QQmlChangeSet::Change> &changes)
{
- return engine->memoryManager->allocObject<QQmlDelegateModelGroupChangeArray>(changes);
+ return engine->memoryManager->allocate<QQmlDelegateModelGroupChangeArray>(changes);
}
quint32 count() const { return d()->changes->count(); }
diff --git a/src/qml/types/qqmldelegatemodel_p.h b/src/qml/types/qqmldelegatemodel_p.h
index b0786cd088..0a76d884ed 100644
--- a/src/qml/types/qqmldelegatemodel_p.h
+++ b/src/qml/types/qqmldelegatemodel_p.h
@@ -88,6 +88,8 @@ class Q_QML_PRIVATE_EXPORT QQmlDelegateModel : public QQmlInstanceModel, public
Q_PROPERTY(QQmlListProperty<QQmlDelegateModelGroup> groups READ groups CONSTANT)
Q_PROPERTY(QObject *parts READ parts CONSTANT)
Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged)
+ Q_PROPERTY(int rows READ rows NOTIFY rowsChanged REVISION 12)
+ Q_PROPERTY(int columns READ columns NOTIFY columnsChanged REVISION 12)
Q_CLASSINFO("DefaultProperty", "delegate")
Q_INTERFACES(QQmlParserStatus)
public:
@@ -107,6 +109,9 @@ public:
QVariant rootIndex() const;
void setRootIndex(const QVariant &root);
+ int rows() const;
+ int columns() const;
+
Q_INVOKABLE QVariant modelIndex(int idx) const;
Q_INVOKABLE QVariant parentModelIndex() const;
@@ -138,6 +143,8 @@ Q_SIGNALS:
void filterGroupChanged();
void defaultGroupsChanged();
void rootIndexChanged();
+ Q_REVISION(12) void rowsChanged();
+ Q_REVISION(12) void columnsChanged();
private Q_SLOTS:
void _q_itemsChanged(int index, int count, const QVector<int> &roles);
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index 18980cfd7c..30401a2105 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -121,7 +121,7 @@ public:
int groupIndex(Compositor::Group group);
int modelIndex() const { return index; }
- void setModelIndex(int idx) { index = idx; Q_EMIT modelIndexChanged(); }
+ virtual void setModelIndex(int idx) { index = idx; Q_EMIT modelIndexChanged(); }
virtual QV4::ReturnedValue get() { return QV4::QObjectWrapper::wrap(v4, this); }
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index c4e33d572d..fd54a51b1d 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -2434,7 +2434,7 @@ QQmlV4Handle QQmlListModel::get(int index) const
QObject *object = m_listModel->getOrCreateModelObject(const_cast<QQmlListModel *>(this), index);
QQmlData *ddata = QQmlData::get(object);
if (ddata->jsWrapper.isNullOrUndefined()) {
- result = scope.engine->memoryManager->allocObject<QV4::ModelObject>(object, const_cast<QQmlListModel *>(this));
+ result = scope.engine->memoryManager->allocate<QV4::ModelObject>(object, const_cast<QQmlListModel *>(this));
// Keep track of the QObjectWrapper in persistent value storage
ddata->jsWrapper.set(scope.engine, result);
} else {
diff --git a/src/qml/types/qqmllistmodel_p.h b/src/qml/types/qqmllistmodel_p.h
index 0c0859dc80..0a9d29ac05 100644
--- a/src/qml/types/qqmllistmodel_p.h
+++ b/src/qml/types/qqmllistmodel_p.h
@@ -64,6 +64,8 @@
#include <private/qv4engine_p.h>
#include <private/qpodvector_p.h>
+QT_REQUIRE_CONFIG(qml_list_model);
+
QT_BEGIN_NAMESPACE
diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h
index ad5e94c909..99e9b30aff 100644
--- a/src/qml/types/qqmllistmodel_p_p.h
+++ b/src/qml/types/qqmllistmodel_p_p.h
@@ -57,6 +57,8 @@
#include <private/qv4qobjectwrapper_p.h>
#include <qqml.h>
+QT_REQUIRE_CONFIG(qml_list_model);
+
QT_BEGIN_NAMESPACE
diff --git a/src/qml/types/qqmllistmodelworkeragent_p.h b/src/qml/types/qqmllistmodelworkeragent_p.h
index 2120f25744..ae2d4b11e0 100644
--- a/src/qml/types/qqmllistmodelworkeragent_p.h
+++ b/src/qml/types/qqmllistmodelworkeragent_p.h
@@ -59,6 +59,8 @@
#include <private/qv8engine_p.h>
+QT_REQUIRE_CONFIG(qml_list_model);
+
QT_BEGIN_NAMESPACE
diff --git a/src/qml/types/qqmlmodelsmodule.cpp b/src/qml/types/qqmlmodelsmodule.cpp
index e217b63c6f..d9756704d1 100644
--- a/src/qml/types/qqmlmodelsmodule.cpp
+++ b/src/qml/types/qqmlmodelsmodule.cpp
@@ -39,7 +39,9 @@
#include "qqmlmodelsmodule_p.h"
#include <QtCore/qitemselectionmodel.h>
+#if QT_CONFIG(qml_list_model)
#include <private/qqmllistmodel_p.h>
+#endif
#if QT_CONFIG(qml_delegate_model)
#include <private/qqmldelegatemodel_p.h>
#endif
@@ -51,10 +53,13 @@ void QQmlModelsModule::defineModule()
{
const char uri[] = "QtQml.Models";
+#if QT_CONFIG(qml_list_model)
qmlRegisterType<QQmlListElement>(uri, 2, 1, "ListElement");
qmlRegisterCustomType<QQmlListModel>(uri, 2, 1, "ListModel", new QQmlListModelParser);
+#endif
#if QT_CONFIG(qml_delegate_model)
qmlRegisterType<QQmlDelegateModel>(uri, 2, 1, "DelegateModel");
+ qmlRegisterType<QQmlDelegateModel,12>(uri, 2, 9, "DelegateModel");
qmlRegisterType<QQmlDelegateModelGroup>(uri, 2, 1, "DelegateModelGroup");
#endif
qmlRegisterType<QQmlObjectModel>(uri, 2, 1, "ObjectModel");
diff --git a/src/qml/types/qqmltimer_p.h b/src/qml/types/qqmltimer_p.h
index d597869994..0160e97a2f 100644
--- a/src/qml/types/qqmltimer_p.h
+++ b/src/qml/types/qqmltimer_p.h
@@ -57,6 +57,8 @@
#include <private/qtqmlglobal_p.h>
+QT_REQUIRE_CONFIG(qml_animation);
+
QT_BEGIN_NAMESPACE
class QQmlTimerPrivate;
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index ef92e4108d..634e2da1c9 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -37,9 +37,12 @@
**
****************************************************************************/
+#include "qtqmlglobal_p.h"
#include "qquickworkerscript_p.h"
+#if QT_CONFIG(qml_list_model)
#include "qqmllistmodel_p.h"
#include "qqmllistmodelworkeragent_p.h"
+#endif
#include <private/qqmlengine_p.h>
#include <private/qqmlexpression_p.h>
@@ -201,7 +204,7 @@ private:
};
QQuickWorkerScriptEnginePrivate::WorkerEngine::WorkerEngine(QQuickWorkerScriptEnginePrivate *parent)
- : QV8Engine(nullptr, new QV4::ExecutionEngine), p(parent)
+ : QV8Engine(new QV4::ExecutionEngine), p(parent)
#if QT_CONFIG(qml_network)
, accessManager(nullptr)
#endif
diff --git a/src/qml/types/types.pri b/src/qml/types/types.pri
index 8bcbd6e544..5d75759281 100644
--- a/src/qml/types/types.pri
+++ b/src/qml/types/types.pri
@@ -1,8 +1,6 @@
SOURCES += \
$$PWD/qqmlbind.cpp \
$$PWD/qqmlconnections.cpp \
- $$PWD/qqmllistmodel.cpp \
- $$PWD/qqmllistmodelworkeragent.cpp \
$$PWD/qqmlmodelsmodule.cpp \
$$PWD/qqmlmodelindexvaluetype.cpp \
$$PWD/qqmlobjectmodel.cpp \
@@ -13,9 +11,6 @@ SOURCES += \
HEADERS += \
$$PWD/qqmlbind_p.h \
$$PWD/qqmlconnections_p.h \
- $$PWD/qqmllistmodel_p.h \
- $$PWD/qqmllistmodel_p_p.h \
- $$PWD/qqmllistmodelworkeragent_p.h \
$$PWD/qqmlmodelsmodule_p.h \
$$PWD/qqmlmodelindexvaluetype_p.h \
$$PWD/qqmlobjectmodel_p.h \
@@ -24,6 +19,17 @@ HEADERS += \
$$PWD/qqmlinstantiator_p.h \
$$PWD/qqmlinstantiator_p_p.h
+qtConfig(qml-list-model) {
+ SOURCES += \
+ $$PWD/qqmllistmodel.cpp \
+ $$PWD/qqmllistmodelworkeragent.cpp
+
+ HEADERS += \
+ $$PWD/qqmllistmodel_p.h \
+ $$PWD/qqmllistmodel_p_p.h \
+ $$PWD/qqmllistmodelworkeragent_p.h
+}
+
qtConfig(qml-delegate-model) {
SOURCES += \
$$PWD/qqmldelegatemodel.cpp
@@ -33,7 +39,7 @@ qtConfig(qml-delegate-model) {
$$PWD/qqmldelegatemodel_p_p.h
}
-qtConfig(animation) {
+qtConfig(qml-animation) {
SOURCES += \
$$PWD/qqmltimer.cpp
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index b4bebb9d5d..c430074f56 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -228,8 +228,8 @@ public:
QV4::ScopedString name(scope, v4->newString(QString::fromUtf8(propertyName)));
QV4::ExecutionContext *global = v4->rootContext();
- QV4::ScopedFunctionObject g(scope, v4->memoryManager->allocObject<QV4::IndexedBuiltinFunction>(global, propertyId, QQmlDMCachedModelData::get_property));
- QV4::ScopedFunctionObject s(scope, v4->memoryManager->allocObject<QV4::IndexedBuiltinFunction>(global, propertyId, QQmlDMCachedModelData::set_property));
+ QV4::ScopedFunctionObject g(scope, v4->memoryManager->allocate<QV4::IndexedBuiltinFunction>(global, propertyId, QQmlDMCachedModelData::get_property));
+ QV4::ScopedFunctionObject s(scope, v4->memoryManager->allocate<QV4::IndexedBuiltinFunction>(global, propertyId, QQmlDMCachedModelData::set_property));
p->setGetter(g);
p->setSetter(s);
proto->insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotEnumerable|QV4::Attr_NotConfigurable);
@@ -330,9 +330,8 @@ bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &, int idx)
{
if (index == -1) {
Q_ASSERT(idx >= 0);
- index = idx;
cachedData.clear();
- emit modelIndexChanged();
+ setModelIndex(idx);
const QMetaObject *meta = metaObject();
const int propertyCount = type->propertyRoles.count();
for (int i = 0; i < propertyCount; ++i)
@@ -399,13 +398,18 @@ QV4::ReturnedValue QQmlDMCachedModelData::set_property(const QV4::FunctionObject
class QQmlDMAbstractItemModelData : public QQmlDMCachedModelData
{
Q_OBJECT
+ Q_PROPERTY(int row MEMBER row NOTIFY rowChanged)
+ Q_PROPERTY(int column MEMBER column NOTIFY columnChanged)
Q_PROPERTY(bool hasModelChildren READ hasModelChildren CONSTANT)
+
public:
QQmlDMAbstractItemModelData(
QQmlDelegateModelItemMetaType *metaType,
VDMModelDelegateDataType *dataType,
int index)
: QQmlDMCachedModelData(metaType, dataType, index)
+ , row(type->model->rowAt(index))
+ , column(type->model->columnAt(index))
{
}
@@ -413,7 +417,7 @@ public:
{
if (index >= 0 && *type->model) {
const QAbstractItemModel * const model = type->model->aim();
- return model->hasChildren(model->index(index, 0, type->model->rootIndex));
+ return model->hasChildren(model->index(row, column, type->model->rootIndex));
} else {
return false;
}
@@ -421,13 +425,13 @@ public:
QVariant value(int role) const override
{
- return type->model->aim()->index(index, 0, type->model->rootIndex).data(role);
+ return type->model->aim()->index(row, column, type->model->rootIndex).data(role);
}
void setValue(int role, const QVariant &value) override
{
type->model->aim()->setData(
- type->model->aim()->index(index, 0, type->model->rootIndex), value, role);
+ type->model->aim()->index(row, column, type->model->rootIndex), value, role);
}
QV4::ReturnedValue get() override
@@ -438,11 +442,21 @@ public:
}
QV4::Scope scope(v4);
QV4::ScopedObject proto(scope, type->prototype.value());
- QV4::ScopedObject o(scope, proto->engine()->memoryManager->allocObject<QQmlDelegateModelItemObject>(this));
+ QV4::ScopedObject o(scope, proto->engine()->memoryManager->allocate<QQmlDelegateModelItemObject>(this));
o->setPrototype(proto);
++scriptRef;
return o.asReturnedValue();
}
+
+ void setModelIndex(int idx) override;
+
+Q_SIGNALS:
+ void rowChanged();
+ void columnChanged();
+
+private:
+ int row;
+ int column;
};
class VDMAbstractItemModelDataType : public VDMModelDelegateDataType
@@ -453,11 +467,16 @@ public:
{
}
- int count(const QQmlAdaptorModel &model) const override
+ int rowCount(const QQmlAdaptorModel &model) const override
{
return model.aim()->rowCount(model.rootIndex);
}
+ int columnCount(const QQmlAdaptorModel &model) const override
+ {
+ return model.aim()->columnCount(model.rootIndex);
+ }
+
void cleanup(QQmlAdaptorModel &model, QQmlDelegateModel *vdm) const override
{
QAbstractItemModel * const aim = model.aim();
@@ -485,9 +504,9 @@ public:
{
QHash<QByteArray, int>::const_iterator it = roleNames.find(role.toUtf8());
if (it != roleNames.end()) {
- return model.aim()->index(index, 0, model.rootIndex).data(*it);
+ return model.aim()->index(model.rowAt(index), model.columnAt(index), model.rootIndex).data(*it);
} else if (role == QLatin1String("hasModelChildren")) {
- return QVariant(model.aim()->hasChildren(model.aim()->index(index, 0, model.rootIndex)));
+ return QVariant(model.aim()->hasChildren(model.aim()->index(model.rowAt(index), model.columnAt(index), model.rootIndex)));
} else {
return QVariant();
}
@@ -503,7 +522,7 @@ public:
QVariant modelIndex(const QQmlAdaptorModel &model, int index) const override
{
return model
- ? QVariant::fromValue(model.aim()->index(index, 0, model.rootIndex))
+ ? QVariant::fromValue(model.aim()->index(model.rowAt(index), model.columnAt(index), model.rootIndex))
: QVariant();
}
@@ -558,6 +577,22 @@ public:
}
};
+void QQmlDMAbstractItemModelData::setModelIndex(int idx)
+{
+ QQmlDMCachedModelData::setModelIndex(idx);
+
+ int prevRow = row;
+ int prevColumn = column;
+
+ row = type->model->rowAt(idx);
+ column = type->model->columnAt(idx);
+
+ if (row != prevRow)
+ emit rowChanged();
+ if (column != prevColumn)
+ emit columnChanged();
+}
+
//-----------------------------------------------------------------
// QQmlListAccessor
//-----------------------------------------------------------------
@@ -613,7 +648,7 @@ public:
{
QQmlAdaptorModelEngineData *data = engineData(v4);
QV4::Scope scope(v4);
- QV4::ScopedObject o(scope, v4->memoryManager->allocObject<QQmlDelegateModelItemObject>(this));
+ QV4::ScopedObject o(scope, v4->memoryManager->allocate<QQmlDelegateModelItemObject>(this));
QV4::ScopedObject p(scope, data->listItemProto.value());
o->setPrototype(p);
++scriptRef;
@@ -653,11 +688,16 @@ class VDMListDelegateDataType : public QQmlAdaptorModel::Accessors
public:
inline VDMListDelegateDataType() {}
- int count(const QQmlAdaptorModel &model) const override
+ int rowCount(const QQmlAdaptorModel &model) const override
{
return model.list.count();
}
+ int columnCount(const QQmlAdaptorModel &) const override
+ {
+ return 1;
+ }
+
QVariant value(const QQmlAdaptorModel &model, int index, const QString &role) const override
{
return role == QLatin1String("modelData")
@@ -737,11 +777,16 @@ public:
free(metaObject);
}
- int count(const QQmlAdaptorModel &model) const override
+ int rowCount(const QQmlAdaptorModel &model) const override
{
return model.list.count();
}
+ int columnCount(const QQmlAdaptorModel &) const override
+ {
+ return 1;
+ }
+
QVariant value(const QQmlAdaptorModel &model, int index, const QString &role) const override
{
if (QObject *object = model.list.at(index).value<QObject *>())
@@ -958,6 +1003,38 @@ bool QQmlAdaptorModel::isValid() const
return accessors != &qt_vdm_null_accessors;
}
+int QQmlAdaptorModel::count() const
+{
+ return rowCount() * columnCount();
+}
+
+int QQmlAdaptorModel::rowCount() const
+{
+ return qMax(0, accessors->rowCount(*this));
+}
+
+int QQmlAdaptorModel::columnCount() const
+{
+ return qMax(isValid() ? 1 : 0, accessors->columnCount(*this));
+}
+
+int QQmlAdaptorModel::rowAt(int index) const
+{
+ int count = rowCount();
+ return count <= 0 ? -1 : index % count;
+}
+
+int QQmlAdaptorModel::columnAt(int index) const
+{
+ int count = rowCount();
+ return count <= 0 ? -1 : index / count;
+}
+
+int QQmlAdaptorModel::indexAt(int row, int column) const
+{
+ return row + (column * rowCount());
+}
+
void QQmlAdaptorModel::objectDestroyed(QObject *)
{
setModel(QVariant(), nullptr, nullptr);
diff --git a/src/qml/util/qqmladaptormodel_p.h b/src/qml/util/qqmladaptormodel_p.h
index b152a886a5..b706fcb5f2 100644
--- a/src/qml/util/qqmladaptormodel_p.h
+++ b/src/qml/util/qqmladaptormodel_p.h
@@ -56,6 +56,7 @@
#include "private/qqmllistaccessor_p.h"
#include <private/qqmlguard_p.h>
+#include <private/qqmlnullablevalue_p.h>
QT_REQUIRE_CONFIG(qml_delegate_model);
@@ -75,7 +76,8 @@ public:
public:
inline Accessors() {}
virtual ~Accessors();
- virtual int count(const QQmlAdaptorModel &) const { return 0; }
+ virtual int rowCount(const QQmlAdaptorModel &) const { return 0; }
+ virtual int columnCount(const QQmlAdaptorModel &) const { return 0; }
virtual void cleanup(QQmlAdaptorModel &, QQmlDelegateModel * = nullptr) const {}
virtual QVariant value(const QQmlAdaptorModel &, int, const QString &) const {
@@ -116,11 +118,16 @@ public:
void invalidateModel(QQmlDelegateModel *vdm);
bool isValid() const;
+ int count() const;
+ int rowCount() const;
+ int columnCount() const;
+ int rowAt(int index) const;
+ int columnAt(int index) const;
+ int indexAt(int row, int column) const;
inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); }
inline const QAbstractItemModel *aim() const { return static_cast<const QAbstractItemModel *>(object()); }
- inline int count() const { return qMax(0, accessors->count(*this)); }
inline QVariant value(int index, const QString &role) const {
return accessors->value(*this, index, role); }
inline QQmlDelegateModelItem *createItem(QQmlDelegateModelItemMetaType *metaType, int index) {