From 576a1ee31f87ea20e5b9b63ba88b8da901f2dd7c Mon Sep 17 00:00:00 2001 From: Roberto Raggi <roberto.raggi@nokia.com> Date: Mon, 16 Nov 2009 16:18:08 +0100 Subject: [PATCH] Build the list of the visible AST nodes (aka AST path). --- src/plugins/cppeditor/cppquickfix.cpp | 113 ++++++++++++++++++++------ src/plugins/cppeditor/cppquickfix.h | 9 +- 2 files changed, 94 insertions(+), 28 deletions(-) diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp index 601b717c65f..db3a8142543 100644 --- a/src/plugins/cppeditor/cppquickfix.cpp +++ b/src/plugins/cppeditor/cppquickfix.cpp @@ -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()) { diff --git a/src/plugins/cppeditor/cppquickfix.h b/src/plugins/cppeditor/cppquickfix.h index 0f4320cc5ab..5059a753ccf 100644 --- a/src/plugins/cppeditor/cppquickfix.h +++ b/src/plugins/cppeditor/cppquickfix.h @@ -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; -- GitLab