diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-09-12 01:00:34 +0200 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-09-12 01:00:34 +0200 |
commit | 2cf7a378ede8a6ab3172646e88b54efefa5c5931 (patch) | |
tree | 975afbc814981abebb0a01fa711e620b1c294abd /src/qml/qml | |
parent | 08113c55190a76d8a3586eb2e383ae9c2bd516c7 (diff) | |
parent | 1909f99aac4a14d70ffcc004fc9e16c154485c25 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: Ia585e9fec3f68a3f9a7d27a65b825e499d468125
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqml.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlglobal_p.h | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmlpropertycachecreator_p.h | 13 | ||||
-rw-r--r-- | src/qml/qml/qqmltype.cpp | 65 | ||||
-rw-r--r-- | src/qml/qml/qqmltype_p.h | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmltype_p_p.h | 22 | ||||
-rw-r--r-- | src/qml/qml/qqmltypecompiler.cpp | 14 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper.cpp | 56 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/v8/qqmlbuiltinfunctions.cpp | 48 |
12 files changed, 155 insertions, 98 deletions
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index a93b012c70..6295345fa4 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -102,7 +102,7 @@ class QQmlPropertyValueInterceptor; void Q_QML_EXPORT qmlClearTypeRegistrations(); template<typename T> -int qmlRegisterAnonymousType(const char *uri, int versionMajor=1) +int qmlRegisterAnonymousType(const char *uri, int versionMajor) { QML_GETTYPENAMES @@ -136,7 +136,7 @@ int qmlRegisterAnonymousType(const char *uri, int versionMajor=1) template<typename T> QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType() { - return qmlRegisterAnonymousType<T>(""); + return qmlRegisterAnonymousType<T>("", 1); } int Q_QML_EXPORT qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message); diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 136159993a..96891af416 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -98,11 +98,11 @@ QT_BEGIN_NAMESPACE static int signalIdx = -1; \ static int methodIdx = -1; \ if (signalIdx < 0) { \ - Q_ASSERT(((int)(*signal) - '0') == QSIGNAL_CODE); \ + Q_ASSERT((int(*signal) - '0') == QSIGNAL_CODE); \ signalIdx = SenderType::staticMetaObject.indexOfSignal(signal+1); \ } \ if (methodIdx < 0) { \ - int code = ((int)(*method) - '0'); \ + int code = (int(*method) - '0'); \ Q_ASSERT(code == QSLOT_CODE || code == QSIGNAL_CODE); \ if (code == QSLOT_CODE) \ methodIdx = ReceiverType::staticMetaObject.indexOfSlot(method+1); \ @@ -137,11 +137,11 @@ QT_BEGIN_NAMESPACE static int signalIdx = -1; \ static int methodIdx = -1; \ if (signalIdx < 0) { \ - Q_ASSERT(((int)(*signal) - '0') == QSIGNAL_CODE); \ + Q_ASSERT((int(*signal) - '0') == QSIGNAL_CODE); \ signalIdx = SenderType::staticMetaObject.indexOfSignal(signal+1); \ } \ if (methodIdx < 0) { \ - int code = ((int)(*method) - '0'); \ + int code = (int(*method) - '0'); \ Q_ASSERT(code == QSLOT_CODE || code == QSIGNAL_CODE); \ if (code == QSLOT_CODE) \ methodIdx = ReceiverType::staticMetaObject.indexOfSlot(method+1); \ diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 2c641d3845..c2674b402a 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -739,9 +739,16 @@ QQmlType QQmlMetaType::typeForUrl(const QString &urlString, const QUrl url = QQmlTypeLoader::normalize(QUrl(urlString)); QQmlMetaTypeDataPtr data; - QQmlType ret(data->urlToType.value(url)); - if (ret.isValid() && ret.sourceUrl() == url) - return ret; + { + QQmlType ret(data->urlToType.value(url)); + if (ret.isValid() && ret.sourceUrl() == url) + return ret; + } + { + QQmlType ret(data->urlToNonFileImportType.value(url)); + if (ret.isValid() && ret.sourceUrl() == url) + return ret; + } const int dot = qualifiedType.indexOf(QLatin1Char('.')); const QString typeName = dot < 0 diff --git a/src/qml/qml/qqmlpropertycachecreator_p.h b/src/qml/qml/qqmlpropertycachecreator_p.h index 9c7a69d571..def4480198 100644 --- a/src/qml/qml/qqmlpropertycachecreator_p.h +++ b/src/qml/qml/qqmlpropertycachecreator_p.h @@ -256,17 +256,8 @@ inline QQmlRefPointer<QQmlPropertyCache> QQmlPropertyCacheCreator<ObjectContaine Q_ASSERT(typeRef); QQmlType qmltype = typeRef->type; if (!qmltype.isValid()) { - QString propertyName = stringAt(context.instantiatingBinding->propertyNameIndex); - if (imports->resolveType(propertyName, &qmltype, nullptr, nullptr, nullptr)) { - if (qmltype.isComposite()) { - QQmlRefPointer<QQmlTypeData> tdata = enginePrivate->typeLoader.getType(qmltype.sourceUrl()); - Q_ASSERT(tdata); - Q_ASSERT(tdata->isComplete()); - - auto compilationUnit = tdata->compilationUnit(); - qmltype = QQmlMetaType::qmlType(compilationUnit->metaTypeId); - } - } + imports->resolveType(stringAt(context.instantiatingBinding->propertyNameIndex), + &qmltype, nullptr, nullptr, nullptr); } const QMetaObject *attachedMo = qmltype.attachedPropertiesType(enginePrivate); diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp index 252ff26a64..3615749da1 100644 --- a/src/qml/qml/qqmltype.cpp +++ b/src/qml/qml/qqmltype.cpp @@ -154,10 +154,10 @@ bool QQmlType::availableInVersion(const QHashedStringRef &module, int vmajor, in return module == d->module && vmajor == d->version_maj && vminor >= d->version_min; } -QQmlType QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const +QQmlType QQmlTypePrivate::resolveCompositeBaseType(QQmlEnginePrivate *engine) const { Q_ASSERT(isComposite()); - if (!engine || !d) + if (!engine) return QQmlType(); QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl())); if (td.isNull() || !td->isComplete()) @@ -167,7 +167,7 @@ QQmlType QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const return QQmlMetaType::qmlType(mo); } -QQmlPropertyCache *QQmlType::compositePropertyCache(QQmlEnginePrivate *engine) const +QQmlPropertyCache *QQmlTypePrivate::compositePropertyCache(QQmlEnginePrivate *engine) const { // similar logic to resolveCompositeBaseType Q_ASSERT(isComposite()); @@ -262,24 +262,30 @@ void QQmlTypePrivate::init() const lock.unlock(); } -void QQmlTypePrivate::initEnums(const QQmlPropertyCache *cache) const +void QQmlTypePrivate::initEnums(QQmlEnginePrivate *engine) const { - if ((isEnumFromBaseSetup || !baseMetaObject) - && (isEnumFromCacheSetup || !cache)) { + const QQmlPropertyCache *cache = (!isEnumFromCacheSetup && isComposite()) + ? compositePropertyCache(engine) + : nullptr; + + const QMetaObject *metaObject = !isEnumFromCacheSetup + ? baseMetaObject // beware: It could be a singleton type without metaobject + : nullptr; + + if (!cache && !metaObject) return; - } init(); QMutexLocker lock(QQmlMetaType::typeRegistrationLock()); - if (!isEnumFromCacheSetup && cache) { + if (cache) { insertEnumsFromPropertyCache(cache); isEnumFromCacheSetup = true; } - if (!isEnumFromBaseSetup && baseMetaObject) { // could be singleton type without metaobject - insertEnums(baseMetaObject); + if (metaObject) { + insertEnums(metaObject); isEnumFromBaseSetup = true; } } @@ -548,7 +554,7 @@ bool QQmlType::isInterface() const bool QQmlType::isComposite() const { - return d && (d->regType == CompositeType || d->regType == CompositeSingletonType); + return d && d->isComposite(); } bool QQmlType::isCompositeSingleton() const @@ -617,7 +623,7 @@ QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlEnginePrivat QQmlType base; if (d->regType == CompositeType) - base = resolveCompositeBaseType(engine); + base = d->resolveCompositeBaseType(engine); return base.attachedPropertiesFunction(engine); } @@ -630,7 +636,7 @@ const QMetaObject *QQmlType::attachedPropertiesType(QQmlEnginePrivate *engine) c QQmlType base; if (d->regType == CompositeType) - base = resolveCompositeBaseType(engine); + base = d->resolveCompositeBaseType(engine); return base.attachedPropertiesType(engine); } @@ -649,7 +655,7 @@ int QQmlType::attachedPropertiesId(QQmlEnginePrivate *engine) const QQmlType base; if (d->regType == CompositeType) - base = resolveCompositeBaseType(engine); + base = d->resolveCompositeBaseType(engine); return base.attachedPropertiesId(engine); } #endif @@ -689,24 +695,16 @@ int QQmlType::index() const QUrl QQmlType::sourceUrl() const { - if (d) { - if (d->regType == CompositeType) - return d->extraData.fd->url; - else if (d->regType == CompositeSingletonType) - return d->extraData.sd->singletonInstanceInfo->url; - } - return QUrl(); + return d ? d->sourceUrl() : QUrl(); } int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &name, bool *ok) const { Q_ASSERT(ok); if (d) { - const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr; - *ok = true; - d->initEnums(cache); + d->initEnums(engine); int *rv = d->enums.value(name); if (rv) @@ -721,11 +719,9 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &name { Q_ASSERT(ok); if (d) { - const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr; - *ok = true; - d->initEnums(cache); + d->initEnums(engine); int *rv = d->enums.value(name); if (rv) @@ -740,10 +736,9 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QV4::String *name, bool { Q_ASSERT(ok); if (d) { - const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr; *ok = true; - d->initEnums(cache); + d->initEnums(engine); int *rv = d->enums.value(name); if (rv) @@ -758,10 +753,9 @@ int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QV4::String *name { Q_ASSERT(ok); if (d) { - const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr; *ok = true; - d->initEnums(cache); + d->initEnums(engine); int *rv = d->scopedEnumIndex.value(name); if (rv) @@ -776,10 +770,9 @@ int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QString &name, bo { Q_ASSERT(ok); if (d) { - const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr; *ok = true; - d->initEnums(cache); + d->initEnums(engine); int *rv = d->scopedEnumIndex.value(name); if (rv) @@ -828,10 +821,9 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &scope { Q_ASSERT(ok); if (d) { - const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr; *ok = true; - d->initEnums(cache); + d->initEnums(engine); int *rv = d->scopedEnumIndex.value(QHashedCStringRef(scopedEnumName.constData(), scopedEnumName.length())); if (rv) { @@ -851,10 +843,9 @@ int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &scope { Q_ASSERT(ok); if (d) { - const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : nullptr; *ok = true; - d->initEnums(cache); + d->initEnums(engine); int *rv = d->scopedEnumIndex.value(QHashedStringRef(scopedEnumName)); if (rv) { diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h index 4dec20600b..ec27b38a73 100644 --- a/src/qml/qml/qqmltype_p.h +++ b/src/qml/qml/qqmltype_p.h @@ -182,11 +182,7 @@ public: }; private: - QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const; - int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const; - QQmlPropertyCache *compositePropertyCache(QQmlEnginePrivate *engine) const; friend uint qHash(const QQmlType &t, uint seed); - QQmlRefPointer<const QQmlTypePrivate> d; }; diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h index d381e11df4..6a2d961de8 100644 --- a/src/qml/qml/qqmltype_p_p.h +++ b/src/qml/qml/qqmltype_p_p.h @@ -66,10 +66,30 @@ public: QQmlTypePrivate(QQmlType::RegistrationType type); void init() const; - void initEnums(const QQmlPropertyCache *cache = nullptr) const; + void initEnums(QQmlEnginePrivate *engine) const; void insertEnums(const QMetaObject *metaObject) const; void insertEnumsFromPropertyCache(const QQmlPropertyCache *cache) const; + QUrl sourceUrl() const + { + switch (regType) { + case QQmlType::CompositeType: + return extraData.fd->url; + case QQmlType::CompositeSingletonType: + return extraData.sd->singletonInstanceInfo->url; + default: + return QUrl(); + } + } + + bool isComposite() const + { + return regType == QQmlType::CompositeType || regType == QQmlType::CompositeSingletonType; + } + + QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const; + QQmlPropertyCache *compositePropertyCache(QQmlEnginePrivate *engine) const; + QQmlType::RegistrationType regType; struct QQmlCppTypeData diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp index e7633a1bba..9a6bd73326 100644 --- a/src/qml/qml/qqmltypecompiler.cpp +++ b/src/qml/qml/qqmltypecompiler.cpp @@ -328,18 +328,8 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio const QmlIR::Object *attachedObj = qmlObjects.at(binding->value.objectIndex); auto *typeRef = resolvedType(binding->propertyNameIndex); QQmlType type = typeRef ? typeRef->type : QQmlType(); - if (!type.isValid()) { - if (imports->resolveType(propertyName, &type, nullptr, nullptr, nullptr)) { - if (type.isComposite()) { - QQmlRefPointer<QQmlTypeData> tdata = enginePrivate->typeLoader.getType(type.sourceUrl()); - Q_ASSERT(tdata); - Q_ASSERT(tdata->isComplete()); - - auto compilationUnit = tdata->compilationUnit(); - type = QQmlMetaType::qmlType(compilationUnit->metaTypeId); - } - } - } + if (!type.isValid()) + imports->resolveType(propertyName, &type, nullptr, nullptr, nullptr); const QMetaObject *attachedType = type.attachedPropertiesType(enginePrivate); if (!attachedType) diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 3a18bbf7c9..42e7d2c4b4 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -964,8 +964,10 @@ QString QQmlTypeLoader::absoluteFilePath(const QString &path) bool QQmlTypeLoader::fileExists(const QString &path, const QString &file) { - if (path.isEmpty()) + const QChar nullChar(QChar::Null); + if (path.isEmpty() || path.contains(nullChar) || file.isEmpty() || file.contains(nullChar)) return false; + Q_ASSERT(path.endsWith(QLatin1Char('/'))); if (path.at(0) == QLatin1Char(':')) { // qrc resource diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 931f37b35a..ef4a628a04 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -476,6 +476,34 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object, } // Fall through to base implementation } + + if (name->startsWithUpper()) { + bool ok = false; + int value = type.enumValue(QQmlEnginePrivate::get(engine->qmlEngine()), name, &ok); + if (ok) { + lookup->qmlEnumValueLookup.ic = This->internalClass(); + lookup->qmlEnumValueLookup.encodedEnumValue + = QV4::Value::fromInt32(value).asReturnedValue(); + lookup->getter = QQmlTypeWrapper::lookupEnumValue; + return lookup->getter(lookup, engine, *object); + } + + value = type.scopedEnumIndex(QQmlEnginePrivate::get(engine->qmlEngine()), name, &ok); + if (ok) { + Scoped<QQmlScopedEnumWrapper> enumWrapper( + scope, engine->memoryManager->allocate<QQmlScopedEnumWrapper>()); + enumWrapper->d()->typePrivate = type.priv(); + QQmlType::refHandle(enumWrapper->d()->typePrivate); + enumWrapper->d()->scopeEnumIndex = value; + + lookup->qmlScopedEnumWrapperLookup.ic = This->internalClass(); + lookup->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper + = static_cast<Heap::Object*>(enumWrapper->heapObject()); + lookup->getter = QQmlTypeWrapper::lookupScopedEnum; + return enumWrapper.asReturnedValue(); + } + // Fall through to base implementation + } // Fall through to base implementation } return QV4::Object::virtualResolveLookupGetter(object, engine, lookup); @@ -519,6 +547,34 @@ ReturnedValue QQmlTypeWrapper::lookupSingletonProperty(Lookup *l, ExecutionEngin return QObjectWrapper::lookupGetterImpl(l, engine, obj, /*useOriginalProperty*/ true, revertLookup); } +ReturnedValue QQmlTypeWrapper::lookupEnumValue(Lookup *l, ExecutionEngine *engine, const Value &base) +{ + auto *o = static_cast<Heap::Object *>(base.heapObject()); + if (!o || o->internalClass != l->qmlEnumValueLookup.ic) { + l->getter = Lookup::getterGeneric; + return Lookup::getterGeneric(l, engine, base); + } + + return l->qmlEnumValueLookup.encodedEnumValue; +} + +ReturnedValue QQmlTypeWrapper::lookupScopedEnum(Lookup *l, ExecutionEngine *engine, const Value &base) +{ + Scope scope(engine); + Scoped<QQmlScopedEnumWrapper> enumWrapper(scope, static_cast<Heap::QQmlScopedEnumWrapper *>( + l->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper)); + + auto *o = static_cast<Heap::Object *>(base.heapObject()); + if (!o || o->internalClass != l->qmlScopedEnumWrapperLookup.ic) { + QQmlType::derefHandle(enumWrapper->d()->typePrivate); + l->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper = nullptr; + l->getter = Lookup::getterGeneric; + return Lookup::getterGeneric(l, engine, base); + } + + return enumWrapper.asReturnedValue(); +} + void Heap::QQmlScopedEnumWrapper::destroy() { QQmlType::derefHandle(typePrivate); diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 6b51f421b3..7dc3f55310 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -115,6 +115,8 @@ struct Q_QML_EXPORT QQmlTypeWrapper : Object static bool virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value); static ReturnedValue lookupSingletonProperty(Lookup *l, ExecutionEngine *engine, const Value &base); + static ReturnedValue lookupEnumValue(Lookup *l, ExecutionEngine *engine, const Value &base); + static ReturnedValue lookupScopedEnum(Lookup *l, ExecutionEngine *engine, const Value &base); protected: static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 2e213e7dc3..355150b786 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -1941,30 +1941,32 @@ ReturnedValue GlobalExtensions::method_qsTr(const FunctionObject *b, const Value THROW_GENERIC_ERROR("qsTr(): third argument (n) must be a number"); QString context; - if (QQmlContextData *ctxt = scope.engine->callingQmlContext()) { - QString path = ctxt->urlString(); - int lastSlash = path.lastIndexOf(QLatin1Char('/')); - int lastDot = path.lastIndexOf(QLatin1Char('.')); - int length = lastDot - (lastSlash + 1); - context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString(); - } else { - CppStackFrame *frame = scope.engine->currentStackFrame; - // The first non-empty source URL in the call stack determines the translation context. - while (frame && context.isEmpty()) { - if (CompiledData::CompilationUnitBase *baseUnit = frame->v4Function->compilationUnit) { - const auto *unit = static_cast<const CompiledData::CompilationUnit *>(baseUnit); - QString fileName = unit->fileName(); - QUrl url(unit->fileName()); - if (url.isValid() && url.isRelative()) { - context = url.fileName(); - } else { - context = QQmlFile::urlToLocalFileOrQrc(fileName); - if (context.isEmpty() && fileName.startsWith(QLatin1String(":/"))) - context = fileName; - } - context = QFileInfo(context).baseName(); + CppStackFrame *frame = scope.engine->currentStackFrame; + // The first non-empty source URL in the call stack determines the translation context. + while (frame && context.isEmpty()) { + if (CompiledData::CompilationUnitBase *baseUnit = frame->v4Function->compilationUnit) { + const auto *unit = static_cast<const CompiledData::CompilationUnit *>(baseUnit); + QString fileName = unit->fileName(); + QUrl url(unit->fileName()); + if (url.isValid() && url.isRelative()) { + context = url.fileName(); + } else { + context = QQmlFile::urlToLocalFileOrQrc(fileName); + if (context.isEmpty() && fileName.startsWith(QLatin1String(":/"))) + context = fileName; } - frame = frame->parent; + context = QFileInfo(context).baseName(); + } + frame = frame->parent; + } + + if (context.isEmpty()) { + if (QQmlContextData *ctxt = scope.engine->callingQmlContext()) { + QString path = ctxt->urlString(); + int lastSlash = path.lastIndexOf(QLatin1Char('/')); + int lastDot = path.lastIndexOf(QLatin1Char('.')); + int length = lastDot - (lastSlash + 1); + context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString(); } } |