summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWarwick Allison <warwick.allison@nokia.com>2009-07-02 05:41:41 (GMT)
committerWarwick Allison <warwick.allison@nokia.com>2009-07-02 05:41:41 (GMT)
commitff4140013a993a90ae26cbd56e9d75760ec3e40d (patch)
tree32aab6ba822029267ed459f8ce9adde0a956d5c0
parentbaea2c29340b14c6ec1f560a09627f23dd358363 (diff)
downloadQt-ff4140013a993a90ae26cbd56e9d75760ec3e40d.zip
Qt-ff4140013a993a90ae26cbd56e9d75760ec3e40d.tar.gz
Qt-ff4140013a993a90ae26cbd56e9d75760ec3e40d.tar.bz2
First conversion to new module handling.
Works same as before for now, but now the variables and methods are all in the right place. In particular, type resolving is per-component, not per-engine, even though it is the engine that ultimately has the ability to find types, because each component will have a different set of available types. Designed to be optimizable - QmlEngine could share data between QmlEngine::Import objects, and the import objects could read types in bulk rather than always searching.
-rw-r--r--src/declarative/fx/qfxitem.cpp2
-rw-r--r--src/declarative/fx/qfxwebview.cpp2
-rw-r--r--src/declarative/qml/qmlcomponent.cpp2
-rw-r--r--src/declarative/qml/qmlcompositetypemanager.cpp23
-rw-r--r--src/declarative/qml/qmlcompositetypemanager_p.h5
-rw-r--r--src/declarative/qml/qmlcontext.cpp29
-rw-r--r--src/declarative/qml/qmlcontext.h1
-rw-r--r--src/declarative/qml/qmlengine.cpp202
-rw-r--r--src/declarative/qml/qmlengine.h21
-rw-r--r--src/declarative/qml/qmlengine_p.h1
-rw-r--r--src/declarative/qml/qmlscriptparser.cpp16
-rw-r--r--src/declarative/qml/qmlscriptparser_p.h9
12 files changed, 116 insertions, 197 deletions
diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp
index 7ccad5f..b5c2c0e 100644
--- a/src/declarative/fx/qfxitem.cpp
+++ b/src/declarative/fx/qfxitem.cpp
@@ -1982,7 +1982,7 @@ void QFxItem::newChild(const QString &type)
{
Q_D(QFxItem);
- QUrl url = qmlContext(this)->resolvedUri(QUrl(type));
+ QUrl url = qmlContext(this)->resolvedUrl(QUrl(type));
if (url.isEmpty())
return;
diff --git a/src/declarative/fx/qfxwebview.cpp b/src/declarative/fx/qfxwebview.cpp
index 3ab64bc..c6a8ebf 100644
--- a/src/declarative/fx/qfxwebview.cpp
+++ b/src/declarative/fx/qfxwebview.cpp
@@ -1006,7 +1006,7 @@ QFxWebView *QFxWebPage::view()
QObject *QFxWebPage::createPlugin(const QString &, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
{
- QUrl comp = qmlContext(view())->resolvedUri(url);
+ QUrl comp = qmlContext(view())->resolvedUrl(url);
return new QWidget_Dummy_Plugin(comp,view(),paramNames,paramValues);
}
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index 293082f..988d7c2 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -122,7 +122,7 @@ void QmlComponentPrivate::typeDataReady()
void QmlComponentPrivate::fromTypeData(QmlCompositeTypeData *data)
{
- url = QUrl(data->url);
+ url = data->imports.baseUrl();
QmlCompiledComponent *c = data->toCompiledComponent(engine);
if (!c) {
diff --git a/src/declarative/qml/qmlcompositetypemanager.cpp b/src/declarative/qml/qmlcompositetypemanager.cpp
index ef77803..1a67bf4 100644
--- a/src/declarative/qml/qmlcompositetypemanager.cpp
+++ b/src/declarative/qml/qmlcompositetypemanager.cpp
@@ -88,7 +88,7 @@ QmlComponent *QmlCompositeTypeData::toComponent(QmlEngine *engine)
component = new QmlComponent(engine, cc, -1, -1, 0);
} else {
component = new QmlComponent(engine, 0);
- component->d_func()->url = QUrl(url);
+ component->d_func()->url = imports.baseUrl();
component->d_func()->errors = errors;
}
@@ -103,8 +103,8 @@ QmlCompositeTypeData::toCompiledComponent(QmlEngine *engine)
if (status == Complete && !compiledComponent) {
compiledComponent = new QmlCompiledComponent;
- compiledComponent->url = QUrl(url);
- compiledComponent->name = url.toLatin1(); // ###
+ compiledComponent->url = imports.baseUrl();
+ compiledComponent->name = compiledComponent->url.toString().toLatin1(); // ###
QmlCompiler compiler;
if (!compiler.compile(engine, this, compiledComponent)) {
@@ -143,7 +143,7 @@ QmlCompositeTypeData *QmlCompositeTypeManager::get(const QUrl &url)
if (!unit) {
unit = new QmlCompositeTypeData;
unit->status = QmlCompositeTypeData::Waiting;
- unit->url = url.toString();
+ unit->imports.setBaseUrl(url);
components.insert(url.toString(), unit);
loadSource(unit);
@@ -158,7 +158,7 @@ QmlCompositeTypeManager::getImmediate(const QByteArray &data, const QUrl &url)
{
QmlCompositeTypeData *unit = new QmlCompositeTypeData;
unit->status = QmlCompositeTypeData::Waiting;
- unit->url = url.toString();
+ unit->imports.setBaseUrl(url);
setData(unit, data, url);
return unit;
}
@@ -209,7 +209,7 @@ void QmlCompositeTypeManager::replyFinished()
void QmlCompositeTypeManager::loadSource(QmlCompositeTypeData *unit)
{
- QUrl url(unit->url);
+ QUrl url(unit->imports.baseUrl());
if (url.scheme() == QLatin1String("file")) {
@@ -250,8 +250,9 @@ void QmlCompositeTypeManager::setData(QmlCompositeTypeData *unit,
doComplete(unit);
} else {
-
- engine->addNameSpacePaths(unit->data.nameSpacePaths());
+ foreach (QmlScriptParser::Import imp, unit->data.imports()) {
+ engine->addImport(&unit->imports, imp.uri, imp.prefix, imp.version_major, imp.version_minor);
+ }
compile(unit);
}
@@ -319,13 +320,13 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit)
continue;
}
- QUrl url = engine->componentUrl(QUrl(QLatin1String(type + ".qml")), QUrl(unit->url));
+ QUrl url = engine->resolveType(unit->imports, QString(type));
QmlCompositeTypeData *urlUnit = components.value(url.toString());
if (!urlUnit) {
urlUnit = new QmlCompositeTypeData;
urlUnit->status = QmlCompositeTypeData::Waiting;
- urlUnit->url = url.toString();
+ urlUnit->imports.setBaseUrl(url);
components.insert(url.toString(), urlUnit);
loadSource(urlUnit);
@@ -338,7 +339,7 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit)
unit->status = QmlCompositeTypeData::Error;
{
QmlError error;
- error.setUrl(QUrl(unit->url));
+ error.setUrl(unit->imports.baseUrl());
error.setDescription(tr("Type %1 unavailable").arg(QLatin1String(type)));
unit->errors << error;
}
diff --git a/src/declarative/qml/qmlcompositetypemanager_p.h b/src/declarative/qml/qmlcompositetypemanager_p.h
index 96e77d6..a393da4 100644
--- a/src/declarative/qml/qmlcompositetypemanager_p.h
+++ b/src/declarative/qml/qmlcompositetypemanager_p.h
@@ -57,10 +57,10 @@
#include <private/qmlscriptparser_p.h>
#include <private/qmlrefcount_p.h>
#include <QtDeclarative/qmlerror.h>
+#include <QtDeclarative/qmlengine.h>
QT_BEGIN_NAMESPACE
-class QmlEngine;
class QmlCompiledComponent;
class QmlComponentPrivate;
class QmlComponent;
@@ -86,7 +86,8 @@ struct QmlCompositeTypeData : public QmlRefCount
QList<QmlError> errors;
- QString url;
+ QmlEngine::Imports imports;
+
QList<QmlCompositeTypeData *> dependants;
// Return a QmlComponent if the QmlCompositeTypeData is not in the Waiting
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index e5016f2..60cb231 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -449,35 +449,6 @@ QUrl QmlContext::resolvedUrl(const QUrl &src)
}
/*!
- Resolves the component URI \a src relative to the URL of the
- containing component, and according to the
- \l {QmlEngine::nameSpacePaths()} {namespace paths} of the
- context's engine, returning the resolved URL.
-
- \sa QmlEngine::componentUrl(), setBaseUrl()
-*/
-QUrl QmlContext::resolvedUri(const QUrl &src)
-{
- QmlContext *ctxt = this;
- if (src.isRelative()) {
- if (ctxt) {
- while(ctxt) {
- if (ctxt->d_func()->url.isValid())
- break;
- else
- ctxt = ctxt->parentContext();
- }
-
- if (ctxt)
- return ctxt->d_func()->engine->componentUrl(src, ctxt->d_func()->url);
- }
- return QUrl();
- } else {
- return ctxt->d_func()->engine->componentUrl(src, QUrl());
- }
-}
-
-/*!
Explicitly sets the url both resolveUri() and resolveUrl() will
use for relative references to \a baseUrl.
diff --git a/src/declarative/qml/qmlcontext.h b/src/declarative/qml/qmlcontext.h
index ce5fe52..44d8caa 100644
--- a/src/declarative/qml/qmlcontext.h
+++ b/src/declarative/qml/qmlcontext.h
@@ -77,7 +77,6 @@ public:
static QmlContext *activeContext();
- QUrl resolvedUri(const QUrl &);
QUrl resolvedUrl(const QUrl &);
void setBaseUrl(const QUrl &);
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index d645fb3..dc33b38 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -483,132 +483,6 @@ QmlContext *QmlEngine::activeContext()
}
/*!
- Sets the mappings from namespace URIs to URL to \a map.
-
- \sa nameSpacePaths()
-*/
-void QmlEngine::setNameSpacePaths(const QMap<QString,QString>& map)
-{
- Q_D(QmlEngine);
- d->nameSpacePaths = map;
-}
-
-/*!
- Adds mappings (given by \a map) from namespace URIs to URL.
-
- \sa nameSpacePaths()
-*/
-void QmlEngine::addNameSpacePaths(const QMap<QString,QString>& map)
-{
- Q_D(QmlEngine);
- d->nameSpacePaths.unite(map);
-}
-
-/*!
- Adds a mapping from namespace URI \a ns to URL \a path.
-
- \sa nameSpacePaths()
-*/
-void QmlEngine::addNameSpacePath(const QString& ns, const QString& path)
-{
- Q_D(QmlEngine);
- d->nameSpacePaths.insertMulti(ns,path);
-}
-
-/*!
- Returns the mapping from namespace URIs to URLs.
-
- Currently, only the empty namespace is supported
- (i.e. types cannot be qualified with a namespace).
-
- The QML \c import statement can be used to import a directory of
- components into the empty namespace.
-
- \qml
- import "MyModuleDirectory"
- \endqml
-
- This is also possible from C++:
-
- \code
- engine->addNameSpacePath("","file:///opt/abcdef");
- \endcode
-
- \sa componentUrl()
-*/
-QMap<QString,QString> QmlEngine::nameSpacePaths() const
-{
- Q_D(const QmlEngine);
- return d->nameSpacePaths;
-}
-
-/*!
- Returns the URL for the component source \a src, as mapped
- by the nameSpacePaths(), resolved relative to \a baseUrl.
-
- \sa nameSpacePaths()
-*/
-QUrl QmlEngine::componentUrl(const QUrl& src, const QUrl& baseUrl) const
-{
- Q_D(const QmlEngine);
-
- // Find the most-specific namespace matching src.
- // For files, multiple paths can be given, the first found is used.
- QUrl r;
- QMap<QString, QString>::const_iterator i = d->nameSpacePaths.constBegin();
- QString rns=QLatin1String(":"); // ns of r, if file found, initial an imposible namespace
- QString srcstring = src.toString();
- while (i != d->nameSpacePaths.constEnd()) {
- QString ns = i.key();
- QString path = i.value();
- if (ns != rns) {
- if (srcstring.startsWith(ns) && (ns.length()==0 || srcstring[ns.length()]==QLatin1Char('/'))) {
- QString file = ns.length()==0 ? srcstring : srcstring.mid(ns.length()+1);
- QUrl cr = baseUrl.resolved(QUrl(path + QLatin1String("/") + file));
- QString lf = cr.toLocalFile();
- if (lf.isEmpty() || QFile::exists(lf)) {
- r = cr;
- rns = ns;
- }
- }
- }
- ++i;
- }
- if (r.isEmpty())
- r = baseUrl.resolved(src);
- return r;
-}
-
-/*!
- Returns the list of base urls the engine browses to find sub-components.
-
- The search path consists of the base of the \a url, and, in the case of local files,
- the directories imported using the "import" statement in \a qml.
- */
-QList<QUrl> QmlEngine::componentSearchPath(const QByteArray &qml, const QUrl &url) const
-{
- QList<QUrl> searchPath;
-
- searchPath << url.resolved(QUrl(QLatin1String(".")));
-
- if (QFileInfo(url.toLocalFile()).exists()) {
- QmlScriptParser parser;
- if (parser.parse(qml, url)) {
- for (int i = 0; i < parser.imports().size(); ++i) {
- QUrl importUrl = QUrl(parser.imports().at(i).uri);
- if (importUrl.isRelative()) {
- searchPath << url.resolved(importUrl);
- } else {
- searchPath << importUrl;
- }
- }
- }
- }
-
- return searchPath;
-}
-
-/*!
Sets the common QNetworkAccessManager, \a network, used by all QML elements instantiated
by this engine.
@@ -1700,4 +1574,80 @@ void QmlExpressionLog::setResult(const QVariant &r)
m_result = r;
}
+class QmlImportsPrivate {
+public:
+ void add(const QString& uri, const QString& prefix, int version_major, int version_minor)
+ {
+ TypeSet *s = set.value(prefix);
+ if (!s)
+ set.insert(prefix,(s=new TypeSet));
+ QString url = uri;
+ s->urls.append(url);
+ s->vmaj.append(version_major);
+ s->vmin.append(version_minor);
+ }
+
+ QUrl find(const QString& base, const QString& type)
+ {
+ TypeSet *s = 0;
+ int dot = type.indexOf(QLatin1Char('.'));
+ if (dot >= 0) {
+ while (!s) {
+ s = set.value(type.left(dot));
+ int ndot = type.indexOf(QLatin1Char('.'),dot+1);
+ if (ndot > 0)
+ dot = ndot;
+ else
+ break;
+ }
+ } else {
+ s = set.value("");
+ }
+ QString unqtype = type.mid(dot+1);
+ QUrl baseUrl(base);
+ if (s) {
+ for (int i=0; i<s->urls.count(); ++i) {
+ QUrl url = baseUrl.resolved(QUrl(s->urls.at(i) +"/"+ unqtype + QLatin1String(".qml")));
+ // XXX search non-files too! (eg. zip files, see QT-524)
+ QFileInfo f(url.toLocalFile());
+ if (f.exists())
+ return url;
+ }
+ }
+ return baseUrl.resolved(QUrl(type + QLatin1String(".qml")));
+ }
+
+private:
+ struct TypeSet {
+ QStringList urls;
+ QList<int> vmaj;
+ QList<int> vmin;
+ };
+ QHash<QString,TypeSet* > set;
+};
+
+QmlEngine::Imports::Imports() :
+ d(new QmlImportsPrivate)
+{
+}
+
+QmlEngine::Imports::~Imports()
+{
+}
+
+void QmlEngine::Imports::setBaseUrl(const QUrl& url)
+{
+ base = url;
+}
+
+void QmlEngine::addImport(Imports* imports, const QString& uri, const QString& prefix, int version_major, int version_minor) const
+{
+ imports->d->add(uri,prefix,version_major,version_minor);
+}
+
+QUrl QmlEngine::resolveType(const Imports& imports, const QString& type) const
+{
+ return imports.d->find(imports.base,type);
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlengine.h b/src/declarative/qml/qmlengine.h
index f114379..b74ad21 100644
--- a/src/declarative/qml/qmlengine.h
+++ b/src/declarative/qml/qmlengine.h
@@ -42,6 +42,7 @@
#ifndef QMLENGINE_H
#define QMLENGINE_H
+#include <QtCore/qurl.h>
#include <QtCore/qobject.h>
#include <QtCore/qmap.h>
#include <QtScript/qscriptvalue.h>
@@ -54,6 +55,7 @@ QT_MODULE(Declarative)
class QmlComponent;
class QmlEnginePrivate;
+class QmlImportsPrivate;
class QmlExpression;
class QmlContext;
class QUrl;
@@ -74,13 +76,18 @@ public:
void clearComponentCache();
- void setNameSpacePaths(const QMap<QString,QString>& map);
- void addNameSpacePaths(const QMap<QString,QString>& map);
- void addNameSpacePath(const QString&,const QString&);
- QMap<QString,QString> nameSpacePaths() const;
- QUrl componentUrl(const QUrl& src, const QUrl& baseUrl) const;
-
- QList<QUrl> componentSearchPath(const QByteArray &qml, const QUrl &url) const;
+ struct Imports {
+ Imports();
+ ~Imports();
+ void setBaseUrl(const QUrl& url);
+ QUrl baseUrl() const { return base; }
+ private:
+ friend class QmlEngine;
+ QUrl base;
+ QmlImportsPrivate *d;
+ };
+ void addImport(Imports*, const QString& uri, const QString& prefix, int version_major, int version_minor) const;
+ QUrl resolveType(const Imports&, const QString& type) const;
void setNetworkAccessManager(QNetworkAccessManager *);
QNetworkAccessManager *networkAccessManager() const;
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index 93ae704..ca65e3e 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -161,7 +161,6 @@ public:
mutable QNetworkAccessManager *networkAccessManager;
QmlCompositeTypeManager typeManager;
- QMap<QString,QString> nameSpacePaths;
mutable quint32 uniqueId;
quint32 getUniqueId() const {
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index 7475943..4358a3e 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -463,7 +463,6 @@ bool ProcessAST::visit(AST::UiProgram *node)
bool ProcessAST::visit(AST::UiImport *node)
{
QString fileName = node->fileName->asString();
- _parser->addNamespacePath(fileName);
AST::SourceLocation startLoc = node->importToken;
AST::SourceLocation endLoc = node->semicolonToken;
@@ -471,6 +470,10 @@ bool ProcessAST::visit(AST::UiImport *node)
QmlScriptParser::Import import;
import.location = location(startLoc, endLoc);
import.uri = fileName;
+ // XXX not used yet...
+ import.prefix = "";
+ import.version_major = 0;
+ import.version_minor = 0;
_parser->_imports << import;
@@ -836,11 +839,6 @@ bool QmlScriptParser::parse(const QByteArray &qmldata, const QUrl &url)
return _errors.isEmpty();
}
-QMap<QString,QString> QmlScriptParser::nameSpacePaths() const
-{
- return _nameSpacePaths;
-}
-
QStringList QmlScriptParser::types() const
{
return _typeNames;
@@ -867,7 +865,6 @@ void QmlScriptParser::clear()
root->release();
root = 0;
}
- _nameSpacePaths.clear();
_typeNames.clear();
_errors.clear();
@@ -896,9 +893,4 @@ void QmlScriptParser::setTree(Object *tree)
root = tree;
}
-void QmlScriptParser::addNamespacePath(const QString &path)
-{
- _nameSpacePaths.insertMulti(QString(), path);
-}
-
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlscriptparser_p.h b/src/declarative/qml/qmlscriptparser_p.h
index a4cbd82..05e70a5 100644
--- a/src/declarative/qml/qmlscriptparser_p.h
+++ b/src/declarative/qml/qmlscriptparser_p.h
@@ -72,9 +72,12 @@ public:
class Import
{
public:
- Import() {}
+ Import() : version_major(0), version_minor(0) {}
QString uri;
+ QString prefix;
+ int version_major;
+ int version_minor;
QmlParser::LocationSpan location;
};
@@ -83,7 +86,6 @@ public:
bool parse(const QByteArray &data, const QUrl &url = QUrl());
- QMap<QString,QString> nameSpacePaths() const;
QStringList types() const;
QmlParser::Object *tree() const;
@@ -100,12 +102,9 @@ public:
void setScriptFile(const QString &filename) {_scriptFile = filename; }
QString scriptFile() const { return _scriptFile; }
- void addNamespacePath(const QString &path);
-
// ### private:
QList<QmlError> _errors;
- QMap<QString,QString> _nameSpacePaths;
QmlParser::Object *root;
QList<Import> _imports;
QStringList _typeNames;