Commit 13cbfecc authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

Small fixes to property lookups.

parent f3e8cc3d
......@@ -26,7 +26,10 @@ QmlLookupContext::~QmlLookupContext()
QmlSymbol *QmlLookupContext::resolve(const QString &name)
{
// ### TODO: look at property definitions
// look at property definitions
if (QmlSymbol *propertySymbol = resolveProperty(name, _scopes.top(), _doc->fileName()))
return propertySymbol;
if (name == "parent") {
for (int i = _scopes.size() - 2; i >= 0; --i) {
Node *scope = _scopes.at(i);
......@@ -56,9 +59,14 @@ QmlSymbol *QmlLookupContext::createSymbol(const QString &fileName, QmlJS::AST::U
return symbol;
}
QmlSymbol *QmlLookupContext::resolveType(const QString &name)
QmlSymbol *QmlLookupContext::resolveType(const QString &name, const QString &fileName)
{
UiProgram *prog = _doc->program();
// TODO: handle import-as.
DuiDocument::Ptr document = _snapshot[fileName];
if (document.isNull())
return 0;
UiProgram *prog = document->program();
if (!prog)
return 0;
......@@ -76,7 +84,7 @@ QmlSymbol *QmlLookupContext::resolveType(const QString &name)
const QString path = import->fileName->asString();
const QMap<QString, DuiDocument::Ptr> importedTypes = _snapshot.componentsDefinedByImportedDocuments(_doc, path);
const QMap<QString, DuiDocument::Ptr> importedTypes = _snapshot.componentsDefinedByImportedDocuments(document, path);
if (importedTypes.contains(name)) {
DuiDocument::Ptr importedDoc = importedTypes.value(name);
......@@ -88,3 +96,75 @@ QmlSymbol *QmlLookupContext::resolveType(const QString &name)
return 0;
}
QmlSymbol *QmlLookupContext::resolveProperty(const QString &name, Node *scope, const QString &fileName)
{
UiQualifiedId *typeName = 0;
if (UiObjectBinding *binding = cast<UiObjectBinding*>(scope)) {
if (QmlSymbol *symbol = resolveProperty(name, binding->initializer, fileName))
return symbol;
else
typeName = binding->qualifiedTypeNameId;
} else if (UiObjectDefinition *definition = cast<UiObjectDefinition*>(scope)) {
if (QmlSymbol *symbol = resolveProperty(name, definition->initializer, fileName))
return symbol;
else
typeName = definition->qualifiedTypeNameId;
} // TODO: extend this to handle (JavaScript) block scopes.
if (typeName == 0)
return 0;
QmlSymbol *typeSymbol = resolveType(toString(typeName), fileName);
if (typeSymbol && typeSymbol->isSymbolFromFile()) {
return resolveProperty(name, typeSymbol->asSymbolFromFile()->node(), typeSymbol->asSymbolFromFile()->fileName());
}
return 0;
}
QmlSymbol *QmlLookupContext::resolveProperty(const QString &name, QmlJS::AST::UiObjectInitializer *initializer, const QString &fileName)
{
if (!initializer)
return 0;
for (UiObjectMemberList *iter = initializer->members; iter; iter = iter->next) {
UiObjectMember *member = iter->member;
if (!member)
continue;
if (UiPublicMember *publicMember = cast<UiPublicMember*>(member)) {
if (name == publicMember->name->asString())
return createSymbol(fileName, publicMember);
} else if (UiObjectBinding *objectBinding = cast<UiObjectBinding*>(member)) {
if (name == toString(objectBinding->qualifiedId))
return createSymbol(fileName, objectBinding);
} else if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) {
if (name == toString(arrayBinding->qualifiedId))
return createSymbol(fileName, arrayBinding);
} else if (UiScriptBinding *scriptBinding = cast<UiScriptBinding*>(member)) {
if (name == toString(scriptBinding->qualifiedId))
return createSymbol(fileName, scriptBinding);
}
}
return 0;
}
QString QmlLookupContext::toString(UiQualifiedId *id)
{
QString str;
for (UiQualifiedId *iter = id; iter; iter = iter->next) {
if (!(iter->name))
continue;
str.append(iter->name->asString());
if (iter->next)
str.append('.');
}
return str;
}
......@@ -19,7 +19,10 @@ public:
~QmlLookupContext();
QmlSymbol *resolve(const QString &name);
QmlSymbol *resolveType(const QString &name);
QmlSymbol *resolveType(const QString &name)
{ return resolveType(name, _doc->fileName()); }
QmlSymbol *resolveType(QmlJS::AST::UiQualifiedId *name)
{ return resolveType(toString(name), _doc->fileName()); }
DuiDocument::Ptr document() const
{ return _doc; }
......@@ -27,6 +30,12 @@ public:
private:
QmlSymbol *createSymbol(const QString &fileName, QmlJS::AST::UiObjectMember *node);
QmlSymbol *resolveType(const QString &name, const QString &fileName);
QmlSymbol *resolveProperty(const QString &name, QmlJS::AST::Node *scope, const QString &fileName);
QmlSymbol *resolveProperty(const QString &name, QmlJS::AST::UiObjectInitializer *initializer, const QString &fileName);
static QString toString(QmlJS::AST::UiQualifiedId *id);
private:
QStack<QmlJS::AST::Node *> _scopes;
DuiDocument::Ptr _doc;
......
......@@ -108,26 +108,9 @@ bool QmlResolveExpression::visit(FieldMemberExpression *ast)
return false;
}
static inline QString toString(UiQualifiedId *id)
{
QString str;
for (UiQualifiedId *iter = id; iter; iter = iter->next) {
if (!(iter->name))
continue;
str.append(iter->name->asString());
if (iter->next)
str.append('.');
}
return str;
}
bool QmlResolveExpression::visit(QmlJS::AST::UiQualifiedId *ast)
{
_value = _context.resolveType(toString(ast));
_value = _context.resolveType(ast);
return false;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment