81 static inline constexpr QLatin1String anonPrefix = QLatin1String(
"$anonymous$");
82 static inline constexpr QLatin1String internalPrefix = QLatin1String(
"$internal$");
83 static inline constexpr QLatin1String modulePrefix = QLatin1String(
"$module$");
86 static inline constexpr QLatin1String s_inProcessMarker = QLatin1String(
"$InProcess$");
88 struct ImportedTypes {
89 ImportedTypes(QQmlJS::ContextualTypes &&types, QList<QQmlJS::DiagnosticMessage> &&warnings,
90 QList<QQmlJS::Import> &&moduleImports = {})
91 : m_types(std::move(types)),
92 m_warnings(std::move(warnings)),
93 m_moduleImports(std::move(moduleImports))
96 ImportedTypes(
const ImportedTypes &) =
default;
97 ImportedTypes(ImportedTypes &&) =
default;
98 ImportedTypes &operator=(
const ImportedTypes &) =
default;
99 ImportedTypes &operator=(ImportedTypes &&) =
default;
100 ~ImportedTypes() =
default;
104 m_types.clearTypes();
108 const QQmlJS::ContextualTypes &contextualTypes()
const {
return m_types; }
109 const QList<QQmlJS::DiagnosticMessage> &warnings()
const {
return m_warnings; };
110 const QList<QQmlJS::Import> &moduleImports()
const {
return m_moduleImports; }
112 void setCurrentFileSelector(
const QString &selector)
114 m_types.setCurrentFileSelector(selector);
117 bool isEmpty()
const {
return m_types.types().isEmpty(); }
119 bool hasType(
const QString &name)
const {
return m_types.hasType(name); }
120 QQmlJS::ImportedScope<QQmlJSScope::ConstPtr> type(
const QString &name)
const
122 return m_types.type(name);
124 QString name(
const QQmlJSScope::ConstPtr &type)
const {
return m_types.name(type); }
125 void setType(
const QString &name,
const QQmlJS::ContextualType &type)
127 m_types.setType(name, type);
129 bool isNullType(
const QString &name)
const {
return m_types.isNullType(name); }
130 const QHash<QString, QQmlJS::ContextualType> &types()
const {
return m_types.types(); }
131 const auto &names()
const {
return m_types.names(); }
133 void add(ImportedTypes &&other)
135 m_types.addTypes(std::move(other.m_types));
136 m_warnings.append(std::move(other.m_warnings));
139 void addWarnings(QList<QQmlJS::DiagnosticMessage> &&warnings)
141 m_warnings.append(std::move(warnings));
145 QQmlJS::ContextualTypes m_types;
146 QList<QQmlJS::DiagnosticMessage> m_warnings;
150 QList<QQmlJS::Import> m_moduleImports;
153 struct VersionedImport
157 QTypeRevision version;
159 friend bool operator==(
const VersionedImport &a,
const VersionedImport &b)
161 return a.module == b.module && a.name == b.name && a.version == b.version;
164 friend bool operator!=(
const VersionedImport &a,
const VersionedImport &b)
170 void registerVersionedImports(
const ImportedTypes &imported);
171 QList<VersionedImport> versionedImports(
const QString &filePath)
const
173 return m_versionedImports.value(filePath);
176 QQmlJSImporter(
const QStringList &importPaths, QQmlJSResourceFileMapper *mapper,
177 QQmlJSImporterFlags flags = QQmlJSImporterFlags{});
179 const QQmlJSResourceFileMapper *resourceFileMapper()
const {
return m_mapper; }
180 void setResourceFileMapper(
const QQmlJSResourceFileMapper *mapper) { m_mapper = mapper; }
182 QQmlJSResourceFileMapper *metaDataMapper()
const {
return m_metaDataMapper; }
183 void setMetaDataMapper(QQmlJSResourceFileMapper *mapper) { m_metaDataMapper = mapper; }
185 ImportedTypes importHardCodedBuiltins();
186 QList<QQmlJS::DiagnosticMessage> importQmldirs(
const QStringList &qmltypesFiles);
188 QQmlJSScope::Ptr importFile(
const QString &file);
189 ImportedTypes importDirectory(
const QString &directory, quint8 precedence,
190 const QString &prefix = QString());
193 QHash<QString, QQmlJSScope::Ptr> importedFiles()
const {
return m_importedFiles; }
195 ImportedTypes importModule(
const QString &module, quint8 precedence,
196 const QString &prefix = QString(),
197 QTypeRevision version = QTypeRevision(),
198 QStringList *staticModuleList =
nullptr);
200 ImportedTypes builtinInternalNames();
202 QStringList importPaths()
const {
return m_importPaths; }
203 void setImportPaths(
const QStringList &importPaths);
207 QQmlJSScope::ConstPtr jsGlobalObject();
208 QString pathOfModule(
const QString &moduleName, QTypeRevision revision)
const
210 const auto it = m_seenImports.constFind({ moduleName, revision });
211 return it != m_seenImports.constEnd() ? *it : QString();
214 struct ImportVisitorPrerequisites
216 ImportVisitorPrerequisites(QQmlJSScope::Ptr target, QQmlJSLogger *logger,
217 const QString &implicitImportDirectory = {},
218 const QStringList &qmldirFiles = {})
221 m_implicitImportDirectory(implicitImportDirectory),
222 m_qmldirFiles(qmldirFiles)
224 Q_ASSERT(target && logger);
227 QQmlJSScope::Ptr m_target;
228 QQmlJSLogger *m_logger;
229 QString m_implicitImportDirectory;
230 QStringList m_qmldirFiles;
232 void runImportVisitor(QQmlJS::AST::Node *rootNode,
233 const ImportVisitorPrerequisites &prerequisites);
236
237
238
239
240
241
242 using ImportVisitor = std::function<
void(QQmlJS::AST::Node *rootNode, QQmlJSImporter *self,
243 const ImportVisitorPrerequisites &prerequisites)>;
245 void setImportVisitor(ImportVisitor visitor) { m_importVisitor = visitor; }
246 void setFlags(
const QQmlJSImporterFlags &flags) { m_flags = flags; }
247 QQmlJSImporterFlags flags()
const {
return m_flags; }
250 struct AvailableTypes
252 AvailableTypes(QQmlJS::ContextualTypes builtins)
253 : cppNames(std::move(builtins))
254 , qmlNames(QQmlJS::ContextualTypes::QML, {}, {}, cppNames.arrayType())
259 QQmlJS::ContextualTypes cppNames;
262 QQmlJS::ContextualTypes qmlNames;
265 QStringList staticModules;
268 QList<QQmlJS::DiagnosticMessage> warnings;
272 QList<QQmlJS::Import> moduleImports;
275 bool hasSystemModule =
false;
278 bool wasFound =
true;
282 enum Type :
bool { Directory, Qmldir };
285 bool isStaticModule =
false;
286 bool isSystemModule =
false;
287 Type type = Directory;
289 QList<QQmlJSExportedScope> objects;
290 QHash<QString, QQmlJSExportedScope> scripts;
291 QList<QQmlDirParser::Import> imports;
292 QList<QQmlDirParser::Import> dependencies;
293 QList<QQmlDirParser::Export> exports;
296 QList<QQmlJS::DiagnosticMessage> warnings;
299 struct CachedImportKey
301 QQmlJS::Import import;
304 QTypeRevision searchVersion;
307 friend size_t qHash(
const CachedImportKey &key, size_t seed = 0)
noexcept
309 return qHashMulti(seed, key.import, key.searchVersion);
312 friend bool operator==(
const CachedImportKey &a,
const CachedImportKey &b)
314 return a.import == b.import && a.searchVersion == b.searchVersion;
317 friend bool operator!=(
const CachedImportKey &a,
const CachedImportKey &b)
323 AvailableTypes builtinImportHelper();
324 bool getTypesFromCache(AvailableTypes *types,
const CachedImportKey &cacheKey,
326 bool importHelper(
const QString &module, AvailableTypes *types, quint8 precedence,
327 const QString &prefix, QTypeRevision version, QTypeRevision searchVersion,
328 bool isDependency =
false,
bool isFile =
false);
329 void processImport(
const QQmlJS::Import &importDescription,
const Import &import,
330 quint8 precedence, AvailableTypes *types);
331 static void insertAliases(
const QQmlJS::ContextualType &type,
332 QQmlJSImporter::AvailableTypes *types);
333 void insertExport(
const QQmlJS::ContextualType &type,
const QQmlJS::Export &valExport,
334 const QString &qmlName,
335 QHash<QString, QList<QQmlJSScope::Export>> *seenExports,
336 QQmlJSImporter::AvailableTypes *types)
const;
338 resolveConflictingExports(
const QQmlJS::Import &importDescription,
339 const QQmlJSExportedScope &val, quint8 precedence,
340 QHash<QString, QList<QQmlJSScope::Export>> *seenExports,
341 QQmlJSImporter::AvailableTypes *types);
342 enum SeenVersion { LowerVersion, SameVersion, HigherVersion };
343 void insertExportWithConflictingVersion(
const QQmlJSExportedScope &val, quint8 precedence,
344 const QString &qmlName,
345 const QQmlJSScope::Export &valExport,
346 const QQmlJSScope::ConstPtr &scope,
347 QHash<QString, QList<QQmlJSScope::Export>> *seenExports,
348 QQmlJSImporter::AvailableTypes *types,
349 SeenVersion seenVersion)
const;
350 SeenVersion computeSeenVersion(
const QQmlJS::Import &importDescription,
351 const QList<QQmlJS::Export> &existingExports,
352 QTypeRevision valExportVersion)
const;
353 void insertExports(
const QQmlJS::Import &importDescription,
const QQmlJSExportedScope &val,
354 const QString &cppName, quint8 precedence,
355 QHash<QString, QList<QQmlJSScope::Export>> *seenExports,
356 QQmlJSImporter::AvailableTypes *types);
357 static QTypeRevision resolveImportVersion(
const Import &import, QTypeRevision version);
358 void importDependencies(
const Import &import, quint8 precedence, AvailableTypes *types,
359 const QString &prefix, QTypeRevision resolvedVersion,
360 QTypeRevision searchVersion,
bool isDependency);
361 QQmlDirParser createQmldirParserForFile(
const QString &filename, Import *import);
362 void readQmltypes(
const QString &filename, Import *result);
363 Import readQmldir(
const QString &dirname);
364 Import readDirectory(
const QString &directory);
366 QQmlJSScope::Ptr localFile2QQmlJSScope(
const QString &filePath);
367 static void setQualifiedNamesOn(
const Import &import);
369 QStringList m_importPaths;
371 QHash<std::pair<QString, QTypeRevision>, QString> m_seenImports;
373 QHash<CachedImportKey, QSharedPointer<AvailableTypes>> m_cachedImportTypes;
374 QHash<QString, Import> m_seenQmldirFilesAndDirectories;
376 QHash<QString, QQmlJSScope::Ptr> m_importedFiles;
379 QHash<QString, QList<VersionedImport>> m_versionedImports;
380 std::optional<AvailableTypes> m_builtins;
382 const QQmlJSResourceFileMapper *m_mapper =
nullptr;
383 QQmlJSResourceFileMapper *m_metaDataMapper =
nullptr;
384 QQmlJSImporterFlags m_flags;
385 bool useOptionalImports()
const {
return m_flags.testFlag(UseOptionalImports); };
386 bool preferQmlFilesFromSourceFolder()
const
388 return m_flags.testFlag(PreferQmlFilesFromSourceFolder);
391 ImportVisitor m_importVisitor;