aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2017-03-27 14:53:52 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2017-03-27 14:53:52 +0200
commite321dc6bee3645e2492914f99fc30f8019e9383b (patch)
tree4e1c42ea70967e11bf6c4920397b2478bdc55e4c
parentd1c43e44572f5b554467e5f1c2db4914b549b569 (diff)
parente2863c80fed06104eedfe83bce2737f2d24908a6 (diff)
Merge remote-tracking branch 'origin/5.9' into dev
Conflicts: src/qml/jsruntime/qv4functionobject_p.h Change-Id: I4bbed45f1fe02cf64df3c8a5f92f811e38e772f3
-rw-r--r--.gitmodules5
-rw-r--r--examples/qml/doc/src/qml-extending.qdoc18
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp9
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h2
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp5
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h4
-rw-r--r--src/qml/compiler/qv4compileddata.cpp7
-rw-r--r--src/qml/compiler/qv4compileddata_p.h7
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp2
-rw-r--r--src/qml/memory/qv4heap_p.h2
-rw-r--r--src/qml/qml/qqmltypeloader.cpp52
-rw-r--r--src/qml/qml/qqmltypeloader_p.h3
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.cpp12
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.h1
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations (renamed from tests/manual/v4/TestExpectations)0
-rw-r--r--tests/auto/qml/ecmascripttests/ecmascripttests.pro20
m---------tests/auto/qml/ecmascripttests/test2620
-rwxr-xr-xtests/auto/qml/ecmascripttests/test262.py (renamed from tests/manual/v4/test262.py)19
-rw-r--r--tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp77
-rw-r--r--tests/auto/qml/qml.pro3
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp53
-rw-r--r--tests/auto/qml/qmlmin/tst_qmlmin.cpp1
-rw-r--r--tests/auto/qmltest/BLACKLIST1
m---------tests/manual/v4/test2620
-rw-r--r--tests/manual/v4/tests.pro15
-rw-r--r--tools/qmlcachegen/qmlcachegen.cpp8
27 files changed, 253 insertions, 75 deletions
diff --git a/.gitmodules b/.gitmodules
index 881629497e..c9561f396d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -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
diff --git a/examples/qml/doc/src/qml-extending.qdoc b/examples/qml/doc/src/qml-extending.qdoc
index b4174426a8..f99aca5457 100644
--- a/examples/qml/doc/src/qml-extending.qdoc
+++ b/examples/qml/doc/src/qml-extending.qdoc
@@ -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.
*/
/*!
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 18fccc8f43..218f5675dc 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -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
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index b579a963a1..64bf111d9a 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -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;
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 109eb86c2e..a3b8784fc8 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -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.
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index 2b59e7e42f..11261e3099 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -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)
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index edb5edb0bc..c56f08c2f0 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -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));
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 9c21d5e9ae..6e9121b5e3 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -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;
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index d375153058..d8929026ca 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -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 {
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 3b92096386..b28a5f9000 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -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())
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index 89e69fd9d6..1347a9bd6e 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -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)
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index eedb649ef6..f115d4227c 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -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;
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 1bd2c7f1e1..48e7d5cba4 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -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);
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp
index 7214a255df..f29c58ad9e 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.cpp
+++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp
@@ -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.
*/
/*!
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.h b/src/quick/scenegraph/util/qsgsimplematerial.h
index 0e7219d7bd..b5b8815b4a 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.h
+++ b/src/quick/scenegraph/util/qsgsimplematerial.h
@@ -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"; }
diff --git a/tests/manual/v4/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 27498de473..27498de473 100644
--- a/tests/manual/v4/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
diff --git a/tests/auto/qml/ecmascripttests/ecmascripttests.pro b/tests/auto/qml/ecmascripttests/ecmascripttests.pro
new file mode 100644
index 0000000000..6d3ee12307
--- /dev/null
+++ b/tests/auto/qml/ecmascripttests/ecmascripttests.pro
@@ -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
+
diff --git a/tests/auto/qml/ecmascripttests/test262 b/tests/auto/qml/ecmascripttests/test262
new file mode 160000
+Subproject d60c4ed97e69639bc5bc1db43a98828debf80c8
diff --git a/tests/manual/v4/test262.py b/tests/auto/qml/ecmascripttests/test262.py
index 3b5bfa119a..99f029cffd 100755
--- a/tests/manual/v4/test262.py
+++ b/tests/auto/qml/ecmascripttests/test262.py
@@ -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)
diff --git a/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp b/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp
new file mode 100644
index 0000000000..2ce0cfe210
--- /dev/null
+++ b/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp
@@ -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"
+
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index b347b603bb..a9b18e9f32 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -62,7 +62,8 @@ PRIVATETESTS += \
qqmlimport \
qqmlobjectmodel \
qmldiskcache \
- qv4mm
+ qv4mm \
+ ecmascripttests
qtHaveModule(widgets) {
PUBLICTESTS += \
diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
index 17aa6087d2..3402aeebc1 100644
--- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
+++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
@@ -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"
diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
index 90868d2ead..171c2bda8a 100644
--- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp
+++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
@@ -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)
diff --git a/tests/auto/qmltest/BLACKLIST b/tests/auto/qmltest/BLACKLIST
index c38347b42a..d324e9da5d 100644
--- a/tests/auto/qmltest/BLACKLIST
+++ b/tests/auto/qmltest/BLACKLIST
@@ -9,3 +9,4 @@ linux
linux
[ListView::test_listInteractiveCurrentIndexEnforce]
linux
+macos-10.12
diff --git a/tests/manual/v4/test262 b/tests/manual/v4/test262
deleted file mode 160000
-Subproject 9741ac4655808ac46c127e3d1d8ba3d27ada618
diff --git a/tests/manual/v4/tests.pro b/tests/manual/v4/tests.pro
deleted file mode 100644
index ce4a34f7a0..0000000000
--- a/tests/manual/v4/tests.pro
+++ /dev/null
@@ -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
-
diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp
index 657b1e8501..f24ec40184 100644
--- a/tools/qmlcachegen/qmlcachegen.cpp
+++ b/tools/qmlcachegen/qmlcachegen.cpp
@@ -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;