Commit ab642bc8 authored by Christian Kamm's avatar Christian Kamm

QmlJS: Add refcounting to FakeMetaObjects.

Previously they were leaked when a qmldump or the C++ exported QML
type list updated.

Just deleting the previous FakeMetaObjects is not an option, as they
might still be used in a QmlObjectValue owned by an Engine.

Reviewed-by: Erik Verbruggen
parent 62d66fcd
......@@ -147,7 +147,7 @@ public:
virtual void findMacroUsages(const CPlusPlus::Macro &macro) = 0;
virtual QList<LanguageUtils::FakeMetaObject *> exportedQmlObjects() const = 0;
virtual QList<LanguageUtils::FakeMetaObject::ConstPtr> exportedQmlObjects() const = 0;
Q_SIGNALS:
void documentUpdated(CPlusPlus::Document::Ptr doc);
......
......@@ -128,9 +128,9 @@ void FakeMetaObject::setSuperclassName(const QString &superclass)
QString FakeMetaObject::superclassName() const
{ return m_superName; }
void FakeMetaObject::setSuperclass(FakeMetaObject *superClass)
void FakeMetaObject::setSuperclass(ConstPtr superClass)
{ m_super = superClass; }
const FakeMetaObject *FakeMetaObject::superClass() const
FakeMetaObject::ConstPtr FakeMetaObject::superClass() const
{ return m_super; }
void FakeMetaObject::addEnum(const FakeMetaEnum &fakeEnum)
......
......@@ -41,6 +41,7 @@
#include <QtCore/QStringList>
#include <QtCore/QList>
#include <QtCore/QHash>
#include <QtCore/QSharedPointer>
namespace LanguageUtils {
......@@ -118,6 +119,9 @@ class LANGUAGEUTILS_EXPORT FakeMetaObject {
Q_DISABLE_COPY(FakeMetaObject);
public:
typedef QSharedPointer<FakeMetaObject> Ptr;
typedef QSharedPointer<const FakeMetaObject> ConstPtr;
class Export {
public:
QString package;
......@@ -128,7 +132,7 @@ public:
private:
QList<Export> m_exports;
const FakeMetaObject *m_super;
ConstPtr m_super;
QString m_superName;
QList<FakeMetaEnum> m_enums;
QHash<QString, int> m_enumNameToIndex;
......@@ -145,8 +149,8 @@ public:
void setSuperclassName(const QString &superclass);
QString superclassName() const;
void setSuperclass(FakeMetaObject *superClass);
const FakeMetaObject *superClass() const;
void setSuperclass(ConstPtr superClass);
ConstPtr superClass() const;
void addEnum(const FakeMetaEnum &fakeEnum);
int enumeratorCount() const;
......
......@@ -39,16 +39,14 @@
#include <QtCore/QSharedPointer>
#include <QtCore/QString>
#include <languageutils/fakemetaobject.h>
#include "parser/qmldirparser_p.h"
#include "parser/qmljsengine_p.h"
#include "qmljs_global.h"
QT_QML_BEGIN_NAMESPACE
namespace LanguageUtils {
class FakeMetaObject;
}
namespace QmlJS {
class Bind;
......@@ -134,7 +132,7 @@ private:
bool _valid;
QList<QmlDirParser::Component> _components;
QList<QmlDirParser::Plugin> _plugins;
typedef QList<const LanguageUtils::FakeMetaObject *> FakeMetaObjectList;
typedef QList<LanguageUtils::FakeMetaObject::ConstPtr> FakeMetaObjectList;
FakeMetaObjectList _metaObjects;
DumpStatus _dumpStatus;
......
This diff is collapsed.
......@@ -35,6 +35,7 @@
#define QMLJS_INTERPRETER_H
#include <languageutils/componentversion.h>
#include <languageutils/fakemetaobject.h>
#include <qmljs/qmljsdocument.h>
#include <qmljs/qmljs_global.h>
#include <qmljs/parser/qmljsastfwd_p.h>
......@@ -46,13 +47,6 @@
#include <QtCore/QSet>
#include <QtCore/QMutex>
namespace LanguageUtils {
class FakeMetaObject;
class FakeMetaMethod;
class FakeMetaProperty;
class FakeMetaEnum;
}
namespace QmlJS {
class NameId;
......@@ -452,7 +446,7 @@ private:
class QMLJS_EXPORT QmlObjectValue: public ObjectValue
{
public:
QmlObjectValue(const LanguageUtils::FakeMetaObject *metaObject, const QString &className,
QmlObjectValue(LanguageUtils::FakeMetaObject::ConstPtr metaObject, const QString &className,
const QString &packageName, const LanguageUtils::ComponentVersion version,
Engine *engine);
virtual ~QmlObjectValue();
......@@ -478,10 +472,10 @@ public:
protected:
const Value *findOrCreateSignature(int index, const LanguageUtils::FakeMetaMethod &method,
QString *methodName) const;
bool isDerivedFrom(const LanguageUtils::FakeMetaObject *base) const;
bool isDerivedFrom(LanguageUtils::FakeMetaObject::ConstPtr base) const;
private:
const LanguageUtils::FakeMetaObject *_metaObject;
LanguageUtils::FakeMetaObject::ConstPtr _metaObject;
const QString _packageName;
const LanguageUtils::ComponentVersion _componentVersion;
mutable QHash<int, const Value *> _metaSignature;
......@@ -592,20 +586,20 @@ class QMLJS_EXPORT CppQmlTypesLoader
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;
static QList<LanguageUtils::FakeMetaObject::ConstPtr> builtinObjects;
static QList<LanguageUtils::FakeMetaObject::ConstPtr> cppObjects;
// parses the xml string and fills the newObjects map
static QString parseQmlTypeXml(const QByteArray &xml,
QMap<QString, LanguageUtils::FakeMetaObject *> *newObjects);
QMap<QString, LanguageUtils::FakeMetaObject::Ptr> *newObjects);
private:
static void setSuperClasses(QMap<QString, LanguageUtils::FakeMetaObject *> *newObjects);
static void setSuperClasses(QMap<QString, LanguageUtils::FakeMetaObject::Ptr> *newObjects);
};
class QMLJS_EXPORT CppQmlTypes
{
public:
void load(Interpreter::Engine *interpreter, const QList<const LanguageUtils::FakeMetaObject *> &objects);
void load(Interpreter::Engine *interpreter, const QList<LanguageUtils::FakeMetaObject::ConstPtr> &objects);
QList<Interpreter::QmlObjectValue *> typesForImport(const QString &prefix, LanguageUtils::ComponentVersion version) const;
Interpreter::QmlObjectValue *typeForImport(const QString &qualifiedName,
......@@ -623,7 +617,7 @@ public:
private:
QmlObjectValue *getOrCreate(const QString &package, const QString &cppName,
const LanguageUtils::FakeMetaObject *metaObject,
LanguageUtils::FakeMetaObject::ConstPtr metaObject,
Engine *engine, bool *created);
......
......@@ -1459,8 +1459,8 @@ static Class *lookupClass(const QString &expression, Scope *scope, TypeOfExpress
return 0;
}
static void populate(LanguageUtils::FakeMetaObject *fmo, Class *klass,
QHash<Class *, LanguageUtils::FakeMetaObject *> *classes,
static void populate(LanguageUtils::FakeMetaObject::Ptr fmo, Class *klass,
QHash<Class *, LanguageUtils::FakeMetaObject::Ptr> *classes,
TypeOfExpression &typeOf)
{
using namespace LanguageUtils;
......@@ -1539,27 +1539,27 @@ static void populate(LanguageUtils::FakeMetaObject *fmo, Class *klass,
if (!baseClass)
return;
FakeMetaObject *baseFmo = classes->value(baseClass);
FakeMetaObject::Ptr baseFmo = classes->value(baseClass);
if (!baseFmo) {
baseFmo = new FakeMetaObject;
baseFmo = FakeMetaObject::Ptr(new FakeMetaObject);
populate(baseFmo, baseClass, classes, typeOf);
}
fmo->setSuperclass(baseFmo);
}
}
QList<LanguageUtils::FakeMetaObject *> CppModelManager::exportedQmlObjects() const
QList<LanguageUtils::FakeMetaObject::ConstPtr> CppModelManager::exportedQmlObjects() const
{
using namespace LanguageUtils;
QList<FakeMetaObject *> exportedObjects;
QHash<Class *, FakeMetaObject *> classes;
QList<FakeMetaObject::ConstPtr> exportedObjects;
QHash<Class *, FakeMetaObject::Ptr> 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;
FakeMetaObject::Ptr fmo(new FakeMetaObject);
fmo->addExport(exportedType.typeName, exportedType.packageName,
ComponentVersion(exportedType.majorVersion, exportedType.minorVersion));
exportedObjects += fmo;
......
......@@ -131,7 +131,7 @@ public:
virtual void findMacroUsages(const CPlusPlus::Macro &macro);
virtual QList<LanguageUtils::FakeMetaObject *> exportedQmlObjects() const;
virtual QList<LanguageUtils::FakeMetaObject::ConstPtr> exportedQmlObjects() const;
void setHeaderSuffixes(const QStringList &suffixes)
{ m_headerSuffixes = suffixes; }
......
......@@ -562,8 +562,5 @@ void ModelManager::updateCppQmlTypes()
if (!cppModelManager)
return;
QList<const LanguageUtils::FakeMetaObject *> constFMOs;
foreach (LanguageUtils::FakeMetaObject *fmo, cppModelManager->exportedQmlObjects())
constFMOs.append(fmo);
Interpreter::CppQmlTypesLoader::cppObjects = constFMOs;
Interpreter::CppQmlTypesLoader::cppObjects = cppModelManager->exportedQmlObjects();
}
......@@ -126,15 +126,15 @@ static QString qmldumpFailedMessage()
return PluginDumper::tr("Type dump of C++ plugin failed.\nCheck 'General Messages' output pane for details.");
}
static QList<const FakeMetaObject *> parseHelper(const QByteArray &xml, QString *error)
static QList<FakeMetaObject::ConstPtr> parseHelper(const QByteArray &xml, QString *error)
{
QList<const FakeMetaObject *> ret;
QMap<QString, FakeMetaObject *> newObjects;
QList<FakeMetaObject::ConstPtr> ret;
QMap<QString, FakeMetaObject::Ptr> newObjects;
*error = Interpreter::CppQmlTypesLoader::parseQmlTypeXml(xml, &newObjects);
if (error->isEmpty()) {
// convert from QList<T *> to QList<const T *>
QMapIterator<QString, FakeMetaObject *> it(newObjects);
QMapIterator<QString, FakeMetaObject::Ptr> it(newObjects);
while (it.hasNext()) {
it.next();
ret.append(it.value());
......@@ -162,7 +162,7 @@ void PluginDumper::qmlPluginTypeDumpDone(int exitCode)
const QByteArray output = process->readAllStandardOutput();
QString error;
QList<const FakeMetaObject *> objectsList = parseHelper(output, &error);
QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(output, &error);
if (exitCode == 0 && !error.isEmpty()) {
libraryInfo.setDumpStatus(LibraryInfo::DumpError, tr("Type dump of C++ plugin failed. Parse error:\n'%1'").arg(error));
}
......@@ -229,7 +229,7 @@ void PluginDumper::dump(const Plugin &plugin)
libraryXmlFile.close();
QString error;
const QList<const FakeMetaObject *> objectsList = parseHelper(xml, &error);
const QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(xml, &error);
if (error.isEmpty()) {
libraryInfo.setMetaObjects(objectsList);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment