aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/Qt6QmlMacros.cmake36
-rw-r--r--src/qml/Qt6QmlModuleDirMappingTemplate.qrc.in2
-rw-r--r--src/qmlcompiler/qqmljsimporter_p.h6
-rw-r--r--src/qmlcompiler/qqmljsutils.cpp44
-rw-r--r--src/qmlcompiler/qqmljsutils_p.h4
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