summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libs/cplusplus/CppDocument.cpp116
-rw-r--r--src/libs/cplusplus/CppDocument.h16
-rw-r--r--src/libs/cplusplus/ModelManagerInterface.h3
-rw-r--r--src/libs/qmljs/qmljsinterpreter.cpp2
-rw-r--r--src/libs/qmljs/qmljsinterpreter.h1
-rw-r--r--src/libs/qmljs/qmljslink.cpp19
-rw-r--r--src/plugins/cpptools/cppmodelmanager.cpp162
-rw-r--r--src/plugins/cpptools/cppmodelmanager.h2
-rw-r--r--src/plugins/qmljstools/qmljsmodelmanager.cpp30
-rw-r--r--src/plugins/qmljstools/qmljsmodelmanager.h8
-rw-r--r--src/plugins/qmljstools/qmljstools_dependencies.pri1
-rw-r--r--src/plugins/qmljstools/qmljstoolsplugin.cpp1
12 files changed, 359 insertions, 2 deletions
diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp
index ef159e9370..c2f6af3882 100644
--- a/src/libs/cplusplus/CppDocument.cpp
+++ b/src/libs/cplusplus/CppDocument.cpp
@@ -585,6 +585,122 @@ void Document::check(CheckMode mode)
}
}
+class FindExposedQmlTypes : protected ASTVisitor
+{
+ Document *_doc;
+ QList<Document::ExportedQmlType> _exportedTypes;
+public:
+ FindExposedQmlTypes(Document *doc)
+ : ASTVisitor(doc->translationUnit())
+ , _doc(doc)
+ {}
+
+ QList<Document::ExportedQmlType> operator()()
+ {
+ _exportedTypes.clear();
+ accept(translationUnit()->ast());
+ return _exportedTypes;
+ }
+
+protected:
+ virtual bool visit(CallAST *ast)
+ {
+ IdExpressionAST *idExp = ast->base_expression->asIdExpression();
+ if (!idExp || !idExp->name)
+ return false;
+ TemplateIdAST *templateId = idExp->name->asTemplateId();
+ if (!templateId || !templateId->identifier_token)
+ return false;
+
+ // check the name
+ const Identifier *templateIdentifier = translationUnit()->identifier(templateId->identifier_token);
+ if (!templateIdentifier)
+ return false;
+ const QString callName = QString::fromUtf8(templateIdentifier->chars());
+ if (callName != QLatin1String("qmlRegisterType"))
+ return false;
+
+ // must have a single typeid template argument
+ if (!templateId->template_argument_list || !templateId->template_argument_list->value
+ || templateId->template_argument_list->next)
+ return false;
+ TypeIdAST *typeId = templateId->template_argument_list->value->asTypeId();
+ if (!typeId)
+ return false;
+
+ // must have four arguments
+ if (!ast->expression_list
+ || !ast->expression_list->value || !ast->expression_list->next
+ || !ast->expression_list->next->value || !ast->expression_list->next->next
+ || !ast->expression_list->next->next->value || !ast->expression_list->next->next->next
+ || !ast->expression_list->next->next->next->value
+ || ast->expression_list->next->next->next->next)
+ return false;
+
+ // first and last arguments must be string literals
+ const StringLiteral *packageLit = 0;
+ const StringLiteral *nameLit = 0;
+ if (StringLiteralAST *packageAst = ast->expression_list->value->asStringLiteral())
+ packageLit = translationUnit()->stringLiteral(packageAst->literal_token);
+ if (StringLiteralAST *nameAst = ast->expression_list->next->next->next->value->asStringLiteral())
+ nameLit = translationUnit()->stringLiteral(nameAst->literal_token);
+ if (!nameLit) {
+ translationUnit()->warning(ast->expression_list->next->next->next->value->firstToken(),
+ "The type will only be available in Qt Creator's QML editors when the type name is a string literal");
+ return false;
+ }
+
+ // second and third argument must be integer literals
+ const NumericLiteral *majorLit = 0;
+ const NumericLiteral *minorLit = 0;
+ if (NumericLiteralAST *majorAst = ast->expression_list->next->value->asNumericLiteral())
+ majorLit = translationUnit()->numericLiteral(majorAst->literal_token);
+ if (NumericLiteralAST *minorAst = ast->expression_list->next->next->value->asNumericLiteral())
+ minorLit = translationUnit()->numericLiteral(minorAst->literal_token);
+
+ // build the descriptor
+ Document::ExportedQmlType exportedType;
+ exportedType.typeName = QString::fromUtf8(nameLit->chars(), nameLit->size());
+ if (packageLit && majorLit && minorLit && majorLit->isInt() && minorLit->isInt()) {
+ exportedType.packageName = QString::fromUtf8(packageLit->chars(), packageLit->size());
+ exportedType.majorVersion = QString::fromUtf8(majorLit->chars(), majorLit->size()).toInt();
+ exportedType.minorVersion = QString::fromUtf8(minorLit->chars(), minorLit->size()).toInt();
+ } else {
+ translationUnit()->warning(ast->base_expression->firstToken(),
+ "The package will only be available in Qt Creator's QML editors when the package name is a string literal and\n"
+ "the versions are integer literals. The type will be available globally.");
+ exportedType.packageName = QLatin1String("<default>");
+ }
+
+ // we want to do lookup later, so also store the surrounding scope
+ unsigned line, column;
+ translationUnit()->getTokenStartPosition(ast->firstToken(), &line, &column);
+ exportedType.scope = _doc->scopeAt(line, column);
+
+ // and the expression
+ const Token begin = translationUnit()->tokenAt(typeId->firstToken());
+ const Token last = translationUnit()->tokenAt(typeId->lastToken() - 1);
+ exportedType.typeExpression = _doc->source().mid(begin.begin(), last.end() - begin.begin());
+
+ _exportedTypes += exportedType;
+
+ return false;
+ }
+};
+
+void Document::findExposedQmlTypes()
+{
+ if (! _translationUnit->ast())
+ return;
+
+ QByteArray token("qmlRegisterType");
+ if (! _translationUnit->control()->findIdentifier(token.constData(), token.size()))
+ return;
+
+ FindExposedQmlTypes finder(this);
+ _exportedQmlTypes = finder();
+}
+
void Document::releaseSource()
{
_source.clear();
diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h
index bbb7aaddb6..a00eeefa1d 100644
--- a/src/libs/cplusplus/CppDocument.h
+++ b/src/libs/cplusplus/CppDocument.h
@@ -125,6 +125,8 @@ public:
void check(CheckMode mode = FullCheck);
+ void findExposedQmlTypes();
+
void releaseSource();
void releaseTranslationUnit();
@@ -318,6 +320,19 @@ public:
const MacroUse *findMacroUseAt(unsigned offset) const;
const UndefinedMacroUse *findUndefinedMacroUseAt(unsigned offset) const;
+ class ExportedQmlType {
+ public:
+ QString packageName;
+ QString typeName;
+ int majorVersion;
+ int minorVersion;
+ Scope *scope;
+ QString typeExpression;
+ };
+
+ QList<ExportedQmlType> exportedQmlTypes() const
+ { return _exportedQmlTypes; }
+
private:
QString _fileName;
Control *_control;
@@ -329,6 +344,7 @@ private:
QList<Block> _skippedBlocks;
QList<MacroUse> _macroUses;
QList<UndefinedMacroUse> _undefinedMacroUses;
+ QList<ExportedQmlType> _exportedQmlTypes;
QByteArray _source;
QDateTime _lastModified;
unsigned _revision;
diff --git a/src/libs/cplusplus/ModelManagerInterface.h b/src/libs/cplusplus/ModelManagerInterface.h
index c58925e613..0a1f3217c4 100644
--- a/src/libs/cplusplus/ModelManagerInterface.h
+++ b/src/libs/cplusplus/ModelManagerInterface.h
@@ -35,6 +35,7 @@
#define CPPMODELMANAGERINTERFACE_H
#include <cplusplus/CppDocument.h>
+#include <languageutils/fakemetaobject.h>
#include <QtCore/QObject>
#include <QtCore/QHash>
#include <QtCore/QPointer>
@@ -146,6 +147,8 @@ public:
virtual void findMacroUsages(const CPlusPlus::Macro &macro) = 0;
+ virtual QList<LanguageUtils::FakeMetaObject *> exportedQmlObjects() const = 0;
+
Q_SIGNALS:
void documentUpdated(CPlusPlus::Document::Ptr doc);
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index e4a0d785c2..da0616cf0a 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -1947,6 +1947,7 @@ const Value *Function::invoke(const Activation *activation) const
////////////////////////////////////////////////////////////////////////////////
QList<const FakeMetaObject *> CppQmlTypesLoader::builtinObjects;
+QList<const FakeMetaObject *> CppQmlTypesLoader::cppObjects;
QStringList CppQmlTypesLoader::load(const QFileInfoList &xmlFiles)
{
@@ -2440,6 +2441,7 @@ Engine::Engine()
initializePrototypes();
_cppQmlTypes.load(this, CppQmlTypesLoader::builtinObjects);
+ _cppQmlTypes.load(this, CppQmlTypesLoader::cppObjects);
// the 'Qt' object is dumped even though it is not exported
// it contains useful information, in particular on enums - add the
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 60fbcababa..758ca27cce 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -593,6 +593,7 @@ public:
/** \return an empty list when successful, error messages otherwise. */
static QStringList load(const QFileInfoList &xmlFiles);
static QList<const LanguageUtils::FakeMetaObject *> builtinObjects;
+ static QList<const LanguageUtils::FakeMetaObject *> cppObjects;
// parses the xml string and fills the newObjects map
static QString parseQmlTypeXml(const QByteArray &xml,
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index d36dbbb021..0c4f85a174 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -162,9 +162,26 @@ void Link::populateImportedTypes(TypeEnvironment *typeEnv, Document::Ptr doc)
{
Q_D(Link);
- if (! (doc->qmlProgram() && doc->qmlProgram()->imports))
+ if (! doc->qmlProgram())
return;
+ // implicit imports: the <default> package is always available
+ const QLatin1String defaultPackage("<default>");
+ if (engine()->cppQmlTypes().hasPackage(defaultPackage)) {
+ ImportInfo info(ImportInfo::LibraryImport, defaultPackage);
+ ObjectValue *import = d->importCache.value(ImportCacheKey(info));
+ if (!import) {
+ import = new ObjectValue(engine());
+ foreach (QmlObjectValue *object,
+ engine()->cppQmlTypes().typesForImport(defaultPackage, ComponentVersion())) {
+ import->setProperty(object->className(), object);
+ }
+ d->importCache.insert(ImportCacheKey(info), import);
+ }
+ typeEnv->addImport(import, info);
+ }
+
+
// implicit imports:
// qml files in the same directory are available without explicit imports
ImportInfo implcitImportInfo(ImportInfo::ImplicitDirectoryImport, doc->path());
diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp
index efe8175dcb..19d3530346 100644
--- a/src/plugins/cpptools/cppmodelmanager.cpp
+++ b/src/plugins/cpptools/cppmodelmanager.cpp
@@ -77,6 +77,7 @@
#include <Token.h>
#include <Parser.h>
#include <Control.h>
+#include <CoreTypes.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
@@ -290,6 +291,8 @@ public:
void operator()()
{
_doc->check(_mode);
+ _doc->findExposedQmlTypes();
+ _doc->releaseSource();
_doc->releaseTranslationUnit();
if (_mode == Document::FastCheck)
@@ -589,7 +592,6 @@ void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type, unsigned
doc->setSource(preprocessedCode);
doc->tokenize();
- doc->releaseSource();
snapshot.insert(doc);
m_todo.remove(fileName);
@@ -601,6 +603,7 @@ void CppPreprocessor::sourceNeeded(QString &fileName, IncludeType type, unsigned
(void) switchDocument(previousDoc);
#else
+ doc->releaseSource();
Document::CheckMode mode = Document::FastCheck;
mode = Document::FullCheck;
doc->parse();
@@ -1418,5 +1421,162 @@ void CppModelManager::GC()
protectSnapshot.unlock();
}
+static FullySpecifiedType stripPointerAndReference(const FullySpecifiedType &type)
+{
+ Type *t = type.type();
+ while (t) {
+ if (PointerType *ptr = t->asPointerType())
+ t = ptr->elementType().type();
+ else if (ReferenceType *ref = t->asReferenceType())
+ t = ref->elementType().type();
+ else
+ break;
+ }
+ return FullySpecifiedType(t);
+}
+
+static QString toQmlType(const FullySpecifiedType &type)
+{
+ Overview overview;
+ QString result = overview(stripPointerAndReference(type));
+ if (result == QLatin1String("QString"))
+ result = QLatin1String("string");
+ return result;
+}
+
+static Class *lookupClass(const QString &expression, Scope *scope, TypeOfExpression &typeOf)
+{
+ QList<LookupItem> results = typeOf(expression, scope);
+ Class *klass = 0;
+ foreach (const LookupItem &item, results) {
+ if (item.declaration()) {
+ klass = item.declaration()->asClass();
+ if (klass)
+ return klass;
+ }
+ }
+ return 0;
+}
+
+static void populate(LanguageUtils::FakeMetaObject *fmo, Class *klass,
+ QHash<Class *, LanguageUtils::FakeMetaObject *> *classes,
+ TypeOfExpression &typeOf)
+{
+ using namespace LanguageUtils;
+
+ Overview namePrinter;
+
+ classes->insert(klass, fmo);
+
+ for (unsigned i = 0; i < klass->memberCount(); ++i) {
+ Symbol *member = klass->memberAt(i);
+ if (!member->name())
+ continue;
+ if (Function *func = member->type()->asFunctionType()) {
+ if (!func->isSlot() && !func->isInvokable() && !func->isSignal())
+ continue;
+ FakeMetaMethod method(namePrinter(func->name()), toQmlType(func->returnType()));
+ if (func->isSignal())
+ method.setMethodType(FakeMetaMethod::Signal);
+ else
+ method.setMethodType(FakeMetaMethod::Slot);
+ for (unsigned a = 0; a < func->argumentCount(); ++a) {
+ Symbol *arg = func->argumentAt(a);
+ QString name(CppModelManager::tr("unnamed"));
+ if (arg->name())
+ name = namePrinter(arg->name());
+ method.addParameter(name, toQmlType(arg->type()));
+ }
+ fmo->addMethod(method);
+ }
+ if (QtPropertyDeclaration *propDecl = member->asQtPropertyDeclaration()) {
+ const FullySpecifiedType &type = propDecl->type();
+ const bool isList = false; // ### fixme
+ const bool isWritable = propDecl->flags() & QtPropertyDeclaration::WriteFunction;
+ const bool isPointer = type.type() && type.type()->isPointerType();
+ FakeMetaProperty property(
+ namePrinter(propDecl->name()),
+ toQmlType(type),
+ isList, isWritable, isPointer);
+ fmo->addProperty(property);
+ }
+ if (QtEnum *qtEnum = member->asQtEnum()) {
+ // find the matching enum
+ Enum *e = 0;
+ QList<LookupItem> result = typeOf(namePrinter(qtEnum->name()), klass);
+ foreach (const LookupItem &item, result) {
+ if (item.declaration()) {
+ e = item.declaration()->asEnum();
+ if (e)
+ break;
+ }
+ }
+ if (!e)
+ continue;
+
+ FakeMetaEnum metaEnum(namePrinter(e->name()));
+ for (unsigned j = 0; j < e->memberCount(); ++j) {
+ Symbol *enumMember = e->memberAt(j);
+ if (!enumMember->name())
+ continue;
+ metaEnum.addKey(namePrinter(enumMember->name()), 0);
+ }
+ fmo->addEnum(metaEnum);
+ }
+ }
+
+ // only single inheritance is supported
+ if (klass->baseClassCount() > 0) {
+ BaseClass *base = klass->baseClassAt(0);
+ if (!base->name())
+ return;
+
+ const QString baseClassName = namePrinter(base->name());
+ fmo->setSuperclassName(baseClassName);
+
+ Class *baseClass = lookupClass(baseClassName, klass, typeOf);
+ if (!baseClass)
+ return;
+
+ FakeMetaObject *baseFmo = classes->value(baseClass);
+ if (!baseFmo) {
+ baseFmo = new FakeMetaObject;
+ populate(baseFmo, baseClass, classes, typeOf);
+ }
+ fmo->setSuperclass(baseFmo);
+ }
+}
+
+QList<LanguageUtils::FakeMetaObject *> CppModelManager::exportedQmlObjects() const
+{
+ using namespace LanguageUtils;
+ QList<FakeMetaObject *> exportedObjects;
+ QHash<Class *, FakeMetaObject *> classes;
+
+ const Snapshot currentSnapshot = snapshot();
+ foreach (Document::Ptr doc, currentSnapshot) {
+ TypeOfExpression typeOf;
+ typeOf.init(doc, currentSnapshot);
+ foreach (const Document::ExportedQmlType &exportedType, doc->exportedQmlTypes()) {
+ FakeMetaObject *fmo = new FakeMetaObject;
+ fmo->addExport(exportedType.typeName, exportedType.packageName,
+ ComponentVersion(exportedType.majorVersion, exportedType.minorVersion));
+ exportedObjects += fmo;
+
+ Class *klass = lookupClass(exportedType.typeExpression, exportedType.scope, typeOf);
+ if (!klass)
+ continue;
+
+ // add the no-package export, so the cpp name can be used in properties
+ Overview overview;
+ fmo->addExport(overview(klass->name()), QString(), ComponentVersion());
+
+ populate(fmo, klass, &classes, typeOf);
+ }
+ }
+
+ return exportedObjects;
+}
+
#endif
diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h
index 865421a16e..bd0bef0962 100644
--- a/src/plugins/cpptools/cppmodelmanager.h
+++ b/src/plugins/cpptools/cppmodelmanager.h
@@ -131,6 +131,8 @@ public:
virtual void findMacroUsages(const CPlusPlus::Macro &macro);
+ virtual QList<LanguageUtils::FakeMetaObject *> exportedQmlObjects() const;
+
void setHeaderSuffixes(const QStringList &suffixes)
{ m_headerSuffixes = suffixes; }
diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp
index 69f43c5579..0477f9ed01 100644
--- a/src/plugins/qmljstools/qmljsmodelmanager.cpp
+++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp
@@ -39,6 +39,7 @@
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/mimedatabase.h>
+#include <cplusplus/ModelManagerInterface.h>
#include <qmljs/qmljsinterpreter.h>
#include <qmljs/qmljsbind.h>
#include <qmljs/parser/qmldirparser_p.h>
@@ -56,6 +57,7 @@
#include <qtconcurrent/runextensions.h>
#include <QTextStream>
#include <QCoreApplication>
+#include <QTimer>
#include <QDebug>
@@ -72,6 +74,11 @@ ModelManager::ModelManager(QObject *parent):
{
m_synchronizer.setCancelOnWait(true);
+ m_updateCppQmlTypesTimer = new QTimer(this);
+ m_updateCppQmlTypesTimer->setInterval(1000);
+ m_updateCppQmlTypesTimer->setSingleShot(true);
+ connect(m_updateCppQmlTypesTimer, SIGNAL(timeout()), SLOT(updateCppQmlTypes()));
+
qRegisterMetaType<QmlJS::Document::Ptr>("QmlJS::Document::Ptr");
qRegisterMetaType<QmlJS::LibraryInfo>("QmlJS::LibraryInfo");
@@ -81,6 +88,16 @@ ModelManager::ModelManager(QObject *parent):
updateImportPaths();
}
+void ModelManager::delayedInitialization()
+{
+ CPlusPlus::CppModelManagerInterface *cppModelManager =
+ CPlusPlus::CppModelManagerInterface::instance();
+ if (cppModelManager) {
+ connect(cppModelManager, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)),
+ m_updateCppQmlTypesTimer, SLOT(start()));
+ }
+}
+
void ModelManager::loadQmlTypeDescriptions()
{
if (Core::ICore::instance()) {
@@ -537,3 +554,16 @@ void ModelManager::loadPluginTypes(const QString &libraryPath, const QString &im
{
m_pluginDumper->loadPluginTypes(libraryPath, importPath, importUri);
}
+
+void ModelManager::updateCppQmlTypes()
+{
+ CPlusPlus::CppModelManagerInterface *cppModelManager =
+ CPlusPlus::CppModelManagerInterface::instance();
+ if (!cppModelManager)
+ return;
+
+ QList<const LanguageUtils::FakeMetaObject *> constFMOs;
+ foreach (LanguageUtils::FakeMetaObject *fmo, cppModelManager->exportedQmlObjects())
+ constFMOs.append(fmo);
+ Interpreter::CppQmlTypesLoader::cppObjects = constFMOs;
+}
diff --git a/src/plugins/qmljstools/qmljsmodelmanager.h b/src/plugins/qmljstools/qmljsmodelmanager.h
index a80f18cdca..1a0b4c2833 100644
--- a/src/plugins/qmljstools/qmljsmodelmanager.h
+++ b/src/plugins/qmljstools/qmljsmodelmanager.h
@@ -44,6 +44,8 @@
#include <QMutex>
#include <QProcess>
+QT_FORWARD_DECLARE_CLASS(QTimer)
+
namespace Core {
class ICore;
class MimeType;
@@ -61,6 +63,8 @@ class QMLJSTOOLS_EXPORT ModelManager: public QmlJS::ModelManagerInterface
public:
ModelManager(QObject *parent = 0);
+ void delayedInitialization();
+
virtual WorkingCopy workingCopy() const;
virtual QmlJS::Snapshot snapshot() const;
@@ -99,6 +103,9 @@ protected:
void updateImportPaths();
+private slots:
+ void updateCppQmlTypes();
+
private:
static bool matchesMimeType(const Core::MimeType &fileMimeType, const Core::MimeType &knownMimeType);
@@ -109,6 +116,7 @@ private:
QStringList m_defaultImportPaths;
QFutureSynchronizer<void> m_synchronizer;
+ QTimer *m_updateCppQmlTypesTimer;
// project integration
QMap<ProjectExplorer::Project *, ProjectInfo> m_projects;
diff --git a/src/plugins/qmljstools/qmljstools_dependencies.pri b/src/plugins/qmljstools/qmljstools_dependencies.pri
index d63c784082..c94524e75c 100644
--- a/src/plugins/qmljstools/qmljstools_dependencies.pri
+++ b/src/plugins/qmljstools/qmljstools_dependencies.pri
@@ -1,4 +1,5 @@
include($$IDE_SOURCE_TREE/src/libs/languageutils/languageutils.pri)
+include($$IDE_SOURCE_TREE/src/libs/cplusplus/cplusplus.pri)
include($$IDE_SOURCE_TREE/src/libs/qmljs/qmljs.pri)
include($$IDE_SOURCE_TREE/src/plugins/projectexplorer/projectexplorer.pri)
include($$IDE_SOURCE_TREE/src/plugins/texteditor/texteditor.pri)
diff --git a/src/plugins/qmljstools/qmljstoolsplugin.cpp b/src/plugins/qmljstools/qmljstoolsplugin.cpp
index c1f0e91e6b..3a456eed75 100644
--- a/src/plugins/qmljstools/qmljstoolsplugin.cpp
+++ b/src/plugins/qmljstools/qmljstoolsplugin.cpp
@@ -89,6 +89,7 @@ bool QmlJSToolsPlugin::initialize(const QStringList &arguments, QString *error)
void QmlJSToolsPlugin::extensionsInitialized()
{
+ m_modelManager->delayedInitialization();
}
ExtensionSystem::IPlugin::ShutdownFlag QmlJSToolsPlugin::aboutToShutdown()