forked from qt-creator/qt-creator
Added a bit more completion for the DUI editor.
This commit is contained in:
90
src/plugins/duieditor/duicompletionvisitor.cpp
Normal file
90
src/plugins/duieditor/duicompletionvisitor.cpp
Normal file
@@ -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
|
||||||
43
src/plugins/duieditor/duicompletionvisitor.h
Normal file
43
src/plugins/duieditor/duicompletionvisitor.h
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user