From d039e2e8307bd272eedc5beae4ecf1a14e47def5 Mon Sep 17 00:00:00 2001 From: mae Date: Thu, 18 Mar 2010 15:54:02 +0100 Subject: Fix local type lookup This change removes the hacky final baseUrl+TypeName+".qml" lookup. In order to still support internal files in remote modules, a new qmldir keyword "internal" is introduced. --- doc/src/declarative/modules.qdoc | 7 +++++++ src/declarative/qml/qdeclarativedirparser.cpp | 10 ++++++++++ src/declarative/qml/qdeclarativedirparser_p.h | 6 ++++-- src/declarative/qml/qdeclarativeengine.cpp | 23 ++++++++++------------ .../data/failingComponent.errors.txt | 2 +- .../data/unregisteredObject.errors.txt | 2 +- .../declarative/qmllanguage/UndeclaredLocal.qml | 3 +++ .../declarative/qmllanguage/WrongTestLocal.qml | 1 + .../qtest/declarative/qmllanguage/qmldir | 1 + .../tst_qdeclarativelanguage.cpp | 3 +++ 10 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml create mode 100644 tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc index ab75f8d..53de32c 100644 --- a/doc/src/declarative/modules.qdoc +++ b/doc/src/declarative/modules.qdoc @@ -143,6 +143,13 @@ since the \e first name-version match is used. Installed files do not need to import the module of which they are a part, as they can refer to the other QML files in the module as relative (local) files. +If the module is imported from a remote location, those files must nevertheless be listed in +the \c qmldir file. Internal files can be marked with the \c internal keyword, to ensure +they are not visible outside the module: + +\code +internal +\endcode Installed and remote files \e must be referred to by version information described above, local files \e may have it. diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp index b6d2115..0e82098 100644 --- a/src/declarative/qml/qdeclarativedirparser.cpp +++ b/src/declarative/qml/qdeclarativedirparser.cpp @@ -151,6 +151,16 @@ bool QDeclarativeDirParser::parse() _plugins.append(entry); + } else if (sections[0] == QLatin1String("internal")) { + if (sectionCount != 3) { + reportError(lineNumber, -1, + QString::fromUtf8("internal types require 2 arguments, but %1 were provided").arg(sectionCount + 1)); + continue; + } + Component entry(sections[1], sections[2], -1, -1); + entry.internal = true; + _components.append(entry); + } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) const Component entry(sections[0], sections[1], -1, -1); diff --git a/src/declarative/qml/qdeclarativedirparser_p.h b/src/declarative/qml/qdeclarativedirparser_p.h index 5df7117..295fa66 100644 --- a/src/declarative/qml/qdeclarativedirparser_p.h +++ b/src/declarative/qml/qdeclarativedirparser_p.h @@ -94,15 +94,17 @@ public: struct Component { Component() - : majorVersion(0), minorVersion(0) {} + : majorVersion(0), minorVersion(0), internal(false) {} Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion) - : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) {} + : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion), + internal(false) {} QString typeName; QString fileName; int majorVersion; int minorVersion; + bool internal; }; QList components() const; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 800434a..174579c 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1363,7 +1363,8 @@ struct QDeclarativeEnginePrivate::ImportedNamespace { QList isLibrary; QList qmlDirContent; - bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return) + bool find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return, QUrl* url_return, + QUrl *base = 0) { for (int i=0; i= c.minorVersion)) { + QUrl candidate = url.resolved(QUrl(c.fileName)); + if (c.internal && base) { + if (base->resolved(QUrl(c.fileName)) != candidate) + continue; // failed attempt to access an internal type + } if (url_return) - *url_return = url.resolved(QUrl(c.fileName)); + *url_return = candidate; return true; } } @@ -1617,7 +1623,7 @@ public: } QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) if (s) { - if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return)) + if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return, &base)) return true; if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) { // qualified, and only 1 url @@ -1627,16 +1633,7 @@ public: } - - /* now comes really nasty code. It makes "private" types load in the remote case, but - it does this by breaking the import order. This must go. Instead private types must - be marked private in the qmldir. */ - if (url_return) { - *url_return = base.resolved(QUrl(QString::fromUtf8(type + ".qml"))); - return true; - } else { - return false; - } + return false; } QDeclarativeEnginePrivate::ImportedNamespace *findNamespace(const QString& type) diff --git a/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt index 0cf0ef3..364ca67 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt +++ b/tests/auto/declarative/qdeclarativelanguage/data/failingComponent.errors.txt @@ -1 +1 @@ -3:5:Type FailingComponent unavailable +3:5:FailingComponent is not a type diff --git a/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt b/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt index 347db05..10e5fb2 100644 --- a/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt +++ b/tests/auto/declarative/qdeclarativelanguage/data/unregisteredObject.errors.txt @@ -1 +1 @@ -2:1:Type UnregisteredObjectType unavailable +2:1:UnregisteredObjectType is not a type diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml new file mode 100644 index 0000000..836c20a --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/UndeclaredLocal.qml @@ -0,0 +1,3 @@ +import Qt 4.6 + +Image { source: "pics/blue.png" } diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml new file mode 100644 index 0000000..8dcb7be --- /dev/null +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/WrongTestLocal.qml @@ -0,0 +1 @@ +UndeclaredInternal {} diff --git a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir index 303c5c8..da10ba9 100644 --- a/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir +++ b/tests/auto/declarative/qdeclarativelanguage/qtest/declarative/qmllanguage/qmldir @@ -1,3 +1,4 @@ Test Test.qml TestSubDir TestSubDir.qml TestLocal TestLocal.qml +internal LocalInternal LocalInternal.qml diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp index 6b564d4..9188d72 100644 --- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp +++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp @@ -1242,6 +1242,9 @@ void tst_qdeclarativelanguage::importsRemote_data() QTest::newRow("remote import") << "import \""+serverdir+"\"\nTest {}" << "QDeclarativeRectangle"; QTest::newRow("remote import with subdir") << "import \""+serverdir+"\"\nTestSubDir {}" << "QDeclarativeText"; QTest::newRow("remote import with local") << "import \""+serverdir+"\"\nTestLocal {}" << "QDeclarativeImage"; + QTest::newRow("wrong remote import with undeclared local") << "import \""+serverdir+"\"\nWrongTestLocal {}" << ""; + QTest::newRow("wrong remote import of internal local") << "import \""+serverdir+"\"\nLocalInternal {}" << ""; + QTest::newRow("wrong remote import of undeclared local") << "import \""+serverdir+"\"\nUndeclaredLocal {}" << ""; } #include "testhttpserver.h" -- cgit v0.12