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 <cplusplus/CppDocument.h>
|
||||||
|
|
||||||
#include <TranslationUnit.h>
|
#include <TranslationUnit.h>
|
||||||
|
#include <ASTVisitor.h>
|
||||||
|
#include <AST.h>
|
||||||
#include <Token.h>
|
#include <Token.h>
|
||||||
|
|
||||||
#include <cpptools/cppmodelmanagerinterface.h>
|
#include <cpptools/cppmodelmanagerinterface.h>
|
||||||
@@ -43,11 +45,58 @@ using namespace CPlusPlus;
|
|||||||
|
|
||||||
namespace {
|
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
|
class HelloQuickFixOp: public QuickFixOperation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HelloQuickFixOp(Document::Ptr doc, const Snapshot &snapshot)
|
HelloQuickFixOp(Document::Ptr doc, const Snapshot &snapshot,
|
||||||
: QuickFixOperation(doc, snapshot)
|
const QTextCursor &textCursor)
|
||||||
|
: QuickFixOperation(doc, snapshot, textCursor)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual QString description() const
|
virtual QString description() const
|
||||||
@@ -55,22 +104,19 @@ public:
|
|||||||
return QLatin1String("Hello"); // ### tr?
|
return QLatin1String("Hello"); // ### tr?
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void apply(QTextCursor cursor)
|
virtual void apply(QTextCursor)
|
||||||
{
|
{
|
||||||
cursor.beginEditBlock();
|
// nothing to do.
|
||||||
cursor.insertBlock();
|
|
||||||
cursor.insertText(QLatin1String("Hello, QuickFix!\n"));
|
|
||||||
cursor.insertText(document()->fileName());
|
|
||||||
cursor.insertBlock();
|
|
||||||
cursor.endEditBlock();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of anonymous namespace
|
} // end of anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
QuickFixOperation::QuickFixOperation(CPlusPlus::Document::Ptr doc, const CPlusPlus::Snapshot &snapshot)
|
QuickFixOperation::QuickFixOperation(CPlusPlus::Document::Ptr doc,
|
||||||
: _doc(doc), _snapshot(snapshot)
|
const CPlusPlus::Snapshot &snapshot,
|
||||||
|
const QTextCursor &textCursor)
|
||||||
|
: _doc(doc), _snapshot(snapshot), _textCursor(textCursor)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
QuickFixOperation::~QuickFixOperation()
|
QuickFixOperation::~QuickFixOperation()
|
||||||
@@ -79,8 +125,21 @@ QuickFixOperation::~QuickFixOperation()
|
|||||||
QTextCursor QuickFixOperation::textCursor() const
|
QTextCursor QuickFixOperation::textCursor() const
|
||||||
{ return _textCursor; }
|
{ return _textCursor; }
|
||||||
|
|
||||||
void QuickFixOperation::setTextCursor(const QTextCursor &tc)
|
QTextCursor QuickFixOperation::cursor(AST *ast) const
|
||||||
{ _textCursor = tc; }
|
{
|
||||||
|
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
|
const CPlusPlus::Token &QuickFixOperation::tokenAt(unsigned index) const
|
||||||
{ return _doc->translationUnit()->tokenAt(index); }
|
{ return _doc->translationUnit()->tokenAt(index); }
|
||||||
@@ -134,14 +193,10 @@ bool CPPQuickFixCollector::supportsEditor(TextEditor::ITextEditable *editor)
|
|||||||
{ return qobject_cast<CPPEditorEditable *>(editor) != 0; }
|
{ return qobject_cast<CPPEditorEditable *>(editor) != 0; }
|
||||||
|
|
||||||
bool CPPQuickFixCollector::triggersCompletion(TextEditor::ITextEditable *)
|
bool CPPQuickFixCollector::triggersCompletion(TextEditor::ITextEditable *)
|
||||||
{
|
{ return false; }
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CPPQuickFixCollector::startCompletion(TextEditor::ITextEditable *editable)
|
int CPPQuickFixCollector::startCompletion(TextEditor::ITextEditable *editable)
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
Q_ASSERT(editable != 0);
|
Q_ASSERT(editable != 0);
|
||||||
|
|
||||||
_editor = qobject_cast<CPPEditor *>(editable->widget());
|
_editor = qobject_cast<CPPEditor *>(editable->widget());
|
||||||
@@ -149,10 +204,22 @@ int CPPQuickFixCollector::startCompletion(TextEditor::ITextEditable *editable)
|
|||||||
|
|
||||||
const SemanticInfo info = _editor->semanticInfo();
|
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) {
|
if (info.doc) {
|
||||||
QuickFixOperationPtr op(new HelloQuickFixOp(info.doc, info.snapshot));
|
ASTPath astPath(info.doc);
|
||||||
_quickFixes.append(op);
|
|
||||||
return editable->position();
|
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;
|
return -1;
|
||||||
@@ -160,8 +227,6 @@ int CPPQuickFixCollector::startCompletion(TextEditor::ITextEditable *editable)
|
|||||||
|
|
||||||
void CPPQuickFixCollector::completions(QList<TextEditor::CompletionItem> *quickFixItems)
|
void CPPQuickFixCollector::completions(QList<TextEditor::CompletionItem> *quickFixItems)
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
|
|
||||||
for (int i = 0; i < _quickFixes.size(); ++i) {
|
for (int i = 0; i < _quickFixes.size(); ++i) {
|
||||||
QuickFixOperationPtr op = _quickFixes.at(i);
|
QuickFixOperationPtr op = _quickFixes.at(i);
|
||||||
|
|
||||||
@@ -174,8 +239,6 @@ void CPPQuickFixCollector::completions(QList<TextEditor::CompletionItem> *quickF
|
|||||||
|
|
||||||
void CPPQuickFixCollector::complete(const TextEditor::CompletionItem &item)
|
void CPPQuickFixCollector::complete(const TextEditor::CompletionItem &item)
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
|
|
||||||
const int index = item.data.toInt();
|
const int index = item.data.toInt();
|
||||||
|
|
||||||
if (index < _quickFixes.size()) {
|
if (index < _quickFixes.size()) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <texteditor/icompletioncollector.h>
|
#include <texteditor/icompletioncollector.h>
|
||||||
|
|
||||||
#include <cplusplus/CppDocument.h>
|
#include <cplusplus/CppDocument.h>
|
||||||
|
#include <ASTfwd.h>
|
||||||
|
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
#include <QtGui/QTextCursor>
|
#include <QtGui/QTextCursor>
|
||||||
@@ -54,18 +55,18 @@ class QuickFixOperation
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
QuickFixOperation(CPlusPlus::Document::Ptr doc,
|
QuickFixOperation(CPlusPlus::Document::Ptr doc,
|
||||||
const CPlusPlus::Snapshot &snapshot);
|
const CPlusPlus::Snapshot &snapshot,
|
||||||
|
const QTextCursor &textCursor);
|
||||||
|
|
||||||
virtual ~QuickFixOperation();
|
virtual ~QuickFixOperation();
|
||||||
|
|
||||||
virtual QString description() const = 0;
|
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::Document::Ptr document() const { return _doc; }
|
||||||
CPlusPlus::Snapshot snapshot() const { return _snapshot; }
|
CPlusPlus::Snapshot snapshot() const { return _snapshot; }
|
||||||
|
|
||||||
QTextCursor textCursor() const;
|
QTextCursor textCursor() const;
|
||||||
void setTextCursor(const QTextCursor &tc);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const CPlusPlus::Token &tokenAt(unsigned index) const;
|
const CPlusPlus::Token &tokenAt(unsigned index) const;
|
||||||
@@ -75,6 +76,8 @@ protected:
|
|||||||
unsigned *column) const;
|
unsigned *column) const;
|
||||||
|
|
||||||
QTextCursor cursor(unsigned index) const;
|
QTextCursor cursor(unsigned index) const;
|
||||||
|
QTextCursor cursor(CPlusPlus::AST *ast) const;
|
||||||
|
|
||||||
QTextCursor moveAtStartOfToken(unsigned index) const;
|
QTextCursor moveAtStartOfToken(unsigned index) const;
|
||||||
QTextCursor moveAtEndOfToken(unsigned index) const;
|
QTextCursor moveAtEndOfToken(unsigned index) const;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user