Merge remote-tracking branch 'origin/dev' into wip/qt6
Change-Id: I4476733af61fcf3a2af1d121a4585c3fae1c240e
This commit is contained in:
commit
880a143eb5
|
@ -58,7 +58,7 @@ Item {
|
|||
property alias cellColor: rectangle.color
|
||||
//![4]
|
||||
//![5]
|
||||
signal clicked(color cellColor)
|
||||
signal clicked(cellColor: color)
|
||||
//![5]
|
||||
|
||||
width: 40; height: 25
|
||||
|
|
|
@ -5,9 +5,9 @@ SUBDIRS += \
|
|||
builtins \
|
||||
qtqml \
|
||||
models \
|
||||
labsmodels \
|
||||
folderlistmodel
|
||||
labsmodels
|
||||
|
||||
qtConfig(qml-itemmodel): SUBDIRS += folderlistmodel
|
||||
qtConfig(qml-worker-script): SUBDIRS += workerscript
|
||||
qtHaveModule(sql): SUBDIRS += localstorage
|
||||
qtConfig(settings): SUBDIRS += settings
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <private/qv4scopedvalue_p.h>
|
||||
#include <QtQml/qqmlextensionplugin.h>
|
||||
#include <QtQml/qqml.h>
|
||||
#include <QtQml/qjsvalue.h>
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include <QtQml/qqml.h>
|
||||
#include <private/qv4util_p.h>
|
||||
#include <private/qv4global_p.h>
|
||||
#include <private/qv4staticvalue_p.h>
|
||||
#include "qtquickparticlesglobal_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include "qqmlpreviewfileloader.h"
|
||||
#include "qqmlpreviewservice.h"
|
||||
|
||||
#include <QtQml/qqmlfile.h>
|
||||
|
||||
#include <QtCore/qlibraryinfo.h>
|
||||
#include <QtCore/qstandardpaths.h>
|
||||
|
||||
|
|
|
@ -93,7 +93,9 @@ QQmlPreviewHandler::QQmlPreviewHandler(QObject *parent) : QObject(parent)
|
|||
|
||||
QQmlPreviewHandler::~QQmlPreviewHandler()
|
||||
{
|
||||
#if QT_CONFIG(translation)
|
||||
removeTranslators();
|
||||
#endif
|
||||
clear();
|
||||
}
|
||||
|
||||
|
@ -223,6 +225,7 @@ void QQmlPreviewHandler::doZoom()
|
|||
m_lastPosition.initLastSavedWindowPosition(m_currentWindow);
|
||||
}
|
||||
|
||||
#if QT_CONFIG(translation)
|
||||
void QQmlPreviewHandler::removeTranslators()
|
||||
{
|
||||
if (!m_qtTranslator.isNull()) {
|
||||
|
@ -255,6 +258,7 @@ void QQmlPreviewHandler::language(const QUrl &context, const QLocale &locale)
|
|||
for (QQmlEngine *engine : qAsConst(m_engines))
|
||||
engine->retranslate();
|
||||
}
|
||||
#endif
|
||||
|
||||
void QQmlPreviewHandler::clear()
|
||||
{
|
||||
|
|
|
@ -81,7 +81,9 @@ public:
|
|||
void loadUrl(const QUrl &url);
|
||||
void rerun();
|
||||
void zoom(qreal newFactor);
|
||||
#if QT_CONFIG(translation)
|
||||
void language(const QUrl &context, const QLocale &locale);
|
||||
#endif
|
||||
|
||||
void clear();
|
||||
|
||||
|
@ -115,7 +117,9 @@ private:
|
|||
void frameSwapped();
|
||||
|
||||
void fpsTimerHit();
|
||||
#if QT_CONFIG(translation)
|
||||
void removeTranslators();
|
||||
#endif
|
||||
|
||||
QScopedPointer<QQuickItem> m_dummyItem;
|
||||
QList<QQmlEngine *> m_engines;
|
||||
|
@ -145,8 +149,10 @@ private:
|
|||
FrameTime m_rendering;
|
||||
FrameTime m_synchronizing;
|
||||
|
||||
#if QT_CONFIG(translation)
|
||||
QScopedPointer<QTranslator> m_qtTranslator;
|
||||
QScopedPointer<QTranslator> m_qmlTranslator;
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -64,7 +64,9 @@ QQmlPreviewServiceImpl::QQmlPreviewServiceImpl(QObject *parent) :
|
|||
connect(this, &QQmlPreviewServiceImpl::load, &m_handler, &QQmlPreviewHandler::loadUrl);
|
||||
connect(this, &QQmlPreviewServiceImpl::rerun, &m_handler, &QQmlPreviewHandler::rerun);
|
||||
connect(this, &QQmlPreviewServiceImpl::zoom, &m_handler, &QQmlPreviewHandler::zoom);
|
||||
#if QT_CONFIG(translation)
|
||||
connect(this, &QQmlPreviewServiceImpl::language, &m_handler, &QQmlPreviewHandler::language);
|
||||
#endif
|
||||
connect(&m_handler, &QQmlPreviewHandler::error, this, &QQmlPreviewServiceImpl::forwardError,
|
||||
Qt::DirectConnection);
|
||||
connect(&m_handler, &QQmlPreviewHandler::fps, this, &QQmlPreviewServiceImpl::forwardFps,
|
||||
|
@ -135,6 +137,7 @@ void QQmlPreviewServiceImpl::messageReceived(const QByteArray &data)
|
|||
emit zoom(static_cast<qreal>(factor));
|
||||
break;
|
||||
}
|
||||
#if QT_CONFIG(translation)
|
||||
case Language: {
|
||||
QUrl context;
|
||||
QString locale;
|
||||
|
@ -143,6 +146,7 @@ void QQmlPreviewServiceImpl::messageReceived(const QByteArray &data)
|
|||
locale.isEmpty() ? QLocale() : QLocale(locale));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
forwardError(QString::fromLatin1("Invalid command: %1").arg(command));
|
||||
break;
|
||||
|
|
|
@ -99,7 +99,9 @@ signals:
|
|||
void rerun();
|
||||
void clearCache();
|
||||
void zoom(qreal factor);
|
||||
#if QT_CONFIG(translation)
|
||||
void language(const QUrl &context, const QLocale &locale);
|
||||
#endif
|
||||
|
||||
private:
|
||||
QScopedPointer<QQmlPreviewFileEngineHandler> m_fileEngine;
|
||||
|
|
|
@ -1,3 +1,35 @@
|
|||
!build_pass {
|
||||
# Create a header containing a hash that describes this library. For a
|
||||
# released version of Qt, we'll use the .tag file that is updated by git
|
||||
# archive with the commit hash. For unreleased versions, we'll ask git
|
||||
# describe. Note that it won't update unless qmake is run again, even if
|
||||
# the commit change also changed something in this library.
|
||||
tagFile = $$PWD/../../.tag
|
||||
tag =
|
||||
exists($$tagFile) {
|
||||
tag = $$cat($$tagFile, singleline)
|
||||
QMAKE_INTERNAL_INCLUDED_FILES += $$tagFile
|
||||
}
|
||||
!equals(tag, "$${LITERAL_DOLLAR}Format:%H$${LITERAL_DOLLAR}") {
|
||||
QML_COMPILE_HASH = $$tag
|
||||
} else:exists($$PWD/../../.git) {
|
||||
commit = $$system(git rev-parse HEAD)
|
||||
QML_COMPILE_HASH = $$commit
|
||||
}
|
||||
compile_hash_contents = \
|
||||
"// Generated file, DO NOT EDIT" \
|
||||
"$${LITERAL_HASH}define QML_COMPILE_HASH \"$$QML_COMPILE_HASH\"" \
|
||||
"$${LITERAL_HASH}define QML_COMPILE_HASH_LENGTH $$str_size($$QML_COMPILE_HASH)"
|
||||
write_file("$$OUT_PWD/qml_compile_hash_p.h", compile_hash_contents)|error()
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/qqmlapiversion_p.h \
|
||||
$$PWD/qqmljsdiagnosticmessage_p.h
|
||||
$$PWD/qqmljsdiagnosticmessage_p.h \
|
||||
$$PWD/qqmljsfixedpoolarray_p.h \
|
||||
$$PWD/qqmljsmemorypool_p.h \
|
||||
$$PWD/qv4alloca_p.h \
|
||||
$$PWD/qv4calldata_p.h \
|
||||
$$PWD/qv4compileddata_p.h \
|
||||
$$PWD/qv4staticvalue_p.h \
|
||||
$$PWD/qv4stringtoarrayindex_p.h
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QQMLJSFIXEDPOOLARRAY_P_H
|
||||
#define QQMLJSFIXEDPOOLARRAY_P_H
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <private/qqmljsmemorypool_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QQmlJS {
|
||||
|
||||
template <typename T>
|
||||
class FixedPoolArray
|
||||
{
|
||||
T *data;
|
||||
int count = 0;
|
||||
|
||||
public:
|
||||
FixedPoolArray()
|
||||
: data(nullptr)
|
||||
{}
|
||||
|
||||
FixedPoolArray(MemoryPool *pool, int size)
|
||||
{ allocate(pool, size); }
|
||||
|
||||
void allocate(MemoryPool *pool, int size)
|
||||
{
|
||||
count = size;
|
||||
data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
|
||||
}
|
||||
|
||||
void allocate(MemoryPool *pool, const QVector<T> &vector)
|
||||
{
|
||||
count = vector.count();
|
||||
data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
|
||||
|
||||
if (QTypeInfo<T>::isComplex) {
|
||||
for (int i = 0; i < count; ++i)
|
||||
new (data + i) T(vector.at(i));
|
||||
} else {
|
||||
memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void allocate(MemoryPool *pool, const Container &container)
|
||||
{
|
||||
count = container.count();
|
||||
data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
|
||||
typename Container::ConstIterator it = container.constBegin();
|
||||
for (int i = 0; i < count; ++i)
|
||||
new (data + i) T(*it++);
|
||||
}
|
||||
|
||||
int size() const
|
||||
{ return count; }
|
||||
|
||||
const T &at(int index) const {
|
||||
Q_ASSERT(index >= 0 && index < count);
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T &at(int index) {
|
||||
Q_ASSERT(index >= 0 && index < count);
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T &operator[](int index) {
|
||||
return at(index);
|
||||
}
|
||||
|
||||
|
||||
int indexOf(const T &value) const {
|
||||
for (int i = 0; i < count; ++i)
|
||||
if (data[i] == value)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const T *begin() const { return data; }
|
||||
const T *end() const { return data + count; }
|
||||
|
||||
T *begin() { return data; }
|
||||
T *end() { return data + count; }
|
||||
};
|
||||
|
||||
} // namespace QQmlJS
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QQMLJSFIXEDPOOLARRAY_P_H
|
|
@ -51,8 +51,6 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qqmljsglobal_p.h"
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
@ -65,7 +63,7 @@ namespace QQmlJS {
|
|||
|
||||
class Managed;
|
||||
|
||||
class QML_PARSER_EXPORT MemoryPool : public QSharedData
|
||||
class MemoryPool : public QSharedData
|
||||
{
|
||||
MemoryPool(const MemoryPool &other);
|
||||
void operator =(const MemoryPool &other);
|
||||
|
@ -162,7 +160,7 @@ private:
|
|||
};
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT Managed
|
||||
class Managed
|
||||
{
|
||||
Q_DISABLE_COPY(Managed)
|
||||
public:
|
||||
|
@ -174,81 +172,6 @@ public:
|
|||
void operator delete(void *, MemoryPool *) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class FixedPoolArray
|
||||
{
|
||||
T *data;
|
||||
int count = 0;
|
||||
|
||||
public:
|
||||
FixedPoolArray()
|
||||
: data(nullptr)
|
||||
{}
|
||||
|
||||
FixedPoolArray(MemoryPool *pool, int size)
|
||||
{ allocate(pool, size); }
|
||||
|
||||
void allocate(MemoryPool *pool, int size)
|
||||
{
|
||||
count = size;
|
||||
data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
|
||||
}
|
||||
|
||||
void allocate(MemoryPool *pool, const QVector<T> &vector)
|
||||
{
|
||||
count = vector.count();
|
||||
data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
|
||||
|
||||
if (QTypeInfo<T>::isComplex) {
|
||||
for (int i = 0; i < count; ++i)
|
||||
new (data + i) T(vector.at(i));
|
||||
} else {
|
||||
memcpy(data, static_cast<const void*>(vector.constData()), count * sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Container>
|
||||
void allocate(MemoryPool *pool, const Container &container)
|
||||
{
|
||||
count = container.count();
|
||||
data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
|
||||
typename Container::ConstIterator it = container.constBegin();
|
||||
for (int i = 0; i < count; ++i)
|
||||
new (data + i) T(*it++);
|
||||
}
|
||||
|
||||
int size() const
|
||||
{ return count; }
|
||||
|
||||
const T &at(int index) const {
|
||||
Q_ASSERT(index >= 0 && index < count);
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T &at(int index) {
|
||||
Q_ASSERT(index >= 0 && index < count);
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T &operator[](int index) {
|
||||
return at(index);
|
||||
}
|
||||
|
||||
|
||||
int indexOf(const T &value) const {
|
||||
for (int i = 0; i < count; ++i)
|
||||
if (data[i] == value)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const T *begin() const { return data; }
|
||||
const T *end() const { return data + count; }
|
||||
|
||||
T *begin() { return data; }
|
||||
T *end() { return data + count; }
|
||||
};
|
||||
|
||||
} // namespace QQmlJS
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -50,6 +50,8 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qscopeguard.h>
|
||||
#include <QtCore/qvector.h>
|
||||
|
@ -62,6 +64,7 @@
|
|||
|
||||
#include <private/qendian_p.h>
|
||||
#include <private/qv4staticvalue_p.h>
|
||||
#include <functional>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -72,12 +75,10 @@ QT_BEGIN_NAMESPACE
|
|||
// Also change the comment behind the number to describe the latest change. This has the added
|
||||
// benefit that if another patch changes the version too, it will result in a merge conflict, and
|
||||
// not get removed silently.
|
||||
#define QV4_DATA_STRUCTURE_VERSION 0x23 // Remove trace slots
|
||||
#define QV4_DATA_STRUCTURE_VERSION 0x24 // Collect function parameter types
|
||||
|
||||
class QIODevice;
|
||||
class QQmlPropertyData;
|
||||
class QQmlTypeNameCache;
|
||||
class QQmlScriptData;
|
||||
class QQmlType;
|
||||
class QQmlEngine;
|
||||
|
||||
|
@ -255,6 +256,29 @@ struct Block
|
|||
};
|
||||
static_assert(sizeof(Block) == 12, "Block structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
|
||||
|
||||
enum class BuiltinType : unsigned int {
|
||||
Var = 0, Variant, Int, Bool, Real, String, Url, Color,
|
||||
Font, Time, Date, DateTime, Rect, Point, Size,
|
||||
Vector2D, Vector3D, Vector4D, Matrix4x4, Quaternion, InvalidBuiltin
|
||||
};
|
||||
|
||||
struct ParameterType
|
||||
{
|
||||
union {
|
||||
quint32 _dummy;
|
||||
quint32_le_bitfield<0, 1> indexIsBuiltinType;
|
||||
quint32_le_bitfield<1, 31> typeNameIndexOrBuiltinType;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(ParameterType) == 4, "ParameterType structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
|
||||
|
||||
struct Parameter
|
||||
{
|
||||
quint32_le nameIndex;
|
||||
ParameterType type;
|
||||
};
|
||||
static_assert(sizeof(Parameter) == 8, "Parameter structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
|
||||
|
||||
// Function is aligned on an 8-byte boundary to make sure there are no bus errors or penalties
|
||||
// for unaligned access. The ordering of the fields is also from largest to smallest.
|
||||
struct Function
|
||||
|
@ -273,6 +297,7 @@ struct Function
|
|||
quint16_le length;
|
||||
quint16_le nFormals;
|
||||
quint32_le formalsOffset; // Can't turn this into a calculated offset because of the mutation in CompilationUnit::createUnitData.
|
||||
ParameterType returnType;
|
||||
quint32_le localsOffset;
|
||||
quint16_le nLocals;
|
||||
quint16_le nLineNumbers;
|
||||
|
@ -294,13 +319,13 @@ struct Function
|
|||
// quint32 formalsIndex[nFormals]
|
||||
// quint32 localsIndex[nLocals]
|
||||
|
||||
const quint32_le *formalsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + formalsOffset); }
|
||||
const Parameter *formalsTable() const { return reinterpret_cast<const Parameter *>(reinterpret_cast<const char *>(this) + formalsOffset); }
|
||||
const quint32_le *localsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + localsOffset); }
|
||||
const CodeOffsetToLine *lineNumberTable() const { return reinterpret_cast<const CodeOffsetToLine *>(reinterpret_cast<const char *>(this) + lineNumberOffset()); }
|
||||
|
||||
// --- QQmlPropertyCacheCreator interface
|
||||
const quint32_le *formalsBegin() const { return formalsTable(); }
|
||||
const quint32_le *formalsEnd() const { return formalsTable() + nFormals; }
|
||||
const Parameter *formalsBegin() const { return formalsTable(); }
|
||||
const Parameter *formalsEnd() const { return formalsTable() + nFormals; }
|
||||
// ---
|
||||
|
||||
const quint32_le *labelInfoTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + labelInfosOffset()); }
|
||||
|
@ -308,7 +333,7 @@ struct Function
|
|||
const char *code() const { return reinterpret_cast<const char *>(this) + codeOffset; }
|
||||
|
||||
static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int labelInfoSize, int codeSize) {
|
||||
int trailingData = (nFormals + nLocals + nInnerfunctions + labelInfoSize)*sizeof (quint32)
|
||||
int trailingData = nFormals * sizeof(Parameter) + (nLocals + nInnerfunctions + labelInfoSize)*sizeof (quint32)
|
||||
+ nLines*sizeof(CodeOffsetToLine);
|
||||
size_t size = align(align(sizeof(Function)) + size_t(trailingData)) + align(codeSize);
|
||||
Q_ASSERT(size < INT_MAX);
|
||||
|
@ -319,7 +344,7 @@ struct Function
|
|||
return (a + 7) & ~size_t(7);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(Function) == 52, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
|
||||
static_assert(sizeof(Function) == 56, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
|
||||
|
||||
struct Method {
|
||||
enum Type {
|
||||
|
@ -602,23 +627,6 @@ struct Enum
|
|||
};
|
||||
static_assert(sizeof(Enum) == 12, "Enum structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
|
||||
|
||||
enum class BuiltinType : unsigned int {
|
||||
Var = 0, Variant, Int, Bool, Real, String, Url, Color,
|
||||
Font, Time, Date, DateTime, Rect, Point, Size,
|
||||
Vector2D, Vector3D, Vector4D, Matrix4x4, Quaternion, InvalidBuiltin
|
||||
};
|
||||
|
||||
struct Parameter
|
||||
{
|
||||
quint32_le nameIndex;
|
||||
union {
|
||||
quint32 _dummy;
|
||||
quint32_le_bitfield<0, 1> indexIsBuiltinType;
|
||||
quint32_le_bitfield<1, 31> typeNameIndexOrBuiltinType;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(Parameter) == 8, "Parameter structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
|
||||
|
||||
struct Signal
|
||||
{
|
||||
quint32_le nameIndex;
|
||||
|
@ -1087,9 +1095,6 @@ struct TypeReferenceMap : QHash<int, TypeReference>
|
|||
|
||||
using DependentTypesHasher = std::function<QByteArray()>;
|
||||
|
||||
// index is per-object binding index
|
||||
typedef QVector<QQmlPropertyData*> BindingPropertyData;
|
||||
|
||||
// This is how this hooks into the existing structures:
|
||||
|
||||
struct CompilationUnitBase
|
||||
|
@ -1119,10 +1124,10 @@ struct CompilationUnitBase
|
|||
}
|
||||
|
||||
// pointers either to data->constants() or little-endian memory copy.
|
||||
QV4::Heap::String **runtimeStrings = nullptr; // Array
|
||||
Heap::String **runtimeStrings = nullptr; // Array
|
||||
const StaticValue* constants = nullptr;
|
||||
QV4::StaticValue *runtimeRegularExpressions = nullptr;
|
||||
QV4::Heap::InternalClass **runtimeClasses = nullptr;
|
||||
Heap::InternalClass **runtimeClasses = nullptr;
|
||||
const StaticValue** imports = nullptr;
|
||||
};
|
||||
|
|
@ -50,14 +50,24 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtQml/private/qtqmlglobal_p.h>
|
||||
#include <QtQml/private/qv4global_p.h>
|
||||
#include <QtCore/private/qnumeric_p.h>
|
||||
|
||||
#ifdef QT_NO_DEBUG
|
||||
#define QV4_NEARLY_ALWAYS_INLINE Q_ALWAYS_INLINE
|
||||
#else
|
||||
#define QV4_NEARLY_ALWAYS_INLINE inline
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QV4 {
|
||||
|
||||
// ReturnedValue is used to return values from runtime methods
|
||||
// the type has to be a primitive type (no struct or union), so that the compiler
|
||||
// will return it in a register on all platforms.
|
||||
// It will be returned in rax on x64, [eax,edx] on x86 and [r0,r1] on arm
|
||||
typedef quint64 ReturnedValue;
|
||||
|
||||
struct Double {
|
||||
quint64 d;
|
||||
|
||||
|
@ -105,7 +115,7 @@ struct Double {
|
|||
}
|
||||
};
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT StaticValue
|
||||
struct StaticValue
|
||||
{
|
||||
StaticValue() = default;
|
||||
constexpr StaticValue(quint64 val) : _val(val) {}
|
||||
|
@ -180,9 +190,9 @@ struct Q_QML_PRIVATE_EXPORT StaticValue
|
|||
|
||||
quint64 _val;
|
||||
|
||||
QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR quint64 &rawValueRef() { return _val; }
|
||||
QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR quint64 rawValue() const { return _val; }
|
||||
QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setRawValue(quint64 raw) { _val = raw; }
|
||||
QV4_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR quint64 &rawValueRef() { return _val; }
|
||||
QV4_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR quint64 rawValue() const { return _val; }
|
||||
QV4_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setRawValue(quint64 raw) { _val = raw; }
|
||||
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
static inline int valueOffset() { return 0; }
|
||||
|
@ -192,22 +202,22 @@ struct Q_QML_PRIVATE_EXPORT StaticValue
|
|||
static inline int tagOffset() { return 0; }
|
||||
#endif
|
||||
static inline constexpr quint64 tagValue(quint32 tag, quint32 value) { return quint64(tag) << 32 | value; }
|
||||
QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setTagValue(quint32 tag, quint32 value) { _val = quint64(tag) << 32 | value; }
|
||||
QML_NEARLY_ALWAYS_INLINE constexpr quint32 value() const { return _val & quint64(~quint32(0)); }
|
||||
QML_NEARLY_ALWAYS_INLINE constexpr quint32 tag() const { return _val >> 32; }
|
||||
QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setTag(quint32 tag) { setTagValue(tag, value()); }
|
||||
QV4_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setTagValue(quint32 tag, quint32 value) { _val = quint64(tag) << 32 | value; }
|
||||
QV4_NEARLY_ALWAYS_INLINE constexpr quint32 value() const { return _val & quint64(~quint32(0)); }
|
||||
QV4_NEARLY_ALWAYS_INLINE constexpr quint32 tag() const { return _val >> 32; }
|
||||
QV4_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setTag(quint32 tag) { setTagValue(tag, value()); }
|
||||
|
||||
QML_NEARLY_ALWAYS_INLINE constexpr int int_32() const
|
||||
QV4_NEARLY_ALWAYS_INLINE constexpr int int_32() const
|
||||
{
|
||||
return int(value());
|
||||
}
|
||||
QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setInt_32(int i)
|
||||
QV4_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setInt_32(int i)
|
||||
{
|
||||
setTagValue(quint32(ValueTypeInternal::Integer), quint32(i));
|
||||
}
|
||||
QML_NEARLY_ALWAYS_INLINE uint uint_32() const { return value(); }
|
||||
QV4_NEARLY_ALWAYS_INLINE uint uint_32() const { return value(); }
|
||||
|
||||
QML_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setEmpty()
|
||||
QV4_NEARLY_ALWAYS_INLINE Q_DECL_RELAXED_CONSTEXPR void setEmpty()
|
||||
{
|
||||
setTagValue(quint32(ValueTypeInternal::Empty), 0);
|
||||
}
|
||||
|
@ -353,7 +363,7 @@ struct Q_QML_PRIVATE_EXPORT StaticValue
|
|||
#endif
|
||||
}
|
||||
|
||||
QML_NEARLY_ALWAYS_INLINE double doubleValue() const {
|
||||
QV4_NEARLY_ALWAYS_INLINE double doubleValue() const {
|
||||
Q_ASSERT(isDouble());
|
||||
double d;
|
||||
StaticValue v = *this;
|
||||
|
@ -362,7 +372,7 @@ struct Q_QML_PRIVATE_EXPORT StaticValue
|
|||
return d;
|
||||
}
|
||||
|
||||
QML_NEARLY_ALWAYS_INLINE void setDouble(double d) {
|
||||
QV4_NEARLY_ALWAYS_INLINE void setDouble(double d) {
|
||||
if (qt_is_nan(d))
|
||||
d = qt_qnan();
|
||||
memcpy(&_val, &d, 8);
|
||||
|
@ -383,7 +393,7 @@ struct Q_QML_PRIVATE_EXPORT StaticValue
|
|||
return false;
|
||||
}
|
||||
|
||||
QML_NEARLY_ALWAYS_INLINE static bool isInt32(double d) {
|
||||
QV4_NEARLY_ALWAYS_INLINE static bool isInt32(double d) {
|
||||
int i = int(d);
|
||||
return (i == d && !(d == 0 && std::signbit(d)));
|
||||
}
|
|
@ -2,21 +2,17 @@ INCLUDEPATH += $$PWD
|
|||
INCLUDEPATH += $$OUT_PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/qv4alloca_p.h \
|
||||
$$PWD/qv4bytecodegenerator_p.h \
|
||||
$$PWD/qv4compileddata_p.h \
|
||||
$$PWD/qv4compiler_p.h \
|
||||
$$PWD/qv4compilercontext_p.h \
|
||||
$$PWD/qv4compilercontrolflow_p.h \
|
||||
$$PWD/qv4compilerglobal_p.h \
|
||||
$$PWD/qv4compilerscanfunctions_p.h \
|
||||
$$PWD/qv4codegen_p.h \
|
||||
$$PWD/qqmlirbuilder_p.h \
|
||||
$$PWD/qv4instr_moth_p.h \
|
||||
$$PWD/qv4bytecodehandler_p.h \
|
||||
$$PWD/qv4calldata_p.h \
|
||||
$$PWD/qv4util_p.h \
|
||||
$$PWD/qv4staticvalue_p.h \
|
||||
$$PWD/qv4stringtoarrayindex_p.h
|
||||
$$PWD/qv4util_p.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qv4bytecodegenerator.cpp \
|
||||
|
|
|
@ -56,6 +56,7 @@ QT_USE_NAMESPACE
|
|||
|
||||
static const quint32 emptyStringIndex = 0;
|
||||
using namespace QmlIR;
|
||||
using namespace QQmlJS;
|
||||
|
||||
#define COMPILE_EXCEPTION(location, desc) \
|
||||
{ \
|
||||
|
@ -63,6 +64,84 @@ using namespace QmlIR;
|
|||
return false; \
|
||||
}
|
||||
|
||||
bool Parameter::init(QV4::Compiler::JSUnitGenerator *stringGenerator, const QString ¶meterName,
|
||||
const QString &typeName)
|
||||
{
|
||||
return init(this, stringGenerator, stringGenerator->registerString(parameterName), stringGenerator->registerString(typeName));
|
||||
}
|
||||
|
||||
bool Parameter::init(QV4::CompiledData::Parameter *param, const QV4::Compiler::JSUnitGenerator *stringGenerator,
|
||||
int parameterNameIndex, int typeNameIndex)
|
||||
{
|
||||
param->nameIndex = parameterNameIndex;
|
||||
return initType(¶m->type, stringGenerator, typeNameIndex);
|
||||
}
|
||||
|
||||
bool Parameter::initType(QV4::CompiledData::ParameterType *paramType, const QV4::Compiler::JSUnitGenerator *stringGenerator, int typeNameIndex)
|
||||
{
|
||||
paramType->indexIsBuiltinType = false;
|
||||
paramType->typeNameIndexOrBuiltinType = 0;
|
||||
const QString typeName = stringGenerator->stringForIndex(typeNameIndex);
|
||||
auto builtinType = stringToBuiltinType(typeName);
|
||||
if (builtinType == QV4::CompiledData::BuiltinType::InvalidBuiltin) {
|
||||
if (typeName.isEmpty() || !typeName.at(0).isUpper())
|
||||
return false;
|
||||
paramType->indexIsBuiltinType = false;
|
||||
paramType->typeNameIndexOrBuiltinType = typeNameIndex;
|
||||
Q_ASSERT(quint32(typeNameIndex) < (1u << 31));
|
||||
} else {
|
||||
paramType->indexIsBuiltinType = true;
|
||||
paramType->typeNameIndexOrBuiltinType = static_cast<quint32>(builtinType);
|
||||
Q_ASSERT(quint32(builtinType) < (1u << 31));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QV4::CompiledData::BuiltinType Parameter::stringToBuiltinType(const QString &typeName)
|
||||
{
|
||||
static const struct TypeNameToType {
|
||||
const char *name;
|
||||
size_t nameLength;
|
||||
QV4::CompiledData::BuiltinType type;
|
||||
} propTypeNameToTypes[] = {
|
||||
{ "int", strlen("int"), QV4::CompiledData::BuiltinType::Int },
|
||||
{ "bool", strlen("bool"), QV4::CompiledData::BuiltinType::Bool },
|
||||
{ "double", strlen("double"), QV4::CompiledData::BuiltinType::Real },
|
||||
{ "real", strlen("real"), QV4::CompiledData::BuiltinType::Real },
|
||||
{ "string", strlen("string"), QV4::CompiledData::BuiltinType::String },
|
||||
{ "url", strlen("url"), QV4::CompiledData::BuiltinType::Url },
|
||||
{ "color", strlen("color"), QV4::CompiledData::BuiltinType::Color },
|
||||
// Internally QTime, QDate and QDateTime are all supported.
|
||||
// To be more consistent with JavaScript we expose only
|
||||
// QDateTime as it matches closely with the Date JS type.
|
||||
// We also call it "date" to match.
|
||||
// { "time", strlen("time"), Property::Time },
|
||||
// { "date", strlen("date"), Property::Date },
|
||||
{ "date", strlen("date"), QV4::CompiledData::BuiltinType::DateTime },
|
||||
{ "rect", strlen("rect"), QV4::CompiledData::BuiltinType::Rect },
|
||||
{ "point", strlen("point"), QV4::CompiledData::BuiltinType::Point },
|
||||
{ "size", strlen("size"), QV4::CompiledData::BuiltinType::Size },
|
||||
{ "font", strlen("font"), QV4::CompiledData::BuiltinType::Font },
|
||||
{ "vector2d", strlen("vector2d"), QV4::CompiledData::BuiltinType::Vector2D },
|
||||
{ "vector3d", strlen("vector3d"), QV4::CompiledData::BuiltinType::Vector3D },
|
||||
{ "vector4d", strlen("vector4d"), QV4::CompiledData::BuiltinType::Vector4D },
|
||||
{ "quaternion", strlen("quaternion"), QV4::CompiledData::BuiltinType::Quaternion },
|
||||
{ "matrix4x4", strlen("matrix4x4"), QV4::CompiledData::BuiltinType::Matrix4x4 },
|
||||
{ "variant", strlen("variant"), QV4::CompiledData::BuiltinType::Variant },
|
||||
{ "var", strlen("var"), QV4::CompiledData::BuiltinType::Var }
|
||||
};
|
||||
static const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
|
||||
sizeof(propTypeNameToTypes[0]);
|
||||
|
||||
for (int typeIndex = 0; typeIndex < propTypeNameToTypesCount; ++typeIndex) {
|
||||
const TypeNameToType *t = propTypeNameToTypes + typeIndex;
|
||||
if (typeName == QLatin1String(t->name, static_cast<int>(t->nameLength))) {
|
||||
return t->type;
|
||||
}
|
||||
}
|
||||
return QV4::CompiledData::BuiltinType::InvalidBuiltin;
|
||||
}
|
||||
|
||||
void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::AST::SourceLocation &loc)
|
||||
{
|
||||
inheritedTypeNameIndex = typeNameIndex;
|
||||
|
@ -247,64 +326,11 @@ QStringList Signal::parameterStringList(const QV4::Compiler::StringTableGenerato
|
|||
{
|
||||
QStringList result;
|
||||
result.reserve(parameters->count);
|
||||
for (SignalParameter *param = parameters->first; param; param = param->next)
|
||||
for (Parameter *param = parameters->first; param; param = param->next)
|
||||
result << stringPool->stringForIndex(param->nameIndex);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void replaceWithSpace(QString &str, int idx, int n)
|
||||
{
|
||||
QChar *data = str.data() + idx;
|
||||
const QChar space(QLatin1Char(' '));
|
||||
for (int ii = 0; ii < n; ++ii)
|
||||
*data++ = space;
|
||||
}
|
||||
|
||||
void Document::removeScriptPragmas(QString &script)
|
||||
{
|
||||
const QLatin1String pragma("pragma");
|
||||
const QLatin1String library("library");
|
||||
|
||||
QQmlJS::Lexer l(nullptr);
|
||||
l.setCode(script, 0);
|
||||
|
||||
int token = l.lex();
|
||||
|
||||
while (true) {
|
||||
if (token != QQmlJSGrammar::T_DOT)
|
||||
return;
|
||||
|
||||
int startOffset = l.tokenOffset();
|
||||
int startLine = l.tokenStartLine();
|
||||
|
||||
token = l.lex();
|
||||
|
||||
if (token != QQmlJSGrammar::T_PRAGMA ||
|
||||
l.tokenStartLine() != startLine ||
|
||||
script.midRef(l.tokenOffset(), l.tokenLength()) != pragma)
|
||||
return;
|
||||
|
||||
token = l.lex();
|
||||
|
||||
if (token != QQmlJSGrammar::T_IDENTIFIER ||
|
||||
l.tokenStartLine() != startLine)
|
||||
return;
|
||||
|
||||
const QStringRef pragmaValue = script.midRef(l.tokenOffset(), l.tokenLength());
|
||||
int endOffset = l.tokenLength() + l.tokenOffset();
|
||||
|
||||
token = l.lex();
|
||||
if (l.tokenStartLine() == startLine)
|
||||
return;
|
||||
|
||||
if (pragmaValue == library) {
|
||||
replaceWithSpace(script, startOffset, endOffset - startOffset);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Document::Document(bool debugMode)
|
||||
: jsModule(debugMode)
|
||||
, program(nullptr)
|
||||
|
@ -764,40 +790,6 @@ bool IRBuilder::visit(QQmlJS::AST::UiEnumDeclaration *node)
|
|||
|
||||
bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
|
||||
{
|
||||
static const struct TypeNameToType {
|
||||
const char *name;
|
||||
size_t nameLength;
|
||||
QV4::CompiledData::BuiltinType type;
|
||||
} propTypeNameToTypes[] = {
|
||||
{ "int", strlen("int"), QV4::CompiledData::BuiltinType::Int },
|
||||
{ "bool", strlen("bool"), QV4::CompiledData::BuiltinType::Bool },
|
||||
{ "double", strlen("double"), QV4::CompiledData::BuiltinType::Real },
|
||||
{ "real", strlen("real"), QV4::CompiledData::BuiltinType::Real },
|
||||
{ "string", strlen("string"), QV4::CompiledData::BuiltinType::String },
|
||||
{ "url", strlen("url"), QV4::CompiledData::BuiltinType::Url },
|
||||
{ "color", strlen("color"), QV4::CompiledData::BuiltinType::Color },
|
||||
// Internally QTime, QDate and QDateTime are all supported.
|
||||
// To be more consistent with JavaScript we expose only
|
||||
// QDateTime as it matches closely with the Date JS type.
|
||||
// We also call it "date" to match.
|
||||
// { "time", strlen("time"), Property::Time },
|
||||
// { "date", strlen("date"), Property::Date },
|
||||
{ "date", strlen("date"), QV4::CompiledData::BuiltinType::DateTime },
|
||||
{ "rect", strlen("rect"), QV4::CompiledData::BuiltinType::Rect },
|
||||
{ "point", strlen("point"), QV4::CompiledData::BuiltinType::Point },
|
||||
{ "size", strlen("size"), QV4::CompiledData::BuiltinType::Size },
|
||||
{ "font", strlen("font"), QV4::CompiledData::BuiltinType::Font },
|
||||
{ "vector2d", strlen("vector2d"), QV4::CompiledData::BuiltinType::Vector2D },
|
||||
{ "vector3d", strlen("vector3d"), QV4::CompiledData::BuiltinType::Vector3D },
|
||||
{ "vector4d", strlen("vector4d"), QV4::CompiledData::BuiltinType::Vector4D },
|
||||
{ "quaternion", strlen("quaternion"), QV4::CompiledData::BuiltinType::Quaternion },
|
||||
{ "matrix4x4", strlen("matrix4x4"), QV4::CompiledData::BuiltinType::Matrix4x4 },
|
||||
{ "variant", strlen("variant"), QV4::CompiledData::BuiltinType::Variant },
|
||||
{ "var", strlen("var"), QV4::CompiledData::BuiltinType::Var }
|
||||
};
|
||||
static const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
|
||||
sizeof(propTypeNameToTypes[0]);
|
||||
|
||||
if (node->type == QQmlJS::AST::UiPublicMember::Signal) {
|
||||
Signal *signal = New<Signal>();
|
||||
QString signalName = node->name.toString();
|
||||
|
@ -807,7 +799,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
|
|||
signal->location.line = loc.startLine;
|
||||
signal->location.column = loc.startColumn;
|
||||
|
||||
signal->parameters = New<PoolList<SignalParameter> >();
|
||||
signal->parameters = New<PoolList<Parameter> >();
|
||||
|
||||
QQmlJS::AST::UiParameterList *p = node->parameters;
|
||||
while (p) {
|
||||
|
@ -818,38 +810,13 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
|
|||
return false;
|
||||
}
|
||||
|
||||
const TypeNameToType *type = nullptr;
|
||||
for (int typeIndex = 0; typeIndex < propTypeNameToTypesCount; ++typeIndex) {
|
||||
const TypeNameToType *t = propTypeNameToTypes + typeIndex;
|
||||
if (memberType == QLatin1String(t->name, static_cast<int>(t->nameLength))) {
|
||||
type = t;
|
||||
break;
|
||||
}
|
||||
Parameter *param = New<Parameter>();
|
||||
if (!param->init(jsGenerator, p->name.toString(), memberType)) {
|
||||
QString errStr = QCoreApplication::translate("QQmlParser","Invalid signal parameter type: ");
|
||||
errStr.append(memberType);
|
||||
recordError(node->typeToken, errStr);
|
||||
return false;
|
||||
}
|
||||
|
||||
SignalParameter *param = New<SignalParameter>();
|
||||
|
||||
if (!type) {
|
||||
if (memberType.at(0).isUpper()) {
|
||||
// Must be a QML object type.
|
||||
// Lazily determine type during compilation.
|
||||
param->indexIsBuiltinType = false;
|
||||
param->typeNameIndexOrBuiltinType = registerString(memberType);
|
||||
Q_ASSERT(quint32(jsGenerator->getStringId(memberType)) < (1u << 31));
|
||||
} else {
|
||||
QString errStr = QCoreApplication::translate("QQmlParser","Invalid signal parameter type: ");
|
||||
errStr.append(memberType);
|
||||
recordError(node->typeToken, errStr);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// the parameter is a known basic type
|
||||
param->indexIsBuiltinType = true;
|
||||
param->typeNameIndexOrBuiltinType = static_cast<quint32>(type->type);
|
||||
Q_ASSERT(quint32(type->type) < (1u << 31));
|
||||
}
|
||||
|
||||
param->nameIndex = registerString(p->name.toString());
|
||||
signal->parameters->append(param);
|
||||
p = p->next;
|
||||
}
|
||||
|
@ -875,15 +842,10 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
|
|||
Property *property = New<Property>();
|
||||
property->isReadOnly = node->isReadonlyMember;
|
||||
|
||||
bool typeFound = false;
|
||||
|
||||
for (int ii = 0; !typeFound && ii < propTypeNameToTypesCount; ++ii) {
|
||||
const TypeNameToType *t = propTypeNameToTypes + ii;
|
||||
if (memberType == QLatin1String(t->name, static_cast<int>(t->nameLength))) {
|
||||
property->setBuiltinType(t->type);
|
||||
typeFound = true;
|
||||
}
|
||||
}
|
||||
QV4::CompiledData::BuiltinType builtinPropertyType = Parameter::stringToBuiltinType(memberType);
|
||||
bool typeFound = builtinPropertyType != QV4::CompiledData::BuiltinType::InvalidBuiltin;
|
||||
if (typeFound)
|
||||
property->setBuiltinType(builtinPropertyType);
|
||||
|
||||
if (!typeFound && memberType.at(0).isUpper()) {
|
||||
const QStringRef &typeModifier = node->typeModifier;
|
||||
|
@ -960,13 +922,16 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node)
|
|||
f->index = index;
|
||||
f->nameIndex = registerString(funDecl->name.toString());
|
||||
|
||||
const QStringList formals = funDecl->formals ? funDecl->formals->formals() : QStringList();
|
||||
QString returnTypeName = funDecl->typeAnnotation ? funDecl->typeAnnotation->type->toString() : QString();
|
||||
Parameter::initType(&f->returnType, jsGenerator, registerString(returnTypeName));
|
||||
|
||||
const QQmlJS::AST::BoundNames formals = funDecl->formals ? funDecl->formals->formals() : QQmlJS::AST::BoundNames();
|
||||
int formalsCount = formals.size();
|
||||
f->formals.allocate(pool, formalsCount);
|
||||
|
||||
int i = 0;
|
||||
for (const QString &arg : formals) {
|
||||
f->formals[i] = registerString(arg);
|
||||
for (const auto &arg : formals) {
|
||||
f->formals[i].init(jsGenerator, arg.id, arg.typeName());
|
||||
++i;
|
||||
}
|
||||
|
||||
|
@ -1696,7 +1661,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen
|
|||
signalToWrite->nParameters = s->parameters->count;
|
||||
|
||||
QV4::CompiledData::Parameter *parameterToWrite = reinterpret_cast<QV4::CompiledData::Parameter*>(signalPtr + sizeof(*signalToWrite));
|
||||
for (SignalParameter *param = s->parameters->first; param; param = param->next, ++parameterToWrite)
|
||||
for (Parameter *param = s->parameters->first; param; param = param->next, ++parameterToWrite)
|
||||
*parameterToWrite = *param;
|
||||
|
||||
int size = QV4::CompiledData::Signal::calculateSize(s->parameters->count);
|
||||
|
@ -1782,19 +1747,11 @@ char *QmlUnitGenerator::writeBindings(char *bindingPtr, const Object *o, Binding
|
|||
return bindingPtr;
|
||||
}
|
||||
|
||||
JSCodeGen::JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *jsUnitGenerator,
|
||||
QV4::Compiler::Module *jsModule, QQmlJS::Engine *jsEngine,
|
||||
QQmlJS::AST::UiProgram *qmlRoot,
|
||||
const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames)
|
||||
: QV4::Compiler::Codegen(jsUnitGenerator, /*strict mode*/false)
|
||||
, sourceCode(sourceCode)
|
||||
, jsEngine(jsEngine)
|
||||
, qmlRoot(qmlRoot)
|
||||
, stringPool(stringPool)
|
||||
JSCodeGen::JSCodeGen(Document *document, const QSet<QString> &globalNames)
|
||||
: QV4::Compiler::Codegen(&document->jsGenerator, /*strict mode*/false), document(document)
|
||||
{
|
||||
m_globalNames = globalNames;
|
||||
|
||||
_module = jsModule;
|
||||
_module = &document->jsModule;
|
||||
_fileNameIsUrl = true;
|
||||
}
|
||||
|
||||
|
@ -1802,17 +1759,17 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
|
|||
{
|
||||
auto qmlName = [&](const CompiledFunctionOrExpression &c) {
|
||||
if (c.nameIndex != 0)
|
||||
return stringPool->stringForIndex(c.nameIndex);
|
||||
return document->stringAt(c.nameIndex);
|
||||
else
|
||||
return QStringLiteral("%qml-expression-entry");
|
||||
};
|
||||
QVector<int> runtimeFunctionIndices(functions.size());
|
||||
|
||||
QV4::Compiler::ScanFunctions scan(this, sourceCode, QV4::Compiler::ContextType::Global);
|
||||
QV4::Compiler::ScanFunctions scan(this, document->code, QV4::Compiler::ContextType::Global);
|
||||
scan.enterGlobalEnvironment(QV4::Compiler::ContextType::Binding);
|
||||
for (const CompiledFunctionOrExpression &f : functions) {
|
||||
Q_ASSERT(f.node != qmlRoot);
|
||||
Q_ASSERT(f.parentNode && f.parentNode != qmlRoot);
|
||||
Q_ASSERT(f.node != document->program);
|
||||
Q_ASSERT(f.parentNode && f.parentNode != document->program);
|
||||
QQmlJS::AST::FunctionDeclaration *function = QQmlJS::AST::cast<QQmlJS::AST::FunctionDeclaration*>(f.node);
|
||||
|
||||
if (function) {
|
||||
|
@ -1835,7 +1792,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
|
|||
for (int i = 0; i < functions.count(); ++i) {
|
||||
const CompiledFunctionOrExpression &qmlFunction = functions.at(i);
|
||||
QQmlJS::AST::Node *node = qmlFunction.node;
|
||||
Q_ASSERT(node != qmlRoot);
|
||||
Q_ASSERT(node != document->program);
|
||||
|
||||
QQmlJS::AST::FunctionDeclaration *function = QQmlJS::AST::cast<QQmlJS::AST::FunctionDeclaration*>(node);
|
||||
|
||||
|
@ -1850,7 +1807,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
|
|||
body = function->body;
|
||||
} else {
|
||||
// Synthesize source elements.
|
||||
QQmlJS::MemoryPool *pool = jsEngine->pool();
|
||||
QQmlJS::MemoryPool *pool = document->jsParserEngine.pool();
|
||||
|
||||
QQmlJS::AST::Statement *stmt = node->statementCast();
|
||||
if (!stmt) {
|
||||
|
@ -1870,3 +1827,58 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
|
|||
|
||||
return runtimeFunctionIndices;
|
||||
}
|
||||
|
||||
bool JSCodeGen::generateCodeForComponents(const QVector<quint32> &componentRoots)
|
||||
{
|
||||
for (int i = 0; i < componentRoots.count(); ++i) {
|
||||
if (!compileComponent(componentRoots.at(i)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return compileComponent(/*root object*/0);
|
||||
}
|
||||
|
||||
bool JSCodeGen::compileComponent(int contextObject)
|
||||
{
|
||||
const QmlIR::Object *obj = document->objects.at(contextObject);
|
||||
if (obj->flags & QV4::CompiledData::Object::IsComponent) {
|
||||
Q_ASSERT(obj->bindingCount() == 1);
|
||||
const QV4::CompiledData::Binding *componentBinding = obj->firstBinding();
|
||||
Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object);
|
||||
contextObject = componentBinding->value.objectIndex;
|
||||
}
|
||||
|
||||
return compileJavaScriptCodeInObjectsRecursively(contextObject, contextObject);
|
||||
}
|
||||
|
||||
bool JSCodeGen::compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex)
|
||||
{
|
||||
QmlIR::Object *object = document->objects.at(objectIndex);
|
||||
if (object->flags & QV4::CompiledData::Object::IsComponent)
|
||||
return true;
|
||||
|
||||
if (object->functionsAndExpressions->count > 0) {
|
||||
QList<QmlIR::CompiledFunctionOrExpression> functionsToCompile;
|
||||
for (QmlIR::CompiledFunctionOrExpression *foe = object->functionsAndExpressions->first; foe; foe = foe->next)
|
||||
functionsToCompile << *foe;
|
||||
const QVector<int> runtimeFunctionIndices = generateJSCodeForFunctionsAndBindings(functionsToCompile);
|
||||
if (hasError())
|
||||
return false;
|
||||
|
||||
object->runtimeFunctionIndices.allocate(document->jsParserEngine.pool(),
|
||||
runtimeFunctionIndices);
|
||||
}
|
||||
|
||||
for (const QmlIR::Binding *binding = object->firstBinding(); binding; binding = binding->next) {
|
||||
if (binding->type < QV4::CompiledData::Binding::Type_Object)
|
||||
continue;
|
||||
|
||||
int target = binding->value.objectIndex;
|
||||
int scope = binding->type == QV4::CompiledData::Binding::Type_Object ? target : scopeObjectIndex;
|
||||
|
||||
if (!compileJavaScriptCodeInObjectsRecursively(binding->value.objectIndex, scope))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include <private/qv4compiler_p.h>
|
||||
#include <private/qv4compileddata_p.h>
|
||||
#include <private/qqmljsmemorypool_p.h>
|
||||
#include <private/qqmljsfixedpoolarray_p.h>
|
||||
#include <private/qv4codegen_p.h>
|
||||
#include <private/qv4compiler_p.h>
|
||||
#include <QTextStream>
|
||||
|
@ -215,22 +216,30 @@ struct Enum
|
|||
};
|
||||
|
||||
|
||||
struct SignalParameter : public QV4::CompiledData::Parameter
|
||||
struct Parameter : public QV4::CompiledData::Parameter
|
||||
{
|
||||
SignalParameter *next;
|
||||
Parameter *next;
|
||||
|
||||
bool init(QV4::Compiler::JSUnitGenerator *stringGenerator, const QString ¶meterName, const QString &typeName);
|
||||
static bool init(QV4::CompiledData::Parameter *param, const QV4::Compiler::JSUnitGenerator *stringGenerator,
|
||||
int parameterNameIndex, int typeNameIndex);
|
||||
static bool initType(QV4::CompiledData::ParameterType *paramType,
|
||||
const QV4::Compiler::JSUnitGenerator *stringGenerator, int typeNameIndex);
|
||||
|
||||
static QV4::CompiledData::BuiltinType stringToBuiltinType(const QString &typeName);
|
||||
};
|
||||
|
||||
struct Signal
|
||||
{
|
||||
int nameIndex;
|
||||
QV4::CompiledData::Location location;
|
||||
PoolList<SignalParameter> *parameters;
|
||||
PoolList<Parameter> *parameters;
|
||||
|
||||
QStringList parameterStringList(const QV4::Compiler::StringTableGenerator *stringPool) const;
|
||||
|
||||
int parameterCount() const { return parameters->count; }
|
||||
PoolList<SignalParameter>::Iterator parametersBegin() const { return parameters->begin(); }
|
||||
PoolList<SignalParameter>::Iterator parametersEnd() const { return parameters->end(); }
|
||||
PoolList<Parameter>::Iterator parametersBegin() const { return parameters->begin(); }
|
||||
PoolList<Parameter>::Iterator parametersEnd() const { return parameters->end(); }
|
||||
|
||||
Signal *next;
|
||||
};
|
||||
|
@ -260,17 +269,18 @@ struct Function
|
|||
QV4::CompiledData::Location location;
|
||||
int nameIndex;
|
||||
quint32 index; // index in parsedQML::functions
|
||||
FixedPoolArray<int> formals;
|
||||
QQmlJS::FixedPoolArray<Parameter> formals;
|
||||
QV4::CompiledData::ParameterType returnType;
|
||||
|
||||
// --- QQmlPropertyCacheCreator interface
|
||||
const int *formalsBegin() const { return formals.begin(); }
|
||||
const int *formalsEnd() const { return formals.end(); }
|
||||
const Parameter *formalsBegin() const { return formals.begin(); }
|
||||
const Parameter *formalsEnd() const { return formals.end(); }
|
||||
// ---
|
||||
|
||||
Function *next;
|
||||
};
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT CompiledFunctionOrExpression
|
||||
struct Q_QMLCOMPILER_PRIVATE_EXPORT CompiledFunctionOrExpression
|
||||
{
|
||||
CompiledFunctionOrExpression()
|
||||
{}
|
||||
|
@ -281,7 +291,7 @@ struct Q_QML_PRIVATE_EXPORT CompiledFunctionOrExpression
|
|||
CompiledFunctionOrExpression *next = nullptr;
|
||||
};
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT Object
|
||||
struct Q_QMLCOMPILER_PRIVATE_EXPORT Object
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Object)
|
||||
public:
|
||||
|
@ -340,9 +350,9 @@ public:
|
|||
QString bindingAsString(Document *doc, int scriptIndex) const;
|
||||
|
||||
PoolList<CompiledFunctionOrExpression> *functionsAndExpressions;
|
||||
FixedPoolArray<int> runtimeFunctionIndices;
|
||||
QQmlJS::FixedPoolArray<int> runtimeFunctionIndices;
|
||||
|
||||
FixedPoolArray<quint32> namedObjectsInComponent;
|
||||
QQmlJS::FixedPoolArray<quint32> namedObjectsInComponent;
|
||||
int namedObjectsInComponentCount() const { return namedObjectsInComponent.size(); }
|
||||
const quint32 *namedObjectsInComponentTable() const { return namedObjectsInComponent.begin(); }
|
||||
|
||||
|
@ -357,7 +367,7 @@ private:
|
|||
PoolList<Function> *functions;
|
||||
};
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT Pragma
|
||||
struct Q_QMLCOMPILER_PRIVATE_EXPORT Pragma
|
||||
{
|
||||
enum PragmaType {
|
||||
PragmaSingleton = 0x1
|
||||
|
@ -367,7 +377,7 @@ struct Q_QML_PRIVATE_EXPORT Pragma
|
|||
QV4::CompiledData::Location location;
|
||||
};
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT Document
|
||||
struct Q_QMLCOMPILER_PRIVATE_EXPORT Document
|
||||
{
|
||||
Document(bool debugMode);
|
||||
QString code;
|
||||
|
@ -383,11 +393,9 @@ struct Q_QML_PRIVATE_EXPORT Document
|
|||
|
||||
int registerString(const QString &str) { return jsGenerator.registerString(str); }
|
||||
QString stringAt(int index) const { return jsGenerator.stringForIndex(index); }
|
||||
|
||||
static void removeScriptPragmas(QString &script);
|
||||
};
|
||||
|
||||
class Q_QML_PRIVATE_EXPORT ScriptDirectivesCollector : public QQmlJS::Directives
|
||||
class Q_QMLCOMPILER_PRIVATE_EXPORT ScriptDirectivesCollector : public QQmlJS::Directives
|
||||
{
|
||||
QmlIR::Document *document;
|
||||
QQmlJS::Engine *engine;
|
||||
|
@ -401,7 +409,7 @@ public:
|
|||
void importModule(const QString &uri, const QString &version, const QString &module, int lineNumber, int column) override;
|
||||
};
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT IRBuilder : public QQmlJS::AST::Visitor
|
||||
struct Q_QMLCOMPILER_PRIVATE_EXPORT IRBuilder : public QQmlJS::AST::Visitor
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(QQmlCodeGenerator)
|
||||
public:
|
||||
|
@ -432,7 +440,7 @@ public:
|
|||
|
||||
void throwRecursionDepthError() override
|
||||
{
|
||||
recordError(AST::SourceLocation(),
|
||||
recordError(QQmlJS::AST::SourceLocation(),
|
||||
QStringLiteral("Maximum statement or expression depth exceeded"));
|
||||
}
|
||||
|
||||
|
@ -451,13 +459,19 @@ public:
|
|||
QStringRef textRefAt(const QQmlJS::AST::SourceLocation &first,
|
||||
const QQmlJS::AST::SourceLocation &last) const;
|
||||
|
||||
void setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement, AST::Node *parentNode);
|
||||
void setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement,
|
||||
QQmlJS::AST::Node *parentNode);
|
||||
void tryGeneratingTranslationBinding(const QStringRef &base, QQmlJS::AST::ArgumentList *args, QV4::CompiledData::Binding *binding);
|
||||
|
||||
void appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value, AST::Node *parentNode);
|
||||
void appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value,
|
||||
QQmlJS::AST::Node *parentNode);
|
||||
void appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment = false);
|
||||
void appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, QQmlJS::AST::Statement *value, AST::Node *parentNode);
|
||||
void appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem = false, bool isOnAssignment = false);
|
||||
void appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation,
|
||||
const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex,
|
||||
QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode);
|
||||
void appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation,
|
||||
const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex,
|
||||
int objectIndex, bool isListItem = false, bool isOnAssignment = false);
|
||||
|
||||
bool appendAlias(QQmlJS::AST::UiPublicMember *node);
|
||||
|
||||
|
@ -499,7 +513,7 @@ public:
|
|||
QV4::Compiler::JSUnitGenerator *jsGenerator;
|
||||
};
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT QmlUnitGenerator
|
||||
struct Q_QMLCOMPILER_PRIVATE_EXPORT QmlUnitGenerator
|
||||
{
|
||||
void generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher = QV4::CompiledData::DependentTypesHasher());
|
||||
|
||||
|
@ -508,34 +522,23 @@ private:
|
|||
char *writeBindings(char *bindingPtr, const Object *o, BindingFilter filter) const;
|
||||
};
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen
|
||||
struct Q_QMLCOMPILER_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen
|
||||
{
|
||||
JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *jsUnitGenerator, QV4::Compiler::Module *jsModule,
|
||||
QQmlJS::Engine *jsEngine, QQmlJS::AST::UiProgram *qmlRoot,
|
||||
const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames);
|
||||
JSCodeGen(Document *document, const QSet<QString> &globalNames);
|
||||
|
||||
// Returns mapping from input functions to index in IR::Module::functions / compiledData->runtimeFunctions
|
||||
QVector<int> generateJSCodeForFunctionsAndBindings(const QList<CompiledFunctionOrExpression> &functions);
|
||||
|
||||
bool generateCodeForComponents(const QVector<quint32> &componentRoots);
|
||||
bool compileComponent(int contextObject);
|
||||
bool compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex);
|
||||
|
||||
private:
|
||||
QString sourceCode;
|
||||
QQmlJS::Engine *jsEngine; // needed for memory pool
|
||||
QQmlJS::AST::UiProgram *qmlRoot;
|
||||
const QV4::Compiler::StringTableGenerator *stringPool;
|
||||
Document *document;
|
||||
};
|
||||
|
||||
} // namespace QmlIR
|
||||
|
||||
inline QQmlJS::DiagnosticMessage qQmlCompileError(const QV4::CompiledData::Location &location,
|
||||
const QString &description)
|
||||
{
|
||||
QQmlJS::DiagnosticMessage error;
|
||||
error.line = location.line;
|
||||
error.column = location.column;
|
||||
error.message = description;
|
||||
return error;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QQMLIRBUILDER_P_H
|
||||
|
|
|
@ -206,7 +206,6 @@ int BytecodeGenerator::addInstructionHelper(Instr::Type type, const Instr &i, in
|
|||
lastInstrType = int(type);
|
||||
lastInstr = i;
|
||||
|
||||
#if QT_CONFIG(qml_debug)
|
||||
if (debugMode && type != Instr::Type::Debug) {
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // broken gcc warns about Instruction::Debug()
|
||||
|
@ -219,9 +218,6 @@ QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // broken gcc warns about Instru
|
|||
}
|
||||
QT_WARNING_POP
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(debugMode);
|
||||
#endif
|
||||
|
||||
const int pos = instructions.size();
|
||||
|
||||
|
|
|
@ -62,6 +62,11 @@ class SourceLocation;
|
|||
}
|
||||
|
||||
namespace QV4 {
|
||||
|
||||
namespace Compiler {
|
||||
struct Context;
|
||||
}
|
||||
|
||||
namespace Moth {
|
||||
|
||||
class BytecodeGenerator {
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include <private/qqmljsast_p.h>
|
||||
#include <private/qqmljslexer_p.h>
|
||||
#include <private/qqmljsparser_p.h>
|
||||
#include <private/qv4stringtoarrayindex_p.h>
|
||||
#include <private/qv4staticvalue_p.h>
|
||||
#include <private/qv4compilercontext_p.h>
|
||||
#include <private/qv4compilercontrolflow_p.h>
|
||||
|
@ -69,6 +68,7 @@ static const bool disable_lookups = false;
|
|||
QT_USE_NAMESPACE
|
||||
using namespace QV4;
|
||||
using namespace QV4::Compiler;
|
||||
using namespace QQmlJS;
|
||||
using namespace QQmlJS::AST;
|
||||
|
||||
static inline void setJumpOutLocation(QV4::Moth::BytecodeGenerator *bytecodeGenerator,
|
||||
|
@ -610,6 +610,8 @@ void Codegen::initializeAndDestructureBindingElement(AST::PatternElement *e, con
|
|||
if (hasError())
|
||||
return;
|
||||
|
||||
accept(e->typeAnnotation);
|
||||
|
||||
if (e->initializer) {
|
||||
if (!baseRef.isValid()) {
|
||||
// assignment
|
||||
|
@ -885,6 +887,12 @@ bool Codegen::visit(ExportDeclaration *ast)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Codegen::visit(TypeAnnotation *ast)
|
||||
{
|
||||
throwSyntaxError(ast->firstSourceLocation(), QLatin1String("Type annotations are not supported (yet)."));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Codegen::visit(StatementList *)
|
||||
{
|
||||
Q_UNREACHABLE();
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include "private/qv4global_p.h"
|
||||
#include <private/qqmljsastvisitor_p.h>
|
||||
#include <private/qqmljsengine_p.h>
|
||||
#include <private/qqmljsast_p.h>
|
||||
|
@ -63,8 +62,6 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QQmlJS;
|
||||
|
||||
namespace QV4 {
|
||||
|
||||
namespace Moth {
|
||||
|
@ -81,7 +78,7 @@ struct ControlFlow;
|
|||
struct ControlFlowCatch;
|
||||
struct ControlFlowFinally;
|
||||
|
||||
class Q_QML_PRIVATE_EXPORT Codegen: protected QQmlJS::AST::Visitor
|
||||
class Q_QMLCOMPILER_PRIVATE_EXPORT Codegen: protected QQmlJS::AST::Visitor
|
||||
{
|
||||
protected:
|
||||
using BytecodeGenerator = QV4::Moth::BytecodeGenerator;
|
||||
|
@ -93,14 +90,14 @@ public:
|
|||
void generateFromProgram(const QString &fileName,
|
||||
const QString &finalUrl,
|
||||
const QString &sourceCode,
|
||||
AST::Program *ast,
|
||||
QQmlJS::AST::Program *ast,
|
||||
Module *module,
|
||||
ContextType contextType = ContextType::Global);
|
||||
|
||||
void generateFromModule(const QString &fileName,
|
||||
const QString &finalUrl,
|
||||
const QString &sourceCode,
|
||||
AST::ESModule *ast,
|
||||
QQmlJS::AST::ESModule *ast,
|
||||
Module *module);
|
||||
|
||||
public:
|
||||
|
@ -487,10 +484,10 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
void enterContext(AST::Node *node);
|
||||
void enterContext(QQmlJS::AST::Node *node);
|
||||
int leaveContext();
|
||||
public:
|
||||
Context *enterBlock(AST::Node *node);
|
||||
Context *enterBlock(QQmlJS::AST::Node *node);
|
||||
int leaveBlock() { return leaveContext(); }
|
||||
protected:
|
||||
void leaveLoop();
|
||||
|
@ -521,18 +518,18 @@ public:
|
|||
int registerQmlContextPropertyGetterLookup(int nameIndex) { return jsUnitGenerator->registerQmlContextPropertyGetterLookup(nameIndex); }
|
||||
|
||||
// Returns index in _module->functions
|
||||
virtual int defineFunction(const QString &name, AST::Node *ast,
|
||||
AST::FormalParameterList *formals,
|
||||
AST::StatementList *body);
|
||||
virtual int defineFunction(const QString &name, QQmlJS::AST::Node *ast,
|
||||
QQmlJS::AST::FormalParameterList *formals,
|
||||
QQmlJS::AST::StatementList *body);
|
||||
|
||||
protected:
|
||||
void statement(AST::Statement *ast);
|
||||
void statement(AST::ExpressionNode *ast);
|
||||
void condition(AST::ExpressionNode *ast, const BytecodeGenerator::Label *iftrue,
|
||||
void statement(QQmlJS::AST::Statement *ast);
|
||||
void statement(QQmlJS::AST::ExpressionNode *ast);
|
||||
void condition(QQmlJS::AST::ExpressionNode *ast, const BytecodeGenerator::Label *iftrue,
|
||||
const BytecodeGenerator::Label *iffalse,
|
||||
bool trueBlockFollowsCondition);
|
||||
|
||||
inline Reference expression(AST::ExpressionNode *ast, const QString &name = QString())
|
||||
inline Reference expression(QQmlJS::AST::ExpressionNode *ast, const QString &name = QString())
|
||||
{
|
||||
if (!ast || hasError())
|
||||
return Reference();
|
||||
|
@ -542,131 +539,134 @@ protected:
|
|||
return popResult();
|
||||
}
|
||||
|
||||
inline void accept(AST::Node *node)
|
||||
inline void accept(QQmlJS::AST::Node *node)
|
||||
{
|
||||
if (!hasError() && node)
|
||||
node->accept(this);
|
||||
}
|
||||
|
||||
void program(AST::Program *ast);
|
||||
void statementList(AST::StatementList *ast);
|
||||
void variableDeclaration(AST::PatternElement *ast);
|
||||
void variableDeclarationList(AST::VariableDeclarationList *ast);
|
||||
void program(QQmlJS::AST::Program *ast);
|
||||
void statementList(QQmlJS::AST::StatementList *ast);
|
||||
void variableDeclaration(QQmlJS::AST::PatternElement *ast);
|
||||
void variableDeclarationList(QQmlJS::AST::VariableDeclarationList *ast);
|
||||
|
||||
Reference targetForPatternElement(AST::PatternElement *p);
|
||||
void initializeAndDestructureBindingElement(AST::PatternElement *e, const Reference &baseRef = Reference(), bool isDefinition = false);
|
||||
void destructurePropertyList(const Reference &object, AST::PatternPropertyList *bindingList, bool isDefinition = false);
|
||||
void destructureElementList(const Reference &array, AST::PatternElementList *bindingList, bool isDefinition = false);
|
||||
void destructurePattern(AST::Pattern *p, const Reference &rhs);
|
||||
Reference targetForPatternElement(QQmlJS::AST::PatternElement *p);
|
||||
void initializeAndDestructureBindingElement(QQmlJS::AST::PatternElement *e, const Reference &baseRef = Reference(), bool isDefinition = false);
|
||||
void destructurePropertyList(const Reference &object, QQmlJS::AST::PatternPropertyList *bindingList, bool isDefinition = false);
|
||||
void destructureElementList(const Reference &array, QQmlJS::AST::PatternElementList *bindingList, bool isDefinition = false);
|
||||
void destructurePattern(QQmlJS::AST::Pattern *p, const Reference &rhs);
|
||||
|
||||
Reference referenceForPropertyName(const Codegen::Reference &object, AST::PropertyName *name);
|
||||
Reference referenceForPropertyName(const Codegen::Reference &object, QQmlJS::AST::PropertyName *name);
|
||||
|
||||
void emitReturn(const Reference &expr);
|
||||
|
||||
// nodes
|
||||
bool visit(AST::ArgumentList *ast) override;
|
||||
bool visit(AST::CaseBlock *ast) override;
|
||||
bool visit(AST::CaseClause *ast) override;
|
||||
bool visit(AST::CaseClauses *ast) override;
|
||||
bool visit(AST::Catch *ast) override;
|
||||
bool visit(AST::DefaultClause *ast) override;
|
||||
bool visit(AST::Elision *ast) override;
|
||||
bool visit(AST::Finally *ast) override;
|
||||
bool visit(AST::FormalParameterList *ast) override;
|
||||
bool visit(AST::Program *ast) override;
|
||||
bool visit(AST::StatementList *ast) override;
|
||||
bool visit(AST::UiArrayMemberList *ast) override;
|
||||
bool visit(AST::UiImport *ast) override;
|
||||
bool visit(AST::UiHeaderItemList *ast) override;
|
||||
bool visit(AST::UiPragma *ast) override;
|
||||
bool visit(AST::UiObjectInitializer *ast) override;
|
||||
bool visit(AST::UiObjectMemberList *ast) override;
|
||||
bool visit(AST::UiParameterList *ast) override;
|
||||
bool visit(AST::UiProgram *ast) override;
|
||||
bool visit(AST::UiQualifiedId *ast) override;
|
||||
bool visit(AST::VariableDeclarationList *ast) override;
|
||||
bool visit(QQmlJS::AST::ArgumentList *ast) override;
|
||||
bool visit(QQmlJS::AST::CaseBlock *ast) override;
|
||||
bool visit(QQmlJS::AST::CaseClause *ast) override;
|
||||
bool visit(QQmlJS::AST::CaseClauses *ast) override;
|
||||
bool visit(QQmlJS::AST::Catch *ast) override;
|
||||
bool visit(QQmlJS::AST::DefaultClause *ast) override;
|
||||
bool visit(QQmlJS::AST::Elision *ast) override;
|
||||
bool visit(QQmlJS::AST::Finally *ast) override;
|
||||
bool visit(QQmlJS::AST::FormalParameterList *ast) override;
|
||||
bool visit(QQmlJS::AST::Program *ast) override;
|
||||
bool visit(QQmlJS::AST::StatementList *ast) override;
|
||||
bool visit(QQmlJS::AST::UiArrayMemberList *ast) override;
|
||||
bool visit(QQmlJS::AST::UiImport *ast) override;
|
||||
bool visit(QQmlJS::AST::UiHeaderItemList *ast) override;
|
||||
bool visit(QQmlJS::AST::UiPragma *ast) override;
|
||||
bool visit(QQmlJS::AST::UiObjectInitializer *ast) override;
|
||||
bool visit(QQmlJS::AST::UiObjectMemberList *ast) override;
|
||||
bool visit(QQmlJS::AST::UiParameterList *ast) override;
|
||||
bool visit(QQmlJS::AST::UiProgram *ast) override;
|
||||
bool visit(QQmlJS::AST::UiQualifiedId *ast) override;
|
||||
bool visit(QQmlJS::AST::VariableDeclarationList *ast) override;
|
||||
|
||||
bool visit(AST::PatternElement *ast) override;
|
||||
bool visit(AST::PatternElementList *ast) override;
|
||||
bool visit(AST::PatternProperty *ast) override;
|
||||
bool visit(AST::PatternPropertyList *ast) override;
|
||||
bool visit(QQmlJS::AST::PatternElement *ast) override;
|
||||
bool visit(QQmlJS::AST::PatternElementList *ast) override;
|
||||
bool visit(QQmlJS::AST::PatternProperty *ast) override;
|
||||
bool visit(QQmlJS::AST::PatternPropertyList *ast) override;
|
||||
|
||||
bool visit(AST::ExportDeclaration *ast) override;
|
||||
bool visit(QQmlJS::AST::ExportDeclaration *ast) override;
|
||||
|
||||
bool visit(QQmlJS::AST::TypeAnnotation *ast) override;
|
||||
|
||||
// expressions
|
||||
bool visit(AST::Expression *ast) override;
|
||||
bool visit(AST::ArrayPattern *ast) override;
|
||||
bool visit(AST::ArrayMemberExpression *ast) override;
|
||||
bool visit(AST::BinaryExpression *ast) override;
|
||||
bool visit(AST::CallExpression *ast) override;
|
||||
bool visit(AST::ConditionalExpression *ast) override;
|
||||
bool visit(AST::DeleteExpression *ast) override;
|
||||
bool visit(AST::FalseLiteral *ast) override;
|
||||
bool visit(AST::SuperLiteral *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;
|
||||
bool visit(AST::NewExpression *ast) override;
|
||||
bool visit(AST::NewMemberExpression *ast) override;
|
||||
bool visit(AST::NotExpression *ast) override;
|
||||
bool visit(AST::NullExpression *ast) override;
|
||||
bool visit(AST::NumericLiteral *ast) override;
|
||||
bool visit(AST::ObjectPattern *ast) override;
|
||||
bool visit(AST::PostDecrementExpression *ast) override;
|
||||
bool visit(AST::PostIncrementExpression *ast) override;
|
||||
bool visit(AST::PreDecrementExpression *ast) override;
|
||||
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;
|
||||
bool visit(AST::TypeOfExpression *ast) override;
|
||||
bool visit(AST::UnaryMinusExpression *ast) override;
|
||||
bool visit(AST::UnaryPlusExpression *ast) override;
|
||||
bool visit(AST::VoidExpression *ast) override;
|
||||
bool visit(AST::FunctionDeclaration *ast) override;
|
||||
bool visit(AST::YieldExpression *ast) override;
|
||||
bool visit(AST::ClassExpression *ast) override;
|
||||
bool visit(AST::ClassDeclaration *ast) override;
|
||||
bool visit(QQmlJS::AST::Expression *ast) override;
|
||||
bool visit(QQmlJS::AST::ArrayPattern *ast) override;
|
||||
bool visit(QQmlJS::AST::ArrayMemberExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::BinaryExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::CallExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::ConditionalExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::DeleteExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::FalseLiteral *ast) override;
|
||||
bool visit(QQmlJS::AST::SuperLiteral *ast) override;
|
||||
bool visit(QQmlJS::AST::FieldMemberExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::TaggedTemplate *ast) override;
|
||||
bool visit(QQmlJS::AST::FunctionExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::IdentifierExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::NestedExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::NewExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::NewMemberExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::NotExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::NullExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::NumericLiteral *ast) override;
|
||||
bool visit(QQmlJS::AST::ObjectPattern *ast) override;
|
||||
bool visit(QQmlJS::AST::PostDecrementExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::PostIncrementExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::PreDecrementExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::PreIncrementExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::RegExpLiteral *ast) override;
|
||||
bool visit(QQmlJS::AST::StringLiteral *ast) override;
|
||||
bool visit(QQmlJS::AST::TemplateLiteral *ast) override;
|
||||
bool visit(QQmlJS::AST::ThisExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::TildeExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::TrueLiteral *ast) override;
|
||||
bool visit(QQmlJS::AST::TypeOfExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::UnaryMinusExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::UnaryPlusExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::VoidExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::FunctionDeclaration *ast) override;
|
||||
bool visit(QQmlJS::AST::YieldExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::ClassExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::ClassDeclaration *ast) override;
|
||||
|
||||
// statements
|
||||
bool visit(AST::Block *ast) override;
|
||||
bool visit(AST::BreakStatement *ast) override;
|
||||
bool visit(AST::ContinueStatement *ast) override;
|
||||
bool visit(AST::DebuggerStatement *ast) override;
|
||||
bool visit(AST::DoWhileStatement *ast) override;
|
||||
bool visit(AST::EmptyStatement *ast) override;
|
||||
bool visit(AST::ExpressionStatement *ast) override;
|
||||
bool visit(AST::ForEachStatement *ast) override;
|
||||
bool visit(AST::ForStatement *ast) override;
|
||||
bool visit(AST::IfStatement *ast) override;
|
||||
bool visit(AST::LabelledStatement *ast) override;
|
||||
bool visit(AST::ReturnStatement *ast) override;
|
||||
bool visit(AST::SwitchStatement *ast) override;
|
||||
bool visit(AST::ThrowStatement *ast) override;
|
||||
bool visit(AST::TryStatement *ast) override;
|
||||
bool visit(AST::VariableStatement *ast) override;
|
||||
bool visit(AST::WhileStatement *ast) override;
|
||||
bool visit(AST::WithStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::Block *ast) override;
|
||||
bool visit(QQmlJS::AST::BreakStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::ContinueStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::DebuggerStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::DoWhileStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::EmptyStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::ExpressionStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::ForEachStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::ForStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::IfStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::LabelledStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::ReturnStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::SwitchStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::ThrowStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::TryStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::VariableStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::WhileStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::WithStatement *ast) override;
|
||||
|
||||
// ui object members
|
||||
bool visit(AST::UiArrayBinding *ast) override;
|
||||
bool visit(AST::UiObjectBinding *ast) override;
|
||||
bool visit(AST::UiObjectDefinition *ast) override;
|
||||
bool visit(AST::UiPublicMember *ast) override;
|
||||
bool visit(AST::UiScriptBinding *ast) override;
|
||||
bool visit(AST::UiSourceElement *ast) override;
|
||||
bool visit(QQmlJS::AST::UiArrayBinding *ast) override;
|
||||
bool visit(QQmlJS::AST::UiObjectBinding *ast) override;
|
||||
bool visit(QQmlJS::AST::UiObjectDefinition *ast) override;
|
||||
bool visit(QQmlJS::AST::UiPublicMember *ast) override;
|
||||
bool visit(QQmlJS::AST::UiScriptBinding *ast) override;
|
||||
bool visit(QQmlJS::AST::UiSourceElement *ast) override;
|
||||
|
||||
bool throwSyntaxErrorOnEvalOrArgumentsInStrictMode(const Reference &r, const AST::SourceLocation &loc);
|
||||
virtual void throwSyntaxError(const AST::SourceLocation &loc, const QString &detail);
|
||||
virtual void throwReferenceError(const AST::SourceLocation &loc, const QString &detail);
|
||||
bool throwSyntaxErrorOnEvalOrArgumentsInStrictMode(const Reference &r,
|
||||
const QQmlJS::AST::SourceLocation &loc);
|
||||
virtual void throwSyntaxError(const QQmlJS::AST::SourceLocation &loc, const QString &detail);
|
||||
virtual void throwReferenceError(const QQmlJS::AST::SourceLocation &loc, const QString &detail);
|
||||
void throwRecursionDepthError() override
|
||||
{
|
||||
throwSyntaxError(AST::SourceLocation(),
|
||||
throwSyntaxError(QQmlJS::AST::SourceLocation(),
|
||||
QStringLiteral("Maximum statement or expression depth exceeded"));
|
||||
}
|
||||
|
||||
|
@ -679,31 +679,33 @@ public:
|
|||
|
||||
ErrorType errorType() const { return _errorType; }
|
||||
bool hasError() const { return _errorType != NoError; }
|
||||
DiagnosticMessage error() const;
|
||||
QQmlJS::DiagnosticMessage error() const;
|
||||
QUrl url() const;
|
||||
|
||||
Reference binopHelper(QSOperator::Op oper, Reference &left, Reference &right);
|
||||
Reference jumpBinop(QSOperator::Op oper, Reference &left, Reference &right);
|
||||
struct Arguments { int argc; int argv; bool hasSpread; };
|
||||
Arguments pushArgs(AST::ArgumentList *args);
|
||||
Arguments pushArgs(QQmlJS::AST::ArgumentList *args);
|
||||
void handleCall(Reference &base, Arguments calldata, int slotForFunction, int slotForThisObject);
|
||||
|
||||
Arguments pushTemplateArgs(AST::TemplateLiteral *args);
|
||||
bool handleTaggedTemplate(Reference base, AST::TaggedTemplate *ast);
|
||||
void createTemplateObject(AST::TemplateLiteral *t);
|
||||
Arguments pushTemplateArgs(QQmlJS::AST::TemplateLiteral *args);
|
||||
bool handleTaggedTemplate(Reference base, QQmlJS::AST::TaggedTemplate *ast);
|
||||
void createTemplateObject(QQmlJS::AST::TemplateLiteral *t);
|
||||
|
||||
void setUseFastLookups(bool b) { useFastLookups = b; }
|
||||
|
||||
void handleTryCatch(AST::TryStatement *ast);
|
||||
void handleTryFinally(AST::TryStatement *ast);
|
||||
void handleTryCatch(QQmlJS::AST::TryStatement *ast);
|
||||
void handleTryFinally(QQmlJS::AST::TryStatement *ast);
|
||||
|
||||
|
||||
Reference referenceForName(const QString &name, bool lhs, const QQmlJS::AST::SourceLocation &accessLocation = QQmlJS::AST::SourceLocation());
|
||||
Reference referenceForName(
|
||||
const QString &name, bool lhs,
|
||||
const QQmlJS::AST::SourceLocation &accessLocation = QQmlJS::AST::SourceLocation());
|
||||
|
||||
QV4::CompiledData::CompilationUnit generateCompilationUnit(bool generateUnitData = true);
|
||||
static QV4::CompiledData::CompilationUnit compileModule(
|
||||
bool debugMode, const QString &url, const QString &sourceCode,
|
||||
const QDateTime &sourceTimeStamp, QList<DiagnosticMessage> *diagnostics);
|
||||
const QDateTime &sourceTimeStamp, QList<QQmlJS::DiagnosticMessage> *diagnostics);
|
||||
|
||||
Context *currentContext() const { return _context; }
|
||||
BytecodeGenerator *generator() const { return bytecodeGenerator; }
|
||||
|
@ -762,7 +764,7 @@ protected:
|
|||
int _returnAddress;
|
||||
Context *_context;
|
||||
Context *_functionContext = nullptr;
|
||||
AST::LabelledStatement *_labelledStatement;
|
||||
QQmlJS::AST::LabelledStatement *_labelledStatement;
|
||||
QV4::Compiler::JSUnitGenerator *jsUnitGenerator;
|
||||
BytecodeGenerator *bytecodeGenerator = nullptr;
|
||||
Moth::BytecodeGenerator::Label *_returnLabel = nullptr;
|
||||
|
@ -806,9 +808,10 @@ protected:
|
|||
};
|
||||
|
||||
private:
|
||||
VolatileMemoryLocations scanVolatileMemoryLocations(AST::Node *ast);
|
||||
void handleConstruct(const Reference &base, AST::ArgumentList *args);
|
||||
void throwError(ErrorType errorType, const AST::SourceLocation &loc, const QString &detail);
|
||||
VolatileMemoryLocations scanVolatileMemoryLocations(QQmlJS::AST::Node *ast);
|
||||
void handleConstruct(const Reference &base, QQmlJS::AST::ArgumentList *args);
|
||||
void throwError(ErrorType errorType, const QQmlJS::AST::SourceLocation &loc,
|
||||
const QString &detail);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -38,13 +38,14 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <qv4compiler_p.h>
|
||||
#include <qv4compileddata_p.h>
|
||||
#include <qv4codegen_p.h>
|
||||
#include <private/qv4compileddata_p.h>
|
||||
#include <private/qv4staticvalue_p.h>
|
||||
#include <private/qv4alloca_p.h>
|
||||
#include <private/qqmljslexer_p.h>
|
||||
#include <private/qqmljsast_p.h>
|
||||
#include <private/qml_compile_hash_p.h>
|
||||
#include <private/qqmlirbuilder_p.h>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
// Efficient implementation that takes advantage of powers of two.
|
||||
|
@ -268,8 +269,11 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
|
|||
registerString(module->finalUrl);
|
||||
for (Context *f : qAsConst(module->functions)) {
|
||||
registerString(f->name);
|
||||
for (int i = 0; i < f->arguments.size(); ++i)
|
||||
registerString(f->arguments.at(i));
|
||||
registerString(f->returnType);
|
||||
for (int i = 0; i < f->arguments.size(); ++i) {
|
||||
registerString(f->arguments.at(i).id);
|
||||
registerString(f->arguments.at(i).typeName());
|
||||
}
|
||||
for (int i = 0; i < f->locals.size(); ++i)
|
||||
registerString(f->locals.at(i));
|
||||
}
|
||||
|
@ -436,7 +440,9 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
|
|||
function->length = irFunction->formals ? irFunction->formals->length() : 0;
|
||||
function->nFormals = irFunction->arguments.size();
|
||||
function->formalsOffset = currentOffset;
|
||||
currentOffset += function->nFormals * sizeof(quint32);
|
||||
currentOffset += function->nFormals * sizeof(CompiledData::Parameter);
|
||||
|
||||
QmlIR::Parameter::initType(&function->returnType, this, getStringId(irFunction->returnType));
|
||||
|
||||
function->sizeOfLocalTemporalDeadZone = irFunction->sizeOfLocalTemporalDeadZone;
|
||||
function->sizeOfRegisterTemporalDeadZone = irFunction->sizeOfRegisterTemporalDeadZone;
|
||||
|
@ -465,9 +471,11 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Conte
|
|||
function->codeSize = irFunction->code.size();
|
||||
|
||||
// write formals
|
||||
quint32_le *formals = (quint32_le *)(f + function->formalsOffset);
|
||||
for (int i = 0; i < irFunction->arguments.size(); ++i)
|
||||
formals[i] = getStringId(irFunction->arguments.at(i));
|
||||
CompiledData::Parameter *formals = (CompiledData::Parameter *)(f + function->formalsOffset);
|
||||
for (int i = 0; i < irFunction->arguments.size(); ++i) {
|
||||
QmlIR::Parameter::init(&formals[i], this, getStringId(irFunction->arguments.at(i).id),
|
||||
getStringId(irFunction->arguments.at(i).typeName()));
|
||||
}
|
||||
|
||||
// write locals
|
||||
quint32_le *locals = (quint32_le *)(f + function->localsOffset);
|
||||
|
|
|
@ -53,9 +53,10 @@
|
|||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <private/qv4global_p.h>
|
||||
#include <private/qv4compilerglobal_p.h>
|
||||
#include <private/qqmljsastfwd_p.h>
|
||||
#include <private/qv4compileddata_p.h>
|
||||
#include <private/qv4staticvalue_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -72,10 +73,12 @@ struct JSClassMember;
|
|||
|
||||
namespace Compiler {
|
||||
|
||||
struct Context;
|
||||
struct Module;
|
||||
struct Class;
|
||||
struct TemplateObject;
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT StringTableGenerator {
|
||||
struct Q_QMLCOMPILER_PRIVATE_EXPORT StringTableGenerator {
|
||||
StringTableGenerator();
|
||||
|
||||
int registerString(const QString &str);
|
||||
|
@ -102,7 +105,7 @@ private:
|
|||
bool frozen = false;
|
||||
};
|
||||
|
||||
struct Q_QML_PRIVATE_EXPORT JSUnitGenerator {
|
||||
struct Q_QMLCOMPILER_PRIVATE_EXPORT JSUnitGenerator {
|
||||
static void generateUnitChecksum(CompiledData::Unit *unit);
|
||||
|
||||
struct MemberInfo {
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include "private/qv4global_p.h"
|
||||
#include <private/qqmljsast_p.h>
|
||||
#include <private/qv4compileddata_p.h>
|
||||
#include <QtCore/QStringList>
|
||||
|
@ -62,8 +61,13 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
namespace QV4 {
|
||||
|
||||
namespace Moth {
|
||||
class BytecodeGenerator;
|
||||
}
|
||||
|
||||
namespace Compiler {
|
||||
|
||||
class Codegen;
|
||||
struct ControlFlow;
|
||||
|
||||
enum class ContextType {
|
||||
|
@ -189,7 +193,8 @@ struct Context {
|
|||
MemberMap members;
|
||||
QSet<QString> usedVariables;
|
||||
QQmlJS::AST::FormalParameterList *formals = nullptr;
|
||||
QStringList arguments;
|
||||
QQmlJS::AST::BoundNames arguments;
|
||||
QString returnType;
|
||||
QStringList locals;
|
||||
QStringList moduleRequests;
|
||||
QVector<ImportEntry> importEntries;
|
||||
|
@ -288,7 +293,7 @@ struct Context {
|
|||
{
|
||||
// search backwards to handle duplicate argument names correctly
|
||||
for (int i = arguments.size() - 1; i >= 0; --i) {
|
||||
if (arguments.at(i) == name)
|
||||
if (arguments.at(i).id == name)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include <private/qv4global_p.h>
|
||||
#include <private/qv4codegen_p.h>
|
||||
#include <private/qqmljsast_p.h>
|
||||
#include <private/qv4bytecodegenerator_p.h>
|
||||
|
@ -279,7 +278,7 @@ struct ControlFlowWith : public ControlFlowUnwind
|
|||
|
||||
struct ControlFlowBlock : public ControlFlowUnwind
|
||||
{
|
||||
ControlFlowBlock(Codegen *cg, AST::Node *ast)
|
||||
ControlFlowBlock(Codegen *cg, QQmlJS::AST::Node *ast)
|
||||
: ControlFlowUnwind(cg, Block)
|
||||
{
|
||||
block = cg->enterBlock(ast);
|
||||
|
@ -314,11 +313,11 @@ struct ControlFlowBlock : public ControlFlowUnwind
|
|||
|
||||
struct ControlFlowCatch : public ControlFlowUnwind
|
||||
{
|
||||
AST::Catch *catchExpression;
|
||||
QQmlJS::AST::Catch *catchExpression;
|
||||
bool insideCatch = false;
|
||||
BytecodeGenerator::ExceptionHandler exceptionLabel;
|
||||
|
||||
ControlFlowCatch(Codegen *cg, AST::Catch *catchExpression)
|
||||
ControlFlowCatch(Codegen *cg, QQmlJS::AST::Catch *catchExpression)
|
||||
: ControlFlowUnwind(cg, Catch), catchExpression(catchExpression),
|
||||
exceptionLabel(generator()->newExceptionHandler())
|
||||
{
|
||||
|
@ -372,10 +371,10 @@ struct ControlFlowCatch : public ControlFlowUnwind
|
|||
|
||||
struct ControlFlowFinally : public ControlFlowUnwind
|
||||
{
|
||||
AST::Finally *finally;
|
||||
QQmlJS::AST::Finally *finally;
|
||||
bool insideFinally = false;
|
||||
|
||||
ControlFlowFinally(Codegen *cg, AST::Finally *finally)
|
||||
ControlFlowFinally(Codegen *cg, QQmlJS::AST::Finally *finally)
|
||||
: ControlFlowUnwind(cg, Finally), finally(finally)
|
||||
{
|
||||
Q_ASSERT(finally != nullptr);
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QV4COMPILERGLOBAL_H
|
||||
#define QV4COMPILERGLOBAL_H
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QString>
|
||||
|
||||
#include <private/qtqmlcompilerglobal_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QV4 {
|
||||
|
||||
enum class ObjectLiteralArgument {
|
||||
Value,
|
||||
Method,
|
||||
Getter,
|
||||
Setter
|
||||
};
|
||||
|
||||
} // namespace QV4
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QV4COMPILERGLOBAL_H
|
|
@ -52,6 +52,7 @@
|
|||
QT_USE_NAMESPACE
|
||||
using namespace QV4;
|
||||
using namespace QV4::Compiler;
|
||||
using namespace QQmlJS;
|
||||
using namespace QQmlJS::AST;
|
||||
|
||||
static CompiledData::Location location(const QQmlJS::AST::SourceLocation &astLocation)
|
||||
|
@ -202,16 +203,16 @@ bool ScanFunctions::visit(ExportDeclaration *declaration)
|
|||
_context->exportEntries << entry;
|
||||
}
|
||||
} else if (auto *vstmt = AST::cast<AST::VariableStatement*>(declaration->variableStatementOrDeclaration)) {
|
||||
QStringList boundNames;
|
||||
BoundNames boundNames;
|
||||
for (VariableDeclarationList *it = vstmt->declarations; it; it = it->next) {
|
||||
if (!it->declaration)
|
||||
continue;
|
||||
it->declaration->boundNames(&boundNames);
|
||||
}
|
||||
for (const QString &name: boundNames) {
|
||||
for (const auto &name: boundNames) {
|
||||
Compiler::ExportEntry entry;
|
||||
entry.localName = name;
|
||||
entry.exportName = name;
|
||||
entry.localName = name.id;
|
||||
entry.exportName = name.id;
|
||||
entry.location = location(vstmt->firstSourceLocation());
|
||||
_context->exportEntries << entry;
|
||||
}
|
||||
|
@ -326,26 +327,26 @@ bool ScanFunctions::visit(PatternElement *ast)
|
|||
if (!ast->isVariableDeclaration())
|
||||
return true;
|
||||
|
||||
QStringList names;
|
||||
BoundNames names;
|
||||
ast->boundNames(&names);
|
||||
|
||||
QQmlJS::AST::SourceLocation lastInitializerLocation = ast->lastSourceLocation();
|
||||
if (_context->lastBlockInitializerLocation.isValid())
|
||||
lastInitializerLocation = _context->lastBlockInitializerLocation;
|
||||
|
||||
for (const QString &name : qAsConst(names)) {
|
||||
if (_context->isStrict && (name == QLatin1String("eval") || name == QLatin1String("arguments")))
|
||||
for (const auto &name : qAsConst(names)) {
|
||||
if (_context->isStrict && (name.id == QLatin1String("eval") || name.id == QLatin1String("arguments")))
|
||||
_cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Variable name may not be eval or arguments in strict mode"));
|
||||
checkName(QStringRef(&name), ast->identifierToken);
|
||||
if (name == QLatin1String("arguments"))
|
||||
checkName(QStringRef(&name.id), ast->identifierToken);
|
||||
if (name.id == QLatin1String("arguments"))
|
||||
_context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
|
||||
if (ast->scope == VariableScope::Const && !ast->initializer && !ast->isForDeclaration && !ast->destructuringPattern()) {
|
||||
_cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Missing initializer in const declaration"));
|
||||
return false;
|
||||
}
|
||||
if (!_context->addLocalVar(name, ast->initializer ? Context::VariableDefinition : Context::VariableDeclaration, ast->scope,
|
||||
if (!_context->addLocalVar(name.id, ast->initializer ? Context::VariableDefinition : Context::VariableDeclaration, ast->scope,
|
||||
/*function*/nullptr, lastInitializerLocation)) {
|
||||
_cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Identifier %1 has already been declared").arg(name));
|
||||
_cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Identifier %1 has already been declared").arg(name.id));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -679,6 +680,9 @@ bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete
|
|||
_context->isArrowFunction = true;
|
||||
else if (expr->isGenerator)
|
||||
_context->isGenerator = true;
|
||||
|
||||
if (expr->typeAnnotation)
|
||||
_context->returnType = expr->typeAnnotation->type->toString();
|
||||
}
|
||||
|
||||
|
||||
|
@ -691,11 +695,11 @@ bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete
|
|||
|
||||
bool isSimpleParameterList = formals && formals->isSimpleParameterList();
|
||||
|
||||
_context->arguments = formals ? formals->formals() : QStringList();
|
||||
_context->arguments = formals ? formals->formals() : BoundNames();
|
||||
|
||||
const QStringList boundNames = formals ? formals->boundNames() : QStringList();
|
||||
const BoundNames boundNames = formals ? formals->boundNames() : BoundNames();
|
||||
for (int i = 0; i < boundNames.size(); ++i) {
|
||||
const QString &arg = boundNames.at(i);
|
||||
const QString &arg = boundNames.at(i).id;
|
||||
if (_context->isStrict || !isSimpleParameterList) {
|
||||
bool duplicate = (boundNames.indexOf(arg, i + 1) != -1);
|
||||
if (duplicate) {
|
||||
|
@ -712,6 +716,7 @@ bool ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParamete
|
|||
if (!_context->arguments.contains(arg))
|
||||
_context->addLocalVar(arg, Context::VariableDefinition, VariableScope::Var);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
// We mean it.
|
||||
//
|
||||
|
||||
#include "private/qv4global_p.h"
|
||||
#include <private/qtqmlcompilerglobal_p.h>
|
||||
#include <private/qqmljsastvisitor_p.h>
|
||||
#include <private/qqmljsast_p.h>
|
||||
#include <private/qqmljsengine_p.h>
|
||||
|
@ -62,8 +62,6 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
using namespace QQmlJS;
|
||||
|
||||
namespace QV4 {
|
||||
|
||||
namespace Moth {
|
||||
|
@ -83,84 +81,87 @@ class ScanFunctions: protected QQmlJS::AST::Visitor
|
|||
typedef QScopedValueRollback<bool> TemporaryBoolAssignment;
|
||||
public:
|
||||
ScanFunctions(Codegen *cg, const QString &sourceCode, ContextType defaultProgramType);
|
||||
void operator()(AST::Node *node);
|
||||
void operator()(QQmlJS::AST::Node *node);
|
||||
|
||||
void enterGlobalEnvironment(ContextType compilationMode);
|
||||
void enterEnvironment(AST::Node *node, ContextType compilationMode, const QString &name);
|
||||
void enterEnvironment(QQmlJS::AST::Node *node, ContextType compilationMode,
|
||||
const QString &name);
|
||||
void leaveEnvironment();
|
||||
|
||||
void enterQmlFunction(AST::FunctionDeclaration *ast)
|
||||
void enterQmlFunction(QQmlJS::AST::FunctionDeclaration *ast)
|
||||
{ enterFunction(ast, false); }
|
||||
|
||||
protected:
|
||||
using Visitor::visit;
|
||||
using Visitor::endVisit;
|
||||
|
||||
void checkDirectivePrologue(AST::StatementList *ast);
|
||||
void checkDirectivePrologue(QQmlJS::AST::StatementList *ast);
|
||||
|
||||
void checkName(const QStringRef &name, const AST::SourceLocation &loc);
|
||||
void checkName(const QStringRef &name, const QQmlJS::AST::SourceLocation &loc);
|
||||
|
||||
bool visit(AST::Program *ast) override;
|
||||
void endVisit(AST::Program *) override;
|
||||
bool visit(QQmlJS::AST::Program *ast) override;
|
||||
void endVisit(QQmlJS::AST::Program *) override;
|
||||
|
||||
bool visit(AST::ESModule *ast) override;
|
||||
void endVisit(AST::ESModule *) override;
|
||||
bool visit(QQmlJS::AST::ESModule *ast) override;
|
||||
void endVisit(QQmlJS::AST::ESModule *) override;
|
||||
|
||||
bool visit(AST::ExportDeclaration *declaration) override;
|
||||
bool visit(AST::ImportDeclaration *declaration) override;
|
||||
bool visit(QQmlJS::AST::ExportDeclaration *declaration) override;
|
||||
bool visit(QQmlJS::AST::ImportDeclaration *declaration) override;
|
||||
|
||||
bool visit(AST::CallExpression *ast) override;
|
||||
bool visit(AST::PatternElement *ast) override;
|
||||
bool visit(AST::IdentifierExpression *ast) override;
|
||||
bool visit(AST::ExpressionStatement *ast) override;
|
||||
bool visit(AST::FunctionExpression *ast) override;
|
||||
bool visit(AST::TemplateLiteral *ast) override;
|
||||
bool visit(AST::SuperLiteral *) override;
|
||||
bool visit(AST::FieldMemberExpression *) override;
|
||||
bool visit(AST::ArrayPattern *) override;
|
||||
bool visit(QQmlJS::AST::CallExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::PatternElement *ast) override;
|
||||
bool visit(QQmlJS::AST::IdentifierExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::ExpressionStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::FunctionExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::TemplateLiteral *ast) override;
|
||||
bool visit(QQmlJS::AST::SuperLiteral *) override;
|
||||
bool visit(QQmlJS::AST::FieldMemberExpression *) override;
|
||||
bool visit(QQmlJS::AST::ArrayPattern *) override;
|
||||
|
||||
bool enterFunction(AST::FunctionExpression *ast, bool enterName);
|
||||
bool enterFunction(QQmlJS::AST::FunctionExpression *ast, bool enterName);
|
||||
|
||||
void endVisit(AST::FunctionExpression *) override;
|
||||
void endVisit(QQmlJS::AST::FunctionExpression *) override;
|
||||
|
||||
bool visit(AST::ObjectPattern *ast) override;
|
||||
bool visit(QQmlJS::AST::ObjectPattern *ast) override;
|
||||
|
||||
bool visit(AST::PatternProperty *ast) override;
|
||||
void endVisit(AST::PatternProperty *) override;
|
||||
bool visit(QQmlJS::AST::PatternProperty *ast) override;
|
||||
void endVisit(QQmlJS::AST::PatternProperty *) override;
|
||||
|
||||
bool visit(AST::FunctionDeclaration *ast) override;
|
||||
void endVisit(AST::FunctionDeclaration *) override;
|
||||
bool visit(QQmlJS::AST::FunctionDeclaration *ast) override;
|
||||
void endVisit(QQmlJS::AST::FunctionDeclaration *) override;
|
||||
|
||||
bool visit(AST::ClassExpression *ast) override;
|
||||
void endVisit(AST::ClassExpression *) override;
|
||||
bool visit(QQmlJS::AST::ClassExpression *ast) override;
|
||||
void endVisit(QQmlJS::AST::ClassExpression *) override;
|
||||
|
||||
bool visit(AST::ClassDeclaration *ast) override;
|
||||
void endVisit(AST::ClassDeclaration *) override;
|
||||
bool visit(QQmlJS::AST::ClassDeclaration *ast) override;
|
||||
void endVisit(QQmlJS::AST::ClassDeclaration *) override;
|
||||
|
||||
bool visit(AST::DoWhileStatement *ast) override;
|
||||
bool visit(AST::ForStatement *ast) override;
|
||||
void endVisit(AST::ForStatement *) override;
|
||||
bool visit(AST::ForEachStatement *ast) override;
|
||||
void endVisit(AST::ForEachStatement *) override;
|
||||
bool visit(QQmlJS::AST::DoWhileStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::ForStatement *ast) override;
|
||||
void endVisit(QQmlJS::AST::ForStatement *) override;
|
||||
bool visit(QQmlJS::AST::ForEachStatement *ast) override;
|
||||
void endVisit(QQmlJS::AST::ForEachStatement *) override;
|
||||
|
||||
bool visit(AST::ThisExpression *ast) override;
|
||||
bool visit(QQmlJS::AST::ThisExpression *ast) override;
|
||||
|
||||
bool visit(AST::Block *ast) override;
|
||||
void endVisit(AST::Block *ast) override;
|
||||
bool visit(QQmlJS::AST::Block *ast) override;
|
||||
void endVisit(QQmlJS::AST::Block *ast) override;
|
||||
|
||||
bool visit(AST::CaseBlock *ast) override;
|
||||
void endVisit(AST::CaseBlock *ast) override;
|
||||
bool visit(QQmlJS::AST::CaseBlock *ast) override;
|
||||
void endVisit(QQmlJS::AST::CaseBlock *ast) override;
|
||||
|
||||
bool visit(AST::Catch *ast) override;
|
||||
void endVisit(AST::Catch *ast) override;
|
||||
bool visit(QQmlJS::AST::Catch *ast) override;
|
||||
void endVisit(QQmlJS::AST::Catch *ast) override;
|
||||
|
||||
bool visit(AST::WithStatement *ast) override;
|
||||
void endVisit(AST::WithStatement *ast) override;
|
||||
bool visit(QQmlJS::AST::WithStatement *ast) override;
|
||||
void endVisit(QQmlJS::AST::WithStatement *ast) override;
|
||||
|
||||
void throwRecursionDepthError() override;
|
||||
|
||||
protected:
|
||||
bool enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::StatementList *body, bool enterName);
|
||||
bool enterFunction(QQmlJS::AST::Node *ast, const QString &name,
|
||||
QQmlJS::AST::FormalParameterList *formals,
|
||||
QQmlJS::AST::StatementList *body, bool enterName);
|
||||
|
||||
void calcEscapingVariables();
|
||||
// fields:
|
||||
|
@ -173,7 +174,7 @@ protected:
|
|||
ContextType defaultProgramType;
|
||||
|
||||
private:
|
||||
static constexpr AST::Node *astNodeForGlobalEnvironment = nullptr;
|
||||
static constexpr QQmlJS::AST::Node *astNodeForGlobalEnvironment = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
//
|
||||
// We mean it.
|
||||
//
|
||||
#include <private/qv4global_p.h>
|
||||
|
||||
#include <private/qv4staticvalue_p.h>
|
||||
#include <private/qv4compileddata_p.h> // for CompiledData::CodeOffsetToLine used by the dumper
|
||||
#include <qendian.h>
|
||||
|
|
|
@ -178,6 +178,13 @@
|
|||
"section": "QML",
|
||||
"condition": "features.thread",
|
||||
"output": [ "privateFeature" ]
|
||||
},
|
||||
"qml-itemmodel": {
|
||||
"label": "QML Item Model",
|
||||
"purpose": "Provides the item model for item views in QML",
|
||||
"section": "QML",
|
||||
"condition": "features.itemmodel",
|
||||
"output": [ "privateFeature" ]
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
|
||||
include($QT_INSTALL_DOCS/config/exampleurl-qtdeclarative.qdocconf)
|
||||
|
||||
project = QtQml
|
||||
description = Qt QML Reference Documentation
|
||||
|
|
|
@ -59,8 +59,8 @@ Rectangle {
|
|||
|
||||
//! [signal declaration]
|
||||
signal trigger
|
||||
signal send (string notice)
|
||||
signal perform (string task, variant object)
|
||||
signal send(notice: string)
|
||||
signal perform(task: string, object: variant)
|
||||
//! [signal declaration]
|
||||
|
||||
//! [signal handler declaration]
|
||||
|
@ -88,7 +88,7 @@ Rectangle {
|
|||
Rectangle {
|
||||
id: messenger
|
||||
|
||||
signal send( string person, string notice)
|
||||
signal send(person: string, notice: string)
|
||||
|
||||
onSend: {
|
||||
console.log("For " + person + ", the notice is: " + notice)
|
||||
|
@ -102,7 +102,7 @@ Rectangle {
|
|||
Rectangle {
|
||||
id: relay
|
||||
|
||||
signal send( string person, string notice)
|
||||
signal send(person: string, notice: string)
|
||||
onSend: console.log("Send signal to: " + person + ", " + notice)
|
||||
|
||||
Component.onCompleted: {
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
function myQmlFunction(msg) {
|
||||
function myQmlFunction(msg: string) : string {
|
||||
console.log("Got message:", msg)
|
||||
return "some return value"
|
||||
}
|
||||
|
|
|
@ -60,13 +60,13 @@ QQmlEngine engine;
|
|||
QQmlComponent component(&engine, "MyItem.qml");
|
||||
QObject *object = component.create();
|
||||
|
||||
QVariant returnedValue;
|
||||
QVariant msg = "Hello from C++";
|
||||
QString returnedValue;
|
||||
QString msg = "Hello from C++";
|
||||
QMetaObject::invokeMethod(object, "myQmlFunction",
|
||||
Q_RETURN_ARG(QVariant, returnedValue),
|
||||
Q_ARG(QVariant, msg));
|
||||
Q_RETURN_ARG(QString, returnedValue),
|
||||
Q_ARG(QString, msg));
|
||||
|
||||
qDebug() << "QML function returned:" << returnedValue.toString();
|
||||
qDebug() << "QML function returned:" << returnedValue;
|
||||
delete object;
|
||||
//![0]
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ Item {
|
|||
id: item
|
||||
width: 100; height: 100
|
||||
|
||||
signal qmlSignal(string msg)
|
||||
signal qmlSignal(msg: string)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
|
|
@ -70,7 +70,7 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
// define the signal the SignalTransition is connected with
|
||||
signal mysignal(string mystr)
|
||||
signal mysignal(mystr: string)
|
||||
// on clicking the button emit the signal with a single string argument
|
||||
onClicked: button.mysignal("test")
|
||||
}
|
||||
|
|
|
@ -166,9 +166,12 @@ updated, and any \c onButtonTextChanged handlers would not be called.
|
|||
|
||||
\section2 Invoking QML Methods
|
||||
|
||||
All QML methods are exposed to the meta-object system and can be called from C++
|
||||
using QMetaObject::invokeMethod(). Method parameters and return values passed
|
||||
from QML are always translated into QVariant values in C++.
|
||||
All QML methods are exposed to the meta-object system and can be called from
|
||||
C++ using QMetaObject::invokeMethod(). You can specify types for the parameters
|
||||
and the return value after the colon character, as shown in the code snippet
|
||||
below. This can be useful, for example, when you want to connect a signal in
|
||||
C++ with a certain signature to a QML-defined method. If you omit the types,
|
||||
the C++ signature will use QVariant.
|
||||
|
||||
Here is a C++ application that calls a QML method using
|
||||
QMetaObject::invokeMethod():
|
||||
|
@ -182,9 +185,12 @@ QMetaObject::invokeMethod():
|
|||
\li \snippet qml/qtbinding/functions-qml/main.cpp 0
|
||||
\endtable
|
||||
|
||||
Notice the Q_RETURN_ARG() and Q_ARG() arguments for QMetaObject::invokeMethod()
|
||||
must be specified as QVariant types, as this is the generic data type used for
|
||||
QML method parameters and return values.
|
||||
Notice the parameter and return type specified after the colon. You can use \l
|
||||
{QML Basic Types}{basic types} and \l {QML Object Types}{object types} as type
|
||||
names.
|
||||
|
||||
If the type is omitted in QML, then you must specify QVariant as type with
|
||||
Q_RETURN_ARG() and Q_ARG() when calling QMetaObject::invokeMethod.
|
||||
|
||||
|
||||
\section2 Connecting to QML Signals
|
||||
|
@ -210,9 +216,8 @@ QObject::connect(), so that the \c cppSlot() method is called whenever the
|
|||
\snippet qml/qtbinding/signals-qml/main.cpp 0
|
||||
\endtable
|
||||
|
||||
When a QML object type is used as a signal parameter, the parameter should
|
||||
use \l var as the type, and the value should be received in C++ using the
|
||||
QVariant type:
|
||||
A QML object type in a signal parameter is translated to a pointer to the class
|
||||
in C++:
|
||||
|
||||
\table
|
||||
\row
|
||||
|
@ -226,7 +231,7 @@ QVariant type:
|
|||
id: item
|
||||
width: 100; height: 100
|
||||
|
||||
signal qmlSignal(var anObject)
|
||||
signal qmlSignal(anObject: Item)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
@ -241,18 +246,16 @@ QVariant type:
|
|||
{
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
void cppSlot(const QVariant &v) {
|
||||
qDebug() << "Called the C++ slot with value:" << v;
|
||||
void cppSlot(QQuickItem *item) {
|
||||
qDebug() << "Called the C++ slot with item:" << item;
|
||||
|
||||
QQuickItem *item =
|
||||
qobject_cast<QQuickItem*>(v.value<QObject*>());
|
||||
qDebug() << "Item dimensions:" << item->width()
|
||||
<< item->height();
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QApplication app(argc, argv);
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
QQuickView view(QUrl::fromLocalFile("MyItem.qml"));
|
||||
QObject *item = view.rootObject();
|
||||
|
|
|
@ -38,13 +38,14 @@
|
|||
****************************************************************************/
|
||||
#include <qv4argumentsobject_p.h>
|
||||
#include <qv4arrayobject_p.h>
|
||||
#include <qv4alloca_p.h>
|
||||
#include <qv4scopedvalue_p.h>
|
||||
#include <qv4string_p.h>
|
||||
#include <qv4function_p.h>
|
||||
#include <qv4jscall_p.h>
|
||||
#include <qv4symbol_p.h>
|
||||
|
||||
#include <private/qv4alloca_p.h>
|
||||
|
||||
using namespace QV4;
|
||||
|
||||
DEFINE_OBJECT_VTABLE(ArgumentsObject);
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#include "qv4compilationunitmapper_p.h"
|
||||
|
||||
#include "qv4compileddata_p.h"
|
||||
#include <private/qv4compileddata_p.h>
|
||||
#include <QFileInfo>
|
||||
#include <QDateTime>
|
||||
#include <QCoreApplication>
|
||||
|
|
|
@ -52,8 +52,6 @@
|
|||
|
||||
#include <time.h>
|
||||
|
||||
#include <private/qqmljsengine_p.h>
|
||||
|
||||
#include <wtf/MathExtras.h>
|
||||
|
||||
#if defined(Q_OS_LINUX) && QT_CONFIG(timezone)
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
//
|
||||
|
||||
#include "qv4global_p.h"
|
||||
#include <private/qv4staticvalue_p.h>
|
||||
#include <QtCore/qobject.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
#include <qv4engine_p.h>
|
||||
|
||||
#include <private/qv4compileddata_p.h>
|
||||
#include <private/qv4compiler_p.h>
|
||||
#include <private/qv4compilercontext_p.h>
|
||||
#include <private/qv4codegen_p.h>
|
||||
#include <private/qqmljsdiagnosticmessage_p.h>
|
||||
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
#include <private/qintrusivelist_p.h>
|
||||
#include "qv4enginebase_p.h"
|
||||
#include <private/qqmlrefcount_p.h>
|
||||
#include <private/qqmljsengine_p.h>
|
||||
#include <private/qqmldelayedcallqueue_p.h>
|
||||
#include <QtCore/qelapsedtimer.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
#include "qv4string_p.h"
|
||||
#include <private/qv4mm_p.h>
|
||||
#include <qv4codegen_p.h>
|
||||
#include <private/qv4codegen_p.h>
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
# include <time.h>
|
||||
|
|
|
@ -44,11 +44,11 @@
|
|||
#include <private/qv4lookup_p.h>
|
||||
#include <private/qv4qmlcontext_p.h>
|
||||
#include <private/qv4identifiertable_p.h>
|
||||
#include <private/qv4instr_moth_p.h>
|
||||
#include <private/qv4objectproto_p.h>
|
||||
#include <private/qqmlengine_p.h>
|
||||
#include <private/qv4qobjectwrapper_p.h>
|
||||
#include <private/qqmlvaluetypewrapper_p.h>
|
||||
#include <private/qqmlscriptdata_p.h>
|
||||
#include <private/qv4module_p.h>
|
||||
#include <private/qv4compilationunitmapper_p.h>
|
||||
#include <private/qml_compile_hash_p.h>
|
||||
|
@ -784,7 +784,7 @@ QString ExecutableCompilationUnit::bindingValueAsString(const CompiledData::Bind
|
|||
case Binding::Type_Boolean:
|
||||
return binding->value.b ? QStringLiteral("true") : QStringLiteral("false");
|
||||
case Binding::Type_Number:
|
||||
return QString::number(bindingValueAsNumber(binding));
|
||||
return QString::number(bindingValueAsNumber(binding), 'g', QLocale::FloatingPointShortest);
|
||||
case Binding::Type_Invalid:
|
||||
return QString();
|
||||
#if !QT_CONFIG(translation)
|
||||
|
|
|
@ -61,9 +61,13 @@
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QQmlScriptData;
|
||||
class QQmlEnginePrivate;
|
||||
namespace QV4 {
|
||||
|
||||
// index is per-object binding index
|
||||
typedef QVector<QQmlPropertyData*> BindingPropertyData;
|
||||
|
||||
class CompilationUnitMapper;
|
||||
struct ResolvedTypeReference;
|
||||
// map from name index
|
||||
|
@ -131,7 +135,7 @@ public:
|
|||
// index is object index. This allows fast access to the
|
||||
// property data when initializing bindings, avoiding expensive
|
||||
// lookups by string (property name).
|
||||
QVector<CompiledData::BindingPropertyData> bindingPropertyDataPerObject;
|
||||
QVector<BindingPropertyData> bindingPropertyDataPerObject;
|
||||
|
||||
// mapping from component object index (CompiledData::Unit object index that points to component) to identifier hash of named objects
|
||||
// this is initialized on-demand by QQmlContextData
|
||||
|
|
|
@ -100,9 +100,9 @@ Function::Function(ExecutionEngine *engine, ExecutableCompilationUnit *unit,
|
|||
for (quint32 i = 0; i < compiledFunction->nLocals; ++i)
|
||||
ic = ic->addMember(engine->identifierTable->asPropertyKey(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable);
|
||||
|
||||
const quint32_le *formalsIndices = compiledFunction->formalsTable();
|
||||
const CompiledData::Parameter *formalsIndices = compiledFunction->formalsTable();
|
||||
for (quint32 i = 0; i < compiledFunction->nFormals; ++i)
|
||||
ic = ic->addMember(engine->identifierTable->asPropertyKey(compilationUnit->runtimeStrings[formalsIndices[i]]), Attr_NotConfigurable);
|
||||
ic = ic->addMember(engine->identifierTable->asPropertyKey(compilationUnit->runtimeStrings[formalsIndices[i].nameIndex]), Attr_NotConfigurable);
|
||||
internalClass = ic->d();
|
||||
|
||||
nFormals = compiledFunction->nFormals;
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "qv4global_p.h"
|
||||
#include <private/qv4executablecompilationunit_p.h>
|
||||
#include <private/qv4context_p.h>
|
||||
#include <private/qv4string_p.h>
|
||||
|
||||
namespace JSC {
|
||||
class MacroAssemblerCodeRef;
|
||||
|
@ -93,7 +94,7 @@ public:
|
|||
return static_cast<QV4::ExecutableCompilationUnit *>(compilationUnit);
|
||||
}
|
||||
|
||||
QV4::Heap::String *runtimeString(uint i)
|
||||
QV4::Heap::String *runtimeString(uint i) const
|
||||
{
|
||||
return compilationUnit->runtimeStrings[i];
|
||||
}
|
||||
|
@ -120,7 +121,7 @@ public:
|
|||
void updateInternalClass(ExecutionEngine *engine, const QList<QByteArray> ¶meters);
|
||||
|
||||
inline Heap::String *name() const {
|
||||
return compilationUnit->runtimeStrings[compiledFunction->nameIndex];
|
||||
return runtimeString(compiledFunction->nameIndex);
|
||||
}
|
||||
|
||||
static QString prettyName(const Function *function, const void *address);
|
||||
|
|
|
@ -59,10 +59,10 @@
|
|||
#include "private/qqmlbuiltinfunctions_p.h"
|
||||
#include <private/qv4jscall_p.h>
|
||||
#include <private/qv4vme_moth_p.h>
|
||||
#include <private/qv4alloca_p.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <algorithm>
|
||||
#include "qv4alloca_p.h"
|
||||
#include "qv4profiling_p.h"
|
||||
|
||||
using namespace QV4;
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
//
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <private/qv4compilerglobal_p.h>
|
||||
#include <QString>
|
||||
|
||||
#ifdef QT_NO_DEBUG
|
||||
|
@ -207,11 +208,6 @@ struct SetMapObject;
|
|||
struct PromiseObject;
|
||||
struct PromiseCapability;
|
||||
|
||||
// ReturnedValue is used to return values from runtime methods
|
||||
// the type has to be a primitive type (no struct or union), so that the compiler
|
||||
// will return it in a register on all platforms.
|
||||
// It will be returned in rax on x64, [eax,edx] on x86 and [r0,r1] on arm
|
||||
typedef quint64 ReturnedValue;
|
||||
struct CallData;
|
||||
struct Scope;
|
||||
struct ScopedValue;
|
||||
|
@ -341,13 +337,6 @@ struct Q_QML_EXPORT StackFrame {
|
|||
};
|
||||
typedef QVector<StackFrame> StackTrace;
|
||||
|
||||
enum class ObjectLiteralArgument {
|
||||
Value,
|
||||
Method,
|
||||
Getter,
|
||||
Setter
|
||||
};
|
||||
|
||||
namespace JIT {
|
||||
|
||||
enum class CallResultDestination {
|
||||
|
|
|
@ -49,18 +49,14 @@
|
|||
#include "qv4string_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 <qv4codegen_p.h>
|
||||
#include <private/qv4codegen_p.h>
|
||||
#include <private/qv4alloca_p.h>
|
||||
#include "private/qlocale_tools_p.h"
|
||||
#include "private/qtools_p.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QString>
|
||||
#include <iostream>
|
||||
#include "qv4alloca_p.h"
|
||||
|
||||
#include <wtf/MathExtras.h>
|
||||
|
||||
|
|
|
@ -167,7 +167,6 @@ void QV4Include::finished()
|
|||
QByteArray data = m_reply->readAll();
|
||||
|
||||
QString code = QString::fromUtf8(data);
|
||||
QmlIR::Document::removeScriptPragmas(code);
|
||||
|
||||
QV4::Scoped<QV4::QmlContext> qml(scope, m_qmlContext.value());
|
||||
QV4::Script script(v4, qml, /*parse as QML binding*/false, code, m_url.toString());
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
|
||||
#include <qglobal.h>
|
||||
|
||||
#include <QtQml/private/qv4staticvalue_p.h>
|
||||
#include <private/qv4staticvalue_p.h>
|
||||
#include <QtCore/qnumeric.h>
|
||||
#include <QtCore/private/qnumeric_p.h>
|
||||
#include <cmath>
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include <private/qv4variantobject_p.h>
|
||||
#include <private/qv4identifiertable_p.h>
|
||||
#include <private/qv4lookup_p.h>
|
||||
#include <private/qv4qmlcontext_p.h>
|
||||
|
||||
#if QT_CONFIG(qml_sequence_object)
|
||||
#include <private/qv4sequenceobject_p.h>
|
||||
|
@ -80,7 +81,9 @@
|
|||
#include <QtCore/qtimer.h>
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <QtCore/qmetaobject.h>
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
#include <QtCore/qabstractitemmodel.h>
|
||||
#endif
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
|
||||
#include <vector>
|
||||
|
@ -1233,7 +1236,9 @@ private:
|
|||
std::vector<bool> *stdVectorBoolPtr;
|
||||
std::vector<QString> *stdVectorQStringPtr;
|
||||
std::vector<QUrl> *stdVectorQUrlPtr;
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
std::vector<QModelIndex> *stdVectorQModelIndexPtr;
|
||||
#endif
|
||||
|
||||
char allocData[MaxSizeOf7<QVariant,
|
||||
QString,
|
||||
|
@ -1693,8 +1698,10 @@ void *CallArgument::dataPtr()
|
|||
return stdVectorQStringPtr;
|
||||
else if (type == qMetaTypeId<std::vector<QUrl>>())
|
||||
return stdVectorQUrlPtr;
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
else if (type == qMetaTypeId<std::vector<QModelIndex>>())
|
||||
return stdVectorQModelIndexPtr;
|
||||
#endif
|
||||
else if (type != 0)
|
||||
return (void *)&allocData;
|
||||
return nullptr;
|
||||
|
@ -1845,7 +1852,10 @@ bool CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
|
|||
|| callType == qMetaTypeId<std::vector<bool>>()
|
||||
|| callType == qMetaTypeId<std::vector<QString>>()
|
||||
|| callType == qMetaTypeId<std::vector<QUrl>>()
|
||||
|| callType == qMetaTypeId<std::vector<QModelIndex>>()) {
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
|| callType == qMetaTypeId<std::vector<QModelIndex>>()
|
||||
#endif
|
||||
) {
|
||||
queryEngine = true;
|
||||
const QV4::Object* object = value.as<QV4::Object>();
|
||||
if (callType == qMetaTypeId<std::vector<int>>()) {
|
||||
|
@ -1863,9 +1873,11 @@ bool CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
|
|||
} else if (callType == qMetaTypeId<std::vector<QUrl>>()) {
|
||||
stdVectorQUrlPtr = nullptr;
|
||||
fromContainerValue<std::vector<QUrl>>(object, callType, &CallArgument::stdVectorQUrlPtr, queryEngine);
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
} else if (callType == qMetaTypeId<std::vector<QModelIndex>>()) {
|
||||
stdVectorQModelIndexPtr = nullptr;
|
||||
fromContainerValue<std::vector<QModelIndex>>(object, callType, &CallArgument::stdVectorQModelIndexPtr, queryEngine);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
} else if (QMetaType::typeFlags(callType)
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
#include <cassert>
|
||||
#include <typeinfo>
|
||||
#include <iostream>
|
||||
#include "qv4alloca_p.h"
|
||||
#include <private/qv4alloca_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include <private/qqmltypewrapper_p.h>
|
||||
#include <private/qqmlengine_p.h>
|
||||
#include <private/qqmljavascriptexpression_p.h>
|
||||
#include <private/qqmljsast_p.h>
|
||||
#include "qv4qobjectwrapper_p.h"
|
||||
#include "qv4symbol_p.h"
|
||||
#include "qv4generatorobject_p.h"
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
//
|
||||
|
||||
#include <private/qv4global_p.h>
|
||||
#include <private/qv4staticvalue_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
|
@ -39,9 +39,10 @@
|
|||
|
||||
#include "qv4engine_p.h"
|
||||
#include "qv4runtimecodegen_p.h"
|
||||
#include "qv4compilerscanfunctions_p.h"
|
||||
#include <private/qv4compilerscanfunctions_p.h>
|
||||
|
||||
using namespace QV4;
|
||||
using namespace QQmlJS;
|
||||
|
||||
void RuntimeCodegen::generateFromFunctionExpression(const QString &fileName,
|
||||
const QString &sourceCode,
|
||||
|
|
|
@ -66,11 +66,11 @@ public:
|
|||
|
||||
void generateFromFunctionExpression(const QString &fileName,
|
||||
const QString &sourceCode,
|
||||
AST::FunctionExpression *ast,
|
||||
QQmlJS::AST::FunctionExpression *ast,
|
||||
Compiler::Module *module);
|
||||
|
||||
void throwSyntaxError(const AST::SourceLocation &loc, const QString &detail) override;
|
||||
void throwReferenceError(const AST::SourceLocation &loc, const QString &detail) override;
|
||||
void throwSyntaxError(const QQmlJS::AST::SourceLocation &loc, const QString &detail) override;
|
||||
void throwReferenceError(const QQmlJS::AST::SourceLocation &loc, const QString &detail) override;
|
||||
|
||||
private:
|
||||
ExecutionEngine *engine;
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include <QScopedValueRollback>
|
||||
|
||||
using namespace QV4;
|
||||
using namespace QQmlJS;
|
||||
|
||||
Script::Script(ExecutionEngine *v4, QmlContext *qml, const QQmlRefPointer<ExecutableCompilationUnit> &compilationUnit)
|
||||
: line(1), column(0), context(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false)
|
||||
|
@ -245,7 +246,6 @@ Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlCo
|
|||
|
||||
QByteArray data = f.readAll();
|
||||
QString sourceCode = QString::fromUtf8(data);
|
||||
QmlIR::Document::removeScriptPragmas(sourceCode);
|
||||
|
||||
auto result = new QV4::Script(engine, qmlContext, /*parseAsBinding*/false, sourceCode, originalUrl.toString());
|
||||
result->contextType = QV4::Compiler::ContextType::ScriptImportedByQML;
|
||||
|
|
|
@ -49,8 +49,10 @@
|
|||
#include "qv4runtime_p.h"
|
||||
#include "qv4objectiterator_p.h"
|
||||
#include <private/qqmlvaluetypewrapper_p.h>
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
#include <private/qqmlmodelindexvaluetype_p.h>
|
||||
#include <QtCore/qabstractitemmodel.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -75,6 +77,16 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
|
|||
}
|
||||
|
||||
// F(elementType, elementTypeName, sequenceType, defaultValue)
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
#define FOREACH_QML_SEQUENCE_TYPE_FOR_ITEMMODEL(F) \
|
||||
F(QModelIndex, QModelIndex, QModelIndexList, QModelIndex()) \
|
||||
F(QModelIndex, QModelIndexVector, QVector<QModelIndex>, QModelIndex()) \
|
||||
F(QModelIndex, QModelIndexStdVector, std::vector<QModelIndex>, QModelIndex()) \
|
||||
F(QItemSelectionRange, QItemSelectionRange, QItemSelection, QItemSelectionRange())
|
||||
#else
|
||||
#define FOREACH_QML_SEQUENCE_TYPE_FOR_ITEMMODEL(F)
|
||||
#endif
|
||||
|
||||
#define FOREACH_QML_SEQUENCE_TYPE(F) \
|
||||
F(int, IntVector, QVector<int>, 0) \
|
||||
F(qreal, RealVector, QVector<qreal>, 0.0) \
|
||||
|
@ -92,10 +104,7 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
|
|||
F(QUrl, Url, QList<QUrl>, QUrl()) \
|
||||
F(QUrl, UrlVector, QVector<QUrl>, QUrl()) \
|
||||
F(QUrl, UrlStdVector, std::vector<QUrl>, QUrl()) \
|
||||
F(QModelIndex, QModelIndex, QModelIndexList, QModelIndex()) \
|
||||
F(QModelIndex, QModelIndexVector, QVector<QModelIndex>, QModelIndex()) \
|
||||
F(QModelIndex, QModelIndexStdVector, std::vector<QModelIndex>, QModelIndex()) \
|
||||
F(QItemSelectionRange, QItemSelectionRange, QItemSelection, QItemSelectionRange())
|
||||
FOREACH_QML_SEQUENCE_TYPE_FOR_ITEMMODEL(F)
|
||||
|
||||
static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, const QString &element)
|
||||
{
|
||||
|
@ -112,6 +121,7 @@ static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, co
|
|||
return engine->newString(element.toString())->asReturnedValue();
|
||||
}
|
||||
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, const QModelIndex &element)
|
||||
{
|
||||
const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(QMetaType::QModelIndex);
|
||||
|
@ -124,6 +134,7 @@ static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, co
|
|||
const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(metaTypeId);
|
||||
return QV4::QQmlValueTypeWrapper::create(engine, QVariant::fromValue(element), vtmo, metaTypeId);
|
||||
}
|
||||
#endif
|
||||
|
||||
static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *, qreal element)
|
||||
{
|
||||
|
@ -150,6 +161,7 @@ static QString convertElementToString(const QUrl &element)
|
|||
return element.toString();
|
||||
}
|
||||
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
static QString convertElementToString(const QModelIndex &element)
|
||||
{
|
||||
return reinterpret_cast<const QQmlModelIndexValueType *>(&element)->toString();
|
||||
|
@ -159,6 +171,7 @@ static QString convertElementToString(const QItemSelectionRange &element)
|
|||
{
|
||||
return reinterpret_cast<const QQmlItemSelectionRangeValueType *>(&element)->toString();
|
||||
}
|
||||
#endif
|
||||
|
||||
static QString convertElementToString(qreal element)
|
||||
{
|
||||
|
@ -192,6 +205,7 @@ template <> QUrl convertValueToElement(const Value &value)
|
|||
return QUrl(value.toQString());
|
||||
}
|
||||
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
template <> QModelIndex convertValueToElement(const Value &value)
|
||||
{
|
||||
const QQmlValueTypeWrapper *v = value.as<QQmlValueTypeWrapper>();
|
||||
|
@ -207,6 +221,7 @@ template <> QItemSelectionRange convertValueToElement(const Value &value)
|
|||
return v->toVariant().value<QItemSelectionRange>();
|
||||
return QItemSelectionRange();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <> qreal convertValueToElement(const Value &value)
|
||||
{
|
||||
|
@ -667,6 +682,7 @@ typedef QQmlSequence<QVector<QUrl> > QQmlUrlVectorList;
|
|||
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlVectorList);
|
||||
typedef QQmlSequence<std::vector<QUrl> > QQmlUrlStdVectorList;
|
||||
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlStdVectorList);
|
||||
#if QT_CONFIG(qml_itemmodel)
|
||||
typedef QQmlSequence<QModelIndexList> QQmlQModelIndexList;
|
||||
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexList);
|
||||
typedef QQmlSequence<QVector<QModelIndex> > QQmlQModelIndexVectorList;
|
||||
|
@ -675,6 +691,7 @@ typedef QQmlSequence<std::vector<QModelIndex> > QQmlQModelIndexStdVectorList;
|
|||
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexStdVectorList);
|
||||
typedef QQmlSequence<QItemSelection> QQmlQItemSelectionRangeList;
|
||||
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQItemSelectionRangeList);
|
||||
#endif
|
||||
typedef QQmlSequence<QList<bool> > QQmlBoolList;
|
||||
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlBoolList);
|
||||
typedef QQmlSequence<QList<qreal> > QQmlRealList;
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include <private/qv4mm_p.h>
|
||||
#include "qv4scopedvalue_p.h"
|
||||
#include "qv4symbol_p.h"
|
||||
#include "qv4alloca_p.h"
|
||||
#include <private/qv4alloca_p.h>
|
||||
#include "qv4jscall_p.h"
|
||||
#include "qv4stringiterator_p.h"
|
||||
#include <QtCore/QDateTime>
|
||||
|
|
|
@ -38,11 +38,11 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "qv4vme_moth_p.h"
|
||||
#include "qv4instr_moth_p.h"
|
||||
|
||||
#include <QtCore/qjsondocument.h>
|
||||
#include <QtCore/qjsonobject.h>
|
||||
|
||||
#include <private/qv4instr_moth_p.h>
|
||||
#include <private/qv4value_p.h>
|
||||
#include <private/qv4debugging_p.h>
|
||||
#include <private/qv4function_p.h>
|
||||
|
@ -56,11 +56,10 @@
|
|||
#include <private/qv4profiling_p.h>
|
||||
#include <private/qv4jscall_p.h>
|
||||
#include <private/qv4generatorobject_p.h>
|
||||
#include <private/qv4alloca_p.h>
|
||||
#include <private/qqmljavascriptexpression_p.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "qv4alloca_p.h"
|
||||
|
||||
#if QT_CONFIG(qml_jit)
|
||||
#include <private/qv4baselinejit_p.h>
|
||||
#endif
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
//
|
||||
|
||||
#include <private/qv4global_p.h>
|
||||
#include <private/qv4staticvalue_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <QtCore/qalgorithms.h>
|
||||
#include <QtCore/private/qnumeric_p.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <private/qv4alloca_p.h>
|
||||
#include <qqmlengine.h>
|
||||
#include "PageReservation.h"
|
||||
#include "PageAllocation.h"
|
||||
|
@ -59,7 +60,6 @@
|
|||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include "qv4alloca_p.h"
|
||||
#include "qv4profiling_p.h"
|
||||
#include "qv4mapobject_p.h"
|
||||
#include "qv4setobject_p.h"
|
||||
|
|
|
@ -4,11 +4,9 @@ HEADERS += \
|
|||
$$PWD/qqmljsastvisitor_p.h \
|
||||
$$PWD/qqmljsengine_p.h \
|
||||
$$PWD/qqmljslexer_p.h \
|
||||
$$PWD/qqmljsmemorypool_p.h \
|
||||
$$PWD/qqmljsglobal_p.h \
|
||||
$$PWD/qqmljskeywords_p.h \
|
||||
$$PWD/qqmljsengine_p.h \
|
||||
$$PWD/qqmljsglobal_p.h \
|
||||
$$PWD/qqmljssourcelocation_p.h
|
||||
|
||||
SOURCES += \
|
||||
|
|
|
@ -299,6 +299,9 @@ public:
|
|||
AST::ExportsList *ExportsList;
|
||||
AST::ExportClause *ExportClause;
|
||||
AST::ExportDeclaration *ExportDeclaration;
|
||||
AST::TypeAnnotation *TypeAnnotation;
|
||||
AST::TypeArgumentList *TypeArgumentList;
|
||||
AST::Type *Type;
|
||||
|
||||
AST::UiProgram *UiProgram;
|
||||
AST::UiHeaderItemList *UiHeaderItemList;
|
||||
|
@ -424,6 +427,8 @@ protected:
|
|||
diagnostic_messages.append(compileError(location, message));
|
||||
}
|
||||
|
||||
bool ensureNoFunctionTypeAnnotations(AST::TypeAnnotation *returnTypeAnnotation, AST::FormalParameterList *formals);
|
||||
|
||||
protected:
|
||||
Engine *driver;
|
||||
MemoryPool *pool;
|
||||
|
@ -594,6 +599,21 @@ int Parser::lookaheadToken(Lexer *lexer)
|
|||
return yytoken;
|
||||
}
|
||||
|
||||
bool Parser::ensureNoFunctionTypeAnnotations(AST::TypeAnnotation *returnValueAnnotation, AST::FormalParameterList *formals)
|
||||
{
|
||||
for (auto formal = formals; formal; formal = formal->next) {
|
||||
if (formal->element && formal->element->typeAnnotation) {
|
||||
syntaxError(formal->element->typeAnnotation->firstSourceLocation(), "Type annotations are not permitted in function parameters in JavaScript functions");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (returnValueAnnotation) {
|
||||
syntaxError(returnValueAnnotation->firstSourceLocation(), "Type annotations are not permitted for the return value of JavaScript functions");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//#define PARSER_DEBUG
|
||||
|
||||
bool Parser::parse(int startToken)
|
||||
|
@ -1086,6 +1106,17 @@ UiParameterListOpt: UiParameterList;
|
|||
} break;
|
||||
./
|
||||
|
||||
UiParameterList: QmlIdentifier T_COLON UiPropertyType;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(3).UiQualifiedId->finish(), stringRef(1));
|
||||
node->identifierToken = loc(1);
|
||||
node->colonToken = loc(2);
|
||||
node->propertyTypeToken = loc(3);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiParameterList: UiPropertyType QmlIdentifier;
|
||||
/.
|
||||
case $rule_number: {
|
||||
|
@ -1096,6 +1127,18 @@ UiParameterList: UiPropertyType QmlIdentifier;
|
|||
} break;
|
||||
./
|
||||
|
||||
UiParameterList: UiParameterList T_COMMA QmlIdentifier T_COLON UiPropertyType;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiParameterList *node = new (pool) AST::UiParameterList(sym(1).UiParameterList, sym(5).UiQualifiedId->finish(), stringRef(3));
|
||||
node->propertyTypeToken = loc(5);
|
||||
node->commaToken = loc(2);
|
||||
node->identifierToken = loc(3);
|
||||
node->colonToken = loc(4);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiParameterList: UiParameterList T_COMMA UiPropertyType QmlIdentifier;
|
||||
/.
|
||||
case $rule_number: {
|
||||
|
@ -1355,7 +1398,7 @@ UiObjectMember: T_READONLY T_PROPERTY UiPropertyType QmlIdentifier T_COLON Expre
|
|||
} break;
|
||||
./
|
||||
|
||||
UiObjectMember: FunctionDeclaration;
|
||||
UiObjectMember: FunctionDeclarationWithTypes;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
|
||||
|
@ -1470,6 +1513,63 @@ JsIdentifier: T_AS;
|
|||
IdentifierReference: JsIdentifier;
|
||||
BindingIdentifier: IdentifierReference;
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
-- Types
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
TypeArguments: Type;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).TypeArgumentList = new (pool) AST::TypeArgumentList(sym(1).Type);
|
||||
} break;
|
||||
./
|
||||
|
||||
TypeArguments: TypeArguments T_COMMA Type;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).TypeArgumentList = new (pool) AST::TypeArgumentList(sym(1).TypeArgumentList, sym(3).Type);
|
||||
} break;
|
||||
./
|
||||
|
||||
Type: UiQualifiedId T_LT TypeArguments T_GT;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).Type = new (pool) AST::Type(sym(1).UiQualifiedId, sym(3).TypeArgumentList->finish());
|
||||
} break;
|
||||
./
|
||||
|
||||
Type: T_RESERVED_WORD;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiQualifiedId *id = new (pool) AST::UiQualifiedId(stringRef(1));
|
||||
id->identifierToken = loc(1);
|
||||
sym(1).Type = new (pool) AST::Type(id->finish());
|
||||
} break;
|
||||
./
|
||||
|
||||
Type: UiQualifiedId;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).Type = new (pool) AST::Type(sym(1).UiQualifiedId);
|
||||
} break;
|
||||
./
|
||||
|
||||
TypeAnnotation: T_COLON Type;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).TypeAnnotation = new (pool) AST::TypeAnnotation(sym(2).Type);
|
||||
sym(1).TypeAnnotation->colonToken = loc(1);
|
||||
} break;
|
||||
./
|
||||
|
||||
TypeAnnotationOpt: TypeAnnotation;
|
||||
TypeAnnotationOpt: ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
sym(1).TypeAnnotation = nullptr;
|
||||
} break;
|
||||
./
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
-- Expressions
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
@ -2851,7 +2951,14 @@ VarDeclaration: Var VariableDeclarationList;
|
|||
VarDeclaration_In: Var VariableDeclarationList_In;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(sym(1).scope));
|
||||
AST::VariableDeclarationList *declarations = sym(2).VariableDeclarationList->finish(sym(1).scope);
|
||||
for (auto it = declarations; it; it = it->next) {
|
||||
if (it->declaration && it->declaration->typeAnnotation) {
|
||||
syntaxError(it->declaration->typeAnnotation->firstSourceLocation(), "Type annotations are not permitted in variable declarations");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
AST::VariableStatement *node = new (pool) AST::VariableStatement(declarations);
|
||||
node->declarationKindToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
|
@ -2888,22 +2995,22 @@ VariableDeclarationList_In: VariableDeclarationList_In T_COMMA VariableDeclarati
|
|||
} break;
|
||||
./
|
||||
|
||||
LexicalBinding: BindingIdentifier InitializerOpt;
|
||||
LexicalBinding: BindingIdentifier TypeAnnotationOpt InitializerOpt;
|
||||
/. case $rule_number: Q_FALLTHROUGH(); ./
|
||||
LexicalBinding_In: BindingIdentifier InitializerOpt_In;
|
||||
LexicalBinding_In: BindingIdentifier TypeAnnotationOpt InitializerOpt_In;
|
||||
/. case $rule_number: Q_FALLTHROUGH(); ./
|
||||
VariableDeclaration: BindingIdentifier InitializerOpt;
|
||||
VariableDeclaration: BindingIdentifier TypeAnnotationOpt InitializerOpt;
|
||||
/. case $rule_number: Q_FALLTHROUGH(); ./
|
||||
VariableDeclaration_In: BindingIdentifier InitializerOpt_In;
|
||||
VariableDeclaration_In: BindingIdentifier TypeAnnotationOpt InitializerOpt_In;
|
||||
/.
|
||||
case $rule_number: {
|
||||
auto *node = new (pool) AST::PatternElement(stringRef(1), sym(2).Expression);
|
||||
auto *node = new (pool) AST::PatternElement(stringRef(1), sym(2).TypeAnnotation, sym(3).Expression);
|
||||
node->identifierToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
// if initializer is an anonymous function expression, we need to assign identifierref as it's name
|
||||
if (auto *f = asAnonymousFunctionDefinition(sym(2).Expression))
|
||||
if (auto *f = asAnonymousFunctionDefinition(sym(3).Expression))
|
||||
f->name = stringRef(1);
|
||||
if (auto *c = asAnonymousClassDefinition(sym(2).Expression))
|
||||
if (auto *c = asAnonymousClassDefinition(sym(3).Expression))
|
||||
c->name = stringRef(1);
|
||||
} break;
|
||||
./
|
||||
|
@ -3053,15 +3160,15 @@ BindingProperty: PropertyName T_COLON BindingPattern InitializerOpt_In;
|
|||
} break;
|
||||
./
|
||||
|
||||
BindingElement: BindingIdentifier InitializerOpt_In;
|
||||
BindingElement: BindingIdentifier TypeAnnotationOpt InitializerOpt_In;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::PatternElement *node = new (pool) AST::PatternElement(stringRef(1), sym(2).Expression);
|
||||
AST::PatternElement *node = new (pool) AST::PatternElement(stringRef(1), sym(2).TypeAnnotation, sym(3).Expression);
|
||||
node->identifierToken = loc(1);
|
||||
// if initializer is an anonymous function expression, we need to assign identifierref as it's name
|
||||
if (auto *f = asAnonymousFunctionDefinition(sym(2).Expression))
|
||||
if (auto *f = asAnonymousFunctionDefinition(sym(3).Expression))
|
||||
f->name = stringRef(1);
|
||||
if (auto *c = asAnonymousClassDefinition(sym(2).Expression))
|
||||
if (auto *c = asAnonymousClassDefinition(sym(3).Expression))
|
||||
c->name = stringRef(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
|
@ -3078,7 +3185,7 @@ BindingElement: BindingPattern InitializerOpt_In;
|
|||
BindingRestElement: T_ELLIPSIS BindingIdentifier;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::PatternElement *node = new (pool) AST::PatternElement(stringRef(2), nullptr, AST::PatternElement::RestElement);
|
||||
AST::PatternElement *node = new (pool) AST::PatternElement(stringRef(2), /*type annotation*/nullptr, nullptr, AST::PatternElement::RestElement);
|
||||
node->identifierToken = loc(2);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
|
@ -3268,12 +3375,16 @@ IterationStatement: T_FOR T_LPAREN ForDeclaration InOrOf Expression_In T_RPAREN
|
|||
} break;
|
||||
./
|
||||
|
||||
ForDeclaration: LetOrConst BindingIdentifier;
|
||||
ForDeclaration: LetOrConst BindingIdentifier TypeAnnotationOpt;
|
||||
/. case $rule_number: Q_FALLTHROUGH(); ./
|
||||
ForDeclaration: Var BindingIdentifier;
|
||||
ForDeclaration: Var BindingIdentifier TypeAnnotationOpt;
|
||||
/.
|
||||
case $rule_number: {
|
||||
auto *node = new (pool) AST::PatternElement(stringRef(2), nullptr);
|
||||
if (auto typeAnnotation = sym(3).TypeAnnotation) {
|
||||
syntaxError(typeAnnotation->firstSourceLocation(), "Type annotations are not permitted in variable declarations");
|
||||
return false;
|
||||
}
|
||||
auto *node = new (pool) AST::PatternElement(stringRef(2), sym(3).TypeAnnotation, nullptr);
|
||||
node->identifierToken = loc(2);
|
||||
node->scope = sym(1).scope;
|
||||
node->isForDeclaration = true;
|
||||
|
@ -3560,59 +3671,85 @@ DebuggerStatement: T_DEBUGGER T_SEMICOLON;
|
|||
-- otherwise conflict.
|
||||
Function: T_FUNCTION %prec REDUCE_HERE;
|
||||
|
||||
FunctionDeclaration: Function BindingIdentifier T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
|
||||
FunctionDeclaration: Function BindingIdentifier T_LPAREN FormalParameters T_RPAREN TypeAnnotationOpt FunctionLBrace FunctionBody FunctionRBrace;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList);
|
||||
if (!ensureNoFunctionTypeAnnotations(sym(6).TypeAnnotation, sym(4).FormalParameterList))
|
||||
return false;
|
||||
AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(8).StatementList,
|
||||
/*type annotation*/nullptr);
|
||||
node->functionToken = loc(1);
|
||||
node->identifierToken = loc(2);
|
||||
node->lparenToken = loc(3);
|
||||
node->rparenToken = loc(5);
|
||||
node->lbraceToken = loc(7);
|
||||
node->rbraceToken = loc(9);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
FunctionDeclarationWithTypes: Function BindingIdentifier T_LPAREN FormalParameters T_RPAREN TypeAnnotationOpt FunctionLBrace FunctionBody FunctionRBrace;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(8).StatementList,
|
||||
sym(6).TypeAnnotation);
|
||||
node->functionToken = loc(1);
|
||||
node->identifierToken = loc(2);
|
||||
node->lparenToken = loc(3);
|
||||
node->rparenToken = loc(5);
|
||||
node->lbraceToken = loc(7);
|
||||
node->rbraceToken = loc(9);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
FunctionDeclaration_Default: FunctionDeclaration;
|
||||
FunctionDeclaration_Default: Function T_LPAREN FormalParameters T_RPAREN TypeAnnotationOpt FunctionLBrace FunctionBody FunctionRBrace;
|
||||
/.
|
||||
case $rule_number: {
|
||||
if (!ensureNoFunctionTypeAnnotations(sym(5).TypeAnnotation, sym(3).FormalParameterList))
|
||||
return false;
|
||||
AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(QStringRef(), sym(3).FormalParameterList, sym(7).StatementList,
|
||||
/*type annotation*/nullptr);
|
||||
node->functionToken = loc(1);
|
||||
node->lparenToken = loc(2);
|
||||
node->rparenToken = loc(4);
|
||||
node->lbraceToken = loc(6);
|
||||
node->rbraceToken = loc(8);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
|
||||
FunctionDeclaration_Default: FunctionDeclaration;
|
||||
FunctionDeclaration_Default: Function T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
|
||||
FunctionExpression: T_FUNCTION BindingIdentifier T_LPAREN FormalParameters T_RPAREN TypeAnnotationOpt FunctionLBrace FunctionBody FunctionRBrace;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(QStringRef(), 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;
|
||||
./
|
||||
|
||||
FunctionExpression: T_FUNCTION BindingIdentifier T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList);
|
||||
if (!ensureNoFunctionTypeAnnotations(sym(6).TypeAnnotation, sym(4).FormalParameterList))
|
||||
return false;
|
||||
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(8).StatementList,
|
||||
/*type annotation*/nullptr);
|
||||
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);
|
||||
node->lbraceToken = loc(7);
|
||||
node->rbraceToken = loc(9);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
FunctionExpression: T_FUNCTION T_LPAREN FormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
|
||||
FunctionExpression: T_FUNCTION T_LPAREN FormalParameters T_RPAREN TypeAnnotationOpt FunctionLBrace FunctionBody FunctionRBrace;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).StatementList);
|
||||
if (!ensureNoFunctionTypeAnnotations(sym(5).TypeAnnotation, sym(3).FormalParameterList))
|
||||
return false;
|
||||
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(7).StatementList,
|
||||
/*type annotation*/nullptr);
|
||||
node->functionToken = loc(1);
|
||||
node->lparenToken = loc(2);
|
||||
node->rparenToken = loc(4);
|
||||
node->lbraceToken = loc(5);
|
||||
node->rbraceToken = loc(7);
|
||||
node->lbraceToken = loc(6);
|
||||
node->rbraceToken = loc(8);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
@ -3722,7 +3859,7 @@ ArrowFunction_In: ArrowParameters T_ARROW ConciseBodyLookahead T_FORCE_BLOCK Fun
|
|||
ArrowParameters: BindingIdentifier;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::PatternElement *e = new (pool) AST::PatternElement(stringRef(1), nullptr, AST::PatternElement::Binding);
|
||||
AST::PatternElement *e = new (pool) AST::PatternElement(stringRef(1), /*type annotation*/nullptr, nullptr, AST::PatternElement::Binding);
|
||||
e->identifierToken = loc(1);
|
||||
sym(1).FormalParameterList = (new (pool) AST::FormalParameterList(nullptr, e))->finish(pool);
|
||||
} break;
|
||||
|
@ -3756,30 +3893,34 @@ ConciseBodyLookahead: ;
|
|||
} break;
|
||||
./
|
||||
|
||||
MethodDefinition: PropertyName T_LPAREN StrictFormalParameters T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
|
||||
MethodDefinition: PropertyName T_LPAREN StrictFormalParameters T_RPAREN TypeAnnotationOpt FunctionLBrace FunctionBody FunctionRBrace;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(1), sym(3).FormalParameterList, sym(6).StatementList);
|
||||
if (!ensureNoFunctionTypeAnnotations(sym(5).TypeAnnotation, sym(3).FormalParameterList))
|
||||
return false;
|
||||
AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(1), sym(3).FormalParameterList, sym(7).StatementList);
|
||||
f->functionToken = sym(1).PropertyName->firstSourceLocation();
|
||||
f->lparenToken = loc(2);
|
||||
f->rparenToken = loc(4);
|
||||
f->lbraceToken = loc(5);
|
||||
f->rbraceToken = loc(7);
|
||||
f->lbraceToken = loc(6);
|
||||
f->rbraceToken = loc(8);
|
||||
AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(1).PropertyName, f, AST::PatternProperty::Method);
|
||||
node->colonToken = loc(2);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
MethodDefinition: T_STAR PropertyName GeneratorLParen StrictFormalParameters T_RPAREN FunctionLBrace GeneratorBody GeneratorRBrace;
|
||||
MethodDefinition: T_STAR PropertyName GeneratorLParen StrictFormalParameters T_RPAREN TypeAnnotationOpt FunctionLBrace GeneratorBody GeneratorRBrace;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList);
|
||||
if (!ensureNoFunctionTypeAnnotations(sym(6).TypeAnnotation, sym(4).FormalParameterList))
|
||||
return false;
|
||||
AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(8).StatementList);
|
||||
f->functionToken = sym(2).PropertyName->firstSourceLocation();
|
||||
f->lparenToken = loc(3);
|
||||
f->rparenToken = loc(5);
|
||||
f->lbraceToken = loc(6);
|
||||
f->rbraceToken = loc(8);
|
||||
f->lbraceToken = loc(7);
|
||||
f->rbraceToken = loc(9);
|
||||
f->isGenerator = true;
|
||||
AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(2).PropertyName, f, AST::PatternProperty::Method);
|
||||
node->colonToken = loc(2);
|
||||
|
@ -3788,30 +3929,34 @@ MethodDefinition: T_STAR PropertyName GeneratorLParen StrictFormalParameters T_R
|
|||
./
|
||||
|
||||
|
||||
MethodDefinition: T_GET PropertyName T_LPAREN T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
|
||||
MethodDefinition: T_GET PropertyName T_LPAREN T_RPAREN TypeAnnotationOpt FunctionLBrace FunctionBody FunctionRBrace;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(2), nullptr, sym(6).StatementList);
|
||||
if (!ensureNoFunctionTypeAnnotations(sym(5).TypeAnnotation, /*formals*/nullptr))
|
||||
return false;
|
||||
AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(2), nullptr, sym(7).StatementList);
|
||||
f->functionToken = sym(2).PropertyName->firstSourceLocation();
|
||||
f->lparenToken = loc(3);
|
||||
f->rparenToken = loc(4);
|
||||
f->lbraceToken = loc(5);
|
||||
f->rbraceToken = loc(7);
|
||||
f->lbraceToken = loc(6);
|
||||
f->rbraceToken = loc(8);
|
||||
AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(2).PropertyName, f, AST::PatternProperty::Getter);
|
||||
node->colonToken = loc(2);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
MethodDefinition: T_SET PropertyName T_LPAREN PropertySetParameterList T_RPAREN FunctionLBrace FunctionBody FunctionRBrace;
|
||||
MethodDefinition: T_SET PropertyName T_LPAREN PropertySetParameterList T_RPAREN TypeAnnotationOpt FunctionLBrace FunctionBody FunctionRBrace;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).StatementList);
|
||||
if (!ensureNoFunctionTypeAnnotations(sym(6).TypeAnnotation, sym(4).FormalParameterList))
|
||||
return false;
|
||||
AST::FunctionExpression *f = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(8).StatementList);
|
||||
f->functionToken = sym(2).PropertyName->firstSourceLocation();
|
||||
f->lparenToken = loc(3);
|
||||
f->rparenToken = loc(5);
|
||||
f->lbraceToken = loc(6);
|
||||
f->rbraceToken = loc(8);
|
||||
f->lbraceToken = loc(7);
|
||||
f->rbraceToken = loc(9);
|
||||
AST::PatternProperty *node = new (pool) AST::PatternProperty(sym(2).PropertyName, f, AST::PatternProperty::Setter);
|
||||
node->colonToken = loc(2);
|
||||
sym(1).Node = node;
|
||||
|
|
|
@ -131,7 +131,7 @@ FormalParameterList *ExpressionNode::reparseAsFormalParameterList(MemoryPool *po
|
|||
}
|
||||
AST::PatternElement *binding = nullptr;
|
||||
if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(expr)) {
|
||||
binding = new (pool) AST::PatternElement(idExpr->name, rhs);
|
||||
binding = new (pool) AST::PatternElement(idExpr->name, /*type annotation*/nullptr, rhs);
|
||||
binding->identifierToken = idExpr->identifierToken;
|
||||
} else if (AST::Pattern *p = expr->patternCast()) {
|
||||
SourceLocation loc;
|
||||
|
@ -961,6 +961,7 @@ void FunctionDeclaration::accept0(Visitor *visitor)
|
|||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(formals, visitor);
|
||||
accept(typeAnnotation, visitor);
|
||||
accept(body, visitor);
|
||||
}
|
||||
|
||||
|
@ -971,6 +972,7 @@ void FunctionExpression::accept0(Visitor *visitor)
|
|||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(formals, visitor);
|
||||
accept(typeAnnotation, visitor);
|
||||
accept(body, visitor);
|
||||
}
|
||||
|
||||
|
@ -982,9 +984,9 @@ FunctionExpression *FunctionExpression::asFunctionDefinition()
|
|||
return this;
|
||||
}
|
||||
|
||||
QStringList FormalParameterList::formals() const
|
||||
BoundNames FormalParameterList::formals() const
|
||||
{
|
||||
QStringList formals;
|
||||
BoundNames formals;
|
||||
int i = 0;
|
||||
for (const FormalParameterList *it = this; it; it = it->next) {
|
||||
if (it->element) {
|
||||
|
@ -992,18 +994,18 @@ QStringList FormalParameterList::formals() const
|
|||
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[duplicateIndex].id += QLatin1String("#") + QString::number(i);
|
||||
}
|
||||
formals += name;
|
||||
formals += {name, it->element->typeAnnotation};
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return formals;
|
||||
}
|
||||
|
||||
QStringList FormalParameterList::boundNames() const
|
||||
BoundNames FormalParameterList::boundNames() const
|
||||
{
|
||||
QStringList names;
|
||||
BoundNames names;
|
||||
for (const FormalParameterList *it = this; it; it = it->next) {
|
||||
if (it->element)
|
||||
it->element->boundNames(&names);
|
||||
|
@ -1271,6 +1273,35 @@ void UiQualifiedId::accept0(Visitor *visitor)
|
|||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void Type::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(typeId, visitor);
|
||||
accept(typeArguments, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void TypeArgumentList::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
for (TypeArgumentList *it = this; it; it = it->next)
|
||||
accept(it->typeId, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void TypeAnnotation::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(type, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void UiImport::accept0(Visitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
|
@ -1339,13 +1370,14 @@ void PatternElement::accept0(Visitor *visitor)
|
|||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(bindingTarget, visitor);
|
||||
accept(typeAnnotation, visitor);
|
||||
accept(initializer, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PatternElement::boundNames(QStringList *names)
|
||||
void PatternElement::boundNames(BoundNames *names)
|
||||
{
|
||||
if (bindingTarget) {
|
||||
if (PatternElementList *e = elementList())
|
||||
|
@ -1353,7 +1385,7 @@ void PatternElement::boundNames(QStringList *names)
|
|||
else if (PatternPropertyList *p = propertyList())
|
||||
p->boundNames(names);
|
||||
} else {
|
||||
names->append(bindingIdentifier.toString());
|
||||
names->append({bindingIdentifier.toString(), typeAnnotation});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1369,7 +1401,7 @@ void PatternElementList::accept0(Visitor *visitor)
|
|||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PatternElementList::boundNames(QStringList *names)
|
||||
void PatternElementList::boundNames(BoundNames *names)
|
||||
{
|
||||
for (PatternElementList *it = this; it; it = it->next) {
|
||||
if (it->element)
|
||||
|
@ -1382,13 +1414,14 @@ void PatternProperty::accept0(Visitor *visitor)
|
|||
if (visitor->visit(this)) {
|
||||
accept(name, visitor);
|
||||
accept(bindingTarget, visitor);
|
||||
accept(typeAnnotation, visitor);
|
||||
accept(initializer, visitor);
|
||||
}
|
||||
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PatternProperty::boundNames(QStringList *names)
|
||||
void PatternProperty::boundNames(BoundNames *names)
|
||||
{
|
||||
PatternElement::boundNames(names);
|
||||
}
|
||||
|
@ -1404,7 +1437,7 @@ void PatternPropertyList::accept0(Visitor *visitor)
|
|||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void PatternPropertyList::boundNames(QStringList *names)
|
||||
void PatternPropertyList::boundNames(BoundNames *names)
|
||||
{
|
||||
for (PatternPropertyList *it = this; it; it = it->next)
|
||||
it->property->boundNames(names);
|
||||
|
@ -1478,6 +1511,31 @@ void UiVersionSpecifier::accept0(Visitor *visitor)
|
|||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
QString Type::toString() const
|
||||
{
|
||||
QString result;
|
||||
toString(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Type::toString(QString *out) const
|
||||
{
|
||||
for (QQmlJS::AST::UiQualifiedId *it = typeId; it; it = it->next) {
|
||||
out->append(it->name);
|
||||
|
||||
if (it->next)
|
||||
out->append(QLatin1Char('.'));
|
||||
}
|
||||
|
||||
if (typeArguments) {
|
||||
out->append(QLatin1Char('<'));
|
||||
if (auto subType = static_cast<TypeArgumentList*>(typeArguments)->typeId)
|
||||
subType->toString(out);
|
||||
out->append(QLatin1Char('>'));
|
||||
};
|
||||
}
|
||||
|
||||
} } // namespace QQmlJS::AST
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -53,7 +53,8 @@
|
|||
|
||||
#include "qqmljsastvisitor_p.h"
|
||||
#include "qqmljsglobal_p.h"
|
||||
#include "qqmljsmemorypool_p.h"
|
||||
|
||||
#include <private/qqmljsmemorypool_p.h>
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
|
@ -233,6 +234,9 @@ public:
|
|||
Kind_PatternElementList,
|
||||
Kind_PatternProperty,
|
||||
Kind_PatternPropertyList,
|
||||
Kind_Type,
|
||||
Kind_TypeArgumentList,
|
||||
Kind_TypeAnnotation,
|
||||
|
||||
Kind_UiArrayBinding,
|
||||
Kind_UiImport,
|
||||
|
@ -303,6 +307,131 @@ public:
|
|||
int kind = Kind_Undefined;
|
||||
};
|
||||
|
||||
|
||||
class QML_PARSER_EXPORT UiQualifiedId: public Node
|
||||
{
|
||||
public:
|
||||
QQMLJS_DECLARE_AST_NODE(UiQualifiedId)
|
||||
|
||||
UiQualifiedId(const QStringRef &name)
|
||||
: next(this), name(name)
|
||||
{ kind = K; }
|
||||
|
||||
UiQualifiedId(UiQualifiedId *previous, const QStringRef &name)
|
||||
: name(name)
|
||||
{
|
||||
kind = K;
|
||||
next = previous->next;
|
||||
previous->next = this;
|
||||
}
|
||||
|
||||
UiQualifiedId *finish()
|
||||
{
|
||||
UiQualifiedId *head = next;
|
||||
next = nullptr;
|
||||
return head;
|
||||
}
|
||||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
||||
SourceLocation firstSourceLocation() const override
|
||||
{ return identifierToken; }
|
||||
|
||||
SourceLocation lastSourceLocation() const override
|
||||
{ return next ? next->lastSourceLocation() : identifierToken; }
|
||||
|
||||
// attributes
|
||||
UiQualifiedId *next;
|
||||
QStringRef name;
|
||||
SourceLocation identifierToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT Type: public Node
|
||||
{
|
||||
public:
|
||||
QQMLJS_DECLARE_AST_NODE(Type)
|
||||
|
||||
Type(UiQualifiedId *typeId, Node *typeArguments = nullptr)
|
||||
: typeId(typeId)
|
||||
, typeArguments(typeArguments)
|
||||
{ kind = K; }
|
||||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
||||
SourceLocation firstSourceLocation() const override
|
||||
{ return typeId->firstSourceLocation(); }
|
||||
|
||||
SourceLocation lastSourceLocation() const override
|
||||
{ return typeArguments ? typeArguments->lastSourceLocation() : typeId->lastSourceLocation(); }
|
||||
|
||||
QString toString() const;
|
||||
void toString(QString *out) const;
|
||||
|
||||
// attributes
|
||||
UiQualifiedId *typeId;
|
||||
Node *typeArguments; // TypeArgumentList
|
||||
};
|
||||
|
||||
|
||||
class QML_PARSER_EXPORT TypeArgumentList: public Node
|
||||
{
|
||||
public:
|
||||
QQMLJS_DECLARE_AST_NODE(TypeArgumentList)
|
||||
|
||||
TypeArgumentList(Type *typeId)
|
||||
: typeId(typeId)
|
||||
, next(nullptr)
|
||||
{ kind = K; }
|
||||
|
||||
TypeArgumentList(TypeArgumentList *previous, Type *typeId)
|
||||
: typeId(typeId)
|
||||
{
|
||||
kind = K;
|
||||
next = previous->next;
|
||||
previous->next = this;
|
||||
}
|
||||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
||||
SourceLocation firstSourceLocation() const override
|
||||
{ return typeId->firstSourceLocation(); }
|
||||
|
||||
SourceLocation lastSourceLocation() const override
|
||||
{ return next ? next->lastSourceLocation() : typeId->lastSourceLocation(); }
|
||||
|
||||
inline TypeArgumentList *finish()
|
||||
{
|
||||
TypeArgumentList *front = next;
|
||||
next = nullptr;
|
||||
return front;
|
||||
}
|
||||
|
||||
// attributes
|
||||
Type *typeId;
|
||||
TypeArgumentList *next;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT TypeAnnotation: public Node
|
||||
{
|
||||
public:
|
||||
QQMLJS_DECLARE_AST_NODE(TypeAnnotation)
|
||||
|
||||
TypeAnnotation(Type *type)
|
||||
: type(type)
|
||||
{ kind = K; }
|
||||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
||||
SourceLocation firstSourceLocation() const override
|
||||
{ return colonToken; }
|
||||
|
||||
SourceLocation lastSourceLocation() const override
|
||||
{ return type->lastSourceLocation(); }
|
||||
|
||||
// attributes
|
||||
Type *type;
|
||||
SourceLocation colonToken;
|
||||
};
|
||||
class QML_PARSER_EXPORT ExpressionNode: public Node
|
||||
{
|
||||
public:
|
||||
|
@ -704,6 +833,34 @@ public:
|
|||
SourceLocation propertyNameToken;
|
||||
};
|
||||
|
||||
struct QML_PARSER_EXPORT BoundName
|
||||
{
|
||||
QString id;
|
||||
TypeAnnotation *typeAnnotation = nullptr;
|
||||
BoundName(const QString &id, TypeAnnotation *typeAnnotation)
|
||||
: id(id), typeAnnotation(typeAnnotation)
|
||||
{}
|
||||
BoundName() = default;
|
||||
QString typeName() const { return typeAnnotation ? typeAnnotation->type->toString() : QString(); }
|
||||
};
|
||||
|
||||
struct BoundNames : public QVector<BoundName>
|
||||
{
|
||||
int indexOf(const QString &name, int from = 0) const
|
||||
{
|
||||
auto found = std::find_if(constBegin() + from, constEnd(),
|
||||
[name](const BoundName &it) { return it.id == name; });
|
||||
if (found == constEnd())
|
||||
return -1;
|
||||
return found - constBegin();
|
||||
}
|
||||
|
||||
bool contains(const QString &name) const
|
||||
{
|
||||
return indexOf(name) != -1;
|
||||
}
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT PatternElement : public Node
|
||||
{
|
||||
public:
|
||||
|
@ -728,8 +885,9 @@ public:
|
|||
: initializer(i), type(t)
|
||||
{ kind = K; }
|
||||
|
||||
PatternElement(const QStringRef &n, ExpressionNode *i = nullptr, Type t = Binding)
|
||||
PatternElement(const QStringRef &n, TypeAnnotation *typeAnnotation = nullptr, ExpressionNode *i = nullptr, Type t = Binding)
|
||||
: bindingIdentifier(n), initializer(i), type(t)
|
||||
, typeAnnotation(typeAnnotation)
|
||||
{
|
||||
Q_ASSERT(t >= RestElement);
|
||||
kind = K;
|
||||
|
@ -749,7 +907,7 @@ public:
|
|||
{ return identifierToken.isValid() ? identifierToken : (bindingTarget ? bindingTarget->firstSourceLocation() : initializer->firstSourceLocation()); }
|
||||
|
||||
SourceLocation lastSourceLocation() const override
|
||||
{ return initializer ? initializer->lastSourceLocation() : (bindingTarget ? bindingTarget->lastSourceLocation() : identifierToken); }
|
||||
{ return initializer ? initializer->lastSourceLocation() : (bindingTarget ? bindingTarget->lastSourceLocation() : (typeAnnotation ? typeAnnotation->lastSourceLocation() : identifierToken)); }
|
||||
|
||||
ExpressionNode *destructuringTarget() const { return bindingTarget; }
|
||||
Pattern *destructuringPattern() const { return bindingTarget ? bindingTarget->patternCast() : nullptr; }
|
||||
|
@ -759,7 +917,7 @@ public:
|
|||
bool isVariableDeclaration() const { return scope != VariableScope::NoScope; }
|
||||
bool isLexicallyScoped() const { return scope == VariableScope::Let || scope == VariableScope::Const; }
|
||||
|
||||
virtual void boundNames(QStringList *names);
|
||||
virtual void boundNames(BoundNames *names);
|
||||
|
||||
// attributes
|
||||
SourceLocation identifierToken;
|
||||
|
@ -767,6 +925,7 @@ public:
|
|||
ExpressionNode *bindingTarget = nullptr;
|
||||
ExpressionNode *initializer = nullptr;
|
||||
Type type = Literal;
|
||||
TypeAnnotation *typeAnnotation = nullptr;
|
||||
// when used in a VariableDeclarationList
|
||||
VariableScope scope = VariableScope::NoScope;
|
||||
bool isForDeclaration = false;
|
||||
|
@ -796,7 +955,7 @@ public:
|
|||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
||||
void boundNames(QStringList *names);
|
||||
void boundNames(BoundNames *names);
|
||||
|
||||
SourceLocation firstSourceLocation() const override
|
||||
{ return elision ? elision->firstSourceLocation() : element->firstSourceLocation(); }
|
||||
|
@ -819,7 +978,7 @@ public:
|
|||
{ kind = K; }
|
||||
|
||||
PatternProperty(PropertyName *name, const QStringRef &n, ExpressionNode *i = nullptr)
|
||||
: PatternElement(n, i), name(name)
|
||||
: PatternElement(n, /*type annotation*/nullptr, i), name(name)
|
||||
{ kind = K; }
|
||||
|
||||
PatternProperty(PropertyName *name, Pattern *pattern, ExpressionNode *i = nullptr)
|
||||
|
@ -836,7 +995,7 @@ public:
|
|||
return loc.isValid() ? loc : name->lastSourceLocation();
|
||||
}
|
||||
|
||||
void boundNames(QStringList *names) override;
|
||||
void boundNames(BoundNames *names) override;
|
||||
bool convertLiteralToAssignmentPattern(MemoryPool *pool, SourceLocation *errorLocation, QString *errorMessage) override;
|
||||
|
||||
// attributes
|
||||
|
@ -864,7 +1023,7 @@ public:
|
|||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
||||
void boundNames(QStringList *names);
|
||||
void boundNames(BoundNames *names);
|
||||
|
||||
inline PatternPropertyList *finish ()
|
||||
{
|
||||
|
@ -2154,8 +2313,9 @@ class QML_PARSER_EXPORT FunctionExpression: public ExpressionNode
|
|||
public:
|
||||
QQMLJS_DECLARE_AST_NODE(FunctionExpression)
|
||||
|
||||
FunctionExpression(const QStringRef &n, FormalParameterList *f, StatementList *b):
|
||||
name (n), formals (f), body (b)
|
||||
FunctionExpression(const QStringRef &n, FormalParameterList *f, StatementList *b, TypeAnnotation *typeAnnotation = nullptr):
|
||||
name (n), formals (f), body (b),
|
||||
typeAnnotation(typeAnnotation)
|
||||
{ kind = K; }
|
||||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
@ -2174,6 +2334,7 @@ public:
|
|||
bool isGenerator = false;
|
||||
FormalParameterList *formals;
|
||||
StatementList *body;
|
||||
TypeAnnotation *typeAnnotation;
|
||||
SourceLocation functionToken;
|
||||
SourceLocation identifierToken;
|
||||
SourceLocation lparenToken;
|
||||
|
@ -2187,8 +2348,8 @@ class QML_PARSER_EXPORT FunctionDeclaration: public FunctionExpression
|
|||
public:
|
||||
QQMLJS_DECLARE_AST_NODE(FunctionDeclaration)
|
||||
|
||||
FunctionDeclaration(const QStringRef &n, FormalParameterList *f, StatementList *b):
|
||||
FunctionExpression(n, f, b)
|
||||
FunctionDeclaration(const QStringRef &n, FormalParameterList *f, StatementList *b, TypeAnnotation *typeAnnotation = nullptr):
|
||||
FunctionExpression(n, f, b, typeAnnotation)
|
||||
{ kind = K; }
|
||||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
@ -2258,9 +2419,9 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
QStringList formals() const;
|
||||
BoundNames formals() const;
|
||||
|
||||
QStringList boundNames() const;
|
||||
BoundNames boundNames() const;
|
||||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
||||
|
@ -2809,44 +2970,6 @@ public:
|
|||
SourceLocation semicolonToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiQualifiedId: public Node
|
||||
{
|
||||
public:
|
||||
QQMLJS_DECLARE_AST_NODE(UiQualifiedId)
|
||||
|
||||
UiQualifiedId(const QStringRef &name)
|
||||
: next(this), name(name)
|
||||
{ kind = K; }
|
||||
|
||||
UiQualifiedId(UiQualifiedId *previous, const QStringRef &name)
|
||||
: name(name)
|
||||
{
|
||||
kind = K;
|
||||
next = previous->next;
|
||||
previous->next = this;
|
||||
}
|
||||
|
||||
UiQualifiedId *finish()
|
||||
{
|
||||
UiQualifiedId *head = next;
|
||||
next = nullptr;
|
||||
return head;
|
||||
}
|
||||
|
||||
void accept0(Visitor *visitor) override;
|
||||
|
||||
SourceLocation firstSourceLocation() const override
|
||||
{ return identifierToken; }
|
||||
|
||||
SourceLocation lastSourceLocation() const override
|
||||
{ return next ? next->lastSourceLocation() : identifierToken; }
|
||||
|
||||
// attributes
|
||||
UiQualifiedId *next;
|
||||
QStringRef name;
|
||||
SourceLocation identifierToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiImport: public Node
|
||||
{
|
||||
public:
|
||||
|
@ -3114,10 +3237,10 @@ public:
|
|||
void accept0(Visitor *) override;
|
||||
|
||||
SourceLocation firstSourceLocation() const override
|
||||
{ return propertyTypeToken; }
|
||||
{ return colonToken.isValid() ? identifierToken : propertyTypeToken; }
|
||||
|
||||
SourceLocation lastSourceLocation() const override
|
||||
{ return next ? next->lastSourceLocation() : identifierToken; }
|
||||
{ return next ? next->lastSourceLocation() : (colonToken.isValid() ? propertyTypeToken : identifierToken); }
|
||||
|
||||
inline UiParameterList *finish ()
|
||||
{
|
||||
|
@ -3133,6 +3256,7 @@ public:
|
|||
SourceLocation commaToken;
|
||||
SourceLocation propertyTypeToken;
|
||||
SourceLocation identifierToken;
|
||||
SourceLocation colonToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiPublicMember: public UiObjectMember
|
||||
|
|
|
@ -158,6 +158,9 @@ class NestedExpression;
|
|||
class ClassExpression;
|
||||
class ClassDeclaration;
|
||||
class ClassElementList;
|
||||
class TypeArgumentList;
|
||||
class Type;
|
||||
class TypeAnnotation;
|
||||
|
||||
// ui elements
|
||||
class UiProgram;
|
||||
|
|
|
@ -403,6 +403,15 @@ public:
|
|||
virtual bool visit(DebuggerStatement *) { return true; }
|
||||
virtual void endVisit(DebuggerStatement *) {}
|
||||
|
||||
virtual bool visit(Type *) { return true; }
|
||||
virtual void endVisit(Type *) {}
|
||||
|
||||
virtual bool visit(TypeArgumentList *) { return true; }
|
||||
virtual void endVisit(TypeArgumentList *) {}
|
||||
|
||||
virtual bool visit(TypeAnnotation *) { return true; }
|
||||
virtual void endVisit(TypeAnnotation *) {}
|
||||
|
||||
virtual void throwRecursionDepthError() = 0;
|
||||
|
||||
quint16 recursionDepth() const { return m_recursionDepth; }
|
||||
|
|
|
@ -52,9 +52,10 @@
|
|||
//
|
||||
|
||||
#include "qqmljsglobal_p.h"
|
||||
#include "qqmljsmemorypool_p.h"
|
||||
#include "qqmljssourcelocation_p.h"
|
||||
|
||||
#include <private/qqmljsmemorypool_p.h>
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qset.h>
|
||||
|
||||
|
|
|
@ -39,10 +39,10 @@
|
|||
|
||||
#include "qqmljslexer_p.h"
|
||||
#include "qqmljsengine_p.h"
|
||||
#include "qqmljsmemorypool_p.h"
|
||||
#include "qqmljskeywords_p.h"
|
||||
|
||||
#include <private/qqmljsdiagnosticmessage_p.h>
|
||||
#include <private/qqmljsmemorypool_p.h>
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
|
|
|
@ -19,31 +19,6 @@ gcc:isEqual(QT_ARCH, "mips"): QMAKE_CXXFLAGS += -fno-reorder-blocks
|
|||
|
||||
DEFINES += QT_NO_FOREACH
|
||||
|
||||
!build_pass {
|
||||
# Create a header containing a hash that describes this library. For a
|
||||
# released version of Qt, we'll use the .tag file that is updated by git
|
||||
# archive with the commit hash. For unreleased versions, we'll ask git
|
||||
# describe. Note that it won't update unless qmake is run again, even if
|
||||
# the commit change also changed something in this library.
|
||||
tagFile = $$PWD/../../.tag
|
||||
tag =
|
||||
exists($$tagFile) {
|
||||
tag = $$cat($$tagFile, singleline)
|
||||
QMAKE_INTERNAL_INCLUDED_FILES += $$tagFile
|
||||
}
|
||||
!equals(tag, "$${LITERAL_DOLLAR}Format:%H$${LITERAL_DOLLAR}") {
|
||||
QML_COMPILE_HASH = $$tag
|
||||
} else:exists($$PWD/../../.git) {
|
||||
commit = $$system(git rev-parse HEAD)
|
||||
QML_COMPILE_HASH = $$commit
|
||||
}
|
||||
compile_hash_contents = \
|
||||
"// Generated file, DO NOT EDIT" \
|
||||
"$${LITERAL_HASH}define QML_COMPILE_HASH \"$$QML_COMPILE_HASH\"" \
|
||||
"$${LITERAL_HASH}define QML_COMPILE_HASH_LENGTH $$str_size($$QML_COMPILE_HASH)"
|
||||
write_file("$$OUT_PWD/qml_compile_hash_p.h", compile_hash_contents)|error()
|
||||
}
|
||||
|
||||
exists("qqml_enable_gcov") {
|
||||
QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage -fno-elide-constructors
|
||||
LIBS_PRIVATE += -lgcov
|
||||
|
@ -64,7 +39,9 @@ greaterThan(QT_CLANG_MAJOR_VERSION, 3)|greaterThan(QT_CLANG_MINOR_VERSION, 3)| \
|
|||
WERROR += -Wno-error=unused-const-variable
|
||||
|
||||
HEADERS += qtqmlglobal.h \
|
||||
qtqmlglobal_p.h
|
||||
qtqmlglobal_p.h \
|
||||
qtqmlcompilerglobal.h \
|
||||
qtqmlcompilerglobal_p.h
|
||||
|
||||
#modules
|
||||
include(common/common.pri)
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
SOURCES += \
|
||||
$$PWD/qqml.cpp \
|
||||
$$PWD/qqmldatablob.cpp \
|
||||
$$PWD/qqmldirdata.cpp \
|
||||
$$PWD/qqmlerror.cpp \
|
||||
$$PWD/qqmlopenmetaobject.cpp \
|
||||
$$PWD/qqmlscriptblob.cpp \
|
||||
$$PWD/qqmlscriptdata.cpp \
|
||||
$$PWD/qqmltypedata.cpp \
|
||||
$$PWD/qqmltypeloaderqmldircontent.cpp \
|
||||
$$PWD/qqmltypeloaderthread.cpp \
|
||||
$$PWD/qqmlvmemetaobject.cpp \
|
||||
$$PWD/qqmlengine.cpp \
|
||||
$$PWD/qqmlexpression.cpp \
|
||||
|
@ -61,10 +68,18 @@ SOURCES += \
|
|||
$$PWD/qqmlpropertyvalidator.cpp
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/qqmldatablob_p.h \
|
||||
$$PWD/qqmldirdata_p.h \
|
||||
$$PWD/qqmlglobal_p.h \
|
||||
$$PWD/qqmlopenmetaobject_p.h \
|
||||
$$PWD/qqmlscriptblob_p.h \
|
||||
$$PWD/qqmlscriptdata_p.h \
|
||||
$$PWD/qqmltypedata_p.h \
|
||||
$$PWD/qqmltypeloaderqmldircontent_p.h \
|
||||
$$PWD/qqmltypeloaderthread_p.h \
|
||||
$$PWD/qqmlvmemetaobject_p.h \
|
||||
$$PWD/qqml.h \
|
||||
$$PWD/qqmlerror.h \
|
||||
$$PWD/qqmlproperty.h \
|
||||
$$PWD/qqmlcomponent.h \
|
||||
$$PWD/qqmlcomponent_p.h \
|
||||
|
@ -163,5 +178,13 @@ qtConfig(qml-locale) {
|
|||
$$PWD/qqmllocale.cpp
|
||||
}
|
||||
|
||||
qtConfig(qml-network) {
|
||||
HEADERS += \
|
||||
$$PWD/qqmltypeloadernetworkreplyproxy_p.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qqmltypeloadernetworkreplyproxy.cpp
|
||||
}
|
||||
|
||||
include(ftw/ftw.pri)
|
||||
include(v8/v8.pri)
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtQml/qqmlfile.h>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QTranslator>
|
||||
#include <QQmlComponent>
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <private/qqmlbuiltinfunctions_p.h>
|
||||
#include <private/qqmlvmemetaobject_p.h>
|
||||
#include <private/qqmlvaluetypewrapper_p.h>
|
||||
#include <private/qv4qmlcontext_p.h>
|
||||
#include <private/qv4qobjectwrapper_p.h>
|
||||
#include <private/qv4variantobject_p.h>
|
||||
#include <private/qv4jscall_p.h>
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
|
||||
#include <private/qqmlabstractbinding_p.h>
|
||||
#include <private/qqmljavascriptexpression_p.h>
|
||||
#include <private/qv4functionobject_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include <private/qv4value_p.h>
|
||||
#include <private/qv4jscall_p.h>
|
||||
#include <private/qv4qobjectwrapper_p.h>
|
||||
#include <private/qv4qmlcontext_p.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
|
|
|
@ -569,6 +569,12 @@ void QQmlComponent::setData(const QByteArray &data, const QUrl &url)
|
|||
{
|
||||
Q_D(QQmlComponent);
|
||||
|
||||
if (!d->engine) {
|
||||
// ###Qt6: In Qt 6, it should be impossible for users to create a QQmlComponent without an engine, and we can remove this check
|
||||
qWarning("QQmlComponent: Must provide an engine before calling setData");
|
||||
return;
|
||||
}
|
||||
|
||||
d->clear();
|
||||
|
||||
d->url = url;
|
||||
|
@ -774,6 +780,12 @@ QObject *QQmlComponent::create(QQmlContext *context)
|
|||
{
|
||||
Q_D(QQmlComponent);
|
||||
|
||||
if (!d->engine) {
|
||||
// ###Qt6: In Qt 6, it should be impossible for users to create a QQmlComponent without an engine, and we can remove this check
|
||||
qWarning("QQmlComponent: Must provide an engine before calling create");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!context)
|
||||
context = d->engine->rootContext();
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "qqmlerror.h"
|
||||
#include "qqml.h"
|
||||
#include <private/qqmlobjectcreator_p.h>
|
||||
#include <private/qqmltypedata_p.h>
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#include "qqmlcustomparser_p.h"
|
||||
|
||||
#include <private/qqmltypecompiler_p.h>
|
||||
#include <private/qv4compileddata_p.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
|
||||
#include "qqmlerror.h"
|
||||
#include "qqmlbinding_p.h"
|
||||
#include <private/qqmltypecompiler_p.h>
|
||||
#include <private/qv4compileddata_p.h>
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qxmlstream.h>
|
||||
|
|
|
@ -0,0 +1,639 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 <private/qqmldatablob_p.h>
|
||||
#include <private/qqmlglobal_p.h>
|
||||
#include <private/qqmlprofiler_p.h>
|
||||
#include <private/qqmltypeloader_p.h>
|
||||
#include <private/qqmltypeloaderthread_p.h>
|
||||
|
||||
#include <QtQml/qqmlengine.h>
|
||||
|
||||
#ifdef DATABLOB_DEBUG
|
||||
#define ASSERT_CALLBACK() do { if (!m_typeLoader || !m_typeLoader->m_thread->isThisThread()) qFatal("QQmlDataBlob: An API call was made outside a callback"); } while (false)
|
||||
#else
|
||||
#define ASSERT_CALLBACK()
|
||||
#endif
|
||||
|
||||
DEFINE_BOOL_CONFIG_OPTION(dumpErrors, QML_DUMP_ERRORS);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
\class QQmlDataBlob
|
||||
\brief The QQmlDataBlob encapsulates a data request that can be issued to a QQmlTypeLoader.
|
||||
\internal
|
||||
|
||||
QQmlDataBlob's are loaded by a QQmlTypeLoader. The user creates the QQmlDataBlob
|
||||
and then calls QQmlTypeLoader::load() or QQmlTypeLoader::loadWithStaticData() to load it.
|
||||
The QQmlTypeLoader invokes callbacks on the QQmlDataBlob as data becomes available.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QQmlDataBlob::Status
|
||||
|
||||
This enum describes the status of the data blob.
|
||||
|
||||
\list
|
||||
\li Null The blob has not yet been loaded by a QQmlTypeLoader
|
||||
\li Loading The blob is loading network data. The QQmlDataBlob::setData() callback has not yet been
|
||||
invoked or has not yet returned.
|
||||
\li WaitingForDependencies The blob is waiting for dependencies to be done before continuing.
|
||||
This status only occurs after the QQmlDataBlob::setData() callback has been made, and when the
|
||||
blob has outstanding dependencies.
|
||||
\li Complete The blob's data has been loaded and all dependencies are done.
|
||||
\li Error An error has been set on this blob.
|
||||
\endlist
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QQmlDataBlob::Type
|
||||
|
||||
This enum describes the type of the data blob.
|
||||
|
||||
\list
|
||||
\li QmlFile This is a QQmlTypeData
|
||||
\li JavaScriptFile This is a QQmlScriptData
|
||||
\li QmldirFile This is a QQmlQmldirData
|
||||
\endlist
|
||||
*/
|
||||
|
||||
/*!
|
||||
Create a new QQmlDataBlob for \a url and of the provided \a type.
|
||||
*/
|
||||
QQmlDataBlob::QQmlDataBlob(const QUrl &url, Type type, QQmlTypeLoader *manager)
|
||||
: m_typeLoader(manager), m_type(type), m_url(url), m_finalUrl(url), m_redirectCount(0),
|
||||
m_inCallback(false), m_isDone(false)
|
||||
{
|
||||
//Set here because we need to get the engine from the manager
|
||||
if (m_typeLoader->engine() && m_typeLoader->engine()->urlInterceptor())
|
||||
m_url = m_typeLoader->engine()->urlInterceptor()->intercept(m_url,
|
||||
(QQmlAbstractUrlInterceptor::DataType)m_type);
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
QQmlDataBlob::~QQmlDataBlob()
|
||||
{
|
||||
Q_ASSERT(m_waitingOnMe.isEmpty());
|
||||
|
||||
cancelAllWaitingFor();
|
||||
}
|
||||
|
||||
/*!
|
||||
Must be called before loading can occur.
|
||||
*/
|
||||
void QQmlDataBlob::startLoading()
|
||||
{
|
||||
Q_ASSERT(status() == QQmlDataBlob::Null);
|
||||
m_data.setStatus(QQmlDataBlob::Loading);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the type provided to the constructor.
|
||||
*/
|
||||
QQmlDataBlob::Type QQmlDataBlob::type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the blob's status.
|
||||
*/
|
||||
QQmlDataBlob::Status QQmlDataBlob::status() const
|
||||
{
|
||||
return m_data.status();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the status is Null.
|
||||
*/
|
||||
bool QQmlDataBlob::isNull() const
|
||||
{
|
||||
return status() == Null;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the status is Loading.
|
||||
*/
|
||||
bool QQmlDataBlob::isLoading() const
|
||||
{
|
||||
return status() == Loading;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the status is WaitingForDependencies.
|
||||
*/
|
||||
bool QQmlDataBlob::isWaiting() const
|
||||
{
|
||||
return status() == WaitingForDependencies ||
|
||||
status() == ResolvingDependencies;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the status is Complete.
|
||||
*/
|
||||
bool QQmlDataBlob::isComplete() const
|
||||
{
|
||||
return status() == Complete;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the status is Error.
|
||||
*/
|
||||
bool QQmlDataBlob::isError() const
|
||||
{
|
||||
return status() == Error;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns true if the status is Complete or Error.
|
||||
*/
|
||||
bool QQmlDataBlob::isCompleteOrError() const
|
||||
{
|
||||
Status s = status();
|
||||
return s == Error || s == Complete;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the data download progress from 0 to 1.
|
||||
*/
|
||||
qreal QQmlDataBlob::progress() const
|
||||
{
|
||||
quint8 p = m_data.progress();
|
||||
if (p == 0xFF) return 1.;
|
||||
else return qreal(p) / qreal(0xFF);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the physical url of the data. Initially this is the same as
|
||||
finalUrl(), but if a URL interceptor is set, it will work on this URL
|
||||
and leave finalUrl() alone.
|
||||
|
||||
\sa finalUrl()
|
||||
*/
|
||||
QUrl QQmlDataBlob::url() const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
QString QQmlDataBlob::urlString() const
|
||||
{
|
||||
if (m_urlString.isEmpty())
|
||||
m_urlString = m_url.toString();
|
||||
|
||||
return m_urlString;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the logical URL to be used for resolving further URLs referred to in
|
||||
the code.
|
||||
|
||||
This is the blob url passed to the constructor. If a URL interceptor rewrites
|
||||
the URL, this one stays the same. If a network redirect happens while fetching
|
||||
the data, this url is updated to reflect the new location. Therefore, if both
|
||||
an interception and a redirection happen, the final url will indirectly
|
||||
incorporate the result of the interception, potentially breaking further
|
||||
lookups.
|
||||
|
||||
\sa url()
|
||||
*/
|
||||
QUrl QQmlDataBlob::finalUrl() const
|
||||
{
|
||||
return m_finalUrl;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the finalUrl() as a string.
|
||||
*/
|
||||
QString QQmlDataBlob::finalUrlString() const
|
||||
{
|
||||
if (m_finalUrlString.isEmpty())
|
||||
m_finalUrlString = m_finalUrl.toString();
|
||||
|
||||
return m_finalUrlString;
|
||||
}
|
||||
|
||||
/*!
|
||||
Return the errors on this blob.
|
||||
|
||||
May only be called from the load thread, or after the blob isCompleteOrError().
|
||||
*/
|
||||
QList<QQmlError> QQmlDataBlob::errors() const
|
||||
{
|
||||
Q_ASSERT(isCompleteOrError() || (m_typeLoader && m_typeLoader->m_thread->isThisThread()));
|
||||
return m_errors;
|
||||
}
|
||||
|
||||
/*!
|
||||
Mark this blob as having \a errors.
|
||||
|
||||
All outstanding dependencies will be cancelled. Requests to add new dependencies
|
||||
will be ignored. Entry into the Error state is irreversable.
|
||||
|
||||
The setError() method may only be called from within a QQmlDataBlob callback.
|
||||
*/
|
||||
void QQmlDataBlob::setError(const QQmlError &errors)
|
||||
{
|
||||
ASSERT_CALLBACK();
|
||||
|
||||
QList<QQmlError> l;
|
||||
l << errors;
|
||||
setError(l);
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
*/
|
||||
void QQmlDataBlob::setError(const QList<QQmlError> &errors)
|
||||
{
|
||||
ASSERT_CALLBACK();
|
||||
|
||||
Q_ASSERT(status() != Error);
|
||||
Q_ASSERT(m_errors.isEmpty());
|
||||
|
||||
m_errors = errors; // Must be set before the m_data fence
|
||||
m_data.setStatus(Error);
|
||||
|
||||
if (dumpErrors()) {
|
||||
qWarning().nospace() << "Errors for " << urlString();
|
||||
for (int ii = 0; ii < errors.count(); ++ii)
|
||||
qWarning().nospace() << " " << qPrintable(errors.at(ii).toString());
|
||||
}
|
||||
cancelAllWaitingFor();
|
||||
|
||||
if (!m_inCallback)
|
||||
tryDone();
|
||||
}
|
||||
|
||||
void QQmlDataBlob::setError(const QQmlJS::DiagnosticMessage &error)
|
||||
{
|
||||
QQmlError e;
|
||||
e.setColumn(error.column);
|
||||
e.setLine(error.line);
|
||||
e.setDescription(error.message);
|
||||
e.setUrl(url());
|
||||
setError(e);
|
||||
}
|
||||
|
||||
void QQmlDataBlob::setError(const QVector<QQmlJS::DiagnosticMessage> &errors)
|
||||
{
|
||||
QList<QQmlError> finalErrors;
|
||||
finalErrors.reserve(errors.count());
|
||||
for (const auto &error : errors) {
|
||||
QQmlError e;
|
||||
e.setColumn(error.column);
|
||||
e.setLine(error.line);
|
||||
e.setDescription(error.message);
|
||||
e.setUrl(url());
|
||||
finalErrors << e;
|
||||
}
|
||||
setError(finalErrors);
|
||||
}
|
||||
|
||||
void QQmlDataBlob::setError(const QString &description)
|
||||
{
|
||||
QQmlError e;
|
||||
e.setDescription(description);
|
||||
e.setUrl(url());
|
||||
setError(e);
|
||||
}
|
||||
|
||||
/*!
|
||||
Wait for \a blob to become complete or to error. If \a blob is already
|
||||
complete or in error, or this blob is already complete, this has no effect.
|
||||
|
||||
The setError() method may only be called from within a QQmlDataBlob callback.
|
||||
*/
|
||||
void QQmlDataBlob::addDependency(QQmlDataBlob *blob)
|
||||
{
|
||||
ASSERT_CALLBACK();
|
||||
|
||||
Q_ASSERT(status() != Null);
|
||||
|
||||
if (!blob ||
|
||||
blob->status() == Error || blob->status() == Complete ||
|
||||
status() == Error || status() == Complete || m_isDone)
|
||||
return;
|
||||
|
||||
for (auto existingDep: qAsConst(m_waitingFor))
|
||||
if (existingDep.data() == blob)
|
||||
return;
|
||||
|
||||
m_data.setStatus(WaitingForDependencies);
|
||||
|
||||
m_waitingFor.append(blob);
|
||||
blob->m_waitingOnMe.append(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn void QQmlDataBlob::dataReceived(const Data &data)
|
||||
|
||||
Invoked when data for the blob is received. Implementors should use this callback
|
||||
to determine a blob's dependencies. Within this callback you may call setError()
|
||||
or addDependency().
|
||||
*/
|
||||
|
||||
/*!
|
||||
Invoked once data has either been received or a network error occurred, and all
|
||||
dependencies are complete.
|
||||
|
||||
You can set an error in this method, but you cannot add new dependencies. Implementors
|
||||
should use this callback to finalize processing of data.
|
||||
|
||||
The default implementation does nothing.
|
||||
|
||||
XXX Rename processData() or some such to avoid confusion between done() (processing thread)
|
||||
and completed() (main thread)
|
||||
*/
|
||||
void QQmlDataBlob::done()
|
||||
{
|
||||
}
|
||||
|
||||
#if QT_CONFIG(qml_network)
|
||||
/*!
|
||||
Invoked if there is a network error while fetching this blob.
|
||||
|
||||
The default implementation sets an appropriate QQmlError.
|
||||
*/
|
||||
void QQmlDataBlob::networkError(QNetworkReply::NetworkError networkError)
|
||||
{
|
||||
Q_UNUSED(networkError);
|
||||
|
||||
QQmlError error;
|
||||
error.setUrl(m_url);
|
||||
|
||||
const char *errorString = nullptr;
|
||||
switch (networkError) {
|
||||
default:
|
||||
errorString = "Network error";
|
||||
break;
|
||||
case QNetworkReply::ConnectionRefusedError:
|
||||
errorString = "Connection refused";
|
||||
break;
|
||||
case QNetworkReply::RemoteHostClosedError:
|
||||
errorString = "Remote host closed the connection";
|
||||
break;
|
||||
case QNetworkReply::HostNotFoundError:
|
||||
errorString = "Host not found";
|
||||
break;
|
||||
case QNetworkReply::TimeoutError:
|
||||
errorString = "Timeout";
|
||||
break;
|
||||
case QNetworkReply::ProxyConnectionRefusedError:
|
||||
case QNetworkReply::ProxyConnectionClosedError:
|
||||
case QNetworkReply::ProxyNotFoundError:
|
||||
case QNetworkReply::ProxyTimeoutError:
|
||||
case QNetworkReply::ProxyAuthenticationRequiredError:
|
||||
case QNetworkReply::UnknownProxyError:
|
||||
errorString = "Proxy error";
|
||||
break;
|
||||
case QNetworkReply::ContentAccessDenied:
|
||||
errorString = "Access denied";
|
||||
break;
|
||||
case QNetworkReply::ContentNotFoundError:
|
||||
errorString = "File not found";
|
||||
break;
|
||||
case QNetworkReply::AuthenticationRequiredError:
|
||||
errorString = "Authentication required";
|
||||
break;
|
||||
};
|
||||
|
||||
error.setDescription(QLatin1String(errorString));
|
||||
|
||||
setError(error);
|
||||
}
|
||||
#endif // qml_network
|
||||
|
||||
/*!
|
||||
Called if \a blob, which was previously waited for, has an error.
|
||||
|
||||
The default implementation does nothing.
|
||||
*/
|
||||
void QQmlDataBlob::dependencyError(QQmlDataBlob *blob)
|
||||
{
|
||||
Q_UNUSED(blob);
|
||||
}
|
||||
|
||||
/*!
|
||||
Called if \a blob, which was previously waited for, has completed.
|
||||
|
||||
The default implementation does nothing.
|
||||
*/
|
||||
void QQmlDataBlob::dependencyComplete(QQmlDataBlob *blob)
|
||||
{
|
||||
Q_UNUSED(blob);
|
||||
}
|
||||
|
||||
/*!
|
||||
Called when all blobs waited for have completed. This occurs regardless of
|
||||
whether they are in error, or complete state.
|
||||
|
||||
The default implementation does nothing.
|
||||
*/
|
||||
void QQmlDataBlob::allDependenciesDone()
|
||||
{
|
||||
m_data.setStatus(QQmlDataBlob::ResolvingDependencies);
|
||||
}
|
||||
|
||||
/*!
|
||||
Called when the download progress of this blob changes. \a progress goes
|
||||
from 0 to 1.
|
||||
|
||||
This callback is only invoked if an asynchronous load for this blob is
|
||||
made. An asynchronous load is one in which the Asynchronous mode is
|
||||
specified explicitly, or one that is implicitly delayed due to a network
|
||||
operation.
|
||||
|
||||
The default implementation does nothing.
|
||||
*/
|
||||
void QQmlDataBlob::downloadProgressChanged(qreal progress)
|
||||
{
|
||||
Q_UNUSED(progress);
|
||||
}
|
||||
|
||||
/*!
|
||||
Invoked on the main thread sometime after done() was called on the load thread.
|
||||
|
||||
You cannot modify the blobs state at all in this callback and cannot depend on the
|
||||
order or timeliness of these callbacks. Implementors should use this callback to notify
|
||||
dependencies on the main thread that the blob is done and not a lot else.
|
||||
|
||||
This callback is only invoked if an asynchronous load for this blob is
|
||||
made. An asynchronous load is one in which the Asynchronous mode is
|
||||
specified explicitly, or one that is implicitly delayed due to a network
|
||||
operation.
|
||||
|
||||
The default implementation does nothing.
|
||||
*/
|
||||
void QQmlDataBlob::completed()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void QQmlDataBlob::tryDone()
|
||||
{
|
||||
if (status() != Loading && m_waitingFor.isEmpty() && !m_isDone) {
|
||||
m_isDone = true;
|
||||
addref();
|
||||
|
||||
#ifdef DATABLOB_DEBUG
|
||||
qWarning("QQmlDataBlob::done() %s", qPrintable(urlString()));
|
||||
#endif
|
||||
done();
|
||||
|
||||
if (status() != Error)
|
||||
m_data.setStatus(Complete);
|
||||
|
||||
notifyAllWaitingOnMe();
|
||||
|
||||
// Locking is not required here, as anyone expecting callbacks must
|
||||
// already be protected against the blob being completed (as set above);
|
||||
#ifdef DATABLOB_DEBUG
|
||||
qWarning("QQmlDataBlob: Dispatching completed");
|
||||
#endif
|
||||
m_typeLoader->m_thread->callCompleted(this);
|
||||
|
||||
release();
|
||||
}
|
||||
}
|
||||
|
||||
void QQmlDataBlob::cancelAllWaitingFor()
|
||||
{
|
||||
while (m_waitingFor.count()) {
|
||||
QQmlRefPointer<QQmlDataBlob> blob = m_waitingFor.takeLast();
|
||||
|
||||
Q_ASSERT(blob->m_waitingOnMe.contains(this));
|
||||
|
||||
blob->m_waitingOnMe.removeOne(this);
|
||||
}
|
||||
}
|
||||
|
||||
void QQmlDataBlob::notifyAllWaitingOnMe()
|
||||
{
|
||||
while (m_waitingOnMe.count()) {
|
||||
QQmlDataBlob *blob = m_waitingOnMe.takeLast();
|
||||
|
||||
Q_ASSERT(std::any_of(blob->m_waitingFor.constBegin(), blob->m_waitingFor.constEnd(),
|
||||
[this](const QQmlRefPointer<QQmlDataBlob> &waiting) { return waiting.data() == this; }));
|
||||
|
||||
blob->notifyComplete(this);
|
||||
}
|
||||
}
|
||||
|
||||
void QQmlDataBlob::notifyComplete(QQmlDataBlob *blob)
|
||||
{
|
||||
Q_ASSERT(blob->status() == Error || blob->status() == Complete);
|
||||
QQmlCompilingProfiler prof(typeLoader()->profiler(), blob);
|
||||
|
||||
m_inCallback = true;
|
||||
|
||||
QQmlRefPointer<QQmlDataBlob> blobRef;
|
||||
for (int i = 0; i < m_waitingFor.count(); ++i) {
|
||||
if (m_waitingFor.at(i).data() == blob) {
|
||||
blobRef = m_waitingFor.takeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Q_ASSERT(blobRef);
|
||||
|
||||
if (blob->status() == Error) {
|
||||
dependencyError(blob);
|
||||
} else if (blob->status() == Complete) {
|
||||
dependencyComplete(blob);
|
||||
}
|
||||
|
||||
if (!isError() && m_waitingFor.isEmpty())
|
||||
allDependenciesDone();
|
||||
|
||||
m_inCallback = false;
|
||||
|
||||
tryDone();
|
||||
}
|
||||
|
||||
QString QQmlDataBlob::SourceCodeData::readAll(QString *error) const
|
||||
{
|
||||
error->clear();
|
||||
if (hasInlineSourceCode)
|
||||
return inlineSourceCode;
|
||||
|
||||
QFile f(fileInfo.absoluteFilePath());
|
||||
if (!f.open(QIODevice::ReadOnly)) {
|
||||
*error = f.errorString();
|
||||
return QString();
|
||||
}
|
||||
|
||||
const qint64 fileSize = fileInfo.size();
|
||||
|
||||
if (uchar *mappedData = f.map(0, fileSize)) {
|
||||
QString source = QString::fromUtf8(reinterpret_cast<const char *>(mappedData), fileSize);
|
||||
f.unmap(mappedData);
|
||||
return source;
|
||||
}
|
||||
|
||||
QByteArray data(fileSize, Qt::Uninitialized);
|
||||
if (f.read(data.data(), data.length()) != data.length()) {
|
||||
*error = f.errorString();
|
||||
return QString();
|
||||
}
|
||||
return QString::fromUtf8(data);
|
||||
}
|
||||
|
||||
QDateTime QQmlDataBlob::SourceCodeData::sourceTimeStamp() const
|
||||
{
|
||||
if (hasInlineSourceCode)
|
||||
return QDateTime();
|
||||
|
||||
return fileInfo.lastModified();
|
||||
}
|
||||
|
||||
bool QQmlDataBlob::SourceCodeData::exists() const
|
||||
{
|
||||
if (hasInlineSourceCode)
|
||||
return true;
|
||||
return fileInfo.exists();
|
||||
}
|
||||
|
||||
bool QQmlDataBlob::SourceCodeData::isEmpty() const
|
||||
{
|
||||
if (hasInlineSourceCode)
|
||||
return inlineSourceCode.isEmpty();
|
||||
return fileInfo.size() == 0;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -0,0 +1,257 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QQMLDATABLOB_P_H
|
||||
#define QQMLDATABLOB_P_H
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include <private/qqmlrefcount_p.h>
|
||||
#include <private/qqmljsdiagnosticmessage_p.h>
|
||||
#include <private/qv4compileddata_p.h>
|
||||
|
||||
#if QT_CONFIG(qml_network)
|
||||
#include <QtNetwork/qnetworkreply.h>
|
||||
#endif
|
||||
|
||||
#include <QtQml/qqmlerror.h>
|
||||
#include <QtQml/qqmlabstracturlinterceptor.h>
|
||||
|
||||
#include <QtCore/qdatetime.h>
|
||||
#include <QtCore/qfileinfo.h>
|
||||
#include <QtCore/qurl.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QQmlTypeLoader;
|
||||
class Q_QML_PRIVATE_EXPORT QQmlDataBlob : public QQmlRefCount
|
||||
{
|
||||
public:
|
||||
enum Status {
|
||||
Null, // Prior to QQmlTypeLoader::load()
|
||||
Loading, // Prior to data being received and dataReceived() being called
|
||||
WaitingForDependencies, // While there are outstanding addDependency()s
|
||||
ResolvingDependencies, // While resolving outstanding dependencies, to detect cycles
|
||||
Complete, // Finished
|
||||
Error // Error
|
||||
};
|
||||
|
||||
enum Type { //Matched in QQmlAbstractUrlInterceptor
|
||||
QmlFile = QQmlAbstractUrlInterceptor::QmlFile,
|
||||
JavaScriptFile = QQmlAbstractUrlInterceptor::JavaScriptFile,
|
||||
QmldirFile = QQmlAbstractUrlInterceptor::QmldirFile
|
||||
};
|
||||
|
||||
QQmlDataBlob(const QUrl &, Type, QQmlTypeLoader* manager);
|
||||
~QQmlDataBlob() override;
|
||||
|
||||
void startLoading();
|
||||
|
||||
QQmlTypeLoader *typeLoader() const { return m_typeLoader; }
|
||||
|
||||
Type type() const;
|
||||
|
||||
Status status() const;
|
||||
bool isNull() const;
|
||||
bool isLoading() const;
|
||||
bool isWaiting() const;
|
||||
bool isComplete() const;
|
||||
bool isError() const;
|
||||
bool isCompleteOrError() const;
|
||||
|
||||
qreal progress() const;
|
||||
|
||||
QUrl url() const;
|
||||
QString urlString() const;
|
||||
QUrl finalUrl() const;
|
||||
QString finalUrlString() const;
|
||||
|
||||
QList<QQmlError> errors() const;
|
||||
|
||||
class SourceCodeData {
|
||||
public:
|
||||
QString readAll(QString *error) const;
|
||||
QDateTime sourceTimeStamp() const;
|
||||
bool exists() const;
|
||||
bool isEmpty() const;
|
||||
private:
|
||||
friend class QQmlDataBlob;
|
||||
friend class QQmlTypeLoader;
|
||||
QString inlineSourceCode;
|
||||
QFileInfo fileInfo;
|
||||
bool hasInlineSourceCode = false;
|
||||
};
|
||||
|
||||
protected:
|
||||
// Can be called from within callbacks
|
||||
void setError(const QQmlError &);
|
||||
void setError(const QList<QQmlError> &errors);
|
||||
void setError(const QQmlJS::DiagnosticMessage &error);
|
||||
void setError(const QVector<QQmlJS::DiagnosticMessage> &errors);
|
||||
void setError(const QString &description);
|
||||
void addDependency(QQmlDataBlob *);
|
||||
|
||||
// Callbacks made in load thread
|
||||
virtual void dataReceived(const SourceCodeData &) = 0;
|
||||
virtual void initializeFromCachedUnit(const QV4::CompiledData::Unit*) = 0;
|
||||
virtual void done();
|
||||
#if QT_CONFIG(qml_network)
|
||||
virtual void networkError(QNetworkReply::NetworkError);
|
||||
#endif
|
||||
virtual void dependencyError(QQmlDataBlob *);
|
||||
virtual void dependencyComplete(QQmlDataBlob *);
|
||||
virtual void allDependenciesDone();
|
||||
|
||||
// Callbacks made in main thread
|
||||
virtual void downloadProgressChanged(qreal);
|
||||
virtual void completed();
|
||||
|
||||
protected:
|
||||
// Manager that is currently fetching data for me
|
||||
QQmlTypeLoader *m_typeLoader;
|
||||
|
||||
private:
|
||||
friend class QQmlTypeLoader;
|
||||
friend class QQmlTypeLoaderThread;
|
||||
|
||||
void tryDone();
|
||||
void cancelAllWaitingFor();
|
||||
void notifyAllWaitingOnMe();
|
||||
void notifyComplete(QQmlDataBlob *);
|
||||
|
||||
struct ThreadData {
|
||||
private:
|
||||
enum {
|
||||
StatusMask = 0x0000FFFF,
|
||||
StatusShift = 0,
|
||||
ProgressMask = 0x00FF0000,
|
||||
ProgressShift = 16,
|
||||
AsyncMask = 0x80000000,
|
||||
NoMask = 0
|
||||
};
|
||||
|
||||
public:
|
||||
inline ThreadData()
|
||||
: _p(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline QQmlDataBlob::Status status() const
|
||||
{
|
||||
return QQmlDataBlob::Status((_p.loadRelaxed() & StatusMask) >> StatusShift);
|
||||
}
|
||||
|
||||
inline void setStatus(QQmlDataBlob::Status status)
|
||||
{
|
||||
while (true) {
|
||||
int d = _p.loadRelaxed();
|
||||
int nd = (d & ~StatusMask) | ((status << StatusShift) & StatusMask);
|
||||
if (d == nd || _p.testAndSetOrdered(d, nd)) return;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool isAsync() const
|
||||
{
|
||||
return _p.loadRelaxed() & AsyncMask;
|
||||
}
|
||||
|
||||
inline void setIsAsync(bool v)
|
||||
{
|
||||
while (true) {
|
||||
int d = _p.loadRelaxed();
|
||||
int nd = (d & ~AsyncMask) | (v ? AsyncMask : NoMask);
|
||||
if (d == nd || _p.testAndSetOrdered(d, nd)) return;
|
||||
}
|
||||
}
|
||||
|
||||
inline quint8 progress() const
|
||||
{
|
||||
return quint8((_p.loadRelaxed() & ProgressMask) >> ProgressShift);
|
||||
}
|
||||
|
||||
inline void setProgress(quint8 v)
|
||||
{
|
||||
while (true) {
|
||||
int d = _p.loadRelaxed();
|
||||
int nd = (d & ~ProgressMask) | ((v << ProgressShift) & ProgressMask);
|
||||
if (d == nd || _p.testAndSetOrdered(d, nd)) return;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QAtomicInt _p;
|
||||
};
|
||||
ThreadData m_data;
|
||||
|
||||
// m_errors should *always* be written before the status is set to Error.
|
||||
// We use the status change as a memory fence around m_errors so that locking
|
||||
// isn't required. Once the status is set to Error (or Complete), m_errors
|
||||
// cannot be changed.
|
||||
QList<QQmlError> m_errors;
|
||||
|
||||
Type m_type;
|
||||
|
||||
QUrl m_url;
|
||||
QUrl m_finalUrl;
|
||||
mutable QString m_urlString;
|
||||
mutable QString m_finalUrlString;
|
||||
|
||||
// List of QQmlDataBlob's that are waiting for me to complete.
|
||||
QList<QQmlDataBlob *> m_waitingOnMe;
|
||||
|
||||
// List of QQmlDataBlob's that I am waiting for to complete.
|
||||
QVector<QQmlRefPointer<QQmlDataBlob>> m_waitingFor;
|
||||
|
||||
int m_redirectCount:30;
|
||||
bool m_inCallback:1;
|
||||
bool m_isDone:1;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QQMLDATABLOB_P_H
|
|
@ -43,6 +43,7 @@
|
|||
#include <private/qv4value_p.h>
|
||||
#include <private/qv4jscall_p.h>
|
||||
#include <private/qv4qobjectwrapper_p.h>
|
||||
#include <private/qv4qmlcontext_p.h>
|
||||
|
||||
#include <QQmlError>
|
||||
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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 <private/qqmldirdata_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QQmlQmldirData::QQmlQmldirData(const QUrl &url, QQmlTypeLoader *loader)
|
||||
: QQmlTypeLoader::Blob(url, QmldirFile, loader)
|
||||
{
|
||||
}
|
||||
|
||||
const QString &QQmlQmldirData::content() const
|
||||
{
|
||||
return m_content;
|
||||
}
|
||||
|
||||
const QV4::CompiledData::Import *QQmlQmldirData::import(QQmlTypeLoader::Blob *blob) const
|
||||
{
|
||||
QHash<QQmlTypeLoader::Blob *, const QV4::CompiledData::Import *>::const_iterator it =
|
||||
m_imports.find(blob);
|
||||
if (it == m_imports.end())
|
||||
return nullptr;
|
||||
return *it;
|
||||
}
|
||||
|
||||
void QQmlQmldirData::setImport(QQmlTypeLoader::Blob *blob, const QV4::CompiledData::Import *import)
|
||||
{
|
||||
m_imports[blob] = import;
|
||||
}
|
||||
|
||||
int QQmlQmldirData::priority(QQmlTypeLoader::Blob *blob) const
|
||||
{
|
||||
QHash<QQmlTypeLoader::Blob *, int>::const_iterator it = m_priorities.find(blob);
|
||||
if (it == m_priorities.end())
|
||||
return 0;
|
||||
return *it;
|
||||
}
|
||||
|
||||
void QQmlQmldirData::setPriority(QQmlTypeLoader::Blob *blob, int priority)
|
||||
{
|
||||
m_priorities[blob] = priority;
|
||||
}
|
||||
|
||||
void QQmlQmldirData::dataReceived(const SourceCodeData &data)
|
||||
{
|
||||
QString error;
|
||||
m_content = data.readAll(&error);
|
||||
if (!error.isEmpty()) {
|
||||
setError(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void QQmlQmldirData::initializeFromCachedUnit(const QV4::CompiledData::Unit *)
|
||||
{
|
||||
Q_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -0,0 +1,86 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QQMLDIRDATA_P_H
|
||||
#define QQMLDIRDATA_P_H
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include <private/qqmltypeloader_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_AUTOTEST_EXPORT QQmlQmldirData : public QQmlTypeLoader::Blob
|
||||
{
|
||||
private:
|
||||
friend class QQmlTypeLoader;
|
||||
|
||||
QQmlQmldirData(const QUrl &, QQmlTypeLoader *);
|
||||
|
||||
public:
|
||||
const QString &content() const;
|
||||
|
||||
const QV4::CompiledData::Import *import(QQmlTypeLoader::Blob *) const;
|
||||
void setImport(QQmlTypeLoader::Blob *, const QV4::CompiledData::Import *);
|
||||
|
||||
int priority(QQmlTypeLoader::Blob *) const;
|
||||
void setPriority(QQmlTypeLoader::Blob *, int);
|
||||
|
||||
protected:
|
||||
void dataReceived(const SourceCodeData &) override;
|
||||
void initializeFromCachedUnit(const QV4::CompiledData::Unit *) override;
|
||||
|
||||
private:
|
||||
QString m_content;
|
||||
QHash<QQmlTypeLoader::Blob *, const QV4::CompiledData::Import *> m_imports;
|
||||
QHash<QQmlTypeLoader::Blob *, int> m_priorities;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QQMLDIRDATA_P_H
|
|
@ -51,14 +51,15 @@
|
|||
#include "qqmlscriptstring.h"
|
||||
#include "qqmlglobal_p.h"
|
||||
#include "qqmlcomponent_p.h"
|
||||
#include "qqmldirparser_p.h"
|
||||
#include "qqmlextensioninterface.h"
|
||||
#include "qqmllist_p.h"
|
||||
#include "qqmltypenamecache_p.h"
|
||||
#include "qqmlnotifier_p.h"
|
||||
#include "qqmlincubator.h"
|
||||
#include "qqmlabstracturlinterceptor.h"
|
||||
#include <private/qqmldirparser_p.h>
|
||||
#include <private/qqmlboundsignal_p.h>
|
||||
#include <private/qqmljsdiagnosticmessage_p.h>
|
||||
#include <QtCore/qstandardpaths.h>
|
||||
#include <QtCore/qsettings.h>
|
||||
#include <QtCore/qmetaobject.h>
|
||||
|
@ -1790,7 +1791,7 @@ void QQmlData::deferData(int objectIndex, const QQmlRefPointer<QV4::ExecutableCo
|
|||
deferData->context = context;
|
||||
|
||||
const QV4::CompiledData::Object *compiledObject = compilationUnit->objectAt(objectIndex);
|
||||
const QV4::CompiledData::BindingPropertyData &propertyData = compilationUnit->bindingPropertyDataPerObject.at(objectIndex);
|
||||
const QV4::BindingPropertyData &propertyData = compilationUnit->bindingPropertyDataPerObject.at(objectIndex);
|
||||
|
||||
const QV4::CompiledData::Binding *binding = compiledObject->bindingTable();
|
||||
for (quint32 i = 0; i < compiledObject->nBindings; ++i, ++binding) {
|
||||
|
@ -2115,10 +2116,11 @@ void QQmlEnginePrivate::warning(QQmlEnginePrivate *engine, const QList<QQmlError
|
|||
dumpwarning(error);
|
||||
}
|
||||
|
||||
QList<QQmlError> QQmlEnginePrivate::qmlErrorFromDiagnostics(const QString &fileName, const QList<DiagnosticMessage> &diagnosticMessages)
|
||||
QList<QQmlError> QQmlEnginePrivate::qmlErrorFromDiagnostics(
|
||||
const QString &fileName, const QList<QQmlJS::DiagnosticMessage> &diagnosticMessages)
|
||||
{
|
||||
QList<QQmlError> errors;
|
||||
for (const DiagnosticMessage &m : diagnosticMessages) {
|
||||
for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) {
|
||||
if (m.isWarning()) {
|
||||
qWarning("%s:%d : %s", qPrintable(fileName), m.line, qPrintable(m.message));
|
||||
continue;
|
||||
|
@ -2325,6 +2327,17 @@ QString QQmlEngine::offlineStorageDatabaseFilePath(const QString &databaseName)
|
|||
return d->offlineStorageDatabaseDirectory() + QLatin1String(md5.result().toHex());
|
||||
}
|
||||
|
||||
// #### Qt 6: Remove this function, it exists only for binary compatibility.
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
bool QQmlEngine::addNamedBundle(const QString &name, const QString &fileName)
|
||||
{
|
||||
Q_UNUSED(name)
|
||||
Q_UNUSED(fileName)
|
||||
return false;
|
||||
}
|
||||
|
||||
QString QQmlEnginePrivate::offlineStorageDatabaseDirectory() const
|
||||
{
|
||||
Q_Q(const QQmlEngine);
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include <private/qintrusivelist_p.h>
|
||||
#include <private/qrecyclepool_p.h>
|
||||
#include <private/qfieldlist_p.h>
|
||||
#include <private/qv4engine_p.h>
|
||||
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qpair.h>
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "qqmlscriptstring_p.h"
|
||||
#include "qqmlbinding_p.h"
|
||||
#include <private/qqmlsourcecoordinate_p.h>
|
||||
#include <private/qv4qmlcontext_p.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include <private/qqmlengine_p.h>
|
||||
#include <private/qfieldlist_p.h>
|
||||
#include <private/qqmltypemodule_p.h>
|
||||
#include <private/qqmltypeloaderqmldircontent_p.h>
|
||||
#include <QtCore/qjsonobject.h>
|
||||
#include <QtCore/qjsonarray.h>
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#ifndef QQMLINFO_H
|
||||
#define QQMLINFO_H
|
||||
|
||||
#include <QtQml/qtqmlglobal.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtQml/qqmlerror.h>
|
||||
|
|
|
@ -136,10 +136,10 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
|
|||
QmlIR::Signal *s = pool->New<QmlIR::Signal>();
|
||||
s->nameIndex = serializedSignal->nameIndex;
|
||||
s->location = serializedSignal->location;
|
||||
s->parameters = pool->New<QmlIR::PoolList<QmlIR::SignalParameter> >();
|
||||
s->parameters = pool->New<QmlIR::PoolList<QmlIR::Parameter> >();
|
||||
|
||||
for (uint i = 0; i < serializedSignal->nParameters; ++i) {
|
||||
QmlIR::SignalParameter *p = pool->New<QmlIR::SignalParameter>();
|
||||
QmlIR::Parameter *p = pool->New<QmlIR::Parameter>();
|
||||
*static_cast<QV4::CompiledData::Parameter*>(p) = *serializedSignal->parameterAt(i);
|
||||
s->parameters->append(p);
|
||||
}
|
||||
|
@ -188,11 +188,12 @@ QmlIR::Object *QQmlIRLoader::loadObject(const QV4::CompiledData::Object *seriali
|
|||
f->index = functionIndices.count() - 1;
|
||||
f->location = compiledFunction->location;
|
||||
f->nameIndex = compiledFunction->nameIndex;
|
||||
f->returnType = compiledFunction->returnType;
|
||||
|
||||
f->formals.allocate(pool, int(compiledFunction->nFormals));
|
||||
const quint32_le *formalNameIdx = compiledFunction->formalsTable();
|
||||
const QV4::CompiledData::Parameter *formalNameIdx = compiledFunction->formalsTable();
|
||||
for (uint i = 0; i < compiledFunction->nFormals; ++i, ++formalNameIdx)
|
||||
f->formals[i] = *formalNameIdx;
|
||||
*static_cast<QV4::CompiledData::Parameter*>(&f->formals[i]) = *formalNameIdx;
|
||||
|
||||
object->functions->append(f);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <private/qqmltype_p_p.h>
|
||||
#include <private/qqmltypeloader_p.h>
|
||||
#include <private/qqmlextensionplugin_p.h>
|
||||
#include <private/qv4executablecompilationunit_p.h>
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include <private/qqmlvaluetypeproxybinding_p.h>
|
||||
#include <private/qqmldebugconnector_p.h>
|
||||
#include <private/qqmldebugserviceinterfaces_p.h>
|
||||
#include <private/qqmlscriptdata_p.h>
|
||||
#include <private/qjsvalue_p.h>
|
||||
|
||||
#include <qtqml_tracepoints_p.h>
|
||||
|
@ -735,7 +736,7 @@ void QQmlObjectCreator::setupBindings(bool applyDeferredBindings)
|
|||
QQmlListProperty<void> savedList;
|
||||
qSwap(_currentList, savedList);
|
||||
|
||||
const QV4::CompiledData::BindingPropertyData &propertyData = compilationUnit->bindingPropertyDataPerObject.at(_compiledObjectIndex);
|
||||
const QV4::BindingPropertyData &propertyData = compilationUnit->bindingPropertyDataPerObject.at(_compiledObjectIndex);
|
||||
|
||||
if (_compiledObject->idNameIndex) {
|
||||
const QQmlPropertyData *idProperty = propertyData.last();
|
||||
|
@ -1445,8 +1446,12 @@ void QQmlObjectCreator::clear()
|
|||
return;
|
||||
Q_ASSERT(phase != Startup);
|
||||
|
||||
while (!sharedState->allCreatedObjects.isEmpty())
|
||||
delete sharedState->allCreatedObjects.pop();
|
||||
while (!sharedState->allCreatedObjects.isEmpty()) {
|
||||
auto object = sharedState->allCreatedObjects.pop();
|
||||
if (engine->objectOwnership(object) != QQmlEngine::CppOwnership) {
|
||||
delete object;
|
||||
}
|
||||
}
|
||||
|
||||
while (sharedState->componentAttached) {
|
||||
QQmlComponentAttached *a = sharedState->componentAttached;
|
||||
|
|
|
@ -53,17 +53,16 @@
|
|||
#include <private/qqmlimport_p.h>
|
||||
#include <private/qqmltypenamecache_p.h>
|
||||
#include <private/qv4compileddata_p.h>
|
||||
#include <private/qqmltypecompiler_p.h>
|
||||
#include <private/qfinitestack_p.h>
|
||||
#include <private/qrecursionwatcher_p.h>
|
||||
#include <private/qqmlprofiler_p.h>
|
||||
#include <private/qv4qmlcontext_p.h>
|
||||
|
||||
#include <qpointer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QQmlAbstractBinding;
|
||||
struct QQmlTypeCompiler;
|
||||
class QQmlInstantiationInterrupt;
|
||||
class QQmlIncubatorPrivate;
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue