Commit 4fc2032e authored by Christian Kamm's avatar Christian Kamm
Browse files

QmlJS: Put types with cpp names into a separate package.

In preparation of relocatable plugin types.
parent c99d2ca2
......@@ -658,11 +658,11 @@ const Value *QmlObjectValue::propertyValue(const FakeMetaProperty &prop) const
const QString typeName = prop.typeName();
// ### Verify type resolving.
QmlObjectValue *objectValue = engine()->cppQmlTypes().typeForImport(typeName);
QmlObjectValue *objectValue = engine()->cppQmlTypes().typeByCppName(typeName);
if (objectValue) {
QString packageClassName = objectValue->nameInPackage(packageName());
if (!packageClassName.isEmpty())
objectValue = engine()->cppQmlTypes().typeForImport(packageName() + '.' + packageClassName);
QString fqn = objectValue->fullyQualifiedNameInPackage(packageName());
if (!fqn.isEmpty())
objectValue = engine()->cppQmlTypes().typeByQualifiedName(fqn);
return objectValue;
}
......@@ -724,6 +724,14 @@ QString QmlObjectValue::nameInPackage(const QString &packageName) const
return QString();
}
QString QmlObjectValue::fullyQualifiedNameInPackage(const QString &packageName) const
{
foreach (const FakeMetaObject::Export &exp, _metaObject->exports())
if (exp.package == packageName)
return exp.packageNameVersion;
return QString();
}
ComponentVersion QmlObjectValue::version() const
{ return _componentVersion; }
......@@ -2015,24 +2023,23 @@ void CppQmlTypesLoader::setSuperClasses(QHash<QString, FakeMetaObject::Ptr> *new
}
}
const QLatin1String CppQmlTypes::defaultPackage("<default>");
const QLatin1String CppQmlTypes::cppPackage("<cpp>");
template <typename T>
void CppQmlTypes::load(Engine *engine, const T &objects)
{
// load
QList<FakeMetaObject::ConstPtr> newObjects;
foreach (FakeMetaObject::ConstPtr metaObject, objects) {
for (int i = 0; i < metaObject->exports().size(); ++i) {
const FakeMetaObject::Export &exp = metaObject->exports().at(i);
// make sure we're not loading duplicate objects
if (_typesByFullyQualifiedName.contains(exp.packageNameVersion))
continue;
foreach (const FakeMetaObject::Export &exp, metaObject->exports())
makeObject(engine, metaObject, exp, &newObjects);
newObjects.append(metaObject);
QmlObjectValue *objectValue = new QmlObjectValue(
metaObject, exp.type, exp.package, exp.version, engine);
_typesByPackage[exp.package].append(objectValue);
_typesByFullyQualifiedName[exp.packageNameVersion] = objectValue;
}
FakeMetaObject::Export cppExport;
cppExport.package = cppPackage;
cppExport.type = metaObject->className();
cppExport.packageNameVersion = qualifiedName(cppPackage, cppExport.type, cppExport.version);
makeObject(engine, metaObject, cppExport, &newObjects);
}
// set prototypes
......@@ -2087,37 +2094,9 @@ QList<QmlObjectValue *> CppQmlTypes::typesForImport(const QString &packageName,
return objectValuesByName.values();
}
QmlObjectValue *CppQmlTypes::typeForImport(const QString &qualifiedName,
ComponentVersion version) const
QmlObjectValue *CppQmlTypes::typeByCppName(const QString &cppName) const
{
QString name = qualifiedName;
QString packageName;
int dotIdx = name.indexOf(QLatin1Char('.'));
if (dotIdx != -1) {
packageName = name.left(dotIdx);
name = name.mid(dotIdx + 1);
}
QmlObjectValue *previousCandidate = 0;
foreach (QmlObjectValue *qmlObjectValue, _typesByPackage.value(packageName)) {
const QString typeName = qmlObjectValue->className();
if (typeName != name)
continue;
if (version.isValid() && version < qmlObjectValue->version())
continue;
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
previousCandidate = qmlObjectValue;
}
} else {
previousCandidate = qmlObjectValue;
}
}
return previousCandidate;
return typeByQualifiedName(cppPackage, cppName, ComponentVersion());
}
bool CppQmlTypes::hasPackage(const QString &package) const
......@@ -2143,6 +2122,22 @@ QmlObjectValue *CppQmlTypes::typeByQualifiedName(const QString &package, const Q
return typeByQualifiedName(qualifiedName(package, type, version));
}
void CppQmlTypes::makeObject(Engine *engine,
FakeMetaObject::ConstPtr metaObject,
const LanguageUtils::FakeMetaObject::Export &exp,
QList<LanguageUtils::FakeMetaObject::ConstPtr> *newObjects)
{
// make sure we're not loading duplicate objects
if (_typesByFullyQualifiedName.contains(exp.packageNameVersion))
return;
newObjects->append(metaObject);
QmlObjectValue *objectValue = new QmlObjectValue(
metaObject, exp.type, exp.package, exp.version, engine);
_typesByPackage[exp.package].append(objectValue);
_typesByFullyQualifiedName[exp.packageNameVersion] = objectValue;
}
QmlObjectValue *CppQmlTypes::getOrCreate(const QString &package, const QString &cppName,
FakeMetaObject::ConstPtr metaObject, Engine *engine, bool *created)
{
......@@ -2453,7 +2448,7 @@ Engine::Engine()
// 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
_qtObject->setPrototype(_cppQmlTypes.typeForImport(QLatin1String("Qt")));
_qtObject->setPrototype(_cppQmlTypes.typeByCppName(QLatin1String("Qt")));
}
Engine::~Engine()
......
......@@ -456,6 +456,7 @@ public:
QString packageName() const;
QString nameInPackage(const QString &packageName) const;
QString fullyQualifiedNameInPackage(const QString &packageName) const;
LanguageUtils::ComponentVersion version() const;
QString defaultPropertyName() const;
QString propertyType(const QString &propertyName) const;
......@@ -598,12 +599,16 @@ private:
class QMLJS_EXPORT CppQmlTypes
{
public:
// 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>
void load(Interpreter::Engine *interpreter, const T &objects);
QList<Interpreter::QmlObjectValue *> typesForImport(const QString &prefix, LanguageUtils::ComponentVersion version) const;
Interpreter::QmlObjectValue *typeForImport(const QString &qualifiedName,
LanguageUtils::ComponentVersion version = LanguageUtils::ComponentVersion()) const;
Interpreter::QmlObjectValue *typeByCppName(const QString &cppName) const;
bool hasPackage(const QString &package) const;
......@@ -611,11 +616,15 @@ public:
{ return _typesByFullyQualifiedName; }
static QString qualifiedName(const QString &package, const QString &type, LanguageUtils::ComponentVersion version);
QmlObjectValue *typeByQualifiedName(const QString &name) const;
QmlObjectValue *typeByQualifiedName(const QString &fullyQualifiedName) const;
QmlObjectValue *typeByQualifiedName(const QString &package, const QString &type,
LanguageUtils::ComponentVersion version) const;
private:
void makeObject(Engine *engine,
LanguageUtils::FakeMetaObject::ConstPtr metaObject,
const LanguageUtils::FakeMetaObject::Export &exp,
QList<LanguageUtils::FakeMetaObject::ConstPtr> *newObjects);
QmlObjectValue *getOrCreate(const QString &package, const QString &cppName,
LanguageUtils::FakeMetaObject::ConstPtr metaObject,
Engine *engine, bool *created);
......
......@@ -174,7 +174,7 @@ void Link::populateImportedTypes(TypeEnvironment *typeEnv, Document::Ptr doc)
return;
// implicit imports: the <default> package is always available
const QLatin1String defaultPackage("<default>");
const QString defaultPackage = CppQmlTypes::defaultPackage;
if (engine()->cppQmlTypes().hasPackage(defaultPackage)) {
ImportInfo info(ImportInfo::LibraryImport, defaultPackage);
ObjectValue *import = d->importCache.value(ImportCacheKey(info));
......
......@@ -172,8 +172,6 @@ void TypeDescriptionReader::readComponent(UiObjectDefinition *ast)
return;
}
// ### for backwards compatibility until fixed: export by cpp name
fmo->addExport(fmo->className(), "", ComponentVersion());
_objects->insert(fmo->className(), fmo);
}
......
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