diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2012-03-23 14:31:47 +0100 |
---|---|---|
committer | Kent Hansen <kent.hansen@nokia.com> | 2012-03-23 14:31:47 +0100 |
commit | 0655209fdad022bd0f6eb20ce85522cb56506bf0 (patch) | |
tree | cdba0c1590655f5cb75a68cedff74f8a683db3a2 /src/qml/qml | |
parent | c3babc03c99c6ca5fa210486e133eb456a405bab (diff) | |
parent | 3d8f103c2641f35e7681485102a1b59886db8934 (diff) |
Merge master into api_changes
Conflicts:
src/qml/qml/qqmlboundsignal.cpp
src/qml/qml/qqmlpropertycache.cpp
Change-Id: I5193a193fa301c0b518291645bf626a5fa07118f
Diffstat (limited to 'src/qml/qml')
33 files changed, 223 insertions, 72 deletions
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h index f575285ff6..f058f21e98 100644 --- a/src/qml/qml/ftw/qhashedstring_p.h +++ b/src/qml/qml/ftw/qhashedstring_p.h @@ -59,6 +59,10 @@ #include <private/qflagpointer_p.h> +#if defined(Q_OS_QNX) +#include <stdlib.h> +#endif + QT_BEGIN_NAMESPACE // Enable this to debug hash linking assumptions. diff --git a/src/qml/qml/ftw/qqmlpool.cpp b/src/qml/qml/ftw/qqmlpool.cpp index 6fd11d4b1e..64df87ada5 100644 --- a/src/qml/qml/ftw/qqmlpool.cpp +++ b/src/qml/qml/ftw/qqmlpool.cpp @@ -41,6 +41,10 @@ #include "qqmlpool_p.h" +#ifdef Q_OS_QNX +#include <malloc.h> +#endif + // #define POOL_DEBUG QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlaccessors_p.h b/src/qml/qml/qqmlaccessors_p.h index a603bede9f..8e67a58511 100644 --- a/src/qml/qml/qqmlaccessors_p.h +++ b/src/qml/qml/qqmlaccessors_p.h @@ -47,6 +47,10 @@ #include <QtCore/qhash.h> #include <QtCore/QReadWriteLock> +#ifdef Q_OS_QNX +#include <stdint.h> +#endif + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index f43822ed0e..c4f48ef63d 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -193,8 +193,6 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags) if (!updatingFlag()) { QQmlBindingProfiler prof(m_url, m_lineNumber, m_columnNumber); - if (prof.enabled) - prof.addDetail(expression()); setUpdatingFlag(true); QQmlAbstractExpression::DeleteWatcher watcher(this); diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index aa130d9493..f7d0c00a5c 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -174,13 +174,7 @@ int QQmlBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a) if (QQmlDebugService::isDebuggingEnabled()) QV8DebugService::instance()->signalEmitted(QString::fromAscii(m_signal.methodSignature().constData())); - QQmlHandlingSignalProfiler prof; - if (prof.enabled) { - prof.setSignalInfo(QString::fromLatin1(m_signal.methodSignature().constData()), - m_expression->expression()); - prof.setLocation(m_expression->sourceFile(), m_expression->lineNumber(), - m_expression->columnNumber()); - } + QQmlHandlingSignalProfiler prof(m_signal, m_expression); m_isEvaluating = true; if (!m_paramsValid) { @@ -233,7 +227,10 @@ QQmlBoundSignalParameters::QQmlBoundSignalParameters(const QMetaMethod &method, prop.setWritable(false); } else { QByteArray propType = type; - if (t >= int(QVariant::UserType) || t == QMetaType::UnknownType || t == QMetaType::Void) { + if ((QMetaType::typeFlags(t) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration) { + t = QVariant::Int; + propType = "int"; + } else if (t == QMetaType::UnknownType) { QByteArray scope; QByteArray name; int scopeIdx = propType.lastIndexOf("::"); diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp index c3b8152ce1..dec9911481 100644 --- a/src/qml/qml/qqmlcompiler.cpp +++ b/src/qml/qml/qqmlcompiler.cpp @@ -2217,7 +2217,7 @@ bool QQmlCompiler::buildValueTypeProperty(QObject *type, //optimization for <Type>.<EnumValue> enum assignments bool isEnumAssignment = false; - if (prop->core.isEnum()) + if (prop->core.isEnum() || prop->core.propType == QMetaType::Int) COMPILE_CHECK(testQualifiedEnumAssignment(prop, obj, value, &isEnumAssignment)); if (isEnumAssignment) { @@ -2485,7 +2485,7 @@ bool QQmlCompiler::buildPropertyLiteralAssignment(QQmlScript::Property *prop, if (v->value.isScript()) { //optimization for <Type>.<EnumValue> enum assignments - if (prop->core.isEnum()) { + if (prop->core.isEnum() || prop->core.propType == QMetaType::Int) { bool isEnumAssignment = false; COMPILE_CHECK(testQualifiedEnumAssignment(prop, obj, v, &isEnumAssignment)); if (isEnumAssignment) { @@ -2515,8 +2515,9 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop, QQmlScript::Value *v, bool *isAssignment) { + bool isIntProp = (prop->core.propType == QMetaType::Int) && !prop->core.isEnum(); *isAssignment = false; - if (!prop->core.isEnum()) + if (!prop->core.isEnum() && !isIntProp) return true; QMetaProperty mprop = obj->metaObject()->property(prop->index); @@ -2528,6 +2529,17 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop, if (!string.at(0).isUpper()) return true; + if (isIntProp) { + // Allow enum assignment to ints. + int enumval = evaluateEnum(string.toUtf8()); + if (enumval != -1) { + v->type = Value::Literal; + v->value = QQmlScript::Variant((double)enumval); + *isAssignment = true; + } + return true; + } + QStringList parts = string.split(QLatin1Char('.')); if (parts.count() != 2) return true; diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 6cd5cf6cec..416178e3e1 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -829,7 +829,10 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context) if (rv) { QQmlData *ddata = QQmlData::get(rv); Q_ASSERT(ddata); + //top level objects should never get JS ownership. + //if JS ownership is needed this needs to be explicitly undone (like in component.createObject()) ddata->indestructible = true; + ddata->explicitIndestructibleSet = true; } if (enginePriv->isDebugging && rv) { @@ -1120,7 +1123,8 @@ void QQmlComponent::createObject(QQmlV8Function *args) d->completeCreate(); Q_ASSERT(QQmlData::get(rv)); - QQmlData::get(rv)->setImplicitDestructible(); + QQmlData::get(rv)->explicitIndestructibleSet = false; + QQmlData::get(rv)->indestructible = false; if (!rv) args->returnValue(v8::Null()); @@ -1255,10 +1259,6 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(v8::Handle<v8:: v8::Handle<v8::Value> args[] = { object, valuemap }; v8::Handle<v8::Function>::Cast(function)->Call(v8engine->global(), 2, args); } - - QQmlData *ddata = QQmlData::get(toCreate); - Q_ASSERT(ddata); - ddata->setImplicitDestructible(); } diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h index d10543bde5..97bc04b91d 100644 --- a/src/qml/qml/qqmlcontext_p.h +++ b/src/qml/qml/qqmlcontext_p.h @@ -146,7 +146,7 @@ public: quint32 isJSContext:1; quint32 isPragmaLibraryContext:1; quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name - quint32 dummy:28; + quint32 dummy:27; QQmlContext *publicContext; // VME data that is constructing this context if any diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qml/qqmldirparser.cpp index 7b99214f04..df5f7f8ee9 100644 --- a/src/qml/qml/qqmldirparser.cpp +++ b/src/qml/qml/qqmldirparser.cpp @@ -295,4 +295,18 @@ QList<QQmlDirParser::TypeInfo> QQmlDirParser::typeInfos() const } #endif +QDebug &operator<< (QDebug &debug, const QQmlDirParser::Component &component) +{ + return debug << qPrintable(QString("{%1 %2.%3}").arg(component.typeName) + .arg(component.majorVersion) + .arg(component.minorVersion)); +} + +QDebug &operator<< (QDebug &debug, const QQmlDirParser::Script &script) +{ + return debug << qPrintable(QString("{%1 %2.%3}").arg(script.nameSpace) + .arg(script.majorVersion) + .arg(script.minorVersion)); +} + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmldirparser_p.h b/src/qml/qml/qqmldirparser_p.h index 8c681309ac..f46e1781da 100644 --- a/src/qml/qml/qqmldirparser_p.h +++ b/src/qml/qml/qqmldirparser_p.h @@ -55,6 +55,7 @@ #include <QtCore/QUrl> #include <QtCore/QHash> +#include <QtCore/QDebug> QT_BEGIN_NAMESPACE @@ -160,6 +161,8 @@ private: typedef QList<QQmlDirParser::Component> QQmlDirComponents; typedef QList<QQmlDirParser::Script> QQmlDirScripts; +QDebug &operator<< (QDebug &, const QQmlDirParser::Component &); +QDebug &operator<< (QDebug &, const QQmlDirParser::Script &); QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp index b69fa5da7a..86d9f9588d 100644 --- a/src/qml/qml/qqmlextensionplugin.cpp +++ b/src/qml/qml/qqmlextensionplugin.cpp @@ -97,7 +97,7 @@ QT_BEGIN_NAMESPACE \code TEMPLATE = lib CONFIG += qt plugin - QT += declarative + QT += qml DESTDIR = com/nokia/TimeExample TARGET = qmlqtimeexampleplugin diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 0c1fb3bd93..1224efdaac 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -117,7 +117,7 @@ public: QList<QQmlError> *errors); QString resolvedUri(const QString &dir_arg, QQmlImportDatabase *database); - bool add(const QQmlDirComponents &qmldircomponentsnetwork, + QString add(const QQmlDirComponents &qmldircomponentsnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QQmlScript::Import::Type importType, QQmlImportDatabase *database, QList<QQmlError> *errors); @@ -493,7 +493,7 @@ QString QQmlImportsPrivate::resolvedUri(const QString &dir_arg, QQmlImportDataba return stableRelativePath; } -bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, +QString QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, const QString& uri_arg, const QString& prefix, int vmaj, int vmin, QQmlScript::Import::Type importType, QQmlImportDatabase *database, QList<QQmlError> *errors) @@ -540,7 +540,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, url = QUrl::fromLocalFile(fi.absolutePath()).toString(); uri = resolvedUri(dir, database); if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors)) - return false; + return QString(); break; } } @@ -564,7 +564,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, url = QUrl::fromLocalFile(fi.absolutePath()).toString(); uri = resolvedUri(dir, database); if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors)) - return false; + return QString(); break; } } @@ -586,7 +586,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, url = QUrl::fromLocalFile(absolutePath).toString(); uri = resolvedUri(dir, database); if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors)) - return false; + return QString(); break; } } @@ -604,7 +604,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, error.setDescription(QQmlImportDatabase::tr("module \"%1\" is not installed").arg(uri_arg)); errors->prepend(error); } - return false; + return QString(); } } else { if (importType == QQmlScript::Import::File && qmldircomponents.isEmpty()) { @@ -619,14 +619,14 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, error.setUrl(QUrl(importUrl)); errors->prepend(error); } - return false; // local import dirs must exist + return QString(); // local import dirs must exist } uri = resolvedUri(dir, database); if (uri.endsWith(Slash)) uri.chop(1); if (!typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) { if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,&qmldirscripts,errors)) - return false; + return QString(); } } else { if (prefix.isEmpty()) { @@ -642,7 +642,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, error.setUrl(QUrl(importUrl)); errors->prepend(error); } - return false; + return QString(); } } } @@ -669,7 +669,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin)); errors->prepend(error); } - return false; + return QString(); } } @@ -686,7 +686,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, QQmlError error; error.setDescription(QQmlImportDatabase::tr("\"%1\" is ambiguous. Found in %2 and in %3").arg(uri).arg(url).arg(it->url)); errors->prepend(error); - return false; + return QString(); } } @@ -716,7 +716,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork, s->imports.prepend(data); - return true; + return data.url; } bool QQmlImportsPrivate::find(const QString& type, int *vmajor, int *vminor, QQmlType** type_return, @@ -874,9 +874,11 @@ QQmlImportDatabase::~QQmlImportDatabase() The \a prefix may be empty, in which case the import location is considered for unqualified types. + Returns the resolved URL of the import on success. + The base URL must already have been set with Import::setBaseUrl(). */ -bool QQmlImports::addImport(QQmlImportDatabase *importDb, +QString QQmlImports::addImport(QQmlImportDatabase *importDb, const QString& uri, const QString& prefix, int vmaj, int vmin, QQmlScript::Import::Type importType, const QQmlDirComponents &qmldircomponentsnetwork, diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h index ff19510525..422f2429a0 100644 --- a/src/qml/qml/qqmlimport_p.h +++ b/src/qml/qml/qqmlimport_p.h @@ -93,7 +93,7 @@ public: QQmlType** type_return, QString* url_return, int *version_major, int *version_minor) const; - bool addImport(QQmlImportDatabase *, + QString addImport(QQmlImportDatabase *, const QString& uri, const QString& prefix, int vmaj, int vmin, QQmlScript::Import::Type importType, const QQmlDirComponents &qmldircomponentsnetwork, diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp index aa9777d89e..fad2ae2f28 100644 --- a/src/qml/qml/qqmlincubator.cpp +++ b/src/qml/qml/qqmlincubator.cpp @@ -293,8 +293,9 @@ void QQmlIncubatorPrivate::incubate(QQmlVME::Interrupt &i) if (result) { QQmlData *ddata = QQmlData::get(result); Q_ASSERT(ddata); + //see QQmlComponent::beginCreate for explanation of indestructible ddata->indestructible = true; - + ddata->explicitIndestructibleSet = true; q->setInitialState(result); } diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 5b80f57d01..4af08c28bf 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -512,7 +512,7 @@ QObject *QQmlType::create() const d->m_newFunc(rv); if (rv && !d->m_metaObjects.isEmpty()) - (void *)new QQmlProxyMetaObject(rv, &d->m_metaObjects); + (void)new QQmlProxyMetaObject(rv, &d->m_metaObjects); return rv; } @@ -525,7 +525,7 @@ void QQmlType::create(QObject **out, void **memory, size_t additionalMemory) con d->m_newFunc(rv); if (rv && !d->m_metaObjects.isEmpty()) - (void *)new QQmlProxyMetaObject(rv, &d->m_metaObjects); + (void)new QQmlProxyMetaObject(rv, &d->m_metaObjects); *out = rv; *memory = ((char *)rv) + d->m_allocationSize; diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index afab665ea4..4a1eb79213 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -674,7 +674,13 @@ QStringList QQmlPropertyCache::propertyNames() const return keys; } -static int EnumType(const QMetaObject *meta, const QByteArray &str) +struct StaticQtMetaObject : public QObject +{ + static const QMetaObject *get() + { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; } +}; + +static int EnumType(const QMetaObject *metaobj, const QByteArray &str) { QByteArray scope; QByteArray name; @@ -685,6 +691,11 @@ static int EnumType(const QMetaObject *meta, const QByteArray &str) } else { name = str; } + const QMetaObject *meta; + if (scope == "Qt") + meta = StaticQtMetaObject::get(); + else + meta = metaobj; for (int i = meta->enumeratorCount() - 1; i >= 0; --i) { QMetaEnum m = meta->enumerator(i); if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope))) @@ -727,12 +738,14 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index, for (int ii = 0; ii < argc; ++ii) { int type = m.parameterType(ii); - if (type == QVariant::Invalid) { + if ((QMetaType::typeFlags(type) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration) + type = QVariant::Int; + else if (type == QMetaType::UnknownType) { if (argTypeNames.isEmpty()) argTypeNames = m.parameterTypes(); type = EnumType(object->metaObject(), argTypeNames.at(ii)); } - if (type == QVariant::Invalid) { + if (type == QMetaType::UnknownType) { if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii); free(args); return 0; @@ -754,12 +767,14 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index, for (int ii = 0; ii < argc; ++ii) { int type = m.parameterType(ii); - if (type == QVariant::Invalid) { + if ((QMetaType::typeFlags(type) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration) + type = QVariant::Int; + else if (type == QMetaType::UnknownType) { if (argTypeNames.isEmpty()) argTypeNames = m.parameterTypes(); type = EnumType(object->metaObject(), argTypeNames.at(ii)); } - if (type == QVariant::Invalid) { + if (type == QMetaType::UnknownType) { if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii); return 0; } diff --git a/src/qml/qml/qqmlstringconverters.cpp b/src/qml/qml/qqmlstringconverters.cpp index 473097fab0..04b63ea7cd 100644 --- a/src/qml/qml/qqmlstringconverters.cpp +++ b/src/qml/qml/qqmlstringconverters.cpp @@ -128,6 +128,9 @@ QDateTime QQmlStringConverters::dateTimeFromString(const QString &s, bool *ok) { QDateTime d = QDateTime::fromString(s, Qt::ISODate); if (ok) *ok = d.isValid(); + // V8 never parses a date string as local time. For consistency do the same here. + if (d.timeSpec() == Qt::LocalTime) + d.setTimeSpec(Qt::UTC); return d; } #endif // QT_NO_DATESTRING diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 781915e23e..abe2c0bfa4 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -1558,7 +1558,6 @@ void QQmlTypeData::dataReceived(const QByteArray &data) ref.qualifier = import.qualifier; ref.script = blob; m_scripts << ref; - } } @@ -1657,8 +1656,8 @@ void QQmlTypeData::resolveTypes() import.extractVersion(&vmaj, &vmin); QList<QQmlError> errors; - if (!m_imports.addImport(importDatabase, import.uri, import.qualifier, - vmaj, vmin, import.type, qmldircomponentsnetwork, &errors)) { + if (m_imports.addImport(importDatabase, import.uri, import.qualifier, vmaj, vmin, + import.type, qmldircomponentsnetwork, &errors).isNull()) { QQmlError error; if (errors.size()) { error = errors.takeFirst(); @@ -1859,8 +1858,9 @@ void QQmlScriptBlob::dataReceived(const QByteArray &data) import.extractVersion(&vmaj, &vmin); QList<QQmlError> errors; - if (!m_imports.addImport(importDatabase, import.uri, import.qualifier, vmaj, vmin, - import.type, QQmlDirComponents(), &errors)) { + QString importUrl = m_imports.addImport(importDatabase, import.uri, import.qualifier, vmaj, vmin, + import.type, QQmlDirComponents(), &errors); + if (importUrl.isNull()) { QQmlError error = errors.takeFirst(); // description should be set by addImport(). error.setUrl(m_imports.baseUrl()); @@ -1871,6 +1871,22 @@ void QQmlScriptBlob::dataReceived(const QByteArray &data) setError(errors); return; } + + // Does this library contain any scripts? + QUrl libraryUrl(importUrl); + const QQmlDirParser *dirParser = typeLoader()->qmlDirParser(libraryUrl.path() + QLatin1String("qmldir")); + foreach (const QQmlDirParser::Script &script, dirParser->scripts()) { + QUrl scriptUrl = libraryUrl.resolved(QUrl(script.fileName)); + QQmlScriptBlob *blob = typeLoader()->getScript(scriptUrl); + addDependency(blob); + + ScriptReference ref; + ref.location = import.location.start; + ref.qualifier = script.nameSpace; + ref.nameSpace = import.qualifier; + ref.script = blob; + m_scripts << ref; + } } } } @@ -1902,11 +1918,20 @@ void QQmlScriptBlob::done() m_scriptData->urlString = finalUrlString(); m_scriptData->importCache = new QQmlTypeNameCache(); - for (int ii = 0; !isError() && ii < m_scripts.count(); ++ii) { - const ScriptReference &script = m_scripts.at(ii); + QSet<QString> ns; + + for (int scriptIndex = 0; !isError() && scriptIndex < m_scripts.count(); ++scriptIndex) { + const ScriptReference &script = m_scripts.at(scriptIndex); m_scriptData->scripts.append(script.script); - m_scriptData->importCache->add(script.qualifier, ii); + + if (!script.nameSpace.isNull()) { + if (!ns.contains(script.nameSpace)) { + ns.insert(script.nameSpace); + m_scriptData->importCache->add(script.nameSpace); + } + } + m_scriptData->importCache->add(script.qualifier, scriptIndex, script.nameSpace); } m_imports.populateCache(m_scriptData->importCache, engine); diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index c8c2756bd5..319b2e7a10 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -390,6 +390,7 @@ public: QQmlScript::Location location; QString qualifier; + QString nameSpace; QQmlScriptBlob *script; }; diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index 6309335e59..352684ed5e 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -829,7 +829,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, bindValues.push(binding); binding->m_mePtr = &bindValues.top(); - Q_ASSERT(binding->propertyIndex() == property); + Q_ASSERT(binding->propertyIndex() == (property & 0xFF00FFFF)); Q_ASSERT(binding->object() == target); binding->addToObject(); diff --git a/src/qml/qml/qqmlwatcher.cpp b/src/qml/qml/qqmlwatcher.cpp index 500185762f..4eaa3d2c2a 100644 --- a/src/qml/qml/qqmlwatcher.cpp +++ b/src/qml/qml/qqmlwatcher.cpp @@ -166,13 +166,14 @@ bool QQmlWatcher::addWatch(int id, quint32 objectId, const QString &expr) return false; } -void QQmlWatcher::removeWatch(int id) +bool QQmlWatcher::removeWatch(int id) { if (!m_proxies.contains(id)) - return; + return false; QList<QPointer<QQmlWatchProxy> > proxies = m_proxies.take(id); qDeleteAll(proxies); + return true; } void QQmlWatcher::addPropertyWatch(int id, QObject *object, quint32 debugId, const QMetaProperty &property) diff --git a/src/qml/qml/qqmlwatcher_p.h b/src/qml/qml/qqmlwatcher_p.h index 70dc9d468c..3ca2c83777 100644 --- a/src/qml/qml/qqmlwatcher_p.h +++ b/src/qml/qml/qqmlwatcher_p.h @@ -77,7 +77,7 @@ public: bool addWatch(int id, quint32 objectId, const QByteArray &property); bool addWatch(int id, quint32 objectId, const QString &expr); - void removeWatch(int id); + bool removeWatch(int id); Q_SIGNALS: void propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index df1712976c..56743eb915 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1384,7 +1384,7 @@ void QQmlXMLHttpRequest::readEncoding() if (header.first == "content-type") { int separatorIdx = header.second.indexOf(';'); if (separatorIdx == -1) { - m_mime == header.second; + m_mime = header.second; } else { m_mime = header.second.mid(0, separatorIdx); int charsetIdx = header.second.indexOf("charset="); diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp index 38a3acafa2..0cd6ffd082 100644 --- a/src/qml/qml/v4/qv4bindings.cpp +++ b/src/qml/qml/v4/qv4bindings.cpp @@ -1153,6 +1153,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, } QML_V4_END_INSTR(ConvertColorToString, unaryop) + QML_V4_BEGIN_INSTR(ConvertObjectToBool, unaryop) + { + const Register &src = registers[instr->unaryop.src]; + Register &output = registers[instr->unaryop.output]; + // ### NaN + if (src.isUndefined()) + output.setUndefined(); + else + output.setbool(src.getQObject() != 0); + } + QML_V4_END_INSTR(ConvertObjectToBool, unaryop) + + QML_V4_BEGIN_INSTR(ConvertNullToObject, unaryop) + { + Register &output = registers[instr->unaryop.output]; + output.setQObject(0); + } + QML_V4_END_INSTR(ConvertNullToObject, unaryop) + QML_V4_BEGIN_INSTR(ResolveUrl, unaryop) { const Register &src = registers[instr->unaryop.src]; diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp index 09b0f3861b..c9495e8987 100644 --- a/src/qml/qml/v4/qv4compiler.cpp +++ b/src/qml/qml/v4/qv4compiler.cpp @@ -54,7 +54,6 @@ QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP) DEFINE_BOOL_CONFIG_OPTION(qmlDisableOptimizer, QML_DISABLE_OPTIMIZER) -DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL) DEFINE_BOOL_CONFIG_OPTION(qmlVerboseCompiler, QML_VERBOSE_COMPILER) DEFINE_BOOL_CONFIG_OPTION(qmlBindingsTestEnv, QML_BINDINGS_TEST) @@ -958,6 +957,7 @@ void QV4CompilerPrivate::visitMove(IR::Move *s) case IR::StringType: opcode = V4Instr::ConvertStringToBool; break; case IR::UrlType: opcode = V4Instr::ConvertUrlToBool; break; case IR::ColorType: opcode = V4Instr::ConvertColorToBool; break; + case IR::ObjectType: opcode = V4Instr::ConvertObjectToBool; break; default: break; } // switch } else if (targetTy == IR::IntType) { @@ -1010,6 +1010,11 @@ void QV4CompilerPrivate::visitMove(IR::Move *s) case IR::StringType: opcode = V4Instr::ConvertStringToColor; break; default: break; } // switch + } else if (targetTy == IR::ObjectType) { + switch (sourceTy) { + case IR::NullType: opcode = V4Instr::ConvertNullToObject; break; + default: break; + } // switch } if (opcode != V4Instr::Noop) { V4Instr conv; @@ -1354,9 +1359,6 @@ int QV4Compiler::compile(const Expression &expression, QQmlEnginePrivate *engine { if (!expression.expression.asAST()) return false; - if (!qmlExperimental() && expression.property->isValueTypeSubProperty) - return -1; - if (qmlDisableOptimizer() || !qmlEnableV4) return -1; diff --git a/src/qml/qml/v4/qv4instruction.cpp b/src/qml/qml/v4/qv4instruction.cpp index 1ed8bd245e..cb6ff40589 100644 --- a/src/qml/qml/v4/qv4instruction.cpp +++ b/src/qml/qml/v4/qv4instruction.cpp @@ -189,6 +189,12 @@ void Bytecode::dump(const V4Instr *i, int address) const case V4Instr::ConvertColorToString: INSTR_DUMP << "\t" << "ConvertColorToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; + case V4Instr::ConvertObjectToBool: + INSTR_DUMP << "\t" << "ConvertObjectToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + break; + case V4Instr::ConvertNullToObject: + INSTR_DUMP << "\t" << "ConvertNullToObject" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; + break; case V4Instr::ResolveUrl: INSTR_DUMP << "\t" << "ResolveUrl" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")"; break; diff --git a/src/qml/qml/v4/qv4instruction_p.h b/src/qml/qml/v4/qv4instruction_p.h index d6c790e46f..239cb362cc 100644 --- a/src/qml/qml/v4/qv4instruction_p.h +++ b/src/qml/qml/v4/qv4instruction_p.h @@ -98,6 +98,8 @@ QT_BEGIN_NAMESPACE F(ConvertUrlToString, unaryop) \ F(ConvertColorToBool, unaryop) \ F(ConvertColorToString, unaryop) \ + F(ConvertObjectToBool, unaryop) \ + F(ConvertNullToObject, unaryop) \ F(ResolveUrl, unaryop) \ F(MathSinReal, unaryop) \ F(MathCosReal, unaryop) \ diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp index 481b23eb4a..ea4d1afbbc 100644 --- a/src/qml/qml/v4/qv4irbuilder.cpp +++ b/src/qml/qml/v4/qv4irbuilder.cpp @@ -428,7 +428,7 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast) if (r.isValid()) { if (r.type) { _expr.code = _block->ATTACH_TYPE(name, r.type, IR::Name::ScopeStorage, line, column); - } else if (r.importNamespace) { + } /*else if (r.importNamespace) { QQmlMetaType::ModuleApiInstance *moduleApi = m_expression->importCache->moduleApi(r.importNamespace); if (moduleApi) { if (moduleApi->qobjectCallback) { @@ -439,7 +439,7 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast) if (moduleApi->qobjectApi) _expr.code = _block->MODULE_OBJECT(name, moduleApi->qobjectApi->metaObject(), IR::Name::MemberStorage, line, column); } - } + }*/ //### we can't create the actual QObject here, as we may be running in a thread (can be reenabled once QTBUG-24894 is handled) // We don't support anything else } else { bool found = false; diff --git a/src/qml/qml/v8/qjsconverter_impl_p.h b/src/qml/qml/v8/qjsconverter_impl_p.h index 10b8ab5fae..c2775df7f5 100644 --- a/src/qml/qml/v8/qjsconverter_impl_p.h +++ b/src/qml/qml/v8/qjsconverter_impl_p.h @@ -44,6 +44,10 @@ #ifndef QJSCONVERTER_IMPL_P_H #define QJSCONVERTER_IMPL_P_H +#ifdef Q_OS_QNX +#include <malloc.h> +#endif + QT_BEGIN_NAMESPACE extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **digits_str); diff --git a/src/qml/qml/v8/qjsvalue.cpp b/src/qml/qml/v8/qjsvalue.cpp index 4471e68a61..6ecb97d2e5 100644 --- a/src/qml/qml/v8/qjsvalue.cpp +++ b/src/qml/qml/v8/qjsvalue.cpp @@ -428,7 +428,7 @@ quint32 QJSValue::toUInt() const \table \header \li Input Type \li Result \row \li Undefined \li An invalid QVariant. - \row \li Null \li An invalid QVariant. + \row \li Null \li A QVariant containing a null pointer (QMetaType::VoidStar). \row \li Boolean \li A QVariant containing the value of the boolean. \row \li Number \li A QVariant containing the value of the number. \row \li String \li A QVariant containing the value of the string. diff --git a/src/qml/qml/v8/qjsvalue_impl_p.h b/src/qml/qml/v8/qjsvalue_impl_p.h index fbddcfa5ba..8d22204843 100644 --- a/src/qml/qml/v8/qjsvalue_impl_p.h +++ b/src/qml/qml/v8/qjsvalue_impl_p.h @@ -281,7 +281,7 @@ QVariant QJSValuePrivate::toVariant() const case CNumber: return QVariant(u.m_number); case CNull: - return QVariant(); + return QVariant(QMetaType::VoidStar, 0); case CUndefined: return QVariant(); case JSValue: diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 0cd5d0ad6c..9c570d756b 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1061,7 +1061,9 @@ v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args) QObject *obj = component.beginCreate(effectiveContext); if (obj) { - QQmlData::get(obj, true)->setImplicitDestructible(); + QQmlData::get(obj, true)->explicitIndestructibleSet = false; + QQmlData::get(obj)->indestructible = false; + obj->setParent(parentArg); @@ -1084,7 +1086,7 @@ v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args) } /*! -\qmlmethod object Qt::createComponent(url, mode) +\qmlmethod object Qt::createComponent(url, mode, parent) Returns a \l Component object created using the QML file at the specified \a url, or \c null if an empty string was given. @@ -1099,6 +1101,9 @@ will be \c Component.Loading while it is loading. The status will change to \c Component.Ready if the component loads successfully, or \c Component.Error if loading fails. +If the optional \a parent parameter is given, it should refer to the object +that will become the parent for the created \l Component object. + Call \l {Component::createObject()}{Component.createObject()} on the returned component to create an object instance of the component. @@ -1114,7 +1119,8 @@ use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}. v8::Handle<v8::Value> createComponent(const v8::Arguments &args) { const char *invalidArgs = "Qt.createComponent(): Invalid arguments"; - if (args.Length() < 1 || args.Length() > 2) + const char *invalidParent = "Qt.createComponent(): Invalid parent object"; + if (args.Length() < 1 || args.Length() > 3) V8THROW_ERROR(invalidArgs); QV8Engine *v8engine = V8ENGINE(); @@ -1131,21 +1137,46 @@ v8::Handle<v8::Value> createComponent(const v8::Arguments &args) return v8::Null(); QQmlComponent::CompilationMode compileMode = QQmlComponent::PreferSynchronous; - if (args.Length() == 2) { + + // Default to engine parent; this will be removed in the near future (QTBUG-24841) + QObject *parentArg = engine; + + unsigned consumedCount = 1; + if (args.Length() > 1) { + const v8::Local<v8::Value> &lastArg = args[args.Length()-1]; + + // The second argument could be the mode enum if (args[1]->IsInt32()) { int mode = args[1]->Int32Value(); if (mode != int(QQmlComponent::PreferSynchronous) && mode != int(QQmlComponent::Asynchronous)) V8THROW_ERROR(invalidArgs); compileMode = QQmlComponent::CompilationMode(mode); + consumedCount += 1; } else { - V8THROW_ERROR(invalidArgs); + // The second argument could be the parent only if there are exactly two args + if ((args.Length() != 2) || !(lastArg->IsObject() || lastArg->IsNull())) + V8THROW_ERROR(invalidArgs); + } + + if (consumedCount < args.Length()) { + if (lastArg->IsObject()) { + parentArg = v8engine->toQObject(lastArg); + if (!parentArg) + V8THROW_ERROR(invalidParent); + } else if (lastArg->IsNull()) { + parentArg = 0; + } else { + V8THROW_ERROR(invalidParent); + } } } QUrl url = context->resolvedUrl(QUrl(arg)); - QQmlComponent *c = new QQmlComponent(engine, url, compileMode, engine); + QQmlComponent *c = new QQmlComponent(engine, url, compileMode, parentArg); QQmlComponentPrivate::get(c)->creationContext = effectiveContext; - QQmlData::get(c, true)->setImplicitDestructible(); + QQmlData::get(c, true)->explicitIndestructibleSet = false; + QQmlData::get(c)->indestructible = false; + return v8engine->newQObject(c); } diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index f0df025541..678f9aa3ee 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -1368,7 +1368,8 @@ v8::Handle<v8::Value> QV8Engine::variantToJS(const QVariant &value) } // Converts a JS value to a QVariant. -// Null, Undefined -> QVariant() (invalid) +// Undefined -> QVariant() (invalid) +// Null -> QVariant((void*)0) // Boolean -> QVariant(bool) // Number -> QVariant(double) // String -> QVariant(QString) @@ -1379,8 +1380,10 @@ v8::Handle<v8::Value> QV8Engine::variantToJS(const QVariant &value) QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value) { Q_ASSERT(!value.IsEmpty()); - if (value->IsNull() || value->IsUndefined()) + if (value->IsUndefined()) return QVariant(); + if (value->IsNull()) + return QVariant(QMetaType::VoidStar, 0); if (value->IsBoolean()) return value->ToBoolean()->Value(); if (value->IsInt32()) |