diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/qml/Qt6QmlMacros.cmake | 36 | ||||
| -rw-r--r-- | src/qml/Qt6QmlModuleDirMappingTemplate.qrc.in | 2 | ||||
| -rw-r--r-- | src/qmlcompiler/qqmljsimporter_p.h | 6 | ||||
| -rw-r--r-- | src/qmlcompiler/qqmljsutils.cpp | 44 | ||||
| -rw-r--r-- | src/qmlcompiler/qqmljsutils_p.h | 4 |
5 files changed, 67 insertions, 25 deletions
diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake index 91087da66f..e0ee5d34c9 100644 --- a/src/qml/Qt6QmlMacros.cmake +++ b/src/qml/Qt6QmlMacros.cmake @@ -609,11 +609,10 @@ function(qt6_add_qml_module target) # QML tooling might need to map build dir paths to source dir paths. Create # a mapping file before qt6_target_qml_sources() to be able to use it - if(arg_ENABLE_TYPE_COMPILER) - # But: for now, only enable this when dealing with qmltc - _qt_internal_qml_map_build_files(${target} "${arg_QML_FILES}" dir_map_qrc) - set_property(TARGET ${target} APPEND PROPERTY _qt_generated_qrc_files "${dir_map_qrc}") - endif() + _qt_internal_qml_map_build_files(${target} ${qt_qml_module_resource_prefix} dir_map_qrc) + # use different property from _qt_generated_qrc_files since this qrc is + # special (and is not a real resource file) + set_property(TARGET ${target} APPEND PROPERTY _qt_qml_meta_qrc_files "${dir_map_qrc}") set(cache_target) qt6_target_qml_sources(${target} @@ -1150,7 +1149,7 @@ endfunction() # creates a QRC mapping between QML files in build directory and QML files in # source directory -function(_qt_internal_qml_map_build_files target qml_files qrc_file_out_var) +function(_qt_internal_qml_map_build_files target qml_module_prefix qrc_file_out_var) get_target_property(output_dir ${target} QT_QML_MODULE_OUTPUT_DIRECTORY) if(NOT output_dir) # TODO: we might want to support non-qml modules here (think QML @@ -1161,14 +1160,7 @@ function(_qt_internal_qml_map_build_files target qml_files qrc_file_out_var) endif() set(qrcContents "") - - foreach(qml_file IN LISTS qml_files) - get_filename_component(src_dir_path ${qml_file} ABSOLUTE) - # Note: follow the logic of cloning the QML file over to build dir - __qt_get_relative_resource_path_for_file(file_resource_path ${qml_file}) - set(build_dir_path "${output_dir}/${file_resource_path}") - string(APPEND qrcContents " <file alias=\"${src_dir_path}\">${build_dir_path}</file>\n") - endforeach() + string(APPEND qrcContents " <file alias=\"${qml_module_prefix}\">${output_dir}</file>\n") # dump the contents into the .qrc file set(template_file "${__qt_qml_macros_module_base_dir}/Qt6QmlModuleDirMappingTemplate.qrc.in") @@ -1236,15 +1228,6 @@ function(_qt_internal_target_enable_qmltc target) message(FATAL_ERROR "\"${target}\" is not a known target") endif() - get_target_property(prefix ${target} QT_QML_MODULE_RESOURCE_PREFIX) - if (NOT prefix) - message(FATAL_ERROR - "Target is not a QML module? QT_QML_MODULE_RESOURCE_PREFIX is unspecified") - endif() - if(NOT prefix MATCHES [[/$]]) - string(APPEND prefix "/") - endif() - get_target_property(target_source_dir ${target} SOURCE_DIR) get_target_property(target_binary_dir ${target} BINARY_DIR) @@ -1341,6 +1324,12 @@ function(_qt_internal_target_enable_qmltc target) _qt_internal_genex_getjoinedproperty(qrc_args ${target} _qt_generated_qrc_files "--resource$<SEMICOLON>" "$<SEMICOLON>" ) + # qmltc also needs meta data qrc files when importing types from own module + _qt_internal_genex_getjoinedproperty(metadata_qrc_args ${target} + _qt_qml_meta_qrc_files "--meta-resource$<SEMICOLON>" "$<SEMICOLON>" + ) + list(APPEND qrc_args ${metadata_qrc_args}) + # NB: pass qml files variable as string to preserve its list nature # (otherwise we lose all but first element of the list inside a function) _qt_internal_qml_add_qmltc_file_mapping_resource( @@ -1388,6 +1377,7 @@ function(_qt_internal_target_enable_qmltc target) "${file_absolute}" ${qml_module_files} $<TARGET_PROPERTY:${target},_qt_generated_qrc_files> + $<TARGET_PROPERTY:${target},_qt_qml_meta_qrc_files> ${qmltc_file_map_qrc} COMMENT "Compiling ${qml_file_src} with qmltc" VERBATIM diff --git a/src/qml/Qt6QmlModuleDirMappingTemplate.qrc.in b/src/qml/Qt6QmlModuleDirMappingTemplate.qrc.in index 3cbe0acea0..e7e376bcb2 100644 --- a/src/qml/Qt6QmlModuleDirMappingTemplate.qrc.in +++ b/src/qml/Qt6QmlModuleDirMappingTemplate.qrc.in @@ -1,5 +1,5 @@ <RCC> - <qresource prefix="/qt_qml_module_dir_mapping/"> + <qresource prefix="/"> @qt_qml_module_dir_mapping_contents@ </qresource> </RCC> diff --git a/src/qmlcompiler/qqmljsimporter_p.h b/src/qmlcompiler/qqmljsimporter_p.h index 45e527b967..6aec963586 100644 --- a/src/qmlcompiler/qqmljsimporter_p.h +++ b/src/qmlcompiler/qqmljsimporter_p.h @@ -34,9 +34,12 @@ public: QQmlJSImporter(const QStringList &importPaths, QQmlJSResourceFileMapper *mapper, bool useOptionalImports = false); - QQmlJSResourceFileMapper *resourceFileMapper() { return m_mapper; } + QQmlJSResourceFileMapper *resourceFileMapper() const { return m_mapper; } void setResourceFileMapper(QQmlJSResourceFileMapper *mapper) { m_mapper = mapper; } + QQmlJSResourceFileMapper *metaDataMapper() const { return m_metaDataMapper; } + void setMetaDataMapper(QQmlJSResourceFileMapper *mapper) { m_metaDataMapper = mapper; } + ImportedTypes importBuiltins(); void importQmldirs(const QStringList &qmltypesFiles); @@ -143,6 +146,7 @@ private: QList<QQmlJS::DiagnosticMessage> m_warnings; AvailableTypes m_builtins; QQmlJSResourceFileMapper *m_mapper = nullptr; + QQmlJSResourceFileMapper *m_metaDataMapper = nullptr; bool m_useOptionalImports; ImportVisitorCreator m_createImportVisitor = nullptr; diff --git a/src/qmlcompiler/qqmljsutils.cpp b/src/qmlcompiler/qqmljsutils.cpp index c07c0b6845..548c86eb67 100644 --- a/src/qmlcompiler/qqmljsutils.cpp +++ b/src/qmlcompiler/qqmljsutils.cpp @@ -146,3 +146,47 @@ std::optional<FixSuggestion> QQmlJSUtils::didYouMean(const QString &userInput, return {}; } } + +/*! \internal + + Returns a corresponding source directory path for \a buildDirectoryPath + Returns empty string on error +*/ +std::variant<QString, QQmlJS::DiagnosticMessage> +QQmlJSUtils::sourceDirectoryPath(const QQmlJSImporter *importer, const QString &buildDirectoryPath) +{ + const auto makeError = [](const QString &msg) { + return QQmlJS::DiagnosticMessage { msg, QtWarningMsg, QQmlJS::SourceLocation() }; + }; + + if (!importer->metaDataMapper()) + return makeError(u"QQmlJSImporter::metaDataMapper() is nullptr"_s); + + // for now, meta data contains just a single entry + QQmlJSResourceFileMapper::Filter matchAll { QString(), QStringList(), + QQmlJSResourceFileMapper::Directory + | QQmlJSResourceFileMapper::Recurse }; + QQmlJSResourceFileMapper::Entry entry = importer->metaDataMapper()->entry(matchAll); + if (!entry.isValid()) + return makeError(u"Failed to find meta data entry in QQmlJSImporter::metaDataMapper()"_s); + if (!buildDirectoryPath.startsWith(entry.filePath)) // assume source directory path already + return makeError(u"The module output directory does not match the build directory path"_s); + + QString qrcPath = buildDirectoryPath; + qrcPath.remove(0, entry.filePath.size()); + qrcPath.prepend(entry.resourcePath); + qrcPath.remove(0, 1); // remove extra "/" + + const QStringList sourceDirPaths = importer->resourceFileMapper()->filePaths( + QQmlJSResourceFileMapper::resourceFileFilter(qrcPath)); + if (sourceDirPaths.size() != 1) { + const QString matchedPaths = + sourceDirPaths.isEmpty() ? u"<none>"_s : sourceDirPaths.join(u", "); + return makeError( + QStringLiteral("QRC path %1 (deduced from %2) has unexpected number of mappings " + "(%3). File paths that matched:\n%4") + .arg(qrcPath, buildDirectoryPath, QString::number(sourceDirPaths.size()), + matchedPaths)); + } + return sourceDirPaths[0]; +} diff --git a/src/qmlcompiler/qqmljsutils_p.h b/src/qmlcompiler/qqmljsutils_p.h index 3698d3861b..ab3dbd9745 100644 --- a/src/qmlcompiler/qqmljsutils_p.h +++ b/src/qmlcompiler/qqmljsutils_p.h @@ -29,6 +29,7 @@ #include <optional> #include <functional> #include <type_traits> +#include <variant> QT_BEGIN_NAMESPACE @@ -333,6 +334,9 @@ struct Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSUtils static std::optional<FixSuggestion> didYouMean(const QString &userInput, QStringList candidates, QQmlJS::SourceLocation location); + + static std::variant<QString, QQmlJS::DiagnosticMessage> + sourceDirectoryPath(const QQmlJSImporter *importer, const QString &buildDirectoryPath); }; QT_END_NAMESPACE |
