From 13cbfecced7c6b72e6f4b1f442ed74247386fc3f Mon Sep 17 00:00:00 2001 From: Erik Verbruggen <erik.verbruggen@nokia.com> Date: Wed, 23 Sep 2009 16:40:41 +0200 Subject: [PATCH] Small fixes to property lookups. --- src/plugins/duieditor/qmllookupcontext.cpp | 88 ++++++++++++++++++- src/plugins/duieditor/qmllookupcontext.h | 11 ++- .../duieditor/qmlresolveexpression.cpp | 19 +--- 3 files changed, 95 insertions(+), 23 deletions(-) diff --git a/src/plugins/duieditor/qmllookupcontext.cpp b/src/plugins/duieditor/qmllookupcontext.cpp index 8694959c1c8..1847f355361 100644 --- a/src/plugins/duieditor/qmllookupcontext.cpp +++ b/src/plugins/duieditor/qmllookupcontext.cpp @@ -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; +} diff --git a/src/plugins/duieditor/qmllookupcontext.h b/src/plugins/duieditor/qmllookupcontext.h index 3c98e056344..4813f37e30c 100644 --- a/src/plugins/duieditor/qmllookupcontext.h +++ b/src/plugins/duieditor/qmllookupcontext.h @@ -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; diff --git a/src/plugins/duieditor/qmlresolveexpression.cpp b/src/plugins/duieditor/qmlresolveexpression.cpp index 390ca5586b5..02fc21daa7f 100644 --- a/src/plugins/duieditor/qmlresolveexpression.cpp +++ b/src/plugins/duieditor/qmlresolveexpression.cpp @@ -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; } -- GitLab