From 918a1653da02f712d56bc56c38d235bbf0c41204 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Wed, 20 Apr 2011 10:46:04 +0200 Subject: QmlJS: Fix library-by-path imports. Fixes the problem 5426c3ac2cdf898ca1190a7746ba506ff24abc50 and 7b25f438c67c7cf395ccd2cd846e5d413f6d9222 worked around. Reviewed-by: Erik Verbruggen (cherry picked from commit e21311132ba3fa8cf0d8ade81117f988da8363e9) Change-Id: I5426c3ac2cdf898ca1190a7746ba506ff24abc50xx Reviewed-on: http://codereview.qt.nokia.com/381 Reviewed-by: Qt Sanity Bot Reviewed-by: hjk --- src/libs/qmljs/qmljsinterpreter.cpp | 91 ++++++++++++++++++++++++---- src/libs/qmljs/qmljsinterpreter.h | 13 ++-- src/libs/qmljs/qmljslink.cpp | 21 ------- src/plugins/qmljstools/qmljsplugindumper.cpp | 1 - 4 files changed, 87 insertions(+), 39 deletions(-) diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index 51388b6c996..a060fd1c0b6 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -2029,12 +2029,15 @@ template QList CppQmlTypes::load(Engine *engine, const T &objects) { // load + QList loadedObjects; QList newObjects; foreach (FakeMetaObject::ConstPtr metaObject, objects) { foreach (const FakeMetaObject::Export &exp, metaObject->exports()) { - QmlObjectValue *newObject = makeObject(engine, metaObject, exp); - if (newObject) - newObjects += newObject; + bool wasCreated; + QmlObjectValue *loadedObject = getOrCreate(engine, metaObject, exp, &wasCreated); + loadedObjects += loadedObject; + if (wasCreated) + newObjects += loadedObject; } } @@ -2043,7 +2046,7 @@ QList CppQmlTypes::load(Engine *engine, const T &objects) setPrototypes(object); } - return newObjects; + return loadedObjects; } // explicitly instantiate load for list and hash template QList CppQmlTypes::load< QList >(Engine *, const QList &); @@ -2101,19 +2104,26 @@ QmlObjectValue *CppQmlTypes::typeByQualifiedName(const QString &package, const Q return typeByQualifiedName(qualifiedName(package, type, version)); } -QmlObjectValue *CppQmlTypes::makeObject( +QmlObjectValue *CppQmlTypes::getOrCreate( Engine *engine, FakeMetaObject::ConstPtr metaObject, - const LanguageUtils::FakeMetaObject::Export &exp) + const LanguageUtils::FakeMetaObject::Export &exp, + bool *wasCreated) { // make sure we're not loading duplicate objects - if (_typesByFullyQualifiedName.contains(exp.packageNameVersion)) - return 0; + if (QmlObjectValue *existing = _typesByFullyQualifiedName.value(exp.packageNameVersion)) { + if (wasCreated) + *wasCreated = false; + return existing; + } QmlObjectValue *objectValue = new QmlObjectValue( metaObject, exp.type, exp.package, exp.version, engine); _typesByPackage[exp.package].append(objectValue); _typesByFullyQualifiedName[exp.packageNameVersion] = objectValue; + + if (wasCreated) + *wasCreated = true; return objectValue; } @@ -2141,7 +2151,7 @@ void CppQmlTypes::setPrototypes(QmlObjectValue *object) // needs to create Positioner (Qt) and Positioner (QtQuick) QmlObjectValue *v = object; while (!v->prototype() && !fmo->superclassName().isEmpty()) { - QmlObjectValue *superValue = getOrCreate(targetPackage, fmo->superclassName()); + QmlObjectValue *superValue = getOrCreateForPackage(targetPackage, fmo->superclassName()); if (!superValue) return; v->setPrototype(superValue); @@ -2150,7 +2160,7 @@ void CppQmlTypes::setPrototypes(QmlObjectValue *object) } } -QmlObjectValue *CppQmlTypes::getOrCreate(const QString &package, const QString &cppName) +QmlObjectValue *CppQmlTypes::getOrCreateForPackage(const QString &package, const QString &cppName) { // first get the cpp object value QmlObjectValue *cppObject = typeByCppName(cppName); @@ -2164,10 +2174,9 @@ QmlObjectValue *CppQmlTypes::getOrCreate(const QString &package, const QString & FakeMetaObject::Export exp = metaObject->exportInPackage(package); QmlObjectValue *object = 0; if (exp.isValid()) { - object = typeByQualifiedName(exp.packageNameVersion); - if (!object) - object = makeObject(cppObject->engine(), metaObject, exp); + object = getOrCreate(cppObject->engine(), 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) { @@ -3443,3 +3452,59 @@ ImportInfo TypeEnvironment::importInfo(const QString &name, const Context *conte } return ImportInfo(); } + +#ifdef QT_DEBUG + +class MemberDumper: public MemberProcessor +{ +public: + MemberDumper() {} + + virtual bool processProperty(const QString &name, const Value *) + { + qDebug() << "property: " << name; + return true; + } + + virtual bool processEnumerator(const QString &name, const Value *) + { + qDebug() << "enumerator: " << name; + return true; + } + + virtual bool processSignal(const QString &name, const Value *) + { + qDebug() << "signal: " << name; + return true; + } + + virtual bool processSlot(const QString &name, const Value *) + { + qDebug() << "slot: " << name; + return true; + } + + virtual bool processGeneratedSlot(const QString &name, const Value *) + { + qDebug() << "generated slot: " << name; + return true; + } +}; + +void TypeEnvironment::dump() const +{ + qDebug() << "Type environment contents, in search order:"; + QListIterator it(_imports); + it.toBack(); + while (it.hasPrevious()) { + const Import &i = it.previous(); + const ObjectValue *import = i.object; + const ImportInfo &info = i.info; + + qDebug() << " " << info.name() << " " << info.version().toString() << " as " << info.id() << " : " << import; + MemberDumper dumper; + import->processMembers(&dumper); + } +} + +#endif diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index 636cc955239..a14158678b4 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -633,11 +633,12 @@ public: LanguageUtils::ComponentVersion version) const; private: - QmlObjectValue *makeObject(Engine *engine, - LanguageUtils::FakeMetaObject::ConstPtr metaObject, - const LanguageUtils::FakeMetaObject::Export &exp); void setPrototypes(QmlObjectValue *object); - QmlObjectValue *getOrCreate(const QString &package, const QString &cppName); + QmlObjectValue *getOrCreate(Engine *engine, + LanguageUtils::FakeMetaObject::ConstPtr metaObject, + const LanguageUtils::FakeMetaObject::Export &exp, + bool *wasCreated = 0); + QmlObjectValue *getOrCreateForPackage(const QString &package, const QString &cppName); QHash > _typesByPackage; @@ -1036,6 +1037,10 @@ public: void addImport(const ObjectValue *import, const ImportInfo &info); ImportInfo importInfo(const QString &name, const Context *context) const; + +#ifdef QT_DEBUG + void dump() const; +#endif }; } } // namespace QmlJS::Interpreter diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index c9c1bb8e926..c6cf2e7e8ba 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -181,27 +181,6 @@ void Link::populateImportedTypes(TypeEnvironment *typeEnv, Document::Ptr doc) foreach (const ImportInfo &info, doc->bind()->imports()) { ObjectValue *import = d->importCache.value(ImportCacheKey(info)); - //### Hack: if this document is in a library, and if there is an qmldir file in the same directory, and if the prefix is an import-path, the import means to import everything in this library. - if (info.ast() && info.ast()->fileName && info.ast()->fileName->asString() == QLatin1String(".")) { - const QString importInfoName(info.name()); - if (QFileInfo(QDir(importInfoName), QLatin1String("qmldir")).exists()) { - foreach (const QString &importPath, d->importPaths) { - if (importInfoName.startsWith(importPath)) { - // Got it. - - const QString cleanPath = QFileInfo(importInfoName).canonicalFilePath(); - const QString forcedPackageName = cleanPath.mid(importPath.size() + 1).replace('/', '.').replace('\\', '.'); - import = importNonFile(doc, info, forcedPackageName); - if (import) - d->importCache.insert(ImportCacheKey(info), import); - - break; - } - } - } - } - //### End of hack. - if (!import) { switch (info.type()) { case ImportInfo::FileImport: diff --git a/src/plugins/qmljstools/qmljsplugindumper.cpp b/src/plugins/qmljstools/qmljsplugindumper.cpp index 8e1c5f2113b..07cea32863f 100644 --- a/src/plugins/qmljstools/qmljsplugindumper.cpp +++ b/src/plugins/qmljstools/qmljsplugindumper.cpp @@ -274,7 +274,6 @@ void PluginDumper::dump(const Plugin &plugin) connect(process, SIGNAL(finished(int)), SLOT(qmlPluginTypeDumpDone(int))); connect(process, SIGNAL(error(QProcess::ProcessError)), SLOT(qmlPluginTypeDumpError(QProcess::ProcessError))); QStringList args; - args << QLatin1String("--notrelocatable"); if (plugin.importUri.isEmpty()) { args << QLatin1String("--path"); args << plugin.importPath; -- cgit v1.2.3