From f14e98342c789e8180e69c09099c3d0a8081a5ce Mon Sep 17 00:00:00 2001 From: Erik Verbruggen <erik.verbruggen@nokia.com> Date: Mon, 6 Jul 2009 16:58:03 +0200 Subject: [PATCH] Added a bit more completion for the DUI editor. --- .../duieditor/duicompletionvisitor.cpp | 90 +++++++++++++++++++ src/plugins/duieditor/duicompletionvisitor.h | 43 +++++++++ 2 files changed, 133 insertions(+) create mode 100644 src/plugins/duieditor/duicompletionvisitor.cpp create mode 100644 src/plugins/duieditor/duicompletionvisitor.h diff --git a/src/plugins/duieditor/duicompletionvisitor.cpp b/src/plugins/duieditor/duicompletionvisitor.cpp new file mode 100644 index 00000000000..2dd407b1f41 --- /dev/null +++ b/src/plugins/duieditor/duicompletionvisitor.cpp @@ -0,0 +1,90 @@ +#include <QtCore/QDebug> + +#include "duicompletionvisitor.h" +#include "qmljsast_p.h" + +using namespace QmlJS; +using namespace QmlJS::AST; + +namespace DuiEditor { +namespace Internal { + +DuiCompletionVisitor::DuiCompletionVisitor() +{ +} + +QSet<QString> DuiCompletionVisitor::operator()(QmlJS::AST::UiProgram *ast, int pos) +{ + m_completions.clear(); + m_pos = (quint32) pos; + + Node::acceptChild(ast, this); + + return m_completions; +} + +bool DuiCompletionVisitor::preVisit(QmlJS::AST::Node *node) +{ + if (!m_parentStack.isEmpty()) + m_nodeParents[node] = m_parentStack.top(); + m_parentStack.push(node); + return true; +} + +static QString toString(Statement *stmt) +{ + if (ExpressionStatement *exprStmt = AST::cast<ExpressionStatement*>(stmt)) { + if (IdentifierExpression *idExpr = AST::cast<IdentifierExpression *>(exprStmt->expression)) { + return idExpr->name->asString(); + } + } + + return QString(); +} + +bool DuiCompletionVisitor::visit(UiScriptBinding *ast) +{ + if (!ast) + return false; + + UiObjectDefinition *parentObject = findParentObject(ast); + + if (ast->qualifiedId && ast->qualifiedId->name->asString() == QLatin1String("id")) { + const QString nodeId = toString(ast->statement); + if (!nodeId.isEmpty()) + m_objectToId[parentObject] = nodeId; + } else if (m_objectToId.contains(parentObject)) { + if (ast->qualifiedId && ast->qualifiedId->name) { + const QString parentId = m_objectToId[parentObject]; + m_completions.insert(parentId + "." + ast->qualifiedId->name->asString()); + } + } + + if (ast->firstSourceLocation().begin() >= m_pos && m_pos <= ast->lastSourceLocation().end()) { + UiObjectDefinition *parentsParent = findParentObject(parentObject); + + if (parentsParent) { + m_completions.insert(QLatin1String("parent")); + } + } + + return true; +} + +UiObjectDefinition *DuiCompletionVisitor::findParentObject(Node *node) const +{ + if (!node) + return 0; + + Node *candidate = m_nodeParents[node]; + if (candidate == 0) + return 0; + + if (UiObjectDefinition *parentObject = AST::cast<UiObjectDefinition *>(candidate)) + return parentObject; + else + return findParentObject(candidate); +} + +} // namespace Internal +} // namespace DuiEditor diff --git a/src/plugins/duieditor/duicompletionvisitor.h b/src/plugins/duieditor/duicompletionvisitor.h new file mode 100644 index 00000000000..473ed160257 --- /dev/null +++ b/src/plugins/duieditor/duicompletionvisitor.h @@ -0,0 +1,43 @@ +#ifndef COMPLETIONVISITOR_H +#define COMPLETIONVISITOR_H + +#include <QtCore/QMap> +#include <QtCore/QSet> +#include <QtCore/QStack> +#include <QtCore/QString> + +#include "qmljsastfwd_p.h" +#include "qmljsastvisitor_p.h" +#include "qmljsengine_p.h" + +namespace DuiEditor { +namespace Internal { + +class DuiCompletionVisitor: protected QmlJS::AST::Visitor +{ +public: + DuiCompletionVisitor(); + + QSet<QString> operator()(QmlJS::AST::UiProgram *ast, int pos); + +protected: + virtual bool preVisit(QmlJS::AST::Node *node); + virtual void postVisit(QmlJS::AST::Node *) { m_parentStack.pop(); } + + virtual bool visit(QmlJS::AST::UiScriptBinding *ast); + +private: + QmlJS::AST::UiObjectDefinition *findParentObject(QmlJS::AST::Node *node) const; + +private: + QSet<QString> m_completions; + quint32 m_pos; + QStack<QmlJS::AST::Node *> m_parentStack; + QMap<QmlJS::AST::Node *, QmlJS::AST::Node *> m_nodeParents; + QMap<QmlJS::AST::Node *, QString> m_objectToId; +}; + +} // namespace Internal +} // namespace DuiEditor + +#endif // COMPLETIONVISITOR_H -- GitLab