summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-09-01 04:54:21 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-09-01 04:54:21 (GMT)
commit6cd1863ca3ff0684e1dd1a8d9c13b8f141800072 (patch)
treed5264d12293d7e2e2f00dfc74d1a66def2d083d3
parente15129c0fb995fcfc120aa4b6e7ec56f9254d10b (diff)
parent554fabbcd8888c3f4146ac6f8da2dd7a6d4656b2 (diff)
downloadQt-6cd1863ca3ff0684e1dd1a8d9c13b8f141800072.zip
Qt-6cd1863ca3ff0684e1dd1a8d9c13b8f141800072.tar.gz
Qt-6cd1863ca3ff0684e1dd1a8d9c13b8f141800072.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
-rw-r--r--doc/src/declarative/extending.qdoc2
-rw-r--r--doc/src/declarative/modules.qdoc160
-rw-r--r--src/declarative/fx/qfxwebview.h1
-rw-r--r--src/declarative/qml/qmlcompositetypemanager.cpp19
-rw-r--r--src/declarative/qml/qmlengine.cpp213
-rw-r--r--tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/qmldir1
-rw-r--r--tests/auto/declarative/qmlparser/tst_qmlparser.cpp63
7 files changed, 242 insertions, 217 deletions
diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc
index 833a5db..3235435 100644
--- a/doc/src/declarative/extending.qdoc
+++ b/doc/src/declarative/extending.qdoc
@@ -818,7 +818,7 @@ Rectangle {
\endcode
\endtable
-Components may be collected into \l {Modules of Components} that gives the
+Components may be collected into \l {Modules} that gives the
developer more freedom than just putting files in the same directory.
\section2 Building reusable components
diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc
index 60cf2a4..7c67f60 100644
--- a/doc/src/declarative/modules.qdoc
+++ b/doc/src/declarative/modules.qdoc
@@ -1,123 +1,105 @@
/*!
-\page qmlmodules.html
\target qmlmodules
-\title Modules of Components
-
-A \bold module is a collection of \l Components.
-
-To use a module, include the following statement at the begining
-of your QML:
-
-\code
-import "path"
-\endcode
-
-This allows all components defined in the directory \c path to be used in
-the component where this statement appears.
-
-Currently, \c path may only be a directory relative to the directory containing
-the component issuing the import.
-
-The import statement cannot be used by remote content.
-*/
-
-/*
-
-Ideas for full module support....
-
-See QT-558.
-
-* Modularity within applications
-
-This is the currently-supported mechanism.
+\page qmlmodules.html
+\title Modules
-By using the "import" statement, a subdirectory of types can be added to the
-empty namespace. Alternatively, a type in a subdirectory can be referenced
-explicitly.
+A \bold module is a collection of QML types.
-So, given these files:
+To use types from a module it must be imported using the \c import statement. Successive
+import statements override earlier import statements.
- ./SubModule1/Type1.qml
- ./SubModule2/Type1.qml
+\section1 Importing Built-in Types
-This is valid QML:
+To use built-in types, you must import the module defining them.
+For example, to use types from Qt, import it:
- import "SubModule1"
- Type1 { ... }
- SubModule2.Type1 { ... }
+\code
+import Qt 4.6
+\endcode
+This makes available all types in Qt that were available in Qt 4.6, regardless of the
+actual version of Qt executing the QML.
-* System-installed modules (dependencies)
+Modules can be compiled-in (such as the Qt module), or they can be
+defined in QML files.
-To use system-installed modules, the dependency must be explicitly stated
-using the "require" statement. Types in required modules must still be
-explicitly qualified. Dependencies cannot be added to the empty namespace.
+\section1 Importing QML Files
- QMLPATH=/opt/Nokia/qml:/usr/share/lib/qml
- /opt/Nokia/qml/Module1/Type1.qml
- /usr/share/lib/qml/Module1/Type1.qml
+To import types defined in QML files in directories relative to the file importing them,
+a quoted import directory is used:
- require "Module1"
- Module1.Type1 { ... }
+\code
+import "path"
+\endcode
+This allows all components defined in the directory \c path to be used in
+the component where this statement appears.
-* Grouping of components within application modules
+To import types defined in QML files that are installed somewhere on the system,
+an unquoted URI is used:
-Sub-sub directories allow further grouping of types.
+\code
+import com.nokia.CoolStuff 1.0
+\endcode
- ./SubModule1/Group1/*.qml
- ./SubModule1/Group2/*.qml
+This will access file in the directory \c com/nokia/CoolStuff/, found in some
+location determined outside QML. See QmlEngine::addImportPath() and the \c -L option
+to the \l {qmlviewer}{viewer} application.
- SubModule1.Group1.Type1 { ... }
- SubModule1.Group1.Type2 { ... }
- SubModule1.Group2.Type1 { ... }
- SubModule1.Group2.Type2 { ... }
+The directory of installed files must include a file \c qmldir which specifies the
+mapping from all type names to versioned QML files. It is a list of lines of the form:
- import "SubModule1/Group1"
- Type1 { ... }
+\code
+# <Comment>
+<TypeName> <VersionRange> <File>
+\endcode
- import "SubModule1"
- Group1.Type1 { ... }
+<TypeName> is the type being made available; <VersionRange> is either a single version
+number like \c 4.0 or a range of minor versions like \c 4.0-2; <File> is the (relative)
+file name of the QML file defining the type.
+The same type can be provided by different files in different versions.
+If a type is in multiple major versions, it should be listed on a separate line.
+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.
-* Grouping of components within system-installed modules
+Installed files \e must be referred to by version information described above,
+local files \e may have it.
-System-installed types may also be grouped into types. The hierarchy is a
-global namespace, so such grouping is recommended to reduce clashes.
+The versioning system ensures that a given QML file will work regardless of the version
+of installed software, since a versioned import \e only imports types for that version,
+leaving other identifiers available, even if the actual installed version might otherwise
+use those identifiers.
- /opt/Nokia/qml/Module1/Group1/*.qml
- /opt/Nokia/qml/Module1/Group2/*.qml
+\section1 Namespaces - Named Imports
- require "Module1"
- Module1.Group1.Type1 { ... }
- Module1.Group1.Type2 { ... }
- Module1.Group2.Type1 { ... }
- Module1.Group2.Type2 { ... }
+When importing content it by default imports types into the global namespace.
+You may choose to import the module into another namespace, either to allow identically-named
+types to be referenced, or purely for readability.
- require "Module1/Group1"
- Group1.Type1 { ... }
+To import a module into a namespace:
- // Alternative syntax
- /opt/qml/com/nokia/qml/Module1/Group1/*.qml
- require "com.nokia.qml.Module1.Group1"
- Group1.Type1 { ... }
+\code
+import Qt 4.6 as TheQtLibrary
+\endcode
+Types from Qt 4.6 may then be used, but only by qualifying them with the namespace:
-* Private sub-components
+\code
+TheQtLibrary.Rectangle { ... }
+\endcode
-Directories begining with _ cannot be referenced except by types in the
-directory immediately containing it.
+Multiple modules can be imported into the same namespace in the same way that multiple
+modules can be imported into the global namespace:
- /opt/Nokia/qml/Module1/_private/Type1.qml
- ./SubModule1/_private/Type1.qml
+\code
+import Qt 4.6 as Nokia
+import Ovi 1.0 as Nokia
+\endcode
+*/
- SubModule1._private.Type1 { ... } // Not allowed
- import "SubModule1._private" // Not allowed
- require "SubModule1._private" // Not allowed
- require "SubModule1"
- Module1._private.Type1 { ... } // Not allowed
+/*
- import "_private" // allowed
- Type1 { ... }
+See original requirement QT-558.
*/
diff --git a/src/declarative/fx/qfxwebview.h b/src/declarative/fx/qfxwebview.h
index 3dd1b65..f136e2d 100644
--- a/src/declarative/fx/qfxwebview.h
+++ b/src/declarative/fx/qfxwebview.h
@@ -80,7 +80,6 @@ class QFxWebViewAttached;
class QFxWebSettings;
//### TODO: browser plugins
-//### TODO: smart zooming using e.g. DIV
class Q_DECLARATIVE_EXPORT QFxWebView : public QFxPaintedItem
{
diff --git a/src/declarative/qml/qmlcompositetypemanager.cpp b/src/declarative/qml/qmlcompositetypemanager.cpp
index 1b1f67c..f64547c 100644
--- a/src/declarative/qml/qmlcompositetypemanager.cpp
+++ b/src/declarative/qml/qmlcompositetypemanager.cpp
@@ -329,10 +329,27 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit)
QUrl url;
int majorVersion;
int minorVersion;
- if (!QmlEnginePrivate::get(engine)->resolveType(unit->imports, typeName, &ref.type, &url, &majorVersion, &minorVersion, 0)) {
+ QmlEnginePrivate::ImportedNamespace *typeNamespace = 0;
+ if (!QmlEnginePrivate::get(engine)->resolveType(unit->imports, typeName, &ref.type, &url, &majorVersion, &minorVersion, &typeNamespace)) {
// XXX could produce error message here.
}
+ if (typeNamespace) {
+ QmlError error;
+ error.setUrl(unit->imports.baseUrl());
+ error.setDescription(tr("Namespace %1 cannot be used as a type").arg(QLatin1String(typeName)));
+ if (!parserRef->refObjects.isEmpty()) {
+ QmlParser::Object *obj = parserRef->refObjects.first();
+ error.setLine(obj->location.start.line);
+ error.setColumn(obj->location.start.column);
+ }
+ unit->status = QmlCompositeTypeData::Error;
+ unit->errorType = QmlCompositeTypeData::GeneralError;
+ unit->errors << error;
+ doComplete(unit);
+ return;
+ }
+
if (ref.type) {
foreach (QmlParser::Object *obj, parserRef->refObjects) {
// store namespace for DOM
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index eaa1012..1640dcb 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -1142,65 +1142,71 @@ struct QmlEnginePrivate::ImportedNamespace {
QList<int> majversions;
QList<int> minversions;
QList<bool> isLibrary;
+ QList<bool> isBuiltin;
- QUrl find(const QString& type) const
+ bool find(const QByteArray& type, int *vmajor, int *vminor, QmlType** type_return, QUrl* url_return) const
{
for (int i=0; i<urls.count(); ++i) {
- QUrl url = QUrl(urls.at(i) + QLatin1String("/") + type + QLatin1String(".qml"));
int vmaj = majversions.at(i);
int vmin = minversions.at(i);
- 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());
+
+ if (isBuiltin.at(i)) {
+ QByteArray qt = urls.at(i).toLatin1();
+ qt += "/";
+ qt += type;
+ QmlType *t = QmlMetaType::qmlType(qt,vmaj,vmin);
+ if (vmajor) *vmajor = vmaj;
+ if (vminor) *vminor = vmin;
+ if (t) {
+ if (type_return)
+ *type_return = t;
+ return true;
+ }
+ } else {
+ QUrl url = QUrl(urls.at(i) + QLatin1String("/" + type + ".qml"));
+ 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 {
+ QByteArray lineba = qmldir.readLine();
+ if (lineba.at(0) == '#')
+ continue;
+ int space1 = lineba.indexOf(' ');
+ if (qstrncmp(lineba,type,space1)==0) {
+ // eg. 1.2-5
+ QString line = QString::fromUtf8(lineba);
+ space1 = line.indexOf(QLatin1Char(' ')); // refind in Unicode
+ int space2 = space1 >=0 ? line.indexOf(QLatin1Char(' '),space1+1) : -1;
+ 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);
+ if (url_return)
+ *url_return = url.resolved(mapfile.toString());
+ return true;
+ }
}
}
- }
- } while (!qmldir.atEnd());
+ } while (!qmldir.atEnd());
+ }
+ } else {
+ // XXX search non-files too! (eg. zip files, see QT-524)
+ QFileInfo f(url.toLocalFile());
+ if (f.exists()) {
+ if (url_return)
+ *url_return = url;
+ return true;
+ }
}
- } 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();
- }
-
- QmlType *findBuiltin(const QByteArray& type, int *vmajor, int *vminor) const
- {
- for (int i=0; i<urls.count(); ++i) {
- int vmaj = majversions.at(i);
- int vmin = minversions.at(i);
- QByteArray qt = urls.at(i).toLatin1();
- qt += "/";
- qt += type;
- QmlType *t = QmlMetaType::qmlType(qt,vmaj,vmin);
- if (vmajor) *vmajor = vmaj;
- if (vminor) *vminor = vmin;
- if (t) return t;
- }
- return 0;
+ return false;
}
};
@@ -1220,23 +1226,14 @@ public:
{
QmlEnginePrivate::ImportedNamespace *s;
if (prefix.isEmpty()) {
- if (importType == QmlScriptParser::Import::Library && !vmaj && !vmin) {
- // unversioned library imports are always qualified - if only by final URI component
- // XXX we need not support this
- int lastdot = uri.lastIndexOf(QLatin1Char('.'));
- QString defaultprefix = uri.mid(lastdot+1);
- s = set.value(defaultprefix);
- if (!s)
- set.insert(defaultprefix,(s=new QmlEnginePrivate::ImportedNamespace));
- } else {
- s = &unqualifiedset;
- }
+ s = &unqualifiedset;
} else {
s = set.value(prefix);
if (!s)
set.insert(prefix,(s=new QmlEnginePrivate::ImportedNamespace));
}
QString url = uri;
+ bool isbuiltin = false;
if (importType == QmlScriptParser::Import::Library) {
url.replace(QLatin1Char('.'),QLatin1Char('/'));
bool found = false;
@@ -1250,6 +1247,7 @@ public:
}
if (!found) {
// XXX assume it is a built-in type qualifier
+ isbuiltin = true;
}
} else {
url = base.resolved(QUrl(url)).toString();
@@ -1258,34 +1256,11 @@ public:
s->majversions.prepend(vmaj);
s->minversions.prepend(vmin);
s->isLibrary.prepend(importType == QmlScriptParser::Import::Library);
+ s->isBuiltin.prepend(isbuiltin);
return true;
}
- QUrl find(const QString& type) const
- {
- const QmlEnginePrivate::ImportedNamespace *s = 0;
- int slash = type.indexOf(QLatin1Char('/'));
- if (slash >= 0) {
- while (!s) {
- s = set.value(type.left(slash));
- int nslash = type.indexOf(QLatin1Char('/'),slash+1);
- if (nslash > 0)
- slash = nslash;
- else
- break;
- }
- } else {
- s = &unqualifiedset;
- }
- QString unqualifiedtype = type.mid(slash+1);
- if (s)
- return s->find(unqualifiedtype);
- else
- return QUrl();
- }
-
-
- QmlType *findBuiltin(const QByteArray& type, int *vmajor, int *vminor)
+ bool find(const QByteArray& type, int *vmajor, int *vminor, QmlType** type_return, QUrl* url_return)
{
QmlEnginePrivate::ImportedNamespace *s = 0;
int slash = type.indexOf('/');
@@ -1302,10 +1277,16 @@ public:
s = &unqualifiedset;
}
QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower)
- if (s)
- return s->findBuiltin(unqualifiedtype,vmajor,vminor);
- else
- return 0;
+ if (s) {
+ if (s->find(unqualifiedtype,vmajor,vminor,type_return,url_return))
+ return true;
+ }
+ if (url_return) {
+ *url_return = base.resolved(QUrl(QLatin1String(type + ".qml")));
+ return true;
+ } else {
+ return false;
+ }
}
QmlEnginePrivate::ImportedNamespace *findNamespace(const QString& type)
@@ -1417,40 +1398,27 @@ bool QmlEnginePrivate::addToImport(Imports* imports, const QString& uri, const Q
*/
bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& type, QmlType** type_return, QUrl* url_return, int *vmaj, int *vmin, ImportedNamespace** ns_return) const
{
- if (ns_return) {
- *ns_return = imports.d->findNamespace(QLatin1String(type));
- if (*ns_return)
- return true;
- }
- if (type_return) {
- QmlType* t = imports.d->findBuiltin(type,vmaj,vmin);
- if (!t) {
- // XXX do we really still need this?
- t = QmlMetaType::qmlType(type,0,0); // Try global namespace
- if (vmin) *vmin = 0;
- if (vmaj) *vmaj = 0;
- }
- if (t) {
- if (type_return) *type_return = t;
- if (qmlImportTrace())
- qDebug() << "QmlEngine::resolveType" << type << "= (builtin)";
- return true;
- }
+ ImportedNamespace* ns = imports.d->findNamespace(QLatin1String(type));
+ if (ns) {
+ if (qmlImportTrace())
+ qDebug() << "QmlEngine::resolveType" << type << "is namespace for" << ns->urls;
+ if (ns_return)
+ *ns_return = ns;
+ return true;
}
- if (url_return) {
- QUrl url = imports.d->find(QLatin1String(type));
- if (!url.isValid())
- url = imports.d->base.resolved(QUrl(QLatin1String(type + ".qml")));
-
- if (url.isValid()) {
- if (url_return) *url_return = url;
- if (qmlImportTrace())
- qDebug() << "QmlEngine::resolveType" << type << "=" << url;
+ if (type_return || url_return) {
+ if (imports.d->find(type,vmaj,vmin,type_return,url_return)) {
+ if (qmlImportTrace()) {
+ if (type_return && *type_return)
+ qDebug() << "QmlEngine::resolveType" << type << "=" << (*type_return)->typeName();
+ if (url_return)
+ qDebug() << "QmlEngine::resolveType" << type << "=" << *url_return;
+ }
return true;
}
+ if (qmlImportTrace())
+ qDebug() << "QmlEngine::resolveType" << type << "not found";
}
- if (qmlImportTrace())
- qDebug() << "QmlEngine::resolveType" << type << " not found";
return false;
}
@@ -1466,12 +1434,7 @@ bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& typ
*/
void QmlEnginePrivate::resolveTypeInNamespace(ImportedNamespace* ns, const QByteArray& type, QmlType** type_return, QUrl* url_return, int *vmaj, int *vmin ) const
{
- if (type_return) {
- *type_return = ns->findBuiltin(type,vmaj,vmin);
- }
- if (url_return) {
- *url_return = ns->find(QLatin1String(type));
- }
+ ns->find(type,vmaj,vmin,type_return,url_return);
}
QT_END_NAMESPACE
diff --git a/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/qmldir b/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/qmldir
index f22e179..ba0b42a 100644
--- a/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/qmldir
+++ b/tests/auto/declarative/qmlparser/lib/com/nokia/installedtest/qmldir
@@ -1,2 +1,3 @@
InstalledTest 1.0-3 InstalledTest.qml
InstalledTest 1.4 InstalledTest2.qml
+Rectangle 1.5 InstalledTest2.qml
diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
index c21d672..36471a4 100644
--- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
+++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
@@ -54,6 +54,8 @@ private slots:
void importsLocal();
void importsInstalled_data();
void importsInstalled();
+ void importsOrder_data();
+ void importsOrder();
// regression tests for crashes
void crash1();
@@ -153,6 +155,8 @@ void tst_qmlparser::errors_data()
QTest::newRow("failingComponent") << "failingComponentTest.qml" << "failingComponent.errors.txt" << false;
QTest::newRow("missingSignal") << "missingSignal.qml" << "missingSignal.errors.txt" << false;
QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
+
+ QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
}
void tst_qmlparser::errors()
@@ -694,6 +698,65 @@ void tst_qmlparser::importsInstalled()
testType(qml,type);
}
+
+void tst_qmlparser::importsOrder_data()
+{
+ QTest::addColumn<QString>("qml");
+ QTest::addColumn<QString>("type");
+
+ QTest::newRow("installed import overrides 1") <<
+ "import com.nokia.installedtest 1.0\n"
+ "import com.nokia.installedtest 1.4\n"
+ "InstalledTest {}"
+ << "QFxText";
+ QTest::newRow("installed import overrides 2") <<
+ "import com.nokia.installedtest 1.4\n"
+ "import com.nokia.installedtest 1.0\n"
+ "InstalledTest {}"
+ << "QFxRect";
+ QTest::newRow("installed import re-overrides 1") <<
+ "import com.nokia.installedtest 1.4\n"
+ "import com.nokia.installedtest 1.0\n"
+ "import com.nokia.installedtest 1.4\n"
+ "InstalledTest {}"
+ << "QFxText";
+ QTest::newRow("installed import re-overrides 2") <<
+ "import com.nokia.installedtest 1.4\n"
+ "import com.nokia.installedtest 1.0\n"
+ "import com.nokia.installedtest 1.4\n"
+ "import com.nokia.installedtest 1.0\n"
+ "InstalledTest {}"
+ << "QFxRect";
+
+ QTest::newRow("installed import versus builtin 1") <<
+ "import com.nokia.installedtest 1.5\n"
+ "import Qt 4.6\n"
+ "Rectangle {}"
+ << "QFxRect";
+ QTest::newRow("installed import versus builtin 2") <<
+ "import Qt 4.6\n"
+ "import com.nokia.installedtest 1.5\n"
+ "Rectangle {}"
+ << "QFxText";
+ QTest::newRow("namespaces cannot be overridden by types 1") <<
+ "import Qt 4.6 as Rectangle\n"
+ "import com.nokia.installedtest 1.5\n"
+ "Rectangle {}"
+ << "";
+ QTest::newRow("namespaces cannot be overridden by types 2") <<
+ "import Qt 4.6 as Rectangle\n"
+ "import com.nokia.installedtest 1.5\n"
+ "Rectangle.Image {}"
+ << "QFxImage";
+}
+
+void tst_qmlparser::importsOrder()
+{
+ QFETCH(QString, qml);
+ QFETCH(QString, type);
+ testType(qml,type);
+}
+
void tst_qmlparser::crash1()
{
QmlComponent component(&engine, "Component {}");