diff options
10 files changed, 180 insertions, 45 deletions
diff --git a/examples/declarative/modules/builtin-version.qml b/examples/declarative/modules/builtin-version.qml index 82055b4..69f64ed 100644 --- a/examples/declarative/modules/builtin-version.qml +++ b/examples/declarative/modules/builtin-version.qml @@ -1,5 +1,3 @@ import Qt 4.6 -import com.nokia.Qt 4.7 Rect {} -// and later... SuperRect{} diff --git a/examples/declarative/modules/lib/com/nokia/Foo/Bar.qml b/examples/declarative/modules/lib/com/nokia/Foo/Bar.qml new file mode 100644 index 0000000..270cd46 --- /dev/null +++ b/examples/declarative/modules/lib/com/nokia/Foo/Bar.qml @@ -0,0 +1,5 @@ +import Qt 4.6 +Text { + text: "lib/com/nokia/Foo/Bar.qml" + color: "green" +} diff --git a/examples/declarative/modules/lib/com/nokia/Foo/Bar17.qml b/examples/declarative/modules/lib/com/nokia/Foo/Bar17.qml new file mode 100644 index 0000000..f93fc62 --- /dev/null +++ b/examples/declarative/modules/lib/com/nokia/Foo/Bar17.qml @@ -0,0 +1,5 @@ +import Qt 4.6 +Text { + text: "lib/com/nokia/Foo/Bar17.qml" + color: "white" +} diff --git a/examples/declarative/modules/lib/com/nokia/Foo/Baz.qml b/examples/declarative/modules/lib/com/nokia/Foo/Baz.qml new file mode 100644 index 0000000..4daa37f --- /dev/null +++ b/examples/declarative/modules/lib/com/nokia/Foo/Baz.qml @@ -0,0 +1,5 @@ +import Qt 4.6 +Text { + text: "lib/com/nokia/Foo/Baz.qml" + color: "red" +} diff --git a/examples/declarative/modules/lib/com/nokia/Foo/qmldir b/examples/declarative/modules/lib/com/nokia/Foo/qmldir new file mode 100644 index 0000000..b8111cb --- /dev/null +++ b/examples/declarative/modules/lib/com/nokia/Foo/qmldir @@ -0,0 +1,6 @@ +# Baz was introduced in Foo 1.6 +# Bar 1.5 and 1.6 are the same, but in 1.7 it is reimplemented. +Bar 1.5 Bar.qml +Bar 1.6 Bar.qml +Bar 1.7 Bar17.qml +Baz 1.6 Baz.qml diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 52fd0b7..0a05094 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -1045,36 +1045,39 @@ struct QmlEnginePrivate::ImportedNamespace { QUrl url = QUrl(urls.at(i) + QLatin1String("/") + type + QLatin1String(".qml")); int vmaj = majversions.at(i); int vmin = minversions.at(i); - // XXX search non-files too! (eg. zip files, see QT-524) - QFileInfo f(url.toLocalFile()); - if (f.exists()) { - bool ok=true; - if (vmaj || vmin) { - QString version = QString::number(vmaj) + QLatin1String(".") + QString::number(vmin); - ok=false; - // Check version file - XXX cache these in QmlEngine! - QFile qmldir(urls.at(i)+QLatin1String("/qmldir")); - if (qmldir.open(QIODevice::ReadOnly)) { - do { - QString line = QString::fromUtf8(qmldir.readLine()); - if (line.at(0) == QLatin1Char('#')) - continue; - int space1 = line.indexOf(QLatin1Char(' ')); - int space2 = space1 >=0 ? line.indexOf(QLatin1Char(' '),space1+1) : -1; - QStringRef maptype = line.leftRef(space1); - QStringRef mapversion = line.midRef(space1+1,space2<0?line.length()-space1-2:space2-space1-1); - QStringRef mapfile = space2<0 ? QStringRef() : line.midRef(space2+1,line.length()-space2-2); - if (maptype==type && mapversion==version) { - if (mapfile.isEmpty()) - return url; - else + if (vmaj || vmin) { + // Check version file - XXX cache these in QmlEngine! + QFile qmldir(QUrl(urls.at(i)+QLatin1String("/qmldir")).toLocalFile()); + if (qmldir.open(QIODevice::ReadOnly)) { + do { + QString line = QString::fromUtf8(qmldir.readLine()); + if (line.at(0) == QLatin1Char('#')) + continue; + int space1 = line.indexOf(QLatin1Char(' ')); + int space2 = space1 >=0 ? line.indexOf(QLatin1Char(' '),space1+1) : -1; + QStringRef maptype = line.leftRef(space1); + if (maptype==type) { + // eg. 1.2-5 + QString mapversions = line.mid(space1+1,space2<0?line.length()-space1-2:space2-space1-1); + int dot = mapversions.indexOf(QLatin1Char('.')); + int dash = mapversions.indexOf(QLatin1Char('-')); + int mapvmaj = mapversions.left(dot).toInt(); + if (mapvmaj==vmaj) { + int mapvmin_from = (dash <= 0 ? mapversions.mid(dot+1) : mapversions.mid(dot+1,dash-dot-1)).toInt(); + int mapvmin_to = dash <= 0 ? mapvmin_from : mapversions.mid(dash+1).toInt(); + if (vmin >= mapvmin_from && vmin <= mapvmin_to) { + QStringRef mapfile = space2<0 ? QStringRef() : line.midRef(space2+1,line.length()-space2-2); return url.resolved(mapfile.toString()); + } } - } while (!qmldir.atEnd()); - } + } + } while (!qmldir.atEnd()); } - if (ok) - return url; + } else { + // XXX search non-files too! (eg. zip files, see QT-524) + QFileInfo f(url.toLocalFile()); + if (f.exists()) + return url; // (unversioned) local import } } return QUrl(); @@ -1124,7 +1127,7 @@ public: foreach (QString p, importPath) { QString dir = p+QLatin1Char('/')+url; if (QFile::exists(dir+QLatin1String("/qmldir"))) { - url = dir; + url = QLatin1String("file://")+dir; found = true; break; } diff --git a/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/InstalledTest.qml b/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/InstalledTest.qml new file mode 100644 index 0000000..65f0276 --- /dev/null +++ b/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/InstalledTest.qml @@ -0,0 +1,2 @@ +import Qt 4.6 +Rect {} diff --git a/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/InstalledTest2.qml b/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/InstalledTest2.qml new file mode 100644 index 0000000..a0706ad --- /dev/null +++ b/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/InstalledTest2.qml @@ -0,0 +1,2 @@ +import Qt 4.6 +Text {} diff --git a/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/qmldir b/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/qmldir new file mode 100644 index 0000000..f22e179 --- /dev/null +++ b/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/qmldir @@ -0,0 +1,2 @@ +InstalledTest 1.0-3 InstalledTest.qml +InstalledTest 1.4 InstalledTest2.qml diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp index 92c23d4..9974ef8 100644 --- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp +++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp @@ -13,6 +13,8 @@ class tst_qmlparser : public QObject public: tst_qmlparser() { QmlMetaType::registerCustomStringConverter(qMetaTypeId<MyCustomVariantType>(), myCustomVariantTypeConverter); + QFileInfo fileInfo(__FILE__); + engine.addImportPath(fileInfo.absoluteDir().filePath(QLatin1String("lib"))); } private slots: @@ -512,32 +514,137 @@ void tst_qmlparser::imports_data() QTest::addColumn<QString>("qml"); QTest::addColumn<QString>("type"); - QTest::newRow("missing import") << "Test {}" << ""; - QTest::newRow("not in version 0.0") << "import com.nokia.Test 0.0\nTest {}" << ""; - QTest::newRow("in version 1.0") << "import com.nokia.Test 1.0\nTest {}" << "TestType"; - QTest::newRow("in version 1.1") << "import com.nokia.Test 1.1\nTest {}" << "TestType"; - QTest::newRow("in version 1.3") << "import com.nokia.Test 1.3\nTest {}" << "TestType"; - QTest::newRow("not in version 1.4") << "import com.nokia.Test 1.4\nTest {}" << ""; - QTest::newRow("in version 1.5") << "import com.nokia.Test 1.5\nTest {}" << "TestType"; - QTest::newRow("changed in version 1.8") << "import com.nokia.Test 1.8\nTest {}" << "TestType2"; - QTest::newRow("not in version 1.10") << "import com.nokia.Test 1.10\nTest {}" << ""; - QTest::newRow("back in version 1.12") << "import com.nokia.Test 1.12\nTest {}" << "TestType2"; - QTest::newRow("old in version 1.9") << "import com.nokia.Test 1.9\nOldTest {}" << "TestType"; - QTest::newRow("old in version 1.11") << "import com.nokia.Test 1.11\nOldTest {}" << "TestType"; - QTest::newRow("no old in version 1.12") << "import com.nokia.Test 1.12\nOldTest {}" << ""; + // import built-ins + QTest::newRow("missing import") + << "Test {}" + << ""; + QTest::newRow("not in version 0.0") + << "import com.nokia.Test 0.0\n" + "Test {}" + << ""; + QTest::newRow("in version 1.0") + << "import com.nokia.Test 1.0\n" + "Test {}" + << "TestType"; + QTest::newRow("qualified wrong") + << "import com.nokia.Test 1.0 as T\n" + "Test {}" + << ""; + QTest::newRow("qualified right") + << "import com.nokia.Test 1.0 as T\n" + "T.Test {}" + << "TestType"; + QTest::newRow("qualified right but not in version 0.0") + << "import com.nokia.Test 0.0 as T\n" + "T.Test {}" + << ""; + QTest::newRow("in version 1.1") + << "import com.nokia.Test 1.1\n" + "Test {}" + << "TestType"; + QTest::newRow("in version 1.3") + << "import com.nokia.Test 1.3\n" + "Test {}" + << "TestType"; + QTest::newRow("not in version 1.4") + << "import com.nokia.Test 1.4\n" + "Test {}" + << ""; + QTest::newRow("in version 1.5") + << "import com.nokia.Test 1.5\n" + "Test {}" + << "TestType"; + QTest::newRow("changed in version 1.8") + << "import com.nokia.Test 1.8\n" + "Test {}" + << "TestType2"; + QTest::newRow("not in version 1.10") + << "import com.nokia.Test 1.10\n" + "Test {}" + << ""; + QTest::newRow("back in version 1.12") + << "import com.nokia.Test 1.12\n" + "Test {}" + << "TestType2"; + QTest::newRow("old in version 1.9") + << "import com.nokia.Test 1.9\n" + "OldTest {}" + << "TestType"; + QTest::newRow("old in version 1.11") + << "import com.nokia.Test 1.11\n" + "OldTest {}" + << "TestType"; + QTest::newRow("no old in version 1.12") + << "import com.nokia.Test 1.12\n" + "OldTest {}" + << ""; + QTest::newRow("multiversion 1") + << "import com.nokia.Test 1.11\n" + "import com.nokia.Test 1.12\n" + "Test {}" + << "TestType2"; + QTest::newRow("multiversion 2") + << "import com.nokia.Test 1.11\n" + "import com.nokia.Test 1.12\n" + "OldTest {}" + << "TestType"; + QTest::newRow("qualified multiversion 3") + << "import com.nokia.Test 1.0 as T0\n" + "import com.nokia.Test 1.8 as T8\n" + "T0.Test {}" + << "TestType"; + QTest::newRow("qualified multiversion 4") + << "import com.nokia.Test 1.0 as T0\n" + "import com.nokia.Test 1.8 as T8\n" + "T8.Test {}" + << "TestType2"; + QTest::newRow("qualified multiversion 5") + << "import com.nokia.Test 1.0 as T0\n" + "import com.nokia.Test 1.10 as T10\n" + "T10.Test {}" + << ""; + + // import locals + QTest::newRow("local import") + << "import \"subdir\"\n" + "Test {}" + << "QFxRect"; + QTest::newRow("local import as") + << "import \"subdir\" as T\n" + "T.Test {}" + << "QFxRect"; + QTest::newRow("wrong local import as") + << "import \"subdir\" as T\n" + "Test {}" + << ""; + QTest::newRow("library precedence over local import") + << "import \"subdir\"\n" + "import com.nokia.Test 1.0\n" + "Test {}" + << "TestType"; + + // import installed + QTest::newRow("installed import") + << "import com.nokia.installedtest 1.0\n" + "InstalledTest {}" + << "QFxRect"; + QTest::newRow("installed import") + << "import com.nokia.installedtest 1.4\n" + "InstalledTest {}" + << "QFxText"; } -// Tests the registration of custom variant string converters void tst_qmlparser::imports() { QFETCH(QString, qml); QFETCH(QString, type); - QmlComponent component(&engine, qml.toUtf8(), TEST_FILE("empty.txt")); + QmlComponent component(&engine, qml.toUtf8(), TEST_FILE("empty.txt")); // just a file for relative local imports if (type.isEmpty()) { QVERIFY(component.isError()); } else { + VERIFY_ERRORS(0); QObject *object = component.create(); QVERIFY(object != 0); QCOMPARE(QString(object->metaObject()->className()), type); |