Qt-creator-type-info

From Qt Wiki
Jump to navigation Jump to search

QML Code Model: Type info

The information needed to build the code model are gathered by the ModelManager, in several phases from different sources:

  • when QtCreator loads the qmljslib plugin at start-up, from system and user type descriptors;
  • when a project is opened, from projects type descriptors and qml files;
  • when a source file is opened, modified or saved.

Type Descriptors

Type descriptors are files with extensions qmltypes. Usually they are distributed as part of a Qml module, as described in (Qt documentation)[1]. The base types of Qml are defined in a qmltypes file distributed with QtCreator.

Most of the code model operations are handled by a "model manager".

Plugin Initialization

The QmlJSToolsPlugin::initialize method create a new model manager. The model manager's constructor registers the meta-type QmlJSTools::SemanticInfo and reads the the default type descriptions:

ModelManager::ModelManager
ModelManager::loadDefaultQmlTypeDescription
ModelManager::loadQmlTypeDescriptionInternal

The last method is called two times. It perform the following actions:

  • /qml-type-descriptions is appended to a search path;
  • all *.qmltypes from the resulting path are loaded;
  • builtins.qmltypes is filtered out and saved as CppQmlTypesLoader::defaultQtObjects;
  • all others *.qmltypes are loaded and merged as CppQmlTypesLoader::defaultLibraryObjects.

The first time is called with argument ICore::resourcePath equal to <QTCHOME>/share/qtcreator. The second time it is called with argument ICore::userResourcePath that results equal to $HOME/.config/QtProject. If the directory does not exists, it is created.

Here is the calls chain for reading these files:

CppQmlTypesLoader::loadQmlTypes
CppQmlTypesLoader::parseQmlTypesDescriptions
TypeDescriptionReader::operator()
TypeDescriptionReader::readDocument
TypeDescriptionReader::readModule
TypeDescriptionReader::readComponent || TypeDescriptionReader::readModuleApi

The plugin initialize method also instantiate the following classes:

  • ConsoleManager
  • LocatorData
  • FunctionFilter
  • QmlJSCodeStyleSettingPage
  • BasicBundleProvider

and some other things like action and menus.

Project Loading

After some actions from ProjectExplorerPlugin and SessionManager, there are some calls to model manager:

ModelManager::updateDefaultProjectInfo
ModelManager::defaultProjectInfo

the last method find the active kit and set projectInfo.tryQmlDump if the qt version is valid and its type is DESKTOPQT. If the qt version is valid, it also set projectInfo.qtQmlPath to QT_INSTALL_QML and qtImportPath to QT_INSTALL_IMPORTS. Otherwise these values are token from QLibraryInfo::Qml2ImportPath and QLibaryInfo::ImportsPath.

setupProjectInfoQmlBundles
BasicBundleProvider::mergeBundlesForKit

the last method merges all the relevant bundles depending on the QtQuick version.

Model managerÔÇÖs constructor instantiate also ModelManagerInterface that instantiate PluginDumper, that is a wrapper around qmlplugindump tool. The tool is invoked only in the private slot onLoadBuiltinTypes and the private dump method, that it used only in private slots:

  • onLoadPluginTypes
  • dumpAllPlugins
  • pluginChanged

On the other hand onLoadBuiltinTypes is invoked by loadBuiltinTypes public method and the dumpBuiltins private slot. loadBuiltinTypes is called when opening a project by ModelManagerInterface::updateProjectInfo but if a suitable builtins.qmltypes file is found, it is loaded, and there is no dumping. onLoadPluginTypes is called for each plugin found when opening a project, but if a suitable qmltypes exists it doesnÔÇÖt dump. dumpAllPlugins is called for each plugin used by the project (?), but again, it doesnÔÇÖt dump anything that already exists.

All the calls to onLoadPluginTypes are triggered (passing through the model manager) by LinkPrivate::importLibrary that is called by LinkPrivate::importFileOrDirectory and by LinkPrivate::importNonFile. Both these methods are called by LinkPrivate::populateImportedTypes.

The last one is called by LinkPrivate::linkImports() called by Link::operator(). Before calling LinkPrivate::populateImportedTypes, LinkPrivate::linkImports() loads meta-objects from builtins, defaultQtObjects and defaultLibraryObjects that were created on QtCreator startup. It also calls custom imports for the opened document (?) via `ExtensionSystem::PluginManager::getObjects<CustomImportsProvider>()

ModelManagerInterface::parseLoop: parse all qml files in project and libraries. It skips files with Dialect::QmlTypeInfo and Dialect::QmlProject. Look at class TypeDescritionReader for the parser of QmlTypeInfo dialect.

Open Files

Open files are monitored in order to updating semantic information. The relevant methods are:

QThreadPrivate::start QmlJSEditor::Internal::SemanticInfoUpdater::run
QmlJSEditor::Internal::SemanticInfoUpdater::makeNewSemanticInfo

The scope chain is built here; also the staticAnalysisMessage of SemanticInfo instance are initialized here, by calling an instance of the Check class. This class create new instances of ScopeChain.

QThreadPrivate::start QThreadPoolThread::run
QtConcurrent::StoredInterfaceFunctionCall5 ModelManagerInterface::parse
ModelManagerInterface::parseLoop Check::operator()

start traversing AST, with this as visitor chain of access0 calls, specialized for the types defined in the Abstract Syntax Tree. Relevant method used in static checks are:

Check::visitQmlObject
Check::visit
Check::checkScopeObjectMember
ObjectValue::lookupMember
ASTObjectValue::processMember