[new compiler] Implement proper type resolution
Collect all references to unknown types after parsing, re-use the existing code in QQmlTypeLoader to resolve them and finally use the resolved references map in the QQmlObjectCreator instead of the type name cache directly. Change-Id: I8b83af4f8852e79c33985457081c024358bb9622 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
8c2201e2e5
commit
4b5a7b15fc
|
@ -109,6 +109,7 @@ bool QQmlCodeGenerator::generateFromQml(const QString &code, const QUrl &url, co
|
||||||
qSwap(_imports, output->imports);
|
qSwap(_imports, output->imports);
|
||||||
qSwap(_objects, output->objects);
|
qSwap(_objects, output->objects);
|
||||||
qSwap(_functions, output->functions);
|
qSwap(_functions, output->functions);
|
||||||
|
qSwap(_typeReferences, output->typeReferences);
|
||||||
this->pool = output->jsParserEngine.pool();
|
this->pool = output->jsParserEngine.pool();
|
||||||
this->jsGenerator = &output->jsGenerator;
|
this->jsGenerator = &output->jsGenerator;
|
||||||
|
|
||||||
|
@ -128,9 +129,13 @@ bool QQmlCodeGenerator::generateFromQml(const QString &code, const QUrl &url, co
|
||||||
AST::UiObjectDefinition *rootObject = AST::cast<AST::UiObjectDefinition*>(program->members->member);
|
AST::UiObjectDefinition *rootObject = AST::cast<AST::UiObjectDefinition*>(program->members->member);
|
||||||
Q_ASSERT(rootObject);
|
Q_ASSERT(rootObject);
|
||||||
output->indexOfRootObject = defineQMLObject(rootObject);
|
output->indexOfRootObject = defineQMLObject(rootObject);
|
||||||
|
|
||||||
|
collectTypeReferences();
|
||||||
|
|
||||||
qSwap(_imports, output->imports);
|
qSwap(_imports, output->imports);
|
||||||
qSwap(_objects, output->objects);
|
qSwap(_objects, output->objects);
|
||||||
qSwap(_functions, output->functions);
|
qSwap(_functions, output->functions);
|
||||||
|
qSwap(_typeReferences, output->typeReferences);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,6 +445,8 @@ bool QQmlCodeGenerator::visit(AST::UiPublicMember *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
param->nameIndex = registerString(p->name.toString());
|
param->nameIndex = registerString(p->name.toString());
|
||||||
|
param->location.line = p->identifierToken.startLine;
|
||||||
|
param->location.column = p->identifierToken.startColumn;
|
||||||
signal->parameters->append(param);
|
signal->parameters->append(param);
|
||||||
p = p->next;
|
p = p->next;
|
||||||
}
|
}
|
||||||
|
@ -710,6 +717,22 @@ void QQmlCodeGenerator::recordError(const AST::SourceLocation &location, const Q
|
||||||
errors << error;
|
errors << error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QQmlCodeGenerator::collectTypeReferences()
|
||||||
|
{
|
||||||
|
foreach (QmlObject *obj, _objects) {
|
||||||
|
_typeReferences.add(obj->inheritedTypeNameIndex, obj->location);
|
||||||
|
|
||||||
|
for (QmlProperty *prop = obj->properties->first; prop; prop = prop->next) {
|
||||||
|
if (prop->type >= QV4::CompiledData::Property::Custom)
|
||||||
|
_typeReferences.add(prop->customTypeNameIndex, prop->location);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Signal *sig = obj->qmlSignals->first; sig; sig = sig->next)
|
||||||
|
for (SignalParameter *param = sig->parameters->first; param; param = param->next)
|
||||||
|
_typeReferences.add(param->customTypeNameIndex, param->location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QQmlScript::LocationSpan QQmlCodeGenerator::location(AST::SourceLocation start, AST::SourceLocation end)
|
QQmlScript::LocationSpan QQmlCodeGenerator::location(AST::SourceLocation start, AST::SourceLocation end)
|
||||||
{
|
{
|
||||||
QQmlScript::LocationSpan rv;
|
QQmlScript::LocationSpan rv;
|
||||||
|
|
|
@ -163,6 +163,8 @@ struct ParsedQML
|
||||||
QList<AST::Node*> functions; // FunctionDeclaration, Statement or Expression
|
QList<AST::Node*> functions; // FunctionDeclaration, Statement or Expression
|
||||||
QV4::Compiler::JSUnitGenerator jsGenerator;
|
QV4::Compiler::JSUnitGenerator jsGenerator;
|
||||||
|
|
||||||
|
QV4::CompiledData::TypeReferenceMap typeReferences;
|
||||||
|
|
||||||
QString stringAt(int index) const { return jsGenerator.strings.value(index); }
|
QString stringAt(int index) const { return jsGenerator.strings.value(index); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -220,6 +222,8 @@ public:
|
||||||
|
|
||||||
void recordError(const AST::SourceLocation &location, const QString &description);
|
void recordError(const AST::SourceLocation &location, const QString &description);
|
||||||
|
|
||||||
|
void collectTypeReferences();
|
||||||
|
|
||||||
static QQmlScript::LocationSpan location(AST::SourceLocation start, AST::SourceLocation end);
|
static QQmlScript::LocationSpan location(AST::SourceLocation start, AST::SourceLocation end);
|
||||||
|
|
||||||
int registerString(const QString &str) const { return jsGenerator->registerString(str); }
|
int registerString(const QString &str) const { return jsGenerator->registerString(str); }
|
||||||
|
@ -231,6 +235,8 @@ public:
|
||||||
QList<QmlObject*> _objects;
|
QList<QmlObject*> _objects;
|
||||||
QList<AST::Node*> _functions;
|
QList<AST::Node*> _functions;
|
||||||
|
|
||||||
|
QV4::CompiledData::TypeReferenceMap _typeReferences;
|
||||||
|
|
||||||
QmlObject *_object;
|
QmlObject *_object;
|
||||||
QSet<QString> _propertyNames;
|
QSet<QString> _propertyNames;
|
||||||
QSet<QString> _signalNames;
|
QSet<QString> _signalNames;
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include <QtCore/qstring.h>
|
#include <QtCore/qstring.h>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QHash>
|
||||||
#include <private/qv4value_def_p.h>
|
#include <private/qv4value_def_p.h>
|
||||||
#include <private/qv4executableallocator_p.h>
|
#include <private/qv4executableallocator_p.h>
|
||||||
|
|
||||||
|
@ -73,6 +74,16 @@ struct Location
|
||||||
int column;
|
int column;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// map from name index to location of first use
|
||||||
|
struct TypeReferenceMap : QHash<int, Location>
|
||||||
|
{
|
||||||
|
void add(int nameIndex, const Location &loc) {
|
||||||
|
if (contains(nameIndex))
|
||||||
|
return;
|
||||||
|
insert(nameIndex, loc);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct RegExp
|
struct RegExp
|
||||||
{
|
{
|
||||||
enum Flags {
|
enum Flags {
|
||||||
|
@ -263,6 +274,7 @@ struct Parameter
|
||||||
quint32 type;
|
quint32 type;
|
||||||
quint32 customTypeNameIndex;
|
quint32 customTypeNameIndex;
|
||||||
quint32 reserved;
|
quint32 reserved;
|
||||||
|
Location location;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Signal
|
struct Signal
|
||||||
|
|
|
@ -116,6 +116,14 @@ QQmlCompiledData::~QQmlCompiledData()
|
||||||
types.at(ii).typePropertyCache->release();
|
types.at(ii).typePropertyCache->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (QHash<int, TypeReference>::Iterator resolvedType = resolvedTypes.begin(), end = resolvedTypes.end();
|
||||||
|
resolvedType != end; ++resolvedType) {
|
||||||
|
if (resolvedType->component)
|
||||||
|
resolvedType->component->release();
|
||||||
|
if (resolvedType->typePropertyCache)
|
||||||
|
resolvedType->typePropertyCache->release();
|
||||||
|
}
|
||||||
|
|
||||||
for (int ii = 0; ii < propertyCaches.count(); ++ii)
|
for (int ii = 0; ii < propertyCaches.count(); ++ii)
|
||||||
propertyCaches.at(ii)->release();
|
propertyCaches.at(ii)->release();
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,12 @@ public:
|
||||||
QQmlPropertyCache *propertyCache() const;
|
QQmlPropertyCache *propertyCache() const;
|
||||||
QQmlPropertyCache *createPropertyCache(QQmlEngine *);
|
QQmlPropertyCache *createPropertyCache(QQmlEngine *);
|
||||||
};
|
};
|
||||||
|
// --- old compiler:
|
||||||
QList<TypeReference> types;
|
QList<TypeReference> types;
|
||||||
|
// --- new compiler:
|
||||||
|
// map from name index
|
||||||
|
QHash<int, TypeReference> resolvedTypes;
|
||||||
|
// ---
|
||||||
|
|
||||||
struct V8Program {
|
struct V8Program {
|
||||||
V8Program(const QByteArray &p, QQmlCompiledData *c)
|
V8Program(const QByteArray &p, QQmlCompiledData *c)
|
||||||
|
|
|
@ -900,7 +900,7 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
|
||||||
if (cc->compilationUnit && !cc->compilationUnit->engine)
|
if (cc->compilationUnit && !cc->compilationUnit->engine)
|
||||||
cc->compilationUnit->linkToEngine(v4);
|
cc->compilationUnit->linkToEngine(v4);
|
||||||
|
|
||||||
state.creator = new QmlObjectCreator(context, cc->qmlUnit, cc->compilationUnit, cc->importCache,
|
state.creator = new QmlObjectCreator(context, cc->qmlUnit, cc->compilationUnit, cc->resolvedTypes,
|
||||||
cc->propertyCaches, cc->datas);
|
cc->propertyCaches, cc->datas);
|
||||||
rv = state.creator->create();
|
rv = state.creator->create();
|
||||||
if (!rv)
|
if (!rv)
|
||||||
|
|
|
@ -60,21 +60,22 @@ QT_USE_NAMESPACE
|
||||||
|
|
||||||
static QAtomicInt classIndexCounter(0);
|
static QAtomicInt classIndexCounter(0);
|
||||||
|
|
||||||
QQmlPropertyCacheCreator::QQmlPropertyCacheCreator(QQmlEnginePrivate *enginePrivate, const QV4::CompiledData::QmlUnit *unit, const QUrl &url, QQmlTypeNameCache *typeNameCache, const QQmlImports *imports)
|
QQmlPropertyCacheCreator::QQmlPropertyCacheCreator(QQmlEnginePrivate *enginePrivate, const QV4::CompiledData::QmlUnit *unit, const QUrl &url, const QQmlImports *imports,
|
||||||
|
QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes)
|
||||||
: enginePrivate(enginePrivate)
|
: enginePrivate(enginePrivate)
|
||||||
, unit(unit)
|
, unit(unit)
|
||||||
, url(url)
|
, url(url)
|
||||||
, typeNameCache(typeNameCache)
|
|
||||||
, imports(imports)
|
, imports(imports)
|
||||||
|
, resolvedTypes(resolvedTypes)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQmlPropertyCache **resultCache, QByteArray *vmeMetaObjectData)
|
bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQmlPropertyCache **resultCache, QByteArray *vmeMetaObjectData)
|
||||||
{
|
{
|
||||||
QQmlTypeNameCache::Result res = typeNameCache->query(stringAt(obj->inheritedTypeNameIndex));
|
QQmlType *baseType = resolvedTypes->value(obj->inheritedTypeNameIndex).type;
|
||||||
Q_ASSERT(res.isValid()); // types resolved earlier in resolveTypes()
|
Q_ASSERT(baseType);
|
||||||
|
|
||||||
QQmlPropertyCache *baseTypeCache = enginePrivate->cache(res.type->metaObject());
|
QQmlPropertyCache *baseTypeCache = enginePrivate->cache(baseType->metaObject());
|
||||||
if (obj->nProperties == 0 && obj->nSignals == 0 && obj->nFunctions == 0) {
|
if (obj->nProperties == 0 && obj->nSignals == 0 && obj->nFunctions == 0) {
|
||||||
*resultCache = baseTypeCache;
|
*resultCache = baseTypeCache;
|
||||||
vmeMetaObjectData->clear();
|
vmeMetaObjectData->clear();
|
||||||
|
@ -441,14 +442,15 @@ static void removeBindingOnProperty(QObject *o, int index)
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlObjectCreator::QmlObjectCreator(QQmlContextData *contextData, const QV4::CompiledData::QmlUnit *qmlUnit,
|
QmlObjectCreator::QmlObjectCreator(QQmlContextData *contextData, const QV4::CompiledData::QmlUnit *qmlUnit,
|
||||||
const QV4::CompiledData::CompilationUnit *jsUnit, QQmlTypeNameCache *typeNameCache,
|
const QV4::CompiledData::CompilationUnit *jsUnit,
|
||||||
|
const QHash<int, QQmlCompiledData::TypeReference> &resolvedTypes,
|
||||||
const QList<QQmlPropertyCache*> &propertyCaches,
|
const QList<QQmlPropertyCache*> &propertyCaches,
|
||||||
const QList<QByteArray> &vmeMetaObjectData)
|
const QList<QByteArray> &vmeMetaObjectData)
|
||||||
: engine(contextData->engine)
|
: engine(contextData->engine)
|
||||||
, unit(qmlUnit)
|
, unit(qmlUnit)
|
||||||
, jsUnit(jsUnit)
|
, jsUnit(jsUnit)
|
||||||
, context(contextData)
|
, context(contextData)
|
||||||
, typeNameCache(typeNameCache)
|
, resolvedTypes(resolvedTypes)
|
||||||
, propertyCaches(propertyCaches)
|
, propertyCaches(propertyCaches)
|
||||||
, vmeMetaObjectData(vmeMetaObjectData)
|
, vmeMetaObjectData(vmeMetaObjectData)
|
||||||
, _qobject(0)
|
, _qobject(0)
|
||||||
|
@ -546,11 +548,10 @@ QObject *QmlObjectCreator::create(int index, QObject *parent)
|
||||||
{
|
{
|
||||||
const QV4::CompiledData::Object *obj = unit->objectAt(index);
|
const QV4::CompiledData::Object *obj = unit->objectAt(index);
|
||||||
|
|
||||||
QQmlTypeNameCache::Result res = typeNameCache->query(stringAt(obj->inheritedTypeNameIndex));
|
QQmlType *type = resolvedTypes.value(obj->inheritedTypeNameIndex).type;
|
||||||
if (!res.isValid())
|
Q_ASSERT(type);
|
||||||
return 0;
|
|
||||||
|
|
||||||
QObject *result = res.type->create();
|
QObject *result = type->create();
|
||||||
// ### use no-event variant
|
// ### use no-event variant
|
||||||
if (parent)
|
if (parent)
|
||||||
result->setParent(parent);
|
result->setParent(parent);
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include <private/qqmlimport_p.h>
|
#include <private/qqmlimport_p.h>
|
||||||
#include <private/qqmltypenamecache_p.h>
|
#include <private/qqmltypenamecache_p.h>
|
||||||
#include <private/qv4compileddata_p.h>
|
#include <private/qv4compileddata_p.h>
|
||||||
|
#include <private/qqmlcompiler_p.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
@ -54,7 +55,8 @@ class QQmlPropertyCacheCreator
|
||||||
Q_DECLARE_TR_FUNCTIONS(QQmlPropertyCacheCreator)
|
Q_DECLARE_TR_FUNCTIONS(QQmlPropertyCacheCreator)
|
||||||
public:
|
public:
|
||||||
QQmlPropertyCacheCreator(QQmlEnginePrivate *enginePrivate, const QV4::CompiledData::QmlUnit *unit,
|
QQmlPropertyCacheCreator(QQmlEnginePrivate *enginePrivate, const QV4::CompiledData::QmlUnit *unit,
|
||||||
const QUrl &url, QQmlTypeNameCache *typeNameCache, const QQmlImports *imports);
|
const QUrl &url, const QQmlImports *imports,
|
||||||
|
QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes);
|
||||||
|
|
||||||
QList<QQmlError> errors;
|
QList<QQmlError> errors;
|
||||||
|
|
||||||
|
@ -67,8 +69,8 @@ protected:
|
||||||
QQmlEnginePrivate *enginePrivate;
|
QQmlEnginePrivate *enginePrivate;
|
||||||
const QV4::CompiledData::QmlUnit *unit;
|
const QV4::CompiledData::QmlUnit *unit;
|
||||||
QUrl url;
|
QUrl url;
|
||||||
QQmlTypeNameCache *typeNameCache;
|
|
||||||
const QQmlImports *imports;
|
const QQmlImports *imports;
|
||||||
|
QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QmlObjectCreator
|
class QmlObjectCreator
|
||||||
|
@ -76,7 +78,7 @@ class QmlObjectCreator
|
||||||
Q_DECLARE_TR_FUNCTIONS(QmlObjectCreator)
|
Q_DECLARE_TR_FUNCTIONS(QmlObjectCreator)
|
||||||
public:
|
public:
|
||||||
QmlObjectCreator(QQmlContextData *contextData, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::CompilationUnit *jsUnit,
|
QmlObjectCreator(QQmlContextData *contextData, const QV4::CompiledData::QmlUnit *qmlUnit, const QV4::CompiledData::CompilationUnit *jsUnit,
|
||||||
QQmlTypeNameCache *typeNameCache, const QList<QQmlPropertyCache *> &propertyCaches, const QList<QByteArray> &vmeMetaObjectData);
|
const QHash<int, QQmlCompiledData::TypeReference> &resolvedTypes, const QList<QQmlPropertyCache *> &propertyCaches, const QList<QByteArray> &vmeMetaObjectData);
|
||||||
|
|
||||||
QObject *create(QObject *parent = 0)
|
QObject *create(QObject *parent = 0)
|
||||||
{ return create(unit->indexOfRootObject, parent); }
|
{ return create(unit->indexOfRootObject, parent); }
|
||||||
|
@ -102,7 +104,7 @@ private:
|
||||||
const QV4::CompiledData::QmlUnit *unit;
|
const QV4::CompiledData::QmlUnit *unit;
|
||||||
const QV4::CompiledData::CompilationUnit *jsUnit;
|
const QV4::CompiledData::CompilationUnit *jsUnit;
|
||||||
QQmlContextData *context;
|
QQmlContextData *context;
|
||||||
QQmlTypeNameCache *typeNameCache;
|
const QHash<int, QQmlCompiledData::TypeReference> resolvedTypes;
|
||||||
const QList<QQmlPropertyCache *> propertyCaches;
|
const QList<QQmlPropertyCache *> propertyCaches;
|
||||||
const QList<QByteArray> vmeMetaObjectData;
|
const QList<QByteArray> vmeMetaObjectData;
|
||||||
|
|
||||||
|
|
|
@ -2167,6 +2167,13 @@ void QQmlTypeData::compile()
|
||||||
m_imports.populateCache(m_compiledData->importCache);
|
m_imports.populateCache(m_compiledData->importCache);
|
||||||
m_compiledData->importCache->addref();
|
m_compiledData->importCache->addref();
|
||||||
|
|
||||||
|
for (QHash<int, TypeReference>::ConstIterator resolvedType = m_resolvedTypes.constBegin(), end = m_resolvedTypes.constEnd();
|
||||||
|
resolvedType != end; ++resolvedType) {
|
||||||
|
QQmlCompiledData::TypeReference ref;
|
||||||
|
ref.type = resolvedType->type;
|
||||||
|
m_compiledData->resolvedTypes.insert(resolvedType.key(), ref);
|
||||||
|
}
|
||||||
|
|
||||||
JSCodeGen jsCodeGen;
|
JSCodeGen jsCodeGen;
|
||||||
jsCodeGen.generateJSCodeForFunctionsAndBindings(finalUrlString(), parsedQML.data());
|
jsCodeGen.generateJSCodeForFunctionsAndBindings(finalUrlString(), parsedQML.data());
|
||||||
|
|
||||||
|
@ -2196,8 +2203,8 @@ void QQmlTypeData::compile()
|
||||||
m_compiledData->propertyCaches.reserve(qmlUnit->nObjects);
|
m_compiledData->propertyCaches.reserve(qmlUnit->nObjects);
|
||||||
|
|
||||||
QQmlPropertyCacheCreator propertyCacheBuilder(QQmlEnginePrivate::get(m_typeLoader->engine()),
|
QQmlPropertyCacheCreator propertyCacheBuilder(QQmlEnginePrivate::get(m_typeLoader->engine()),
|
||||||
qmlUnit, m_compiledData->url, m_compiledData->importCache,
|
qmlUnit, m_compiledData->url,
|
||||||
&m_imports);
|
&m_imports, &m_compiledData->resolvedTypes);
|
||||||
|
|
||||||
for (quint32 i = 0; i < qmlUnit->nObjects; ++i) {
|
for (quint32 i = 0; i < qmlUnit->nObjects; ++i) {
|
||||||
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(i);
|
const QV4::CompiledData::Object *obj = qmlUnit->objectAt(i);
|
||||||
|
@ -2255,10 +2262,10 @@ void QQmlTypeData::resolveTypes()
|
||||||
m_scripts << ref;
|
m_scripts << ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- old compiler:
|
||||||
foreach (QQmlScript::TypeReference *parserRef, scriptParser.referencedTypes()) {
|
foreach (QQmlScript::TypeReference *parserRef, scriptParser.referencedTypes()) {
|
||||||
TypeReference ref;
|
TypeReference ref;
|
||||||
|
|
||||||
QString url;
|
|
||||||
int majorVersion = -1;
|
int majorVersion = -1;
|
||||||
int minorVersion = -1;
|
int minorVersion = -1;
|
||||||
QQmlImportNamespace *typeNamespace = 0;
|
QQmlImportNamespace *typeNamespace = 0;
|
||||||
|
@ -2318,6 +2325,80 @@ void QQmlTypeData::resolveTypes()
|
||||||
|
|
||||||
m_types << ref;
|
m_types << ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- new compiler:
|
||||||
|
QV4::CompiledData::TypeReferenceMap typeReferences;
|
||||||
|
QStringList names;
|
||||||
|
if (parsedQML) {
|
||||||
|
typeReferences = parsedQML->typeReferences;
|
||||||
|
names = parsedQML->jsGenerator.strings;
|
||||||
|
} else {
|
||||||
|
// ### collect from available QV4::CompiledData::QmlUnit
|
||||||
|
}
|
||||||
|
for (QV4::CompiledData::TypeReferenceMap::ConstIterator unresolvedRef = typeReferences.constBegin(), end = typeReferences.constEnd();
|
||||||
|
unresolvedRef != end; ++unresolvedRef) {
|
||||||
|
|
||||||
|
TypeReference ref; // resolved reference
|
||||||
|
|
||||||
|
int majorVersion = -1;
|
||||||
|
int minorVersion = -1;
|
||||||
|
QQmlImportNamespace *typeNamespace = 0;
|
||||||
|
QList<QQmlError> errors;
|
||||||
|
|
||||||
|
const QString name = names.at(unresolvedRef.key());
|
||||||
|
bool typeFound = m_imports.resolveType(name, &ref.type,
|
||||||
|
&majorVersion, &minorVersion, &typeNamespace, &errors);
|
||||||
|
if (!typeNamespace && !typeFound && !m_implicitImportLoaded) {
|
||||||
|
// Lazy loading of implicit import
|
||||||
|
if (loadImplicitImport()) {
|
||||||
|
// Try again to find the type
|
||||||
|
errors.clear();
|
||||||
|
typeFound = m_imports.resolveType(name, &ref.type,
|
||||||
|
&majorVersion, &minorVersion, &typeNamespace, &errors);
|
||||||
|
} else {
|
||||||
|
return; //loadImplicitImport() hit an error, and called setError already
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!typeFound || typeNamespace) {
|
||||||
|
// Known to not be a type:
|
||||||
|
// - known to be a namespace (Namespace {})
|
||||||
|
// - type with unknown namespace (UnknownNamespace.SomeType {})
|
||||||
|
QQmlError error;
|
||||||
|
if (typeNamespace) {
|
||||||
|
error.setDescription(QQmlTypeLoader::tr("Namespace %1 cannot be used as a type").arg(name));
|
||||||
|
} else {
|
||||||
|
if (errors.size()) {
|
||||||
|
error = errors.takeFirst();
|
||||||
|
} else {
|
||||||
|
// this should not be possible!
|
||||||
|
// Description should come from error provided by addImport() function.
|
||||||
|
error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database"));
|
||||||
|
}
|
||||||
|
error.setUrl(m_imports.baseUrl());
|
||||||
|
error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(name).arg(error.description()));
|
||||||
|
}
|
||||||
|
|
||||||
|
error.setLine(unresolvedRef->line);
|
||||||
|
error.setColumn(unresolvedRef->column);
|
||||||
|
|
||||||
|
errors.prepend(error);
|
||||||
|
setError(errors);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ref.type->isComposite()) {
|
||||||
|
ref.typeData = typeLoader()->getType(ref.type->sourceUrl());
|
||||||
|
addDependency(ref.typeData);
|
||||||
|
}
|
||||||
|
ref.majorVersion = majorVersion;
|
||||||
|
ref.minorVersion = minorVersion;
|
||||||
|
|
||||||
|
ref.location.line = unresolvedRef->line;
|
||||||
|
ref.location.column = unresolvedRef->column;
|
||||||
|
|
||||||
|
m_resolvedTypes.insert(unresolvedRef.key(), ref);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QQmlTypeData::scriptImported(QQmlScriptBlob *blob, const QQmlScript::Location &location, const QString &qualifier, const QString &/*nameSpace*/)
|
void QQmlTypeData::scriptImported(QQmlScriptBlob *blob, const QQmlScript::Location &location, const QString &qualifier, const QString &/*nameSpace*/)
|
||||||
|
|
|
@ -457,7 +457,12 @@ private:
|
||||||
|
|
||||||
QSet<QString> m_namespaces;
|
QSet<QString> m_namespaces;
|
||||||
|
|
||||||
|
// --- old compiler
|
||||||
QList<TypeReference> m_types;
|
QList<TypeReference> m_types;
|
||||||
|
// --- new compiler
|
||||||
|
// map from name index to resolved type
|
||||||
|
QHash<int, TypeReference> m_resolvedTypes;
|
||||||
|
// ---
|
||||||
bool m_typesResolved:1;
|
bool m_typesResolved:1;
|
||||||
bool m_useNewCompiler:1;
|
bool m_useNewCompiler:1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue