forked from qt-creator/qt-creator
qmljs: track origin of ObjectValues
allows unique identification of types Change-Id: Id4e6a9c1fa23409b1e2d5eb32708a0bacd04a5da Reviewed-by: Tim Jenssen <tim.jenssen@digia.com> Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
This commit is contained in:
@@ -170,13 +170,29 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|
||||||
|
FakeMetaObjectWithOrigin::FakeMetaObjectWithOrigin(FakeMetaObject::ConstPtr fakeMetaObject, const QString &originId)
|
||||||
|
: fakeMetaObject(fakeMetaObject)
|
||||||
|
, originId(originId)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool FakeMetaObjectWithOrigin::operator ==(const FakeMetaObjectWithOrigin &o) const
|
||||||
|
{
|
||||||
|
return fakeMetaObject == o.fakeMetaObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint qHash(const FakeMetaObjectWithOrigin &fmoo, int seed)
|
||||||
|
{
|
||||||
|
return qHash(fmoo.fakeMetaObject, seed);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlJS
|
} // namespace QmlJS
|
||||||
|
|
||||||
CppComponentValue::CppComponentValue(FakeMetaObject::ConstPtr metaObject, const QString &className,
|
CppComponentValue::CppComponentValue(FakeMetaObject::ConstPtr metaObject, const QString &className,
|
||||||
const QString &packageName, const ComponentVersion &componentVersion,
|
const QString &packageName, const ComponentVersion &componentVersion,
|
||||||
const ComponentVersion &importVersion, int metaObjectRevision,
|
const ComponentVersion &importVersion, int metaObjectRevision,
|
||||||
ValueOwner *valueOwner)
|
ValueOwner *valueOwner, const QString &originId)
|
||||||
: ObjectValue(valueOwner),
|
: ObjectValue(valueOwner, originId),
|
||||||
m_metaObject(metaObject),
|
m_metaObject(metaObject),
|
||||||
m_moduleName(packageName),
|
m_moduleName(packageName),
|
||||||
m_componentVersion(componentVersion),
|
m_componentVersion(componentVersion),
|
||||||
@@ -960,8 +976,8 @@ bool MemberProcessor::processGeneratedSlot(const QString &, const Value *)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectValue::ObjectValue(ValueOwner *valueOwner)
|
ObjectValue::ObjectValue(ValueOwner *valueOwner, const QString &originId)
|
||||||
: m_valueOwner(valueOwner),
|
: m_valueOwner(valueOwner), m_originId(originId),
|
||||||
_prototype(0)
|
_prototype(0)
|
||||||
{
|
{
|
||||||
valueOwner->registerValue(this);
|
valueOwner->registerValue(this);
|
||||||
@@ -1374,7 +1390,7 @@ const QLatin1String CppQmlTypes::defaultPackage("<default>");
|
|||||||
const QLatin1String CppQmlTypes::cppPackage("<cpp>");
|
const QLatin1String CppQmlTypes::cppPackage("<cpp>");
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void CppQmlTypes::load(const T &fakeMetaObjects, const QString &overridePackage)
|
void CppQmlTypes::load(const QString &originId, const T &fakeMetaObjects, const QString &overridePackage)
|
||||||
{
|
{
|
||||||
QList<CppComponentValue *> newCppTypes;
|
QList<CppComponentValue *> newCppTypes;
|
||||||
foreach (const FakeMetaObject::ConstPtr &fmo, fakeMetaObjects) {
|
foreach (const FakeMetaObject::ConstPtr &fmo, fakeMetaObjects) {
|
||||||
@@ -1382,7 +1398,7 @@ void CppQmlTypes::load(const T &fakeMetaObjects, const QString &overridePackage)
|
|||||||
QString package = exp.package;
|
QString package = exp.package;
|
||||||
if (package.isEmpty())
|
if (package.isEmpty())
|
||||||
package = overridePackage;
|
package = overridePackage;
|
||||||
m_fakeMetaObjectsByPackage[package].insert(fmo);
|
m_fakeMetaObjectsByPackage[package].insert(FakeMetaObjectWithOrigin(fmo, originId));
|
||||||
|
|
||||||
// make versionless cpp types directly
|
// make versionless cpp types directly
|
||||||
// needed for access to property types that are not exported, like QDeclarativeAnchors
|
// needed for access to property types that are not exported, like QDeclarativeAnchors
|
||||||
@@ -1391,7 +1407,7 @@ void CppQmlTypes::load(const T &fakeMetaObjects, const QString &overridePackage)
|
|||||||
QTC_ASSERT(exp.type == fmo->className(), continue);
|
QTC_ASSERT(exp.type == fmo->className(), continue);
|
||||||
CppComponentValue *cppValue = new CppComponentValue(
|
CppComponentValue *cppValue = new CppComponentValue(
|
||||||
fmo, fmo->className(), cppPackage, ComponentVersion(), ComponentVersion(),
|
fmo, fmo->className(), cppPackage, ComponentVersion(), ComponentVersion(),
|
||||||
ComponentVersion::MaxVersion, m_valueOwner);
|
ComponentVersion::MaxVersion, m_valueOwner, originId);
|
||||||
m_objectsByQualifiedName[qualifiedName(cppPackage, fmo->className(), ComponentVersion())] = cppValue;
|
m_objectsByQualifiedName[qualifiedName(cppPackage, fmo->className(), ComponentVersion())] = cppValue;
|
||||||
newCppTypes += cppValue;
|
newCppTypes += cppValue;
|
||||||
}
|
}
|
||||||
@@ -1407,8 +1423,8 @@ void CppQmlTypes::load(const T &fakeMetaObjects, const QString &overridePackage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// explicitly instantiate load for list and hash
|
// explicitly instantiate load for list and hash
|
||||||
template void CppQmlTypes::load< QList<FakeMetaObject::ConstPtr> >(const QList<FakeMetaObject::ConstPtr> &, const QString &);
|
template void CppQmlTypes::load< QList<FakeMetaObject::ConstPtr> >(const QString &, const QList<FakeMetaObject::ConstPtr> &, const QString &);
|
||||||
template void CppQmlTypes::load< QHash<QString, FakeMetaObject::ConstPtr> >(const QHash<QString, FakeMetaObject::ConstPtr> &, const QString &);
|
template void CppQmlTypes::load< QHash<QString, FakeMetaObject::ConstPtr> >(const QString &, const QHash<QString, FakeMetaObject::ConstPtr> &, const QString &);
|
||||||
|
|
||||||
QList<const CppComponentValue *> CppQmlTypes::createObjectsForImport(const QString &package, ComponentVersion version)
|
QList<const CppComponentValue *> CppQmlTypes::createObjectsForImport(const QString &package, ComponentVersion version)
|
||||||
{
|
{
|
||||||
@@ -1417,7 +1433,8 @@ QList<const CppComponentValue *> CppQmlTypes::createObjectsForImport(const QStri
|
|||||||
QList<const CppComponentValue *> newObjects;
|
QList<const CppComponentValue *> newObjects;
|
||||||
|
|
||||||
// make new exported objects
|
// make new exported objects
|
||||||
foreach (const FakeMetaObject::ConstPtr &fmo, m_fakeMetaObjectsByPackage.value(package)) {
|
foreach (const FakeMetaObjectWithOrigin &fmoo, m_fakeMetaObjectsByPackage.value(package)) {
|
||||||
|
const FakeMetaObject::ConstPtr &fmo = fmoo.fakeMetaObject;
|
||||||
// find the highest-version export for each alias
|
// find the highest-version export for each alias
|
||||||
QHash<QString, FakeMetaObject::Export> bestExports;
|
QHash<QString, FakeMetaObject::Export> bestExports;
|
||||||
foreach (const FakeMetaObject::Export &exp, fmo->exports()) {
|
foreach (const FakeMetaObject::Export &exp, fmo->exports()) {
|
||||||
@@ -1449,7 +1466,8 @@ QList<const CppComponentValue *> CppQmlTypes::createObjectsForImport(const QStri
|
|||||||
|
|
||||||
CppComponentValue *newComponent = new CppComponentValue(
|
CppComponentValue *newComponent = new CppComponentValue(
|
||||||
fmo, name, package, bestExport.version, version,
|
fmo, name, package, bestExport.version, version,
|
||||||
bestExport.metaObjectRevision, m_valueOwner);
|
bestExport.metaObjectRevision, m_valueOwner,
|
||||||
|
fmoo.originId);
|
||||||
|
|
||||||
// use package.cppname importversion as key
|
// use package.cppname importversion as key
|
||||||
m_objectsByQualifiedName.insert(key, newComponent);
|
m_objectsByQualifiedName.insert(key, newComponent);
|
||||||
@@ -1463,6 +1481,8 @@ QList<const CppComponentValue *> CppQmlTypes::createObjectsForImport(const QStri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set their prototypes, creating them if necessary
|
// set their prototypes, creating them if necessary
|
||||||
|
// this ensures that the prototypes of C++ objects are resolved correctly and with the correct
|
||||||
|
// revision, and cannot be hidden by other objects.
|
||||||
foreach (const CppComponentValue *cobject, newObjects) {
|
foreach (const CppComponentValue *cobject, newObjects) {
|
||||||
CppComponentValue *object = const_cast<CppComponentValue *>(cobject);
|
CppComponentValue *object = const_cast<CppComponentValue *>(cobject);
|
||||||
while (!object->prototype()) {
|
while (!object->prototype()) {
|
||||||
@@ -1485,8 +1505,10 @@ QList<const CppComponentValue *> CppQmlTypes::createObjectsForImport(const QStri
|
|||||||
|
|
||||||
// make a new object
|
// make a new object
|
||||||
CppComponentValue *proto = new CppComponentValue(
|
CppComponentValue *proto = new CppComponentValue(
|
||||||
protoFmo, protoCppName, object->moduleName(), ComponentVersion(),
|
protoFmo, protoCppName, object->moduleName(),
|
||||||
object->importVersion(), ComponentVersion::MaxVersion, m_valueOwner);
|
ComponentVersion(),
|
||||||
|
object->importVersion(), ComponentVersion::MaxVersion, m_valueOwner,
|
||||||
|
cppProto->originId());
|
||||||
m_objectsByQualifiedName.insert(key, proto);
|
m_objectsByQualifiedName.insert(key, proto);
|
||||||
object->setPrototype(proto);
|
object->setPrototype(proto);
|
||||||
|
|
||||||
@@ -1786,7 +1808,8 @@ ASTObjectValue::ASTObjectValue(UiQualifiedId *typeName,
|
|||||||
UiObjectInitializer *initializer,
|
UiObjectInitializer *initializer,
|
||||||
const Document *doc,
|
const Document *doc,
|
||||||
ValueOwner *valueOwner)
|
ValueOwner *valueOwner)
|
||||||
: ObjectValue(valueOwner), m_typeName(typeName), m_initializer(initializer), m_doc(doc), m_defaultPropertyRef(0)
|
: ObjectValue(valueOwner, doc->importId()),
|
||||||
|
m_typeName(typeName), m_initializer(initializer), m_doc(doc), m_defaultPropertyRef(0)
|
||||||
{
|
{
|
||||||
if (m_initializer) {
|
if (m_initializer) {
|
||||||
for (UiObjectMemberList *it = m_initializer->members; it; it = it->next) {
|
for (UiObjectMemberList *it = m_initializer->members; it; it = it->next) {
|
||||||
|
@@ -443,7 +443,7 @@ public:
|
|||||||
class QMLJS_EXPORT ObjectValue: public Value
|
class QMLJS_EXPORT ObjectValue: public Value
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ObjectValue(ValueOwner *valueOwner);
|
ObjectValue(ValueOwner *valueOwner, const QString &originId = QString());
|
||||||
~ObjectValue();
|
~ObjectValue();
|
||||||
|
|
||||||
ValueOwner *valueOwner() const;
|
ValueOwner *valueOwner() const;
|
||||||
@@ -475,6 +475,9 @@ public:
|
|||||||
// Value interface
|
// Value interface
|
||||||
const ObjectValue *asObjectValue() const QTC_OVERRIDE;
|
const ObjectValue *asObjectValue() const QTC_OVERRIDE;
|
||||||
void accept(ValueVisitor *visitor) const QTC_OVERRIDE;
|
void accept(ValueVisitor *visitor) const QTC_OVERRIDE;
|
||||||
|
QString originId() const
|
||||||
|
{ return m_originId; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool checkPrototype(const ObjectValue *prototype, QSet<const ObjectValue *> *processed) const;
|
bool checkPrototype(const ObjectValue *prototype, QSet<const ObjectValue *> *processed) const;
|
||||||
@@ -483,6 +486,7 @@ private:
|
|||||||
ValueOwner *m_valueOwner;
|
ValueOwner *m_valueOwner;
|
||||||
QHash<QString, const Value *> m_members;
|
QHash<QString, const Value *> m_members;
|
||||||
QString m_className;
|
QString m_className;
|
||||||
|
QString m_originId;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Value *_prototype;
|
const Value *_prototype;
|
||||||
@@ -542,7 +546,7 @@ public:
|
|||||||
CppComponentValue(LanguageUtils::FakeMetaObject::ConstPtr metaObject, const QString &className,
|
CppComponentValue(LanguageUtils::FakeMetaObject::ConstPtr metaObject, const QString &className,
|
||||||
const QString &moduleName, const LanguageUtils::ComponentVersion &componentVersion,
|
const QString &moduleName, const LanguageUtils::ComponentVersion &componentVersion,
|
||||||
const LanguageUtils::ComponentVersion &importVersion, int metaObjectRevision,
|
const LanguageUtils::ComponentVersion &importVersion, int metaObjectRevision,
|
||||||
ValueOwner *valueOwner);
|
ValueOwner *valueOwner, const QString &originId);
|
||||||
~CppComponentValue();
|
~CppComponentValue();
|
||||||
|
|
||||||
const CppComponentValue *asCppComponentValue() const QTC_OVERRIDE;
|
const CppComponentValue *asCppComponentValue() const QTC_OVERRIDE;
|
||||||
@@ -673,6 +677,18 @@ public:
|
|||||||
QList<ModuleApiInfo> *newModuleApis, QString *errorMessage, QString *warningMessage, const QString &fileName);
|
QList<ModuleApiInfo> *newModuleApis, QString *errorMessage, QString *warningMessage, const QString &fileName);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QMLJS_EXPORT FakeMetaObjectWithOrigin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LanguageUtils::FakeMetaObject::ConstPtr fakeMetaObject;
|
||||||
|
QString originId;
|
||||||
|
FakeMetaObjectWithOrigin(LanguageUtils::FakeMetaObject::ConstPtr fakeMetaObject,
|
||||||
|
const QString &originId);
|
||||||
|
bool operator ==(const FakeMetaObjectWithOrigin &o) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
QMLJS_EXPORT uint qHash(const FakeMetaObjectWithOrigin &fmoo, int seed = 0);
|
||||||
|
|
||||||
class QMLJS_EXPORT CppQmlTypes
|
class QMLJS_EXPORT CppQmlTypes
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -684,7 +700,7 @@ public:
|
|||||||
static const QLatin1String cppPackage;
|
static const QLatin1String cppPackage;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void load(const T &fakeMetaObjects, const QString &overridePackage = QString());
|
void load(const QString &originId, const T &fakeMetaObjects, const QString &overridePackage = QString());
|
||||||
|
|
||||||
QList<const CppComponentValue *> createObjectsForImport(const QString &package, LanguageUtils::ComponentVersion version);
|
QList<const CppComponentValue *> createObjectsForImport(const QString &package, LanguageUtils::ComponentVersion version);
|
||||||
bool hasModule(const QString &module) const;
|
bool hasModule(const QString &module) const;
|
||||||
@@ -703,7 +719,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
// "Package.CppName ImportVersion" -> CppComponentValue
|
// "Package.CppName ImportVersion" -> CppComponentValue
|
||||||
QHash<QString, const CppComponentValue *> m_objectsByQualifiedName;
|
QHash<QString, const CppComponentValue *> m_objectsByQualifiedName;
|
||||||
QHash<QString, QSet<LanguageUtils::FakeMetaObject::ConstPtr> > m_fakeMetaObjectsByPackage;
|
QHash<QString, QSet<FakeMetaObjectWithOrigin> > m_fakeMetaObjectsByPackage;
|
||||||
const ObjectValue *m_cppContextProperties;
|
const ObjectValue *m_cppContextProperties;
|
||||||
ValueOwner *m_valueOwner;
|
ValueOwner *m_valueOwner;
|
||||||
};
|
};
|
||||||
|
@@ -147,10 +147,14 @@ Link::Link(const Snapshot &snapshot, const ViewerContext &vContext, const Librar
|
|||||||
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
||||||
if (modelManager) {
|
if (modelManager) {
|
||||||
ModelManagerInterface::CppDataHash cppDataHash = modelManager->cppData();
|
ModelManagerInterface::CppDataHash cppDataHash = modelManager->cppData();
|
||||||
|
{
|
||||||
// populate engine with types from C++
|
// populate engine with types from C++
|
||||||
foreach (const ModelManagerInterface::CppData &cppData, cppDataHash) {
|
ModelManagerInterface::CppDataHashIterator cppDataHashIterator(cppDataHash);
|
||||||
d->valueOwner->cppQmlTypes().load(cppData.exportedTypes);
|
while (cppDataHashIterator.hasNext()) {
|
||||||
|
cppDataHashIterator.next();
|
||||||
|
d->valueOwner->cppQmlTypes().load(cppDataHashIterator.key(),
|
||||||
|
cppDataHashIterator.value().exportedTypes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// build an object with the context properties from C++
|
// build an object with the context properties from C++
|
||||||
@@ -197,13 +201,13 @@ Context::ImportsPerDocument LinkPrivate::linkImports()
|
|||||||
// load builtin objects
|
// load builtin objects
|
||||||
if (builtins.pluginTypeInfoStatus() == LibraryInfo::DumpDone
|
if (builtins.pluginTypeInfoStatus() == LibraryInfo::DumpDone
|
||||||
|| builtins.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileDone) {
|
|| builtins.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileDone) {
|
||||||
valueOwner->cppQmlTypes().load(builtins.metaObjects());
|
valueOwner->cppQmlTypes().load(QLatin1String("<builtins>"), builtins.metaObjects());
|
||||||
} else {
|
} else {
|
||||||
valueOwner->cppQmlTypes().load(CppQmlTypesLoader::defaultQtObjects);
|
valueOwner->cppQmlTypes().load(QLatin1String("<defaults>"), CppQmlTypesLoader::defaultQtObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
// load library objects shipped with Creator
|
// load library objects shipped with Creator
|
||||||
valueOwner->cppQmlTypes().load(CppQmlTypesLoader::defaultLibraryObjects);
|
valueOwner->cppQmlTypes().load(QLatin1String("<defaultQt4>"), CppQmlTypesLoader::defaultLibraryObjects);
|
||||||
|
|
||||||
if (document) {
|
if (document) {
|
||||||
// do it on document first, to make sure import errors are shown
|
// do it on document first, to make sure import errors are shown
|
||||||
@@ -483,7 +487,7 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const QString packageName = importInfo.name();
|
const QString packageName = importInfo.name();
|
||||||
valueOwner->cppQmlTypes().load(libraryInfo.metaObjects(), packageName);
|
valueOwner->cppQmlTypes().load(libraryPath, libraryInfo.metaObjects(), packageName);
|
||||||
foreach (const CppComponentValue *object, valueOwner->cppQmlTypes().createObjectsForImport(packageName, version)) {
|
foreach (const CppComponentValue *object, valueOwner->cppQmlTypes().createObjectsForImport(packageName, version)) {
|
||||||
import->object->setMember(object->className(), object);
|
import->object->setMember(object->className(), object);
|
||||||
}
|
}
|
||||||
@@ -578,7 +582,7 @@ void LinkPrivate::loadImplicitDefaultImports(Imports *imports)
|
|||||||
if (!import.object) {
|
if (!import.object) {
|
||||||
import.valid = true;
|
import.valid = true;
|
||||||
import.info = info;
|
import.info = info;
|
||||||
import.object = new ObjectValue(valueOwner);
|
import.object = new ObjectValue(valueOwner, QLatin1String("<defaults>"));
|
||||||
foreach (const CppComponentValue *object,
|
foreach (const CppComponentValue *object,
|
||||||
valueOwner->cppQmlTypes().createObjectsForImport(
|
valueOwner->cppQmlTypes().createObjectsForImport(
|
||||||
defaultPackage, maxVersion)) {
|
defaultPackage, maxVersion)) {
|
||||||
|
@@ -142,6 +142,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef QHash<QString, CppData> CppDataHash;
|
typedef QHash<QString, CppData> CppDataHash;
|
||||||
|
typedef QHashIterator<QString, CppData> CppDataHashIterator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModelManagerInterface(QObject *parent = 0);
|
ModelManagerInterface(QObject *parent = 0);
|
||||||
|
Reference in New Issue
Block a user