Merge remote-tracking branch 'origin/5.9' into dev

Conflicts:
	src/qml/jsruntime/qv4functionobject_p.h

Change-Id: I4bbed45f1fe02cf64df3c8a5f92f811e38e772f3
This commit is contained in:
Simon Hausmann 2017-03-27 14:53:52 +02:00
commit e321dc6bee
27 changed files with 254 additions and 76 deletions

5
.gitmodules vendored
View File

@ -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

View File

@ -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.
*/
/*!

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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)

View File

@ -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));

View File

@ -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;

View File

@ -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 {

View File

@ -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())

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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.
*/
/*!

View File

@ -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"; }

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -62,7 +62,8 @@ PRIVATETESTS += \
qqmlimport \
qqmlobjectmodel \
qmldiskcache \
qv4mm
qv4mm \
ecmascripttests
qtHaveModule(widgets) {
PUBLICTESTS += \

View File

@ -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"

View File

@ -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)

View File

@ -9,3 +9,4 @@ linux
linux
[ListView::test_listInteractiveCurrentIndexEnforce]
linux
macos-10.12

@ -1 +0,0 @@
Subproject commit 9741ac4655808ac46c127e3d1d8ba3d27ada618e

View File

@ -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

View File

@ -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;