From 4fc2032e10d156dd64a3a7e9a864f57d6e10ad69 Mon Sep 17 00:00:00 2001 From: Christian Kamm <christian.d.kamm@nokia.com> Date: Tue, 8 Feb 2011 16:18:34 +0100 Subject: [PATCH] QmlJS: Put types with cpp names into a separate package. In preparation of relocatable plugin types. --- src/libs/qmljs/qmljsinterpreter.cpp | 87 +++++++++---------- src/libs/qmljs/qmljsinterpreter.h | 15 +++- src/libs/qmljs/qmljslink.cpp | 2 +- src/libs/qmljs/qmljstypedescriptionreader.cpp | 2 - 4 files changed, 54 insertions(+), 52 deletions(-) diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index ae7d8bad8e4..f74ca3eb95d 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -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() diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index a97a19d5b04..ca1aa026ddd 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -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); diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index c5a2ca34522..2e6c91530ac 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -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)); diff --git a/src/libs/qmljs/qmljstypedescriptionreader.cpp b/src/libs/qmljs/qmljstypedescriptionreader.cpp index a71cd28ccd7..35bce0a826b 100644 --- a/src/libs/qmljs/qmljstypedescriptionreader.cpp +++ b/src/libs/qmljs/qmljstypedescriptionreader.cpp @@ -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); } -- GitLab