qml code model: load builtins import

LinkPrivate::linkImports() would either load the <builtins> or the
<defaults> module, but only process the <defaults> module in
LinkPrivate::populateImportedTypes().

Note: The <defaults> module (from the package '<default>') is the
QtCreator magic replacement for the actual <builtins> modules
(from the package 'QML').

This means that if the <defaults> were loaded, then QtObject would
be recognized as an object from QtQuick.
On the other hand, if the <builtins> were found, then neither
<defaults> nor <builtins> would have been imported and QtObject
would not have been found in the imports (because neither <defaults>
nor <builtins> would have been imported).

The "<defaults>-found" situation happens right after a "reset code
model" while the "<builtins>-found" appears when the qml code finally
found the <builtins> package, usually after running cmake or when a
project was freshly opened in Qt Creator.

Instead, always try to load both <defaults> and <builtins> module.

Also, fix the builtins.qmltypes (that contains the qt creators magic
types) to reflect that Component and QtObject
are both available from the QML package (the <builtins> module), as
else one cannot import QtObject from QtQml after a code mode reset.

Fixes: QTCREATORBUG-28287
Fixes: QTCREATORBUG-28375
Change-Id: I67084a169dc5ca8ec2474b721dbef83cd47037c7
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Sami Shalayel
2022-12-13 11:16:58 +01:00
committed by Thomas Hartmann
parent cb187d7912
commit 90b8e482c9
2 changed files with 24 additions and 9 deletions

View File

@@ -265,7 +265,7 @@ Module {
name: "QDeclarativeComponent" name: "QDeclarativeComponent"
prototype: "QObject" prototype: "QObject"
exports: [ exports: [
"QtQuick/Component 1.0" "QML/Component 1.0"
] ]
exportMetaObjectRevisions: [ exportMetaObjectRevisions: [
0 0
@@ -3209,7 +3209,7 @@ Module {
Component { Component {
name: "QObject" name: "QObject"
exports: [ exports: [
"QtQuick/QtObject 1.0" "QML/QtObject 1.0"
] ]
exportMetaObjectRevisions: [ exportMetaObjectRevisions: [
0 0

View File

@@ -83,6 +83,7 @@ public:
const Utils::FilePath &libraryPath); const Utils::FilePath &libraryPath);
void loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc); void loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc);
void loadImplicitDefaultImports(Imports *imports); void loadImplicitDefaultImports(Imports *imports);
void loadImplicitBuiltinsImports(Imports *imports);
void error(const Document::Ptr &doc, const SourceLocation &loc, const QString &message); void error(const Document::Ptr &doc, const SourceLocation &loc, const QString &message);
void warning(const Document::Ptr &doc, const SourceLocation &loc, const QString &message); void warning(const Document::Ptr &doc, const SourceLocation &loc, const QString &message);
@@ -91,6 +92,8 @@ public:
private: private:
friend class Link; friend class Link;
void loadImplicitImports(Imports *imports, const QString &packageName, const QString &moduleName);
Snapshot m_snapshot; Snapshot m_snapshot;
ValueOwner *m_valueOwner = nullptr; ValueOwner *m_valueOwner = nullptr;
QList<Utils::FilePath> m_importPaths; QList<Utils::FilePath> m_importPaths;
@@ -255,8 +258,11 @@ void LinkPrivate::populateImportedTypes(Imports *imports, const Document::Ptr &d
{ {
importableModuleApis.clear(); importableModuleApis.clear();
// implicit imports: the <default> package is always available // implicit imports: the <default> package is always available (except when the QML package was loaded).
// In the latter case, still try to load the <default>'s module <defaults>.
loadImplicitDefaultImports(imports); loadImplicitDefaultImports(imports);
// Load the <builtins> import, if the QML package was loaded.
loadImplicitBuiltinsImports(imports);
// implicit imports: // implicit imports:
// qml files in the same directory are available without explicit imports // qml files in the same directory are available without explicit imports
@@ -684,20 +690,19 @@ void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, const Document:
} }
} }
void LinkPrivate::loadImplicitDefaultImports(Imports *imports) void LinkPrivate::loadImplicitImports(Imports *imports, const QString &packageName, const QString &moduleName)
{ {
const QString defaultPackage = CppQmlTypes::defaultPackage; if (m_valueOwner->cppQmlTypes().hasModule(packageName)) {
if (m_valueOwner->cppQmlTypes().hasModule(defaultPackage)) {
const ComponentVersion maxVersion(ComponentVersion::MaxVersion, const ComponentVersion maxVersion(ComponentVersion::MaxVersion,
ComponentVersion::MaxVersion); ComponentVersion::MaxVersion);
const ImportInfo info = ImportInfo::moduleImport(defaultPackage, maxVersion, QString()); const ImportInfo info = ImportInfo::moduleImport(packageName, maxVersion, QString());
Import import = importCache.value(ImportCacheKey(info)); Import import = importCache.value(ImportCacheKey(info));
if (!import.object) { if (!import.object) {
import.valid = true; import.valid = true;
import.info = info; import.info = info;
import.object = new ObjectValue(m_valueOwner, QLatin1String("<defaults>")); import.object = new ObjectValue(m_valueOwner, moduleName);
const auto objects = m_valueOwner->cppQmlTypes().createObjectsForImport(defaultPackage, const auto objects = m_valueOwner->cppQmlTypes().createObjectsForImport(packageName,
maxVersion); maxVersion);
for (const CppComponentValue *object : objects) for (const CppComponentValue *object : objects)
import.object->setMember(object->className(), object); import.object->setMember(object->className(), object);
@@ -708,4 +713,14 @@ void LinkPrivate::loadImplicitDefaultImports(Imports *imports)
} }
} }
void LinkPrivate::loadImplicitDefaultImports(Imports *imports)
{
loadImplicitImports(imports, CppQmlTypes::defaultPackage, QLatin1String("<defaults>"));
}
void LinkPrivate::loadImplicitBuiltinsImports(Imports *imports)
{
loadImplicitImports(imports, QLatin1String("QML"), QLatin1String("<builtins>"));
}
} // namespace QmlJS } // namespace QmlJS