Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: src/qml/jsruntime/qv4functionobject_p.h Change-Id: I4bbed45f1fe02cf64df3c8a5f92f811e38e772f3
This commit is contained in:
commit
e321dc6bee
|
@ -1,4 +1,3 @@
|
|||
[submodule "tests/manual/v4/test262"]
|
||||
path = tests/manual/v4/test262
|
||||
[submodule "tests/auto/qml/ecmascripttests/test262"]
|
||||
path = tests/auto/qml/ecmascripttests/test262
|
||||
url = ../qtdeclarative-testsuites.git
|
||||
update = none
|
||||
|
|
|
@ -73,24 +73,24 @@ This example builds on:
|
|||
\li \l {Extending QML - Adding Types Example}
|
||||
\endlist
|
||||
|
||||
Shows how to use \l {QQmlEngine::}{qmlRegisterExtendedType()} to provide an \l {Registering
|
||||
Extension Objects}{extension object} to a \l QLineEdit without modifying or
|
||||
subclassing.
|
||||
Shows how to use \l {QQmlEngine::}{qmlRegisterExtendedType()} to provide an
|
||||
\l {Registering Extension Objects}{extension object} to a \l QLineEdit without modifying or
|
||||
subclassing it.
|
||||
|
||||
Firstly, the LineEditExtension class is registered with the QML system as an extension of QLineEdit:
|
||||
|
||||
\snippet referenceexamples/extended/main.cpp 0
|
||||
|
||||
The QML engine instantiates a \l QLineEdit
|
||||
The QML engine then instantiates a \l QLineEdit:
|
||||
|
||||
\snippet referenceexamples/extended/main.cpp 1
|
||||
|
||||
and sets a property that oly exists on the extension type.
|
||||
In QML, a property is set on the line edit that only exists in the LineEditExtension class:
|
||||
|
||||
\snippet referenceexamples/extended/example.qml 0
|
||||
|
||||
The QML engine instantiates a \l QLineEdit and sets a property that
|
||||
only exists on the extension type. The extension type performs calls on the
|
||||
\l QLineEdit that otherwise will not be accessible to the QML engine.
|
||||
|
||||
The extension type performs calls on the \l QLineEdit that otherwise will
|
||||
not be accessible to the QML engine.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
@ -1361,7 +1361,7 @@ bool IRBuilder::isRedundantNullInitializerForPropertyDeclaration(Property *prope
|
|||
return QQmlJS::AST::cast<QQmlJS::AST::NullExpression *>(expr);
|
||||
}
|
||||
|
||||
QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, QQmlEngine *engine, const QV4::CompiledData::ResolvedTypeReferenceMap &dependentTypes)
|
||||
QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
|
||||
{
|
||||
QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit = output.javaScriptCompilationUnit;
|
||||
QV4::CompiledData::Unit *jsUnit = compilationUnit->createUnitData(&output);
|
||||
|
@ -1404,17 +1404,16 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, QQmlEngine
|
|||
qmlUnit->stringTableSize = output.jsGenerator.stringTable.stringCount();
|
||||
|
||||
#ifndef V4_BOOTSTRAP
|
||||
if (!dependentTypes.isEmpty()) {
|
||||
if (dependencyHasher) {
|
||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||
if (dependentTypes.addToHash(&hash, engine)) {
|
||||
if (dependencyHasher(&hash)) {
|
||||
QByteArray checksum = hash.result();
|
||||
Q_ASSERT(checksum.size() == sizeof(qmlUnit->dependencyMD5Checksum));
|
||||
memcpy(qmlUnit->dependencyMD5Checksum, checksum.constData(), sizeof(qmlUnit->dependencyMD5Checksum));
|
||||
}
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(dependentTypes);
|
||||
Q_UNUSED(engine);
|
||||
Q_UNUSED(dependencyHasher);
|
||||
#endif
|
||||
|
||||
// write imports
|
||||
|
|
|
@ -548,7 +548,7 @@ public:
|
|||
|
||||
struct Q_QML_PRIVATE_EXPORT QmlUnitGenerator
|
||||
{
|
||||
QV4::CompiledData::Unit *generate(Document &output, QQmlEngine *engine, const QV4::CompiledData::ResolvedTypeReferenceMap &dependentTypes);
|
||||
QV4::CompiledData::Unit *generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher = QV4::CompiledData::DependentTypesHasher());
|
||||
|
||||
private:
|
||||
typedef bool (Binding::*BindingFilter)() const;
|
||||
|
|
|
@ -58,10 +58,11 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
QQmlTypeCompiler::QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData,
|
||||
QmlIR::Document *parsedQML, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
|
||||
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache)
|
||||
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
|
||||
: resolvedTypes(resolvedTypeCache)
|
||||
, engine(engine)
|
||||
, typeData(typeData)
|
||||
, dependencyHasher(dependencyHasher)
|
||||
, typeNameCache(typeNameCache)
|
||||
, document(parsedQML)
|
||||
{
|
||||
|
@ -156,7 +157,7 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
|
|||
// Generate QML compiled type data structures
|
||||
|
||||
QmlIR::QmlUnitGenerator qmlGenerator;
|
||||
QV4::CompiledData::Unit *qmlUnit = qmlGenerator.generate(*document, QQmlEnginePrivate::get(engine), resolvedTypes);
|
||||
QV4::CompiledData::Unit *qmlUnit = qmlGenerator.generate(*document, dependencyHasher);
|
||||
|
||||
Q_ASSERT(document->javaScriptCompilationUnit);
|
||||
// The js unit owns the data and will free the qml unit.
|
||||
|
|
|
@ -89,7 +89,8 @@ struct QQmlTypeCompiler
|
|||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(QQmlTypeCompiler)
|
||||
public:
|
||||
QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
|
||||
QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document, const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache,
|
||||
const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
|
||||
|
||||
// --- interface used by QQmlPropertyCacheCreator
|
||||
typedef QmlIR::Object CompiledObject;
|
||||
|
@ -139,6 +140,7 @@ private:
|
|||
QList<QQmlError> errors;
|
||||
QQmlEnginePrivate *engine;
|
||||
QQmlTypeData *typeData;
|
||||
const QV4::CompiledData::DependentTypesHasher &dependencyHasher;
|
||||
QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
|
||||
QmlIR::Document *document;
|
||||
// index is string index of type name (use obj->inheritedTypeNameIndex)
|
||||
|
|
|
@ -331,10 +331,9 @@ void CompilationUnit::finalize(QQmlEnginePrivate *engine)
|
|||
totalObjectCount = objectCount;
|
||||
}
|
||||
|
||||
bool CompilationUnit::verifyChecksum(QQmlEngine *engine,
|
||||
const ResolvedTypeReferenceMap &dependentTypes) const
|
||||
bool CompilationUnit::verifyChecksum(const DependentTypesHasher &dependencyHasher) const
|
||||
{
|
||||
if (dependentTypes.isEmpty()) {
|
||||
if (!dependencyHasher) {
|
||||
for (size_t i = 0; i < sizeof(data->dependencyMD5Checksum); ++i) {
|
||||
if (data->dependencyMD5Checksum[i] != 0)
|
||||
return false;
|
||||
|
@ -342,7 +341,7 @@ bool CompilationUnit::verifyChecksum(QQmlEngine *engine,
|
|||
return true;
|
||||
}
|
||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||
if (!dependentTypes.addToHash(&hash, engine))
|
||||
if (!dependencyHasher(&hash))
|
||||
return false;
|
||||
QByteArray checksum = hash.result();
|
||||
Q_ASSERT(checksum.size() == sizeof(data->dependencyMD5Checksum));
|
||||
|
|
|
@ -787,8 +787,10 @@ struct ResolvedTypeReferenceMap: public QMap<int, ResolvedTypeReference*>
|
|||
{
|
||||
bool addToHash(QCryptographicHash *hash, QQmlEngine *engine) const;
|
||||
};
|
||||
|
||||
using DependentTypesHasher = std::function<bool(QCryptographicHash *)>;
|
||||
#else
|
||||
struct ResolvedTypeReferenceMap {};
|
||||
struct DependentTypesHasher {};
|
||||
#endif
|
||||
|
||||
// index is per-object binding index
|
||||
|
@ -861,8 +863,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public
|
|||
QVector<QQmlScriptData *> dependentScripts;
|
||||
ResolvedTypeReferenceMap resolvedTypes;
|
||||
|
||||
bool verifyChecksum(QQmlEngine *engine,
|
||||
const ResolvedTypeReferenceMap &dependentTypes) const;
|
||||
bool verifyChecksum(const DependentTypesHasher &dependencyHasher) const;
|
||||
|
||||
int metaTypeId;
|
||||
int listMetaTypeId;
|
||||
|
|
|
@ -85,7 +85,7 @@ DECLARE_HEAP_OBJECT(FunctionObject, Object) {
|
|||
unsigned int formalParameterCount() { return function ? function->nFormals : 0; }
|
||||
unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; }
|
||||
|
||||
const QV4::Object *protoProperty() const { return propertyData(Index_Prototype)->cast<QV4::Object>(); }
|
||||
const QV4::Object *protoProperty() const { return propertyData(Index_Prototype)->as<QV4::Object>(); }
|
||||
};
|
||||
|
||||
struct FunctionCtor : FunctionObject {
|
||||
|
|
|
@ -1751,6 +1751,8 @@ Bool Runtime::method_compareEqual(const Value &left, const Value &right)
|
|||
return !left.isNaN();
|
||||
|
||||
if (left.type() == right.type()) {
|
||||
if (left.isDouble() && left.doubleValue() == 0 && right.doubleValue() == 0)
|
||||
return true; // this takes care of -0 == +0 (which obviously have different raw values)
|
||||
if (!left.isManaged())
|
||||
return false;
|
||||
if (left.isString() == right.isString())
|
||||
|
|
|
@ -142,7 +142,7 @@ struct Q_QML_EXPORT Base {
|
|||
else if (_livenessStatus == Destroyed)
|
||||
fprintf(stderr, "ERROR: use of object '%s' after call to destroy() !!\n",
|
||||
vtable()->className);
|
||||
Q_ASSERT(_livenessStatus = Initialized);
|
||||
Q_ASSERT(_livenessStatus == Initialized);
|
||||
}
|
||||
void _checkIsDestroyed() {
|
||||
if (_livenessStatus == Initialized)
|
||||
|
|
|
@ -1525,7 +1525,8 @@ bool QQmlTypeLoader::Blob::qmldirDataAvailable(QQmlQmldirData *data, QList<QQmlE
|
|||
return false;
|
||||
}
|
||||
|
||||
*it = priority;
|
||||
if (it != m_unresolvedImports.end())
|
||||
*it = priority;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2005,6 +2006,16 @@ QQmlTypeData::TypeDataCallback::~TypeDataCallback()
|
|||
{
|
||||
}
|
||||
|
||||
QString QQmlTypeData::TypeReference::qualifiedName() const
|
||||
{
|
||||
QString result;
|
||||
if (!prefix.isEmpty()) {
|
||||
result = prefix + QLatin1Char('.');
|
||||
}
|
||||
result.append(type->qmlTypeName());
|
||||
return result;
|
||||
}
|
||||
|
||||
QQmlTypeData::QQmlTypeData(const QUrl &url, QQmlTypeLoader *manager)
|
||||
: QQmlTypeLoader::Blob(url, QmlFile, manager),
|
||||
m_typesResolved(false), m_implicitImportLoaded(false)
|
||||
|
@ -2150,6 +2161,23 @@ void QQmlTypeData::createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeName
|
|||
aliasCreator.appendAliasPropertiesToMetaObjects();
|
||||
}
|
||||
|
||||
static bool addTypeReferenceChecksumsToHash(const QList<QQmlTypeData::TypeReference> &typeRefs, QCryptographicHash *hash, QQmlEngine *engine)
|
||||
{
|
||||
for (const auto &typeRef: typeRefs) {
|
||||
if (typeRef.typeData) {
|
||||
const auto unit = typeRef.typeData->compilationUnit();
|
||||
hash->addData(unit->data->md5Checksum, sizeof(unit->data->md5Checksum));
|
||||
} else if (typeRef.type) {
|
||||
const auto propertyCache = QQmlEnginePrivate::get(engine)->cache(typeRef.type->metaObject());
|
||||
bool ok = false;
|
||||
hash->addData(propertyCache->checksum(&ok));
|
||||
if (!ok)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void QQmlTypeData::done()
|
||||
{
|
||||
QDeferredCleanup cleanup([this]{
|
||||
|
@ -2230,8 +2258,14 @@ void QQmlTypeData::done()
|
|||
|
||||
QQmlEngine *const engine = typeLoader()->engine();
|
||||
|
||||
const auto dependencyHasher = [engine, resolvedTypeCache, this](QCryptographicHash *hash) {
|
||||
if (!resolvedTypeCache.addToHash(hash, engine))
|
||||
return false;
|
||||
return ::addTypeReferenceChecksumsToHash(m_compositeSingletons, hash, engine);
|
||||
};
|
||||
|
||||
// verify if any dependencies changed if we're using a cache
|
||||
if (m_document.isNull() && !m_compiledData->verifyChecksum(engine, resolvedTypeCache)) {
|
||||
if (m_document.isNull() && !m_compiledData->verifyChecksum(dependencyHasher)) {
|
||||
qCDebug(DBG_DISK_CACHE) << "Checksum mismatch for cached version of" << m_compiledData->url().toString();
|
||||
if (!loadFromSource())
|
||||
return;
|
||||
|
@ -2241,7 +2275,7 @@ void QQmlTypeData::done()
|
|||
|
||||
if (!m_document.isNull()) {
|
||||
// Compile component
|
||||
compile(typeNameCache, resolvedTypeCache);
|
||||
compile(typeNameCache, resolvedTypeCache, dependencyHasher);
|
||||
} else {
|
||||
createTypeAndPropertyCaches(typeNameCache, resolvedTypeCache);
|
||||
}
|
||||
|
@ -2503,14 +2537,15 @@ QString QQmlTypeData::stringAt(int index) const
|
|||
return m_document->jsGenerator.stringTable.stringForIndex(index);
|
||||
}
|
||||
|
||||
void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache)
|
||||
void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache, const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache,
|
||||
const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
|
||||
{
|
||||
Q_ASSERT(m_compiledData.isNull());
|
||||
|
||||
const bool typeRecompilation = m_document && m_document->javaScriptCompilationUnit && m_document->javaScriptCompilationUnit->data->flags & QV4::CompiledData::Unit::PendingTypeCompilation;
|
||||
|
||||
QQmlEnginePrivate * const enginePrivate = QQmlEnginePrivate::get(typeLoader()->engine());
|
||||
QQmlTypeCompiler compiler(enginePrivate, this, m_document.data(), typeNameCache, resolvedTypeCache);
|
||||
QQmlTypeCompiler compiler(enginePrivate, this, m_document.data(), typeNameCache, resolvedTypeCache, dependencyHasher);
|
||||
m_compiledData = compiler.compile();
|
||||
if (!m_compiledData) {
|
||||
setError(compiler.compilationErrors());
|
||||
|
@ -2582,6 +2617,10 @@ void QQmlTypeData::resolveTypes()
|
|||
}
|
||||
}
|
||||
|
||||
std::stable_sort(m_compositeSingletons.begin(), m_compositeSingletons.end(), [](const TypeReference &lhs, const TypeReference &rhs){
|
||||
return lhs.qualifiedName() < rhs.qualifiedName();
|
||||
});
|
||||
|
||||
for (QV4::CompiledData::TypeReferenceMap::ConstIterator unresolvedRef = m_typeReferences.constBegin(), end = m_typeReferences.constEnd();
|
||||
unresolvedRef != end; ++unresolvedRef) {
|
||||
|
||||
|
@ -2920,8 +2959,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
|
|||
irUnit.jsModule.unitFlags |= QV4::CompiledData::Unit::IsSharedLibrary;
|
||||
|
||||
QmlIR::QmlUnitGenerator qmlGenerator;
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap emptyDependencies;
|
||||
QV4::CompiledData::Unit *unitData = qmlGenerator.generate(irUnit, m_typeLoader->engine(), emptyDependencies);
|
||||
QV4::CompiledData::Unit *unitData = qmlGenerator.generate(irUnit);
|
||||
Q_ASSERT(!unit->data);
|
||||
// The js unit owns the data and will free the qml unit.
|
||||
unit->data = unitData;
|
||||
|
|
|
@ -401,6 +401,7 @@ public:
|
|||
int minorVersion;
|
||||
QQmlTypeData *typeData;
|
||||
QString prefix; // used by CompositeSingleton types
|
||||
QString qualifiedName() const;
|
||||
bool needsCreation;
|
||||
};
|
||||
|
||||
|
@ -455,7 +456,7 @@ private:
|
|||
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache
|
||||
) const;
|
||||
void compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
|
||||
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
|
||||
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher);
|
||||
void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
|
||||
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
|
||||
bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref, int lineNumber = -1, int columnNumber = -1, bool reportErrors = true);
|
||||
|
|
|
@ -194,19 +194,15 @@
|
|||
/*!
|
||||
\fn const char *QSGSimpleMaterialShader::uniformMatrixName() const
|
||||
|
||||
Reimplement this function to give a different name to the uniform for
|
||||
item transformation. The default value is \c qt_Matrix.
|
||||
|
||||
Returns the name for the transform matrix uniform of this item.
|
||||
The default value is \c qt_Matrix.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn const char *QSGSimpleMaterialShader::uniformOpacityName() const
|
||||
|
||||
Reimplement this function to give a different name to the uniform for
|
||||
item opacity. The default value is \c qt_Opacity.
|
||||
|
||||
If the shader program does not implement the item opacity, the
|
||||
implemented function should return a null pointer.
|
||||
Returns the name for the opacity uniform of this item.
|
||||
The default value is \c qt_Opacity.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
resolveUniforms();
|
||||
}
|
||||
|
||||
// ### Qt 6: make both virtual and fix docs
|
||||
const char *uniformMatrixName() const { return "qt_Matrix"; }
|
||||
const char *uniformOpacityName() const { return "qt_Opacity"; }
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
CONFIG += testcase
|
||||
TARGET = tst_ecmascripttests
|
||||
QT += testlib
|
||||
macos:CONFIG -= app_bundle
|
||||
SOURCES += tst_ecmascripttests.cpp
|
||||
DEFINES += SRCDIR=\\\"$$PWD\\\"
|
||||
|
||||
TESTSCRIPT=$$PWD/test262.py
|
||||
isEmpty(V4CMD): V4CMD = qmljs
|
||||
|
||||
checkjittarget.target = check-jit
|
||||
checkjittarget.commands = python $$TESTSCRIPT --command=$$V4CMD --parallel --with-test-expectations --update-expectations
|
||||
checkjittarget.depends = all
|
||||
QMAKE_EXTRA_TARGETS += checkjittarget
|
||||
|
||||
checkmothtarget.target = check-interpreter
|
||||
checkmothtarget.commands = python $$TESTSCRIPT --command=\"$$V4CMD --interpret\" --parallel --with-test-expectations
|
||||
checkmothtarget.depends = all
|
||||
QMAKE_EXTRA_TARGETS += checkmothtarget
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit d60c4ed97e69639bc5bc1db43a98828debf80c8a
|
|
@ -555,6 +555,7 @@ class TestSuite(object):
|
|||
print
|
||||
if update_expectations:
|
||||
self.expectations.update(progress)
|
||||
return progress.failed == 0
|
||||
|
||||
def Print(self, tests):
|
||||
cases = self.EnumerateTests(tests)
|
||||
|
@ -567,6 +568,7 @@ def Main():
|
|||
# Uncomment the next line for more logging info.
|
||||
#logging.basicConfig(level=logging.DEBUG)
|
||||
os.environ["TZ"] = "PST8PDT"
|
||||
os.environ["LANG"] = "en_US.UTF-8"
|
||||
parser = BuildOptions()
|
||||
(options, args) = parser.parse_args()
|
||||
ValidateOptions(options)
|
||||
|
@ -578,18 +580,21 @@ def Main():
|
|||
test_suite.Validate()
|
||||
if options.cat:
|
||||
test_suite.Print(args)
|
||||
return 0
|
||||
else:
|
||||
test_suite.Run(options.command, args,
|
||||
options.summary or options.full_summary,
|
||||
options.full_summary,
|
||||
options.parallel,
|
||||
options.update_expectations)
|
||||
if test_suite.Run(options.command, args,
|
||||
options.summary or options.full_summary,
|
||||
options.full_summary,
|
||||
options.parallel,
|
||||
options.update_expectations):
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
Main()
|
||||
sys.exit(0)
|
||||
sys.exit(Main())
|
||||
except Test262Error, e:
|
||||
print "Error: %s" % e.message
|
||||
sys.exit(1)
|
|
@ -0,0 +1,77 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** 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 General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QProcess>
|
||||
#include <QLibraryInfo>
|
||||
|
||||
class tst_EcmaScriptTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void runTests_data();
|
||||
void runTests();
|
||||
};
|
||||
|
||||
void tst_EcmaScriptTests::runTests_data()
|
||||
{
|
||||
QTest::addColumn<QString>("qmljsParameter");
|
||||
|
||||
QTest::newRow("jit") << QStringLiteral("--jit");
|
||||
// Not passing yet: QTest::newRow("interpreter") << QStringLiteral("--interpret");
|
||||
}
|
||||
|
||||
void tst_EcmaScriptTests::runTests()
|
||||
{
|
||||
#if defined(Q_OS_LINUX) && defined(Q_PROCESSOR_X86_64)
|
||||
QFETCH(QString, qmljsParameter);
|
||||
|
||||
QProcess process;
|
||||
process.setProcessChannelMode(QProcess::ForwardedChannels);
|
||||
process.setWorkingDirectory(QLatin1String(SRCDIR));
|
||||
process.setProgram("python");
|
||||
process.setArguments(QStringList() << "test262.py" << "--command=" + QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmljs " + qmljsParameter << "--parallel" << "--with-test-expectations");
|
||||
|
||||
qDebug() << "Going to run" << process.program() << process.arguments() << "in" << process.workingDirectory();
|
||||
|
||||
process.start();
|
||||
QVERIFY(process.waitForStarted());
|
||||
const int timeoutInMSecs = 20 * 60 * 1000;
|
||||
QVERIFY2(process.waitForFinished(timeoutInMSecs), "Tests did not terminate in time -- see output above for details");
|
||||
QVERIFY2(process.exitStatus() == QProcess::NormalExit, "Running the test harness failed -- see output above for details");
|
||||
QVERIFY2(process.exitCode() == 0, "Tests failed -- see output above for details");
|
||||
#else
|
||||
QSKIP("Currently the ecmascript tests are only run on Linux/x86-64");
|
||||
#endif
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_EcmaScriptTests)
|
||||
|
||||
#include "tst_ecmascripttests.moc"
|
||||
|
|
@ -62,7 +62,8 @@ PRIVATETESTS += \
|
|||
qqmlimport \
|
||||
qqmlobjectmodel \
|
||||
qmldiskcache \
|
||||
qv4mm
|
||||
qv4mm \
|
||||
ecmascripttests
|
||||
|
||||
qtHaveModule(widgets) {
|
||||
PUBLICTESTS += \
|
||||
|
|
|
@ -58,6 +58,7 @@ private slots:
|
|||
void localAliases();
|
||||
void cacheResources();
|
||||
void stableOrderOfDependentCompositeTypes();
|
||||
void singletonDependency();
|
||||
};
|
||||
|
||||
// A wrapper around QQmlComponent to ensure the temporary reference counts
|
||||
|
@ -737,6 +738,58 @@ void tst_qmldiskcache::stableOrderOfDependentCompositeTypes()
|
|||
}
|
||||
}
|
||||
|
||||
void tst_qmldiskcache::singletonDependency()
|
||||
{
|
||||
QScopedPointer<QQmlEngine> engine(new QQmlEngine);
|
||||
|
||||
QTemporaryDir tempDir;
|
||||
QVERIFY(tempDir.isValid());
|
||||
|
||||
const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) {
|
||||
QFile f(tempDir.path() + '/' + fileName);
|
||||
const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||
Q_ASSERT(ok);
|
||||
f.write(contents);
|
||||
return f.fileName();
|
||||
};
|
||||
|
||||
writeTempFile("MySingleton.qml", "import QtQml 2.0\npragma Singleton\nQtObject { property int value: 42 }");
|
||||
writeTempFile("qmldir", "singleton MySingleton 1.0 MySingleton.qml");
|
||||
const QString testFilePath = writeTempFile("main.qml", "import QtQml 2.0\nimport \".\"\nQtObject {\n"
|
||||
" property int value: MySingleton.value\n"
|
||||
"}");
|
||||
|
||||
{
|
||||
CleanlyLoadingComponent component(engine.data(), QUrl::fromLocalFile(testFilePath));
|
||||
QScopedPointer<QObject> obj(component.create());
|
||||
QVERIFY(!obj.isNull());
|
||||
QCOMPARE(obj->property("value").toInt(), 42);
|
||||
}
|
||||
|
||||
const QString testFileCachePath = testFilePath + QLatin1Char('c');
|
||||
QVERIFY(QFile::exists(testFileCachePath));
|
||||
QDateTime initialCacheTimeStamp = QFileInfo(testFileCachePath).lastModified();
|
||||
|
||||
engine.reset(new QQmlEngine);
|
||||
waitForFileSystem();
|
||||
|
||||
writeTempFile("MySingleton.qml", "import QtQml 2.0\npragma Singleton\nQtObject { property int value: 100 }");
|
||||
waitForFileSystem();
|
||||
|
||||
{
|
||||
CleanlyLoadingComponent component(engine.data(), QUrl::fromLocalFile(testFilePath));
|
||||
QScopedPointer<QObject> obj(component.create());
|
||||
QVERIFY(!obj.isNull());
|
||||
QCOMPARE(obj->property("value").toInt(), 100);
|
||||
}
|
||||
|
||||
{
|
||||
QVERIFY(QFile::exists(testFileCachePath));
|
||||
QDateTime newCacheTimeStamp = QFileInfo(testFileCachePath).lastModified();
|
||||
QVERIFY2(newCacheTimeStamp > initialCacheTimeStamp, qPrintable(newCacheTimeStamp.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qmldiskcache)
|
||||
|
||||
#include "tst_qmldiskcache.moc"
|
||||
|
|
|
@ -84,6 +84,7 @@ void tst_qmlmin::initTestCase()
|
|||
excludedDirs << "doc/src/snippets/qtquick1/qtbinding";
|
||||
excludedDirs << "doc/src/snippets/qtquick1/imports";
|
||||
excludedDirs << "tests/manual/v4";
|
||||
excludedDirs << "tests/auto/qml/ecmascripttests";
|
||||
excludedDirs << "tests/auto/qml/qmllint";
|
||||
|
||||
// Add invalid files (i.e. files with syntax errors)
|
||||
|
|
|
@ -9,3 +9,4 @@ linux
|
|||
linux
|
||||
[ListView::test_listInteractiveCurrentIndexEnforce]
|
||||
linux
|
||||
macos-10.12
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 9741ac4655808ac46c127e3d1d8ba3d27ada618e
|
|
@ -1,15 +0,0 @@
|
|||
TEMPLATE = aux
|
||||
|
||||
TESTSCRIPT=$$PWD/test262.py
|
||||
isEmpty(V4CMD): V4CMD = qmljs
|
||||
|
||||
checktarget.target = check
|
||||
checktarget.commands = python $$TESTSCRIPT --command=$$V4CMD --parallel --with-test-expectations --update-expectations
|
||||
checktarget.depends = all
|
||||
QMAKE_EXTRA_TARGETS += checktarget
|
||||
|
||||
checkmothtarget.target = check-interpreter
|
||||
checkmothtarget.commands = python $$TESTSCRIPT --command=\"$$V4CMD --interpret\" --parallel --with-test-expectations
|
||||
checkmothtarget.depends = all
|
||||
QMAKE_EXTRA_TARGETS += checkmothtarget
|
||||
|
|
@ -180,9 +180,7 @@ static bool compileQmlFile(const QString &inputFileName, const QString &outputFi
|
|||
// Disable lookups in non-standalone (aka QML) mode
|
||||
isel->setUseFastLookups(false);
|
||||
irDocument.javaScriptCompilationUnit = isel->compile(/*generate unit*/false);
|
||||
// ###
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap dummyDependencies;
|
||||
QV4::CompiledData::Unit *unit = generator.generate(irDocument, /*engine*/nullptr, dummyDependencies);
|
||||
QV4::CompiledData::Unit *unit = generator.generate(irDocument);
|
||||
unit->flags |= QV4::CompiledData::Unit::StaticData;
|
||||
unit->flags |= QV4::CompiledData::Unit::PendingTypeCompilation;
|
||||
irDocument.javaScriptCompilationUnit->data = unit;
|
||||
|
@ -271,9 +269,7 @@ static bool compileJSFile(const QString &inputFileName, const QString &outputFil
|
|||
// Disable lookups in non-standalone (aka QML) mode
|
||||
isel->setUseFastLookups(false);
|
||||
irDocument.javaScriptCompilationUnit = isel->compile(/*generate unit*/false);
|
||||
// ###
|
||||
QV4::CompiledData::ResolvedTypeReferenceMap dummyDependencies;
|
||||
QV4::CompiledData::Unit *unit = generator.generate(irDocument, /*engine*/nullptr, dummyDependencies);
|
||||
QV4::CompiledData::Unit *unit = generator.generate(irDocument);
|
||||
unit->flags |= QV4::CompiledData::Unit::StaticData;
|
||||
irDocument.javaScriptCompilationUnit->data = unit;
|
||||
|
||||
|
|
Loading…
Reference in New Issue