aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2018-06-04 10:45:14 +0200
committerMorten Johan Sørvig <morten.sorvig@qt.io>2018-06-04 10:45:14 +0200
commit3ca5f33c8b9c273f0169ec4c11417328f8071e97 (patch)
tree155da80482fb4593ca074f7a1bf9b22d031dba4a /src/qml/qml
parent5f4698c4e7952d64e78e3a06de5ac28d68415b19 (diff)
parentb7a1bcd83a8f68185b617b860cef6f2d2d7c8d9b (diff)
Merge remote-tracking branch 'gerrit/5.11' into wip/webassembly
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmlcontext.cpp13
-rw-r--r--src/qml/qml/qqmlcontext_p.h5
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp11
-rw-r--r--src/qml/qml/qqmlmetatype_p.h2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp4
-rw-r--r--src/qml/qml/qqmltypeloader.cpp62
-rw-r--r--src/qml/qml/qqmltypeloader_p.h6
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
9 files changed, 62 insertions, 45 deletions
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 5dd3278b4c..3dcfa92416 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -536,7 +536,7 @@ QQmlContextData::QQmlContextData()
QQmlContextData::QQmlContextData(QQmlContext *ctxt)
: engine(nullptr), isInternal(false), isJSContext(false),
isPragmaLibraryContext(false), unresolvedNames(false), hasEmittedDestruction(false), isRootObjectInCreation(false),
- publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1),
+ stronglyReferencedByParent(false), publicContext(ctxt), incubator(nullptr), componentObjectIndex(-1),
contextObject(nullptr), nextChild(nullptr), prevChild(nullptr),
expressions(nullptr), contextObjects(nullptr), idValues(nullptr), idValueCount(0),
componentAttached(nullptr)
@@ -577,7 +577,10 @@ void QQmlContextData::invalidate()
while (childContexts) {
Q_ASSERT(childContexts != this);
- childContexts->invalidate();
+ if (childContexts->stronglyReferencedByParent && !--childContexts->refCount)
+ childContexts->destroy();
+ else
+ childContexts->invalidate();
}
if (prevChild) {
@@ -672,12 +675,16 @@ void QQmlContextData::destroy()
delete this;
}
-void QQmlContextData::setParent(QQmlContextData *p)
+void QQmlContextData::setParent(QQmlContextData *p, bool stronglyReferencedByParent)
{
if (p == parent)
return;
if (p) {
+ Q_ASSERT(!parent);
parent = p;
+ this->stronglyReferencedByParent = stronglyReferencedByParent;
+ if (stronglyReferencedByParent)
+ ++refCount; // balanced in QQmlContextData::invalidate()
engine = p->engine;
nextChild = p->childContexts;
if (nextChild) nextChild->prevChild = &nextChild;
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index 5dfee48848..290b7fc7ee 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -126,7 +126,7 @@ public:
QQmlContextData *parent = nullptr;
QQmlEngine *engine;
- void setParent(QQmlContextData *);
+ void setParent(QQmlContextData *, bool stronglyReferencedByParent = false);
void refreshExpressions();
void addObject(QObject *);
@@ -144,7 +144,8 @@ public:
quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name
quint32 hasEmittedDestruction:1;
quint32 isRootObjectInCreation:1;
- quint32 dummy:26;
+ quint32 stronglyReferencedByParent:1;
+ quint32 dummy:25;
QQmlContext *publicContext;
// The incubator that is constructing this context if any
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 7e11177caa..b27bf3779a 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -1196,6 +1196,8 @@ void QQmlEnginePrivate::registerFinalizeCallback(QObject *obj, int index)
support.
The factory must be set before executing the engine.
+
+ \note QQmlEngine does not take ownership of the factory.
*/
void QQmlEngine::setNetworkAccessManagerFactory(QQmlNetworkAccessManagerFactory *factory)
{
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 8fda7f6f77..d842a7795f 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -424,7 +424,7 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm
d->version_min = type.versionMinor;
d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo;
- d->extraData.sd->singletonInstanceInfo->url = type.url;
+ d->extraData.sd->singletonInstanceInfo->url = QQmlTypeLoader::normalize(type.url);
d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName);
}
@@ -477,7 +477,7 @@ QQmlType::QQmlType(QQmlMetaTypeData *data, const QString &elementName, const QQm
d->version_maj = type.versionMajor;
d->version_min = type.versionMinor;
- d->extraData.fd->url = type.url;
+ d->extraData.fd->url = QQmlTypeLoader::normalize(type.url);
}
QQmlType::QQmlType()
@@ -1710,7 +1710,7 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe
addTypeToData(dtype.priv(), data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(type.url, dtype.priv());
+ files->insertMulti(QQmlTypeLoader::normalize(type.url), dtype.priv());
return dtype;
}
@@ -1731,7 +1731,7 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit
addTypeToData(dtype.priv(), data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(type.url, dtype.priv());
+ files->insertMulti(QQmlTypeLoader::normalize(type.url), dtype.priv());
return dtype;
}
@@ -2253,8 +2253,9 @@ QQmlType QQmlMetaType::qmlType(int userType)
Returns null if no such type is registered.
*/
-QQmlType QQmlMetaType::qmlType(const QUrl &url, bool includeNonFileImports /* = false */)
+QQmlType QQmlMetaType::qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports /* = false */)
{
+ const QUrl url = QQmlTypeLoader::normalize(unNormalizedUrl);
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index cd7afc8a01..51bf485a3e 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -96,7 +96,7 @@ public:
static QQmlType qmlType(const QMetaObject *);
static QQmlType qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor);
static QQmlType qmlType(int);
- static QQmlType qmlType(const QUrl &url, bool includeNonFileImports = false);
+ static QQmlType qmlType(const QUrl &unNormalizedUrl, bool includeNonFileImports = false);
static QQmlPropertyCache *propertyCache(const QMetaObject *metaObject);
static QQmlPropertyCache *propertyCache(const QQmlType &type, int minorVersion);
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 7051fb51da..5aaf79c9e5 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1217,9 +1217,9 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
}
ddata = QQmlData::get(instance, /*create*/true);
- ddata->lineNumber = obj->location.line;
- ddata->columnNumber = obj->location.column;
}
+ ddata->lineNumber = obj->location.line;
+ ddata->columnNumber = obj->location.column;
ddata->setImplicitDestructible();
if (static_cast<quint32>(index) == /*root object*/0 || ddata->rootObjectInCreation) {
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 1cab827b9f..f4c612b187 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -358,9 +358,8 @@ qreal QQmlDataBlob::progress() const
/*!
Returns the physical url of the data. Initially this is the same as
-finalUrl(), but if a network redirect happens while fetching the data, this url
-is updated to reflect the new location. Also, if a URL interceptor is set, it
-will work on this URL and leave finalUrl() alone.
+finalUrl(), but if a URL interceptor is set, it will work on this URL
+and leave finalUrl() alone.
\sa finalUrl()
*/
@@ -381,8 +380,12 @@ QString QQmlDataBlob::urlString() const
Returns the logical URL to be used for resolving further URLs referred to in
the code.
-This is the blob url passed to the constructor. If a network redirect
-happens while fetching the data, this url remains the same.
+This is the blob url passed to the constructor. If a URL interceptor rewrites
+the URL, this one stays the same. If a network redirect happens while fetching
+the data, this url is updated to reflect the new location. Therefore, if both
+an interception and a redirection happen, the final url will indirectly
+incorporate the result of the interception, potentially breaking further
+lookups.
\sa url()
*/
@@ -1184,15 +1187,15 @@ void QQmlTypeLoader::networkReplyFinished(QNetworkReply *reply)
QVariant redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirect.isValid()) {
QUrl url = reply->url().resolved(redirect.toUrl());
- blob->m_url = url;
- blob->m_urlString.clear();
+ blob->m_finalUrl = url;
+ blob->m_finalUrlString.clear();
QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(url));
QObject *nrp = m_thread->networkReplyProxy();
QObject::connect(reply, SIGNAL(finished()), nrp, SLOT(finished()));
m_networkReplies.insert(reply, blob);
#ifdef DATABLOB_DEBUG
- qWarning("QQmlDataBlob: redirected to %s", qPrintable(blob->urlString()));
+ qWarning("QQmlDataBlob: redirected to %s", qPrintable(blob->finalUrlString()));
#endif
return;
}
@@ -1648,14 +1651,24 @@ QQmlImportDatabase *QQmlTypeLoader::importDatabase() const
return &QQmlEnginePrivate::get(engine())->importDatabase;
}
+QUrl QQmlTypeLoader::normalize(const QUrl &unNormalizedUrl)
+{
+ QUrl normalized(unNormalizedUrl);
+ if (normalized.scheme() == QLatin1String("qrc"))
+ normalized.setHost(QString()); // map qrc:///a.qml to qrc:/a.qml
+ return normalized;
+}
+
/*!
Returns a QQmlTypeData for the specified \a url. The QQmlTypeData may be cached.
*/
-QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode)
+QQmlTypeData *QQmlTypeLoader::getType(const QUrl &unNormalizedUrl, Mode mode)
{
- Q_ASSERT(!url.isRelative() &&
- (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() ||
- !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url))));
+ Q_ASSERT(!unNormalizedUrl.isRelative() &&
+ (QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl).isEmpty() ||
+ !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl))));
+
+ const QUrl url = normalize(unNormalizedUrl);
LockHolder<QQmlTypeLoader> holder(this);
@@ -1713,11 +1726,13 @@ QQmlTypeData *QQmlTypeLoader::getType(const QByteArray &data, const QUrl &url, M
/*!
Return a QQmlScriptBlob for \a url. The QQmlScriptData may be cached.
*/
-QQmlScriptBlob *QQmlTypeLoader::getScript(const QUrl &url)
+QQmlScriptBlob *QQmlTypeLoader::getScript(const QUrl &unNormalizedUrl)
{
- Q_ASSERT(!url.isRelative() &&
- (QQmlFile::urlToLocalFileOrQrc(url).isEmpty() ||
- !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(url))));
+ Q_ASSERT(!unNormalizedUrl.isRelative() &&
+ (QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl).isEmpty() ||
+ !QDir::isRelativePath(QQmlFile::urlToLocalFileOrQrc(unNormalizedUrl))));
+
+ const QUrl url = normalize(unNormalizedUrl);
LockHolder<QQmlTypeLoader> holder(this);
@@ -1833,15 +1848,7 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path)
if (*value)
absoluteFilePath = path;
} else {
- bool exists = false;
-#ifdef Q_OS_UNIX
- struct stat statBuf;
- // XXX Avoid encoding entire path. Should store encoded dirpath in cache
- if (::stat(QFile::encodeName(path).constData(), &statBuf) == 0)
- exists = S_ISREG(statBuf.st_mode);
-#else
- exists = QFile::exists(path);
-#endif
+ bool exists = QFile::exists(path);
fileSet->insert(fileName, new bool(exists));
if (exists)
absoluteFilePath = path;
@@ -3010,7 +3017,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
return;
}
- QmlIR::ScriptDirectivesCollector collector(&irUnit.jsParserEngine, &irUnit.jsGenerator);
+ QmlIR::ScriptDirectivesCollector collector(&irUnit);
QList<QQmlError> errors;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Script::precompile(
@@ -3026,9 +3033,6 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
unit.adopt(new QV4::CompiledData::CompilationUnit);
}
irUnit.javaScriptCompilationUnit = unit;
- irUnit.imports = collector.imports;
- if (collector.hasPragmaLibrary)
- irUnit.jsModule.unitFlags |= QV4::CompiledData::Unit::IsSharedLibrary;
QmlIR::QmlUnitGenerator qmlGenerator;
QV4::CompiledData::Unit *unitData = qmlGenerator.generate(irUnit);
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 5988632547..e75719866d 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -305,10 +305,12 @@ public:
QQmlImportDatabase *importDatabase() const;
- QQmlTypeData *getType(const QUrl &url, Mode mode = PreferSynchronous);
+ static QUrl normalize(const QUrl &unNormalizedUrl);
+
+ QQmlTypeData *getType(const QUrl &unNormalizedUrl, Mode mode = PreferSynchronous);
QQmlTypeData *getType(const QByteArray &, const QUrl &url, Mode mode = PreferSynchronous);
- QQmlScriptBlob *getScript(const QUrl &);
+ QQmlScriptBlob *getScript(const QUrl &unNormalizedUrl);
QQmlQmldirData *getQmldir(const QUrl &);
QString absoluteFilePath(const QString &path);
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 9e7c84011b..221754a29a 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1697,7 +1697,7 @@ ReturnedValue ConsoleObject::method_count(const FunctionObject *b, const Value *
QString scriptName = frame->source();
- int value = v8engine->consoleCountHelper(scriptName, frame->lineNumber(), -1);
+ int value = v8engine->consoleCountHelper(scriptName, frame->lineNumber(), 0);
QString message = name + QLatin1String(": ") + QString::number(value);
QMessageLogger(qPrintable(scriptName), frame->lineNumber(),