forked from qt-creator/qt-creator
Build the list of the visible AST nodes (aka AST path).
This commit is contained in:
@@ -33,6 +33,8 @@
|
||||
#include <cplusplus/CppDocument.h>
|
||||
|
||||
#include <TranslationUnit.h>
|
||||
#include <ASTVisitor.h>
|
||||
#include <AST.h>
|
||||
#include <Token.h>
|
||||
|
||||
#include <cpptools/cppmodelmanagerinterface.h>
|
||||
@@ -43,11 +45,58 @@ using namespace CPlusPlus;
|
||||
|
||||
namespace {
|
||||
|
||||
class ASTPath: public ASTVisitor
|
||||
{
|
||||
Document::Ptr _doc;
|
||||
unsigned _line;
|
||||
unsigned _column;
|
||||
QList<AST *> _nodes;
|
||||
|
||||
public:
|
||||
ASTPath(Document::Ptr doc)
|
||||
: ASTVisitor(doc->control()), _doc(doc), _line(0), _column(0) {}
|
||||
|
||||
QList<AST *> operator()(const QTextCursor &cursor)
|
||||
{
|
||||
_nodes.clear();
|
||||
_line = cursor.blockNumber() + 1;
|
||||
_column = cursor.columnNumber() + 1;
|
||||
accept(_doc->translationUnit()->ast());
|
||||
return _nodes;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool preVisit(AST *ast)
|
||||
{
|
||||
unsigned firstToken = ast->firstToken();
|
||||
unsigned lastToken = ast->lastToken();
|
||||
|
||||
if (firstToken > 0 && lastToken > firstToken) {
|
||||
unsigned startLine, startColumn;
|
||||
getTokenStartPosition(firstToken, &startLine, &startColumn);
|
||||
|
||||
if (_line > startLine || (_line == startLine && _column >= startColumn)) {
|
||||
|
||||
unsigned endLine, endColumn;
|
||||
getTokenEndPosition(lastToken - 1, &endLine, &endColumn);
|
||||
|
||||
if (_line < endLine || (_line == endLine && _column < endColumn)) {
|
||||
_nodes.append(ast);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class HelloQuickFixOp: public QuickFixOperation
|
||||
{
|
||||
public:
|
||||
HelloQuickFixOp(Document::Ptr doc, const Snapshot &snapshot)
|
||||
: QuickFixOperation(doc, snapshot)
|
||||
HelloQuickFixOp(Document::Ptr doc, const Snapshot &snapshot,
|
||||
const QTextCursor &textCursor)
|
||||
: QuickFixOperation(doc, snapshot, textCursor)
|
||||
{}
|
||||
|
||||
virtual QString description() const
|
||||
@@ -55,22 +104,19 @@ public:
|
||||
return QLatin1String("Hello"); // ### tr?
|
||||
}
|
||||
|
||||
virtual void apply(QTextCursor cursor)
|
||||
virtual void apply(QTextCursor)
|
||||
{
|
||||
cursor.beginEditBlock();
|
||||
cursor.insertBlock();
|
||||
cursor.insertText(QLatin1String("Hello, QuickFix!\n"));
|
||||
cursor.insertText(document()->fileName());
|
||||
cursor.insertBlock();
|
||||
cursor.endEditBlock();
|
||||
// nothing to do.
|
||||
}
|
||||
};
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
|
||||
QuickFixOperation::QuickFixOperation(CPlusPlus::Document::Ptr doc, const CPlusPlus::Snapshot &snapshot)
|
||||
: _doc(doc), _snapshot(snapshot)
|
||||
QuickFixOperation::QuickFixOperation(CPlusPlus::Document::Ptr doc,
|
||||
const CPlusPlus::Snapshot &snapshot,
|
||||
const QTextCursor &textCursor)
|
||||
: _doc(doc), _snapshot(snapshot), _textCursor(textCursor)
|
||||
{ }
|
||||
|
||||
QuickFixOperation::~QuickFixOperation()
|
||||
@@ -79,8 +125,21 @@ QuickFixOperation::~QuickFixOperation()
|
||||
QTextCursor QuickFixOperation::textCursor() const
|
||||
{ return _textCursor; }
|
||||
|
||||
void QuickFixOperation::setTextCursor(const QTextCursor &tc)
|
||||
{ _textCursor = tc; }
|
||||
QTextCursor QuickFixOperation::cursor(AST *ast) const
|
||||
{
|
||||
TranslationUnit *unit = document()->translationUnit();
|
||||
unsigned startLine, startColumn, endLine, endColumn;
|
||||
unit->getTokenStartPosition(ast->firstToken(), &startLine, &startColumn);
|
||||
unit->getTokenEndPosition(ast->lastToken() - 1, &endLine, &endColumn);
|
||||
|
||||
QTextDocument *textDocument = _textCursor.document();
|
||||
QTextCursor tc(textDocument);
|
||||
tc.setPosition(textDocument->findBlockByNumber(startLine - 1).position() + startColumn - 1);
|
||||
tc.setPosition(textDocument->findBlockByNumber(endLine - 1).position() + endColumn - 1,
|
||||
QTextCursor::KeepAnchor);
|
||||
|
||||
return tc;
|
||||
}
|
||||
|
||||
const CPlusPlus::Token &QuickFixOperation::tokenAt(unsigned index) const
|
||||
{ return _doc->translationUnit()->tokenAt(index); }
|
||||
@@ -134,14 +193,10 @@ bool CPPQuickFixCollector::supportsEditor(TextEditor::ITextEditable *editor)
|
||||
{ return qobject_cast<CPPEditorEditable *>(editor) != 0; }
|
||||
|
||||
bool CPPQuickFixCollector::triggersCompletion(TextEditor::ITextEditable *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
return false;
|
||||
}
|
||||
{ return false; }
|
||||
|
||||
int CPPQuickFixCollector::startCompletion(TextEditor::ITextEditable *editable)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
Q_ASSERT(editable != 0);
|
||||
|
||||
_editor = qobject_cast<CPPEditor *>(editable->widget());
|
||||
@@ -149,10 +204,22 @@ int CPPQuickFixCollector::startCompletion(TextEditor::ITextEditable *editable)
|
||||
|
||||
const SemanticInfo info = _editor->semanticInfo();
|
||||
|
||||
QTextCursor textCursor = _editor->textCursor();
|
||||
|
||||
if (info.revision != _editor->document()->revision()) {
|
||||
// outdated
|
||||
qWarning() << "TODO: outdated semantic info, force a reparse.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (info.doc) {
|
||||
QuickFixOperationPtr op(new HelloQuickFixOp(info.doc, info.snapshot));
|
||||
_quickFixes.append(op);
|
||||
return editable->position();
|
||||
ASTPath astPath(info.doc);
|
||||
|
||||
const QList<AST *> path = astPath(_editor->textCursor());
|
||||
// ### build the list of the quick fix ops by scanning path.
|
||||
|
||||
if (! _quickFixes.isEmpty())
|
||||
return editable->position();
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -160,8 +227,6 @@ int CPPQuickFixCollector::startCompletion(TextEditor::ITextEditable *editable)
|
||||
|
||||
void CPPQuickFixCollector::completions(QList<TextEditor::CompletionItem> *quickFixItems)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
for (int i = 0; i < _quickFixes.size(); ++i) {
|
||||
QuickFixOperationPtr op = _quickFixes.at(i);
|
||||
|
||||
@@ -174,8 +239,6 @@ void CPPQuickFixCollector::completions(QList<TextEditor::CompletionItem> *quickF
|
||||
|
||||
void CPPQuickFixCollector::complete(const TextEditor::CompletionItem &item)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
const int index = item.data.toInt();
|
||||
|
||||
if (index < _quickFixes.size()) {
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <texteditor/icompletioncollector.h>
|
||||
|
||||
#include <cplusplus/CppDocument.h>
|
||||
#include <ASTfwd.h>
|
||||
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtGui/QTextCursor>
|
||||
@@ -54,18 +55,18 @@ class QuickFixOperation
|
||||
|
||||
public:
|
||||
QuickFixOperation(CPlusPlus::Document::Ptr doc,
|
||||
const CPlusPlus::Snapshot &snapshot);
|
||||
const CPlusPlus::Snapshot &snapshot,
|
||||
const QTextCursor &textCursor);
|
||||
|
||||
virtual ~QuickFixOperation();
|
||||
|
||||
virtual QString description() const = 0;
|
||||
virtual void apply(QTextCursor cursor) = 0;
|
||||
virtual void apply(QTextCursor tc) = 0;
|
||||
|
||||
CPlusPlus::Document::Ptr document() const { return _doc; }
|
||||
CPlusPlus::Snapshot snapshot() const { return _snapshot; }
|
||||
|
||||
QTextCursor textCursor() const;
|
||||
void setTextCursor(const QTextCursor &tc);
|
||||
|
||||
protected:
|
||||
const CPlusPlus::Token &tokenAt(unsigned index) const;
|
||||
@@ -75,6 +76,8 @@ protected:
|
||||
unsigned *column) const;
|
||||
|
||||
QTextCursor cursor(unsigned index) const;
|
||||
QTextCursor cursor(CPlusPlus::AST *ast) const;
|
||||
|
||||
QTextCursor moveAtStartOfToken(unsigned index) const;
|
||||
QTextCursor moveAtEndOfToken(unsigned index) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user