Commit 6c925cf0 authored by Christian Kamm's avatar Christian Kamm
Browse files

QmlJS: Rework exported C++ type registry.

The problem was that if you exported
A 1.0, A 1.1 and B 1.0 where A is the prototype of B
the code model had not enough information to know that, depending
on the import, B 1.0's prototype should be A 1.1 or A 1.0.

To solve this problem QmlObjectValues now store the import's version
as well as the local component version. In the example above B 1.0
would have import version 1.1 if the 1.1 module was imported and thus
be able to choose the right prototype.

Change-Id: I7ef33f12ca5a528c62b2a8240f4b5720b0ebd4c3
Reviewed-on: http://codereview.qt-project.org/5129

Reviewed-by: default avatarThomas Hartmann <Thomas.Hartmann@nokia.com>
parent 793031c7
......@@ -43,6 +43,7 @@
#include "parser/qmljsast_p.h"
#include <languageutils/fakemetaobject.h>
#include <utils/qtcassert.h>
#include <QtCore/QFile>
#include <QtCore/QDir>
......@@ -54,6 +55,8 @@
#include <QtCore/QProcess>
#include <QtCore/QDebug>
#include <algorithm>
using namespace LanguageUtils;
using namespace QmlJS;
using namespace QmlJS::AST;
......@@ -157,12 +160,14 @@ public:
} // end of anonymous namespace
QmlObjectValue::QmlObjectValue(FakeMetaObject::ConstPtr metaObject, const QString &className,
const QString &packageName, const ComponentVersion version, ValueOwner *valueOwner)
const QString &packageName, const ComponentVersion &componentVersion,
const ComponentVersion &importVersion, ValueOwner *valueOwner)
: ObjectValue(valueOwner),
_attachedType(0),
_metaObject(metaObject),
_packageName(packageName),
_componentVersion(version)
_moduleName(packageName),
_componentVersion(componentVersion),
_importVersion(importVersion)
{
setClassName(className);
int nEnums = metaObject->enumeratorCount();
......@@ -258,15 +263,18 @@ void QmlObjectValue::processMembers(MemberProcessor *processor) const
const Value *QmlObjectValue::propertyValue(const FakeMetaProperty &prop) const
{
QString typeName = prop.typeName();
const CppQmlTypes &cppTypes = valueOwner()->cppQmlTypes();
// ### Verify type resolving.
QmlObjectValue *objectValue = valueOwner()->cppQmlTypes().typeByCppName(typeName);
if (objectValue) {
FakeMetaObject::Export exp = objectValue->metaObject()->exportInPackage(packageName());
if (exp.isValid())
objectValue = valueOwner()->cppQmlTypes().typeByQualifiedName(exp.packageNameVersion);
// check in the same package/version first
const QmlObjectValue *objectValue = cppTypes.objectByQualifiedName(
_moduleName, typeName, _importVersion);
if (objectValue)
return objectValue;
// fallback to plain cpp name
objectValue = cppTypes.objectByCppName(typeName);
if (objectValue)
return objectValue;
}
// try qml builtin type names
if (const Value *v = valueOwner()->defaultValueForBuiltinType(typeName)) {
......@@ -309,7 +317,7 @@ const Value *QmlObjectValue::propertyValue(const FakeMetaProperty &prop) const
const QmlObjectValue *base = this;
const QStringList components = typeName.split(QLatin1String("::"));
if (components.size() == 2) {
base = valueOwner()->cppQmlTypes().typeByCppName(components.first());
base = valueOwner()->cppQmlTypes().objectByCppName(components.first());
typeName = components.last();
}
if (base) {
......@@ -341,12 +349,15 @@ FakeMetaObject::ConstPtr QmlObjectValue::metaObject() const
return _metaObject;
}
QString QmlObjectValue::packageName() const
{ return _packageName; }
QString QmlObjectValue::moduleName() const
{ return _moduleName; }
ComponentVersion QmlObjectValue::version() const
ComponentVersion QmlObjectValue::componentVersion() const
{ return _componentVersion; }
ComponentVersion QmlObjectValue::importVersion() const
{ return _importVersion; }
QString QmlObjectValue::defaultPropertyName() const
{ return _metaObject->defaultPropertyName(); }
......@@ -448,28 +459,6 @@ bool QmlObjectValue::hasProperty(const QString &propertyName) const
return false;
}
// Returns true if this object is in a package or if there is an object that
// has this one in its prototype chain and is itself in a package.
bool QmlObjectValue::hasChildInPackage() const
{
if (!packageName().isEmpty()
&& packageName() != CppQmlTypes::cppPackage)
return true;
QHashIterator<QString, QmlObjectValue *> it(valueOwner()->cppQmlTypes().types());
while (it.hasNext()) {
it.next();
FakeMetaObject::ConstPtr otherMeta = it.value()->_metaObject;
// if it has only a cpp-package export, it is not really exported
if (otherMeta->exports().size() <= 1)
continue;
for (const QmlObjectValue *other = it.value(); other; other = other->prototype()) {
if (other->metaObject() == _metaObject) // this object is a parent of other
return true;
}
}
return false;
}
bool QmlObjectValue::isDerivedFrom(FakeMetaObject::ConstPtr base) const
{
for (const QmlObjectValue *it = this; it; it = it->prototype()) {
......@@ -1248,172 +1237,145 @@ void CppQmlTypesLoader::parseQmlTypeDescriptions(const QByteArray &xml,
*warningMessage = reader.warningMessage();
}
CppQmlTypes::CppQmlTypes(ValueOwner *valueOwner)
: _valueOwner(valueOwner)
{
}
const QLatin1String CppQmlTypes::defaultPackage("<default>");
const QLatin1String CppQmlTypes::cppPackage("<cpp>");
template <typename T>
QList<QmlObjectValue *> CppQmlTypes::load(ValueOwner *valueOwner, const T &objects)
{
// load
QList<QmlObjectValue *> loadedObjects;
QList<QmlObjectValue *> newObjects;
foreach (FakeMetaObject::ConstPtr metaObject, objects) {
foreach (const FakeMetaObject::Export &exp, metaObject->exports()) {
bool wasCreated;
QmlObjectValue *loadedObject = getOrCreate(valueOwner, metaObject, exp, &wasCreated);
loadedObjects += loadedObject;
if (wasCreated)
newObjects += loadedObject;
void CppQmlTypes::load(const T &fakeMetaObjects, const QString &overridePackage)
{
QList<QmlObjectValue *> newCppTypes;
foreach (const FakeMetaObject::ConstPtr &fmo, fakeMetaObjects) {
foreach (const FakeMetaObject::Export &exp, fmo->exports()) {
QString package = exp.package;
if (package.isEmpty())
package = overridePackage;
_fakeMetaObjectsByPackage[package].insert(fmo);
// make versionless cpp types directly
// needed for access to property types that are not exported, like QDeclarativeAnchors
if (exp.package == cppPackage) {
QTC_ASSERT(exp.version == ComponentVersion(), continue);
QTC_ASSERT(exp.type == fmo->className(), continue);
QmlObjectValue *cppValue = new QmlObjectValue(
fmo, fmo->className(), cppPackage, ComponentVersion(), ComponentVersion(), _valueOwner);
_objectsByQualifiedName[exp.packageNameVersion] = cppValue;
newCppTypes += cppValue;
}
}
}
// set prototypes
foreach (QmlObjectValue *object, newObjects) {
setPrototypes(object);
// set prototypes of cpp types
foreach (QmlObjectValue *object, newCppTypes) {
const QString &protoCppName = object->metaObject()->superclassName();
const QmlObjectValue *proto = objectByCppName(protoCppName);
if (proto)
object->setPrototype(proto);
}
return loadedObjects;
}
// explicitly instantiate load for list and hash
template QList<QmlObjectValue *> CppQmlTypes::load< QList<FakeMetaObject::ConstPtr> >(ValueOwner *, const QList<FakeMetaObject::ConstPtr> &);
template QList<QmlObjectValue *> CppQmlTypes::load< QHash<QString, FakeMetaObject::ConstPtr> >(ValueOwner *, const QHash<QString, FakeMetaObject::ConstPtr> &);
QList<QmlObjectValue *> CppQmlTypes::typesForImport(const QString &packageName, ComponentVersion version) const
{
QHash<QString, QmlObjectValue *> objectValuesByName;
foreach (QmlObjectValue *qmlObjectValue, _typesByPackage.value(packageName)) {
if (qmlObjectValue->version() <= version) {
// we got a candidate.
const QString typeName = qmlObjectValue->className();
QmlObjectValue *previousCandidate = objectValuesByName.value(typeName, 0);
if (previousCandidate) {
// check if our new candidate is newer than the one we found previously
if (previousCandidate->version() < qmlObjectValue->version()) {
// the new candidate has a higher version no. than the one we found previously, so replace it
objectValuesByName.insert(typeName, qmlObjectValue);
}
} else {
objectValuesByName.insert(typeName, qmlObjectValue);
}
template void CppQmlTypes::load< QList<FakeMetaObject::ConstPtr> >(const QList<FakeMetaObject::ConstPtr> &, const QString &);
template void CppQmlTypes::load< QHash<QString, FakeMetaObject::ConstPtr> >(const QHash<QString, FakeMetaObject::ConstPtr> &, const QString &);
QList<const QmlObjectValue *> CppQmlTypes::createObjectsForImport(const QString &package, ComponentVersion version)
{
QList<const QmlObjectValue *> exportedObjects;
// make new exported objects
foreach (const FakeMetaObject::ConstPtr &fmo, _fakeMetaObjectsByPackage.value(package)) {
// find the highest-version export
FakeMetaObject::Export bestExport;
foreach (const FakeMetaObject::Export &exp, fmo->exports()) {
if (exp.package != package || (version.isValid() && exp.version > version))
continue;
if (!bestExport.isValid() || exp.version > bestExport.version)
bestExport = exp;
}
if (!bestExport.isValid())
continue;
// if it already exists, skip
const QString key = qualifiedName(package, fmo->className(), version);
if (_objectsByQualifiedName.contains(key))
continue;
QmlObjectValue *newObject = new QmlObjectValue(
fmo, bestExport.type, package, bestExport.version, version, _valueOwner);
// use package.cppname importversion as key
_objectsByQualifiedName.insert(key, newObject);
exportedObjects += newObject;
}
return objectValuesByName.values();
}
// set their prototypes, creating them if necessary
foreach (const QmlObjectValue *cobject, exportedObjects) {
QmlObjectValue *object = const_cast<QmlObjectValue *>(cobject);
while (!object->prototype()) {
const QString &protoCppName = object->metaObject()->superclassName();
if (protoCppName.isEmpty())
break;
QmlObjectValue *CppQmlTypes::typeByCppName(const QString &cppName) const
{
return typeByQualifiedName(cppPackage, cppName, ComponentVersion());
// if the prototype already exists, done
const QString key = qualifiedName(object->moduleName(), protoCppName, version);
if (const QmlObjectValue *proto = _objectsByQualifiedName.value(key)) {
object->setPrototype(proto);
break;
}
// get the fmo via the cpp name
const QmlObjectValue *cppProto = objectByCppName(protoCppName);
if (!cppProto)
break;
FakeMetaObject::ConstPtr protoFmo = cppProto->metaObject();
// make a new object
QmlObjectValue *proto = new QmlObjectValue(
protoFmo, protoCppName, object->moduleName(), ComponentVersion(),
object->importVersion(), _valueOwner);
_objectsByQualifiedName.insert(key, proto);
object->setPrototype(proto);
// maybe set prototype of prototype
object = proto;
}
}
return exportedObjects;
}
bool CppQmlTypes::hasPackage(const QString &package) const
bool CppQmlTypes::hasModule(const QString &module) const
{
return _typesByPackage.contains(package);
return _fakeMetaObjectsByPackage.contains(module);
}
QString CppQmlTypes::qualifiedName(const QString &package, const QString &type, ComponentVersion version)
QString CppQmlTypes::qualifiedName(const QString &module, const QString &type, ComponentVersion version)
{
return QString("%1/%2 %3").arg(
package, type,
module, type,
version.toString());
}
QmlObjectValue *CppQmlTypes::typeByQualifiedName(const QString &name) const
const QmlObjectValue *CppQmlTypes::objectByQualifiedName(const QString &name) const
{
return _typesByFullyQualifiedName.value(name);
return _objectsByQualifiedName.value(name);
}
QmlObjectValue *CppQmlTypes::typeByQualifiedName(const QString &package, const QString &type, ComponentVersion version) const
const QmlObjectValue *CppQmlTypes::objectByQualifiedName(const QString &package, const QString &type,
ComponentVersion version) const
{
return typeByQualifiedName(qualifiedName(package, type, version));
return objectByQualifiedName(qualifiedName(package, type, version));
}
QmlObjectValue *CppQmlTypes::getOrCreate(
ValueOwner *valueOwner,
FakeMetaObject::ConstPtr metaObject,
const LanguageUtils::FakeMetaObject::Export &exp,
bool *wasCreated)
const QmlObjectValue *CppQmlTypes::objectByCppName(const QString &cppName) const
{
// make sure we're not loading duplicate objects
if (QmlObjectValue *existing = _typesByFullyQualifiedName.value(exp.packageNameVersion)) {
if (wasCreated)
*wasCreated = false;
return existing;
}
QmlObjectValue *objectValue = new QmlObjectValue(
metaObject, exp.type, exp.package, exp.version, valueOwner);
_typesByPackage[exp.package].append(objectValue);
_typesByFullyQualifiedName[exp.packageNameVersion] = objectValue;
if (wasCreated)
*wasCreated = true;
return objectValue;
return objectByQualifiedName(qualifiedName(cppPackage, cppName, ComponentVersion()));
}
void CppQmlTypes::setPrototypes(QmlObjectValue *object)
{
if (!object)
return;
FakeMetaObject::ConstPtr fmo = object->metaObject();
// resolve attached type
// don't do it if the attached type name is the object itself (happens for QDeclarativeKeysAttached)
if (!fmo->attachedTypeName().isEmpty()
&& fmo->className() != fmo->attachedTypeName()) {
QmlObjectValue *attachedObject = typeByCppName(fmo->attachedTypeName());
if (attachedObject && attachedObject != object)
object->setAttachedType(attachedObject);
}
const QString targetPackage = object->packageName();
// set prototypes for whole chain, creating new QmlObjectValues if necessary
// for instance, if an type isn't exported in the package of the super type
// Example: QObject (Qt, QtQuick) -> Positioner (not exported) -> Column (Qt, QtQuick)
// needs to create Positioner (Qt) and Positioner (QtQuick)
QmlObjectValue *v = object;
while (!v->prototype() && !fmo->superclassName().isEmpty()) {
QmlObjectValue *superValue = getOrCreateForPackage(targetPackage, fmo->superclassName());
if (!superValue)
return;
v->setPrototype(superValue);
v = superValue;
fmo = v->metaObject();
}
}
QmlObjectValue *CppQmlTypes::getOrCreateForPackage(const QString &package, const QString &cppName)
{
// first get the cpp object value
QmlObjectValue *cppObject = typeByCppName(cppName);
if (!cppObject) {
// ### disabled for now, should be communicated to the user somehow.
//qWarning() << "QML type system: could not find '" << cppName << "'";
return 0;
}
FakeMetaObject::ConstPtr metaObject = cppObject->metaObject();
FakeMetaObject::Export exp = metaObject->exportInPackage(package);
QmlObjectValue *object = 0;
if (exp.isValid()) {
object = getOrCreate(cppObject->valueOwner(), metaObject, exp);
} else {
// make a convenience object that does not get added to _typesByPackage
const QString qname = qualifiedName(package, cppName, ComponentVersion());
object = typeByQualifiedName(qname);
if (!object) {
object = new QmlObjectValue(
metaObject, cppName, package, ComponentVersion(), cppObject->valueOwner());
_typesByFullyQualifiedName[qname] = object;
}
}
return object;
}
ConvertToNumber::ConvertToNumber(ValueOwner *valueOwner)
: _valueOwner(valueOwner), _result(0)
......
......@@ -418,7 +418,8 @@ class QMLJS_EXPORT QmlObjectValue: public ObjectValue
{
public:
QmlObjectValue(LanguageUtils::FakeMetaObject::ConstPtr metaObject, const QString &className,
const QString &packageName, const LanguageUtils::ComponentVersion version,
const QString &moduleName, const LanguageUtils::ComponentVersion &componentVersion,
const LanguageUtils::ComponentVersion &importVersion,
ValueOwner *valueOwner);
virtual ~QmlObjectValue();
......@@ -433,8 +434,9 @@ public:
LanguageUtils::FakeMetaObject::ConstPtr metaObject() const;
QString packageName() const;
LanguageUtils::ComponentVersion version() const;
QString moduleName() const;
LanguageUtils::ComponentVersion componentVersion() const;
LanguageUtils::ComponentVersion importVersion() const;
QString defaultPropertyName() const;
QString propertyType(const QString &propertyName) const;
......@@ -443,7 +445,6 @@ public:
bool isPointer(const QString &propertyName) const;
bool hasLocalProperty(const QString &typeName) const;
bool hasProperty(const QString &typeName) const;
bool hasChildInPackage() const;
LanguageUtils::FakeMetaEnum getEnum(const QString &typeName, const QmlObjectValue **foundInScope = 0) const;
const QmlEnumValue *getEnumValue(const QString &typeName, const QmlObjectValue **foundInScope = 0) const;
......@@ -455,8 +456,12 @@ protected:
private:
QmlObjectValue *_attachedType;
LanguageUtils::FakeMetaObject::ConstPtr _metaObject;
const QString _packageName;
const QString _moduleName;
// _componentVersion is the version of the export
// _importVersion is the version it's imported as, used to find correct prototypes
// needed in cases when B 1.0 has A 1.1 as prototype when imported as 1.1
const LanguageUtils::ComponentVersion _componentVersion;
const LanguageUtils::ComponentVersion _importVersion;
mutable QHash<int, const Value *> _metaSignature;
QHash<QString, const QmlEnumValue * > _enums;
};
......@@ -571,38 +576,32 @@ public:
class QMLJS_EXPORT CppQmlTypes
{
public:
CppQmlTypes(ValueOwner *valueOwner);
// package name for objects that should be always available
static const QLatin1String defaultPackage;
// package name for objects with their raw cpp name
static const QLatin1String cppPackage;
template <typename T>
QList<QmlObjectValue *> load(ValueOwner *interpreter, const T &objects);
QList<QmlObjectValue *> typesForImport(const QString &prefix, LanguageUtils::ComponentVersion version) const;
QmlObjectValue *typeByCppName(const QString &cppName) const;
bool hasPackage(const QString &package) const;
void load(const T &fakeMetaObjects, const QString &overridePackage = QString());
QHash<QString, QmlObjectValue *> types() const
{ return _typesByFullyQualifiedName; }
QList<const QmlObjectValue *> createObjectsForImport(const QString &package, LanguageUtils::ComponentVersion version);
bool hasModule(const QString &module) const;
static QString qualifiedName(const QString &package, const QString &type, LanguageUtils::ComponentVersion version);
QmlObjectValue *typeByQualifiedName(const QString &fullyQualifiedName) const;
QmlObjectValue *typeByQualifiedName(const QString &package, const QString &type,
LanguageUtils::ComponentVersion version) const;
static QString qualifiedName(const QString &module, const QString &type,
LanguageUtils::ComponentVersion version);
const QmlObjectValue *objectByQualifiedName(const QString &fullyQualifiedName) const;
const QmlObjectValue *objectByQualifiedName(
const QString &package, const QString &type,
LanguageUtils::ComponentVersion version) const;
const QmlObjectValue *objectByCppName(const QString &cppName) const;
private:
void setPrototypes(QmlObjectValue *object);
QmlObjectValue *getOrCreate(ValueOwner *valueOwner,
LanguageUtils::FakeMetaObject::ConstPtr metaObject,
const LanguageUtils::FakeMetaObject::Export &exp,
bool *wasCreated = 0);
QmlObjectValue *getOrCreateForPackage(const QString &package, const QString &cppName);
QHash<QString, QList<QmlObjectValue *> > _typesByPackage;
QHash<QString, QmlObjectValue *> _typesByFullyQualifiedName;
// "Package.CppName ImportVersion" -> QmlObjectValue
QHash<QString, const QmlObjectValue *> _objectsByQualifiedName;
QHash<QString, QSet<LanguageUtils::FakeMetaObject::ConstPtr> > _fakeMetaObjectsByPackage;
ValueOwner *_valueOwner;
};
class ConvertToNumber: protected ValueVisitor // ECMAScript ToInt()
......
......@@ -153,7 +153,7 @@ Link::Link(const Snapshot &snapshot, const QStringList &importPaths, const Libra
// populate engine with types from C++
foreach (const ModelManagerInterface::CppData &cppData, cppDataHash) {
d->valueOwner->cppQmlTypes().load(d->valueOwner, cppData.exportedTypes);
d->valueOwner->cppQmlTypes().load(cppData.exportedTypes);
}
// populate global object with context properties from C++
......@@ -165,7 +165,7 @@ Link::Link(const Snapshot &snapshot, const QStringList &importPaths, const Libra
const Value *value = 0;
const QString cppTypeName = it.value();
if (!cppTypeName.isEmpty())
value = d->valueOwner->cppQmlTypes().typeByCppName(cppTypeName);
value = d->valueOwner->cppQmlTypes().objectByCppName(cppTypeName);
if (!value)
value = d->valueOwner->undefinedValue();
global->setMember(it.key(), value);
......@@ -199,18 +199,18 @@ Context::ImportsPerDocument LinkPrivate::linkImports()
// load builtin objects
if (builtins.pluginTypeInfoStatus() == LibraryInfo::DumpDone
|| builtins.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileDone) {
valueOwner->cppQmlTypes().load(valueOwner, builtins.metaObjects());
valueOwner->cppQmlTypes().load(builtins.metaObjects());
} else {
valueOwner->cppQmlTypes().load(valueOwner, CppQmlTypesLoader::defaultQtObjects);
valueOwner->cppQmlTypes().load(CppQmlTypesLoader::defaultQtObjects);
}
// load library objects shipped with Creator
valueOwner->cppQmlTypes().load(valueOwner, CppQmlTypesLoader::defaultLibraryObjects);
valueOwner->cppQmlTypes().load(CppQmlTypesLoader::defaultLibraryObjects);
// the 'Qt' object is dumped even though it is not exported
// it contains useful information, in particular on enums - add the
// object as a prototype to our custom Qt object to offer these for completion
const_cast<ObjectValue *>(valueOwner->qtObject())->setPrototype(valueOwner->cppQmlTypes().typeByCppName(QLatin1String("Qt")));
const_cast<ObjectValue *>(valueOwner->qtObject())->setPrototype(valueOwner->cppQmlTypes().objectByCppName(QLatin1String("Qt")));
if (document) {
// do it on document first, to make sure import errors are shown
......@@ -363,10 +363,10 @@ Import LinkPrivate::importNonFile(Document::Ptr doc, const ImportInfo &importInf
}
// if there are cpp-based types for this package, use them too
if (valueOwner->cppQmlTypes().hasPackage(packageName)) {
if (valueOwner->cppQmlTypes().hasModule(packageName)) {
importFound = true;
foreach (QmlObjectValue *object,
valueOwner->cppQmlTypes().typesForImport(packageName, version)) {
foreach (const QmlObjectValue *object,
valueOwner->cppQmlTypes().createObjectsForImport(packageName, version)) {
import.object->setMember(object->className(), object);
}
}
......@@ -432,16 +432,14 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
QString packageName;
if (ast && ast->importUri)
packageName = Bind::toString(importInfo.ast()->importUri, '.');
if (errorLoc.isValid() && (packageName.isEmpty() || !valueOwner->cppQmlTypes().hasPackage(packageName))) {
if (errorLoc.isValid() && (packageName.isEmpty() || !valueOwner->cppQmlTypes().hasModule(packageName))) {
error(doc, errorLoc, libraryInfo.pluginTypeInfoError());
}
} else {
QList<QmlObjectValue *> loadedObjects =
valueOwner->cppQmlTypes().load(valueOwner, libraryInfo.metaObjects());
foreach (QmlObjectValue *object, loadedObjects) {
if (object->packageName().isEmpty()) {
import->object->setMember(object->className(), object);
}
} else if (ast && ast->importUri) {
const QString packageName = Bind::toString(importInfo.ast()->importUri, '.');
valueOwner->cppQmlTypes().load(libraryInfo.metaObjects(), packageName);
foreach (const QmlObjectValue *object, valueOwner->cppQmlTypes().createObjectsForImport(packageName, version)) {
import->object->setMember(object->className(), object);
}
}
}
......@@ -526,14 +524,14 @@ void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr d
void LinkPrivate::loadImplicitDefaultImports(Imports *imports)
{
const QString defaultPackage = CppQmlTypes::defaultPackage;
if (valueOwner->cppQmlTypes().hasPackage(defaultPackage)) {
if (valueOwner->cppQmlTypes().hasModule(defaultPackage)) {
ImportInfo info(ImportInfo::LibraryImport, defaultPackage);
Import import = importCache.value(ImportCacheKey(info));
if (!import.object) {
import.info = info;
import.object = new ObjectValue(valueOwner);
foreach (QmlObjectValue *object,
valueOwner->cppQmlTypes().typesForImport(
foreach (const QmlObjectValue *object,
valueOwner->cppQmlTypes().createObjectsForImport(
defaultPackage,
ComponentVersion(ComponentVersion::MaxVersion, ComponentVersion::MaxVersion))) {
import.object->setMember(object->className(), object);
......
......@@ -154,8 +154,8 @@ void ScopeBuilder::setQmlScopeObject(Node *node)
if (const QmlObjectValue *qmlMetaObject = dynamic_cast<const QmlObjectValue *>(prototype)) {