forked from qt-creator/qt-creator
QmlJS: Store plugin metatypes in LibraryInfo. Rework type loading.
This commit is contained in:
@@ -22,6 +22,13 @@ public:
|
||||
int minor() const
|
||||
{ return _minor; }
|
||||
|
||||
// something in the GNU headers introduces the major() and minor() defines,
|
||||
// use these two to disambiguate when necessary
|
||||
int majorVersion() const
|
||||
{ return _major; }
|
||||
int minorVersion() const
|
||||
{ return _minor; }
|
||||
|
||||
bool isValid() const;
|
||||
};
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@ namespace QmlJS {
|
||||
class Bind;
|
||||
class Snapshot;
|
||||
|
||||
namespace Interpreter {
|
||||
class FakeMetaObject;
|
||||
}
|
||||
|
||||
class QMLJS_EXPORT Document
|
||||
{
|
||||
public:
|
||||
@@ -113,6 +117,8 @@ class QMLJS_EXPORT LibraryInfo
|
||||
bool _valid;
|
||||
QList<QmlDirParser::Component> _components;
|
||||
QList<QmlDirParser::Plugin> _plugins;
|
||||
typedef QList<const Interpreter::FakeMetaObject *> FakeMetaObjectList;
|
||||
FakeMetaObjectList _metaObjects;
|
||||
|
||||
public:
|
||||
LibraryInfo();
|
||||
@@ -125,6 +131,12 @@ public:
|
||||
QList<QmlDirParser::Plugin> plugins() const
|
||||
{ return _plugins; }
|
||||
|
||||
FakeMetaObjectList metaObjects() const
|
||||
{ return _metaObjects; }
|
||||
|
||||
void setMetaObjects(const FakeMetaObjectList &objects)
|
||||
{ _metaObjects = objects; }
|
||||
|
||||
bool isValid() const
|
||||
{ return _valid; }
|
||||
};
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <QtCore/QMetaObject>
|
||||
#include <QtCore/QMetaProperty>
|
||||
#include <QtCore/QXmlStreamReader>
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
@@ -205,6 +204,7 @@ class FakeMetaObject {
|
||||
|
||||
QString m_name;
|
||||
QString m_package;
|
||||
QString m_packageNameVersion;
|
||||
ComponentVersion m_version;
|
||||
const FakeMetaObject *m_super;
|
||||
QString m_superName;
|
||||
@@ -218,7 +218,11 @@ class FakeMetaObject {
|
||||
public:
|
||||
FakeMetaObject(const QString &name, const QString &package, ComponentVersion version)
|
||||
: m_name(name), m_package(package), m_version(version), m_super(0)
|
||||
{}
|
||||
{
|
||||
m_packageNameVersion = QString::fromLatin1("%1.%2 %3.%4").arg(
|
||||
package, name,
|
||||
QString::number(version.majorVersion()), QString::number(version.minorVersion()));
|
||||
}
|
||||
|
||||
void setSuperclassName(const QString &superclass)
|
||||
{ m_superName = superclass; }
|
||||
@@ -233,6 +237,8 @@ public:
|
||||
{ return m_name; }
|
||||
QString packageName() const
|
||||
{ return m_package; }
|
||||
QString packageClassVersionString() const
|
||||
{ return m_packageNameVersion; }
|
||||
|
||||
void addEnum(const FakeMetaEnum &fakeEnum)
|
||||
{ m_enumNameToIndex.insert(fakeEnum.name(), m_enums.size()); m_enums.append(fakeEnum); }
|
||||
@@ -916,10 +922,10 @@ bool QmlObjectValue::hasChildInPackage() const
|
||||
{
|
||||
if (!packageName().isEmpty())
|
||||
return true;
|
||||
QHashIterator<QString, FakeMetaObject *> it(CppQmlTypesLoader::instance()->objects);
|
||||
QHashIterator<QString, QmlObjectValue *> it(engine()->cppQmlTypes().types());
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
const FakeMetaObject *other = it.value();
|
||||
const FakeMetaObject *other = it.value()->_metaObject;
|
||||
if (other->packageName().isEmpty())
|
||||
continue;
|
||||
for (const FakeMetaObject *iter = other; iter; iter = iter->superClass()) {
|
||||
@@ -1933,29 +1939,7 @@ const Value *Function::invoke(const Activation *activation) const
|
||||
// typing environment
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CppQmlTypesLoader::CppQmlTypesLoader()
|
||||
{
|
||||
QDir qmldumpExecutable(QCoreApplication::applicationDirPath());
|
||||
#ifndef Q_OS_WIN
|
||||
m_qmldumpPath = qmldumpExecutable.absoluteFilePath(QLatin1String("qmldump"));
|
||||
#else
|
||||
m_qmldumpPath = qmldumpExecutable.absoluteFilePath(QLatin1String("qmldump.exe"));
|
||||
#endif
|
||||
QFileInfo qmldumpFileInfo(m_qmldumpPath);
|
||||
if (!qmldumpFileInfo.exists()) {
|
||||
qWarning() << "QmlJS::Interpreter::CppQmlTypesLoader: qmldump executable does not exist at" << m_qmldumpPath;
|
||||
m_qmldumpPath.clear();
|
||||
} else if (!qmldumpFileInfo.isFile()) {
|
||||
qWarning() << "QmlJS::Interpreter::CppQmlTypesLoader: " << m_qmldumpPath << " is not a file";
|
||||
m_qmldumpPath.clear();
|
||||
}
|
||||
}
|
||||
|
||||
CppQmlTypesLoader *CppQmlTypesLoader::instance()
|
||||
{
|
||||
static CppQmlTypesLoader _instance;
|
||||
return &_instance;
|
||||
}
|
||||
QList<const FakeMetaObject *> CppQmlTypesLoader::objectsFromXml;
|
||||
|
||||
QStringList CppQmlTypesLoader::load(const QFileInfoList &xmlFiles)
|
||||
{
|
||||
@@ -1976,76 +1960,70 @@ QStringList CppQmlTypesLoader::load(const QFileInfoList &xmlFiles)
|
||||
}
|
||||
}
|
||||
|
||||
if (errorMsgs.isEmpty())
|
||||
addObjects(newObjects);
|
||||
if (errorMsgs.isEmpty()) {
|
||||
setSuperClasses(&newObjects);
|
||||
|
||||
// we need to go from QList<T *> of newObjects.values() to QList<const T *>
|
||||
// and there seems to be no better way
|
||||
QMapIterator<QString, FakeMetaObject *> it(newObjects);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
objectsFromXml.append(it.value());
|
||||
}
|
||||
}
|
||||
|
||||
return errorMsgs;
|
||||
}
|
||||
|
||||
void CppQmlTypesLoader::loadPluginTypes(const QString &pluginPath)
|
||||
QString CppQmlTypesLoader::parseQmlTypeXml(const QByteArray &xml, QMap<QString, FakeMetaObject *> *newObjects)
|
||||
{
|
||||
if (m_qmldumpPath.isEmpty())
|
||||
return;
|
||||
|
||||
QProcess *process = new QProcess(this);
|
||||
connect(process, SIGNAL(finished(int)), SLOT(processDone(int)));
|
||||
process->start(m_qmldumpPath, QStringList(pluginPath));
|
||||
}
|
||||
|
||||
void CppQmlTypesLoader::processDone(int exitCode)
|
||||
{
|
||||
QMap<QString, FakeMetaObject *> newObjects;
|
||||
|
||||
QProcess *process = qobject_cast<QProcess *>(sender());
|
||||
if (process && exitCode == 0) {
|
||||
const QByteArray output = process->readAllStandardOutput();
|
||||
QmlXmlReader read(output);
|
||||
if (read(&newObjects))
|
||||
addObjects(newObjects);
|
||||
QmlXmlReader reader(xml);
|
||||
if (!reader(newObjects)) {
|
||||
if (reader.errorMessage().isEmpty())
|
||||
return QLatin1String("unknown error");
|
||||
return reader.errorMessage();
|
||||
}
|
||||
process->deleteLater();
|
||||
setSuperClasses(newObjects);
|
||||
return QString();
|
||||
}
|
||||
|
||||
void CppQmlTypesLoader::addObjects(QMap<QString, FakeMetaObject *> &newObjects)
|
||||
void CppQmlTypesLoader::setSuperClasses(QMap<QString, FakeMetaObject *> *newObjects)
|
||||
{
|
||||
QMapIterator<QString, FakeMetaObject *> it(newObjects);
|
||||
QMapIterator<QString, FakeMetaObject *> it(*newObjects);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
FakeMetaObject *obj = it.value();
|
||||
//if (objects.contains(it.key()))
|
||||
// qWarning() << "QmlJS::Interpreter::MetaTypeSystem: Found duplicate type" << it.key();
|
||||
|
||||
const QString superName = obj->superclassName();
|
||||
if (! superName.isEmpty()) {
|
||||
FakeMetaObject *superClass = objects.value(superName);
|
||||
if (!superClass)
|
||||
superClass = newObjects.value(superName);
|
||||
FakeMetaObject *superClass = newObjects->value(superName);
|
||||
if (superClass)
|
||||
obj->setSuperclass(superClass);
|
||||
//else
|
||||
// qWarning() << "QmlJS::Interpreter::MetaTypeSystem: Can't find superclass" << superName << "for" << it.key();
|
||||
else
|
||||
qWarning() << "QmlJS::Interpreter::MetaTypeSystem: Can't find superclass" << superName << "for" << it.key();
|
||||
}
|
||||
|
||||
objects.insert(it.key(), obj);
|
||||
}
|
||||
}
|
||||
|
||||
void CppQmlTypes::reload(Engine *interpreter)
|
||||
void CppQmlTypes::load(Interpreter::Engine *engine, const QList<const FakeMetaObject *> &objects)
|
||||
{
|
||||
QHash<const FakeMetaObject *, QmlObjectValue *> qmlObjects;
|
||||
_importedTypes.clear();
|
||||
// load
|
||||
foreach (const FakeMetaObject *metaObject, objects) {
|
||||
// make sure we're not loading duplicate objects
|
||||
if (_typesByFullyQualifiedName.contains(metaObject->packageClassVersionString()))
|
||||
continue;
|
||||
|
||||
foreach (const FakeMetaObject *metaObject, CppQmlTypesLoader::instance()->objects) {
|
||||
QmlObjectValue *objectValue = new QmlObjectValue(metaObject, interpreter);
|
||||
qmlObjects.insert(metaObject, objectValue);
|
||||
_importedTypes[metaObject->packageName()].append(objectValue);
|
||||
QmlObjectValue *objectValue = new QmlObjectValue(metaObject, engine);
|
||||
_typesByPackage[metaObject->packageName()].append(objectValue);
|
||||
_typesByFullyQualifiedName[metaObject->packageClassVersionString()] = objectValue;
|
||||
}
|
||||
|
||||
foreach (const FakeMetaObject *metaObject, CppQmlTypesLoader::instance()->objects) {
|
||||
QmlObjectValue *objectValue = qmlObjects.value(metaObject);
|
||||
if (!objectValue)
|
||||
// set prototype correctly
|
||||
foreach (const FakeMetaObject *metaObject, objects) {
|
||||
QmlObjectValue *objectValue = _typesByFullyQualifiedName.value(metaObject->packageClassVersionString());
|
||||
if (!objectValue || !metaObject->superClass())
|
||||
continue;
|
||||
objectValue->setPrototype(qmlObjects.value(metaObject->superClass(), 0));
|
||||
objectValue->setPrototype(_typesByFullyQualifiedName.value(metaObject->superClass()->packageClassVersionString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2053,7 +2031,7 @@ QList<QmlObjectValue *> CppQmlTypes::typesForImport(const QString &packageName,
|
||||
{
|
||||
QMap<QString, QmlObjectValue *> objectValuesByName;
|
||||
|
||||
foreach (QmlObjectValue *qmlObjectValue, _importedTypes.value(packageName)) {
|
||||
foreach (QmlObjectValue *qmlObjectValue, _typesByPackage.value(packageName)) {
|
||||
if (qmlObjectValue->version() <= version) {
|
||||
// we got a candidate.
|
||||
const QString typeName = qmlObjectValue->className();
|
||||
@@ -2084,7 +2062,7 @@ QmlObjectValue *CppQmlTypes::typeForImport(const QString &qualifiedName) const
|
||||
}
|
||||
|
||||
QmlObjectValue *previousCandidate = 0;
|
||||
foreach (QmlObjectValue *qmlObjectValue, _importedTypes.value(packageName)) {
|
||||
foreach (QmlObjectValue *qmlObjectValue, _typesByPackage.value(packageName)) {
|
||||
const QString typeName = qmlObjectValue->className();
|
||||
if (typeName != name)
|
||||
continue;
|
||||
@@ -2105,7 +2083,7 @@ QmlObjectValue *CppQmlTypes::typeForImport(const QString &qualifiedName) const
|
||||
|
||||
bool CppQmlTypes::hasPackage(const QString &package) const
|
||||
{
|
||||
return _importedTypes.contains(package);
|
||||
return _typesByPackage.contains(package);
|
||||
}
|
||||
|
||||
ConvertToNumber::ConvertToNumber(Engine *engine)
|
||||
@@ -2381,7 +2359,7 @@ Engine::Engine()
|
||||
{
|
||||
initializePrototypes();
|
||||
|
||||
_cppQmlTypes.reload(this);
|
||||
_cppQmlTypes.load(this, CppQmlTypesLoader::objectsFromXml);
|
||||
}
|
||||
|
||||
Engine::~Engine()
|
||||
|
||||
@@ -512,40 +512,35 @@ private:
|
||||
// typing environment
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class QMLJS_EXPORT CppQmlTypesLoader : public QObject
|
||||
class QMLJS_EXPORT CppQmlTypesLoader
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CppQmlTypesLoader();
|
||||
static CppQmlTypesLoader *instance();
|
||||
|
||||
QHash<QString, FakeMetaObject *> objects;
|
||||
|
||||
/** \return an empty list when successful, error messages otherwise. */
|
||||
QStringList load(const QFileInfoList &xmlFiles);
|
||||
|
||||
void loadPluginTypes(const QString &pluginPath);
|
||||
|
||||
private slots:
|
||||
void processDone(int exitCode);
|
||||
static QStringList load(const QFileInfoList &xmlFiles);
|
||||
static QList<const FakeMetaObject *> objectsFromXml;
|
||||
|
||||
// parses the xml string and fills the newObjects map
|
||||
static QString parseQmlTypeXml(const QByteArray &xml, QMap<QString, FakeMetaObject *> *newObjects);
|
||||
private:
|
||||
void addObjects(QMap<QString, FakeMetaObject *> &newObjects);
|
||||
QString m_qmldumpPath;
|
||||
static void setSuperClasses(QMap<QString, FakeMetaObject *> *newObjects);
|
||||
};
|
||||
|
||||
class QMLJS_EXPORT CppQmlTypes
|
||||
{
|
||||
public:
|
||||
void reload(Interpreter::Engine *interpreter);
|
||||
void load(Interpreter::Engine *interpreter, const QList<const FakeMetaObject *> &objects);
|
||||
|
||||
QList<Interpreter::QmlObjectValue *> typesForImport(const QString &prefix, ComponentVersion version) const;
|
||||
Interpreter::QmlObjectValue *typeForImport(const QString &qualifiedName) const;
|
||||
|
||||
bool hasPackage(const QString &package) const;
|
||||
|
||||
QHash<QString, QmlObjectValue *> types() const
|
||||
{ return _typesByFullyQualifiedName; }
|
||||
|
||||
private:
|
||||
QHash<QString, QList<QmlObjectValue *> > _importedTypes;
|
||||
QHash<QString, QList<QmlObjectValue *> > _typesByPackage;
|
||||
QHash<QString, QmlObjectValue *> _typesByFullyQualifiedName;
|
||||
};
|
||||
|
||||
class ConvertToNumber: protected ValueVisitor // ECMAScript ToInt()
|
||||
@@ -695,6 +690,8 @@ public:
|
||||
QString typeId(const Value *value);
|
||||
|
||||
// typing:
|
||||
CppQmlTypes &cppQmlTypes()
|
||||
{ return _cppQmlTypes; }
|
||||
const CppQmlTypes &cppQmlTypes() const
|
||||
{ return _cppQmlTypes; }
|
||||
|
||||
|
||||
@@ -269,49 +269,55 @@ void Link::importNonFile(Interpreter::ObjectValue *typeEnv, Document::Ptr doc, A
|
||||
return;
|
||||
}
|
||||
|
||||
// if the package is in the meta type system, use it
|
||||
bool importFound = false;
|
||||
|
||||
// check the filesystem
|
||||
const QString packagePath = Bind::toString(import->importUri, QDir::separator());
|
||||
foreach (const QString &importPath, _importPaths) {
|
||||
QDir dir(importPath);
|
||||
if (!dir.cd(packagePath))
|
||||
continue;
|
||||
|
||||
const LibraryInfo libraryInfo = _snapshot.libraryInfo(dir.path());
|
||||
if (!libraryInfo.isValid())
|
||||
continue;
|
||||
|
||||
importFound = true;
|
||||
|
||||
if (!libraryInfo.plugins().isEmpty())
|
||||
engine()->cppQmlTypes().load(engine(), libraryInfo.metaObjects());
|
||||
|
||||
QSet<QString> importedTypes;
|
||||
foreach (const QmlDirParser::Component &component, libraryInfo.components()) {
|
||||
if (importedTypes.contains(component.typeName))
|
||||
continue;
|
||||
|
||||
ComponentVersion componentVersion(component.majorVersion, component.minorVersion);
|
||||
if (version < componentVersion)
|
||||
continue;
|
||||
|
||||
importedTypes.insert(component.typeName);
|
||||
if (Document::Ptr importedDoc = _snapshot.document(dir.filePath(component.fileName))) {
|
||||
if (importedDoc->bind()->rootObjectValue())
|
||||
namespaceObject->setProperty(component.typeName, importedDoc->bind()->rootObjectValue());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// if there are cpp-based types for this package, use them too
|
||||
if (engine()->cppQmlTypes().hasPackage(packageName)) {
|
||||
importFound = true;
|
||||
foreach (QmlObjectValue *object, engine()->cppQmlTypes().typesForImport(packageName, version)) {
|
||||
namespaceObject->setProperty(object->className(), object);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// check the filesystem
|
||||
const QString packagePath = Bind::toString(import->importUri, QDir::separator());
|
||||
foreach (const QString &importPath, _importPaths) {
|
||||
QDir dir(importPath);
|
||||
if (!dir.cd(packagePath))
|
||||
continue;
|
||||
|
||||
const LibraryInfo libraryInfo = _snapshot.libraryInfo(dir.path());
|
||||
if (!libraryInfo.isValid())
|
||||
continue;
|
||||
|
||||
if (!libraryInfo.plugins().isEmpty())
|
||||
_context->setDocumentImportsPlugins(doc.data());
|
||||
|
||||
QSet<QString> importedTypes;
|
||||
foreach (const QmlDirParser::Component &component, libraryInfo.components()) {
|
||||
if (importedTypes.contains(component.typeName))
|
||||
continue;
|
||||
|
||||
ComponentVersion componentVersion(component.majorVersion, component.minorVersion);
|
||||
if (version < componentVersion)
|
||||
continue;
|
||||
|
||||
importedTypes.insert(component.typeName);
|
||||
if (Document::Ptr importedDoc = _snapshot.document(dir.filePath(component.fileName))) {
|
||||
if (importedDoc->bind()->rootObjectValue())
|
||||
namespaceObject->setProperty(component.typeName, importedDoc->bind()->rootObjectValue());
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
error(doc, locationFromRange(import->firstSourceLocation(), import->lastSourceLocation()),
|
||||
tr("package not found"));
|
||||
if (!importFound) {
|
||||
error(doc, locationFromRange(import->firstSourceLocation(), import->lastSourceLocation()),
|
||||
tr("package not found"));
|
||||
}
|
||||
}
|
||||
|
||||
UiQualifiedId *Link::qualifiedTypeNameId(Node *node)
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <QtConcurrentRun>
|
||||
#include <qtconcurrent/runextensions.h>
|
||||
#include <QTextStream>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
@@ -85,7 +86,7 @@ void ModelManager::loadQmlTypeDescriptions()
|
||||
QDir::Files,
|
||||
QDir::Name);
|
||||
|
||||
const QStringList errors = Interpreter::CppQmlTypesLoader::instance()->load(xmlFiles);
|
||||
const QStringList errors = Interpreter::CppQmlTypesLoader::load(xmlFiles);
|
||||
foreach (const QString &error, errors)
|
||||
qWarning() << qPrintable(error);
|
||||
}
|
||||
@@ -195,7 +196,7 @@ void ModelManager::onLibraryInfoUpdated(const QString &path, const LibraryInfo &
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (!_snapshot.libraryInfo(path).isValid())
|
||||
QmlJS::Interpreter::CppQmlTypesLoader::instance()->loadPluginTypes(path);
|
||||
loadQmlPluginTypes(path);
|
||||
|
||||
_snapshot.insertLibraryInfo(path, info);
|
||||
}
|
||||
@@ -435,3 +436,64 @@ static QStringList environmentImportPaths()
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
void ModelManager::loadQmlPluginTypes(const QString &pluginPath)
|
||||
{
|
||||
static QString qmldumpPath;
|
||||
if (qmldumpPath.isNull()) {
|
||||
QDir qmldumpExecutable(QCoreApplication::applicationDirPath());
|
||||
#ifndef Q_OS_WIN
|
||||
qmldumpPath = qmldumpExecutable.absoluteFilePath(QLatin1String("qmldump"));
|
||||
#else
|
||||
qmldumpPath = qmldumpExecutable.absoluteFilePath(QLatin1String("qmldump.exe"));
|
||||
#endif
|
||||
QFileInfo qmldumpFileInfo(qmldumpPath);
|
||||
if (!qmldumpFileInfo.exists()) {
|
||||
qWarning() << "ModelManager::loadQmlPluginTypes: qmldump executable does not exist at" << qmldumpPath;
|
||||
qmldumpPath.clear();
|
||||
} else if (!qmldumpFileInfo.isFile()) {
|
||||
qWarning() << "ModelManager::loadQmlPluginTypes: " << qmldumpPath << " is not a file";
|
||||
qmldumpPath.clear();
|
||||
}
|
||||
|
||||
}
|
||||
if (qmldumpPath.isEmpty())
|
||||
return;
|
||||
|
||||
QProcess *process = new QProcess(this);
|
||||
connect(process, SIGNAL(finished(int)), SLOT(qmlPluginTypeDumpDone(int)));
|
||||
process->start(qmldumpPath, QStringList(pluginPath));
|
||||
m_runningQmldumps.insert(process, pluginPath);
|
||||
}
|
||||
|
||||
void ModelManager::qmlPluginTypeDumpDone(int exitCode)
|
||||
{
|
||||
QProcess *process = qobject_cast<QProcess *>(sender());
|
||||
if (!process)
|
||||
return;
|
||||
process->deleteLater();
|
||||
if (exitCode != 0)
|
||||
return;
|
||||
|
||||
const QByteArray output = process->readAllStandardOutput();
|
||||
QMap<QString, Interpreter::FakeMetaObject *> newObjects;
|
||||
const QString error = Interpreter::CppQmlTypesLoader::parseQmlTypeXml(output, &newObjects);
|
||||
if (!error.isEmpty())
|
||||
return;
|
||||
|
||||
// convert from QList<T *> to QList<const T *>
|
||||
QList<const Interpreter::FakeMetaObject *> objectsList;
|
||||
QMapIterator<QString, Interpreter::FakeMetaObject *> it(newObjects);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
objectsList.append(it.value());
|
||||
}
|
||||
|
||||
const QString libraryPath = m_runningQmldumps.take(process);
|
||||
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
LibraryInfo libraryInfo = _snapshot.libraryInfo(libraryPath);
|
||||
libraryInfo.setMetaObjects(objectsList);
|
||||
_snapshot.insertLibraryInfo(libraryPath, libraryInfo);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <QFuture>
|
||||
#include <QFutureSynchronizer>
|
||||
#include <QMutex>
|
||||
#include <QProcess>
|
||||
|
||||
namespace Core {
|
||||
class ICore;
|
||||
@@ -74,6 +75,7 @@ private Q_SLOTS:
|
||||
// this should be executed in the GUI thread.
|
||||
void onDocumentUpdated(QmlJS::Document::Ptr doc);
|
||||
void onLibraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info);
|
||||
void qmlPluginTypeDumpDone(int exitCode);
|
||||
|
||||
protected:
|
||||
struct WorkingCopy
|
||||
@@ -94,6 +96,7 @@ protected:
|
||||
bool emitDocChangedOnDisk);
|
||||
|
||||
void loadQmlTypeDescriptions();
|
||||
void loadQmlPluginTypes(const QString &pluginPath);
|
||||
|
||||
private:
|
||||
static bool matchesMimeType(const Core::MimeType &fileMimeType, const Core::MimeType &knownMimeType);
|
||||
@@ -103,6 +106,7 @@ private:
|
||||
QmlJS::Snapshot _snapshot;
|
||||
QStringList m_projectImportPaths;
|
||||
QStringList m_defaultImportPaths;
|
||||
QHash<QProcess *, QString> m_runningQmldumps;
|
||||
|
||||
QFutureSynchronizer<void> m_synchronizer;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
static QHash<QByteArray, const QDeclarativeType *> qmlTypeByCppName;
|
||||
static QHash<QByteArray, QByteArray> cppToQml;
|
||||
static QByteArray pluginPackage;
|
||||
|
||||
QByteArray convertToQmlType(const QByteArray &cppName)
|
||||
{
|
||||
@@ -187,8 +186,6 @@ public:
|
||||
void dump(const QMetaObject *meta, QXmlStreamWriter *xml)
|
||||
{
|
||||
QByteArray qmlTypeName = convertToQmlType(meta->className());
|
||||
if (!pluginPackage.isEmpty() && !qmlTypeName.startsWith(pluginPackage))
|
||||
return;
|
||||
|
||||
xml->writeStartElement("type");
|
||||
|
||||
@@ -258,7 +255,6 @@ int main(int argc, char *argv[])
|
||||
if (pluginPath.exists() && pluginPath.isDir()) {
|
||||
pluginImportPath = pluginPath.absolutePath();
|
||||
pluginImportName = pluginPath.fileName();
|
||||
pluginPackage = (pluginImportName + ".").toLatin1();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,6 +276,7 @@ int main(int argc, char *argv[])
|
||||
QByteArray code = importCode;
|
||||
code += "Item {}";
|
||||
QDeclarativeComponent c(engine);
|
||||
|
||||
c.setData(code, QUrl("xxx"));
|
||||
c.create();
|
||||
if (!c.errors().isEmpty())
|
||||
@@ -335,7 +332,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
QDeclarativeComponent c(engine);
|
||||
c.setData(code, QUrl("xxx"));
|
||||
processObject(c.create(), &metas);
|
||||
|
||||
QObject *object = c.create();
|
||||
if (object)
|
||||
processObject(object, &metas);
|
||||
else
|
||||
qDebug() << "Could not create" << tyName << ":" << c.errorString();
|
||||
}
|
||||
|
||||
QByteArray bytes;
|
||||
|
||||
Reference in New Issue
Block a user