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"
prototype: "QObject"
exports: [
"QtQuick/Component 1.0"
"QML/Component 1.0"
]
exportMetaObjectRevisions: [
0
@@ -3209,7 +3209,7 @@ Module {
Component {
name: "QObject"
exports: [
"QtQuick/QtObject 1.0"
"QML/QtObject 1.0"
]
exportMetaObjectRevisions: [
0

View File

@@ -83,6 +83,7 @@ public:
const Utils::FilePath &libraryPath);
void loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc);
void loadImplicitDefaultImports(Imports *imports);
void loadImplicitBuiltinsImports(Imports *imports);
void error(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:
friend class Link;
void loadImplicitImports(Imports *imports, const QString &packageName, const QString &moduleName);
Snapshot m_snapshot;
ValueOwner *m_valueOwner = nullptr;
QList<Utils::FilePath> m_importPaths;
@@ -255,8 +258,11 @@ void LinkPrivate::populateImportedTypes(Imports *imports, const Document::Ptr &d
{
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);
// Load the <builtins> import, if the QML package was loaded.
loadImplicitBuiltinsImports(imports);
// implicit 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(defaultPackage)) {
if (m_valueOwner->cppQmlTypes().hasModule(packageName)) {
const 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));
if (!import.object) {
import.valid = true;
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);
for (const CppComponentValue *object : objects)
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