Commit bcf50a0a authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Generalized the quickfix collector.

parent 3d81ae85
......@@ -1026,122 +1026,66 @@ QString CppQuickFixOperation::textOf(const AST *ast) const
}
CppQuickFixCollector::CppQuickFixCollector()
: _modelManager(CppTools::CppModelManagerInterface::instance()), _editable(0), _editor(0)
{ }
{
}
CppQuickFixCollector::~CppQuickFixCollector()
{ }
TextEditor::ITextEditable *CppQuickFixCollector::editor() const
{ return _editable; }
int CppQuickFixCollector::startPosition() const
{ return _editable->position(); }
bool CppQuickFixCollector::supportsEditor(TextEditor::ITextEditable *editor)
{ return qobject_cast<CPPEditorEditable *>(editor) != 0; }
bool CppQuickFixCollector::triggersCompletion(TextEditor::ITextEditable *)
{ return false; }
int CppQuickFixCollector::startCompletion(TextEditor::ITextEditable *editable)
{
Q_ASSERT(editable != 0);
_editable = editable;
_editor = qobject_cast<CPPEditor *>(editable->widget());
Q_ASSERT(_editor != 0);
const SemanticInfo info = _editor->semanticInfo();
if (info.revision != _editor->editorRevision()) {
// outdated
qWarning() << "TODO: outdated semantic info, force a reparse.";
return -1;
}
if (info.doc) {
ASTPath astPath(info.doc);
}
const QList<AST *> path = astPath(_editor->textCursor());
if (path.isEmpty())
return -1;
TextEditor::QuickFixState *CppQuickFixCollector::initializeCompletion(TextEditor::ITextEditable *editable)
{
if (CPPEditor *editor = qobject_cast<CPPEditor *>(editable->widget())) {
const SemanticInfo info = editor->semanticInfo();
QSharedPointer<RewriteLogicalAndOp> rewriteLogicalAndOp(new RewriteLogicalAndOp(_editor));
QSharedPointer<SplitIfStatementOp> splitIfStatementOp(new SplitIfStatementOp(_editor));
QSharedPointer<MoveDeclarationOutOfIfOp> moveDeclarationOutOfIfOp(new MoveDeclarationOutOfIfOp(_editor));
QSharedPointer<MoveDeclarationOutOfWhileOp> moveDeclarationOutOfWhileOp(new MoveDeclarationOutOfWhileOp(_editor));
QSharedPointer<SplitSimpleDeclarationOp> splitSimpleDeclarationOp(new SplitSimpleDeclarationOp(_editor));
QSharedPointer<AddBracesToIfOp> addBracesToIfOp(new AddBracesToIfOp(_editor));
QSharedPointer<UseInverseOp> useInverseOp(new UseInverseOp(_editor));
QSharedPointer<FlipBinaryOp> flipBinaryOp(new FlipBinaryOp(_editor));
QSharedPointer<WrapStringLiteral> wrapStringLiteral(new WrapStringLiteral(_editor));
QSharedPointer<CStringToNSString> wrapCString(new CStringToNSString(_editor));
QList<TextEditor::QuickFixOperation::Ptr> candidates;
candidates.append(rewriteLogicalAndOp);
candidates.append(splitIfStatementOp);
candidates.append(moveDeclarationOutOfIfOp);
candidates.append(moveDeclarationOutOfWhileOp);
candidates.append(splitSimpleDeclarationOp);
candidates.append(addBracesToIfOp);
candidates.append(useInverseOp);
candidates.append(flipBinaryOp);
candidates.append(wrapStringLiteral);
if (_editor->mimeType() == CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)
candidates.append(wrapCString);
QMap<int, QList<TextEditor::QuickFixOperation::Ptr> > matchedOps;
CppQuickFixState state;
state.path = path;
state.info = info;
foreach (TextEditor::QuickFixOperation::Ptr op, candidates) {
op->setTextCursor(_editor->textCursor());
int priority = op->match(&state);
if (priority != -1)
matchedOps[priority].append(op);
if (info.revision != editor->editorRevision()) {
// outdated
qWarning() << "TODO: outdated semantic info, force a reparse.";
return 0;
}
QMapIterator<int, QList<TextEditor::QuickFixOperation::Ptr> > it(matchedOps);
it.toBack();
if (it.hasPrevious()) {
it.previous();
if (info.doc) {
ASTPath astPath(info.doc);
_quickFixes = it.value();
const QList<AST *> path = astPath(editor->textCursor());
if (! path.isEmpty()) {
CppQuickFixState *state = new CppQuickFixState;
state->path = path;
state->info = info;
return state;
}
}
if (! _quickFixes.isEmpty())
return editable->position();
}
return -1;
}
void CppQuickFixCollector::completions(QList<TextEditor::CompletionItem> *quickFixItems)
{
for (int i = 0; i < _quickFixes.size(); ++i) {
TextEditor::QuickFixOperation::Ptr op = _quickFixes.at(i);
TextEditor::CompletionItem item(this);
item.text = op->description();
item.data = QVariant::fromValue(i);
quickFixItems->append(item);
}
}
void CppQuickFixCollector::complete(const TextEditor::CompletionItem &item)
{
const int index = item.data.toInt();
if (index < _quickFixes.size()) {
TextEditor::QuickFixOperation::Ptr quickFix = _quickFixes.at(index);
quickFix->perform();
}
return 0;
}
void CppQuickFixCollector::cleanup()
QList<TextEditor::QuickFixOperation::Ptr> CppQuickFixCollector::quickFixOperations(TextEditor::BaseTextEditor *editor) const
{
_quickFixes.clear();
QSharedPointer<RewriteLogicalAndOp> rewriteLogicalAndOp(new RewriteLogicalAndOp(editor));
QSharedPointer<SplitIfStatementOp> splitIfStatementOp(new SplitIfStatementOp(editor));
QSharedPointer<MoveDeclarationOutOfIfOp> moveDeclarationOutOfIfOp(new MoveDeclarationOutOfIfOp(editor));
QSharedPointer<MoveDeclarationOutOfWhileOp> moveDeclarationOutOfWhileOp(new MoveDeclarationOutOfWhileOp(editor));
QSharedPointer<SplitSimpleDeclarationOp> splitSimpleDeclarationOp(new SplitSimpleDeclarationOp(editor));
QSharedPointer<AddBracesToIfOp> addBracesToIfOp(new AddBracesToIfOp(editor));
QSharedPointer<UseInverseOp> useInverseOp(new UseInverseOp(editor));
QSharedPointer<FlipBinaryOp> flipBinaryOp(new FlipBinaryOp(editor));
QSharedPointer<WrapStringLiteral> wrapStringLiteral(new WrapStringLiteral(editor));
QSharedPointer<CStringToNSString> wrapCString(new CStringToNSString(editor));
QList<TextEditor::QuickFixOperation::Ptr> quickFixOperations;
quickFixOperations.append(rewriteLogicalAndOp);
quickFixOperations.append(splitIfStatementOp);
quickFixOperations.append(moveDeclarationOutOfIfOp);
quickFixOperations.append(moveDeclarationOutOfWhileOp);
quickFixOperations.append(splitSimpleDeclarationOp);
quickFixOperations.append(addBracesToIfOp);
quickFixOperations.append(useInverseOp);
quickFixOperations.append(flipBinaryOp);
quickFixOperations.append(wrapStringLiteral);
if (editor->mimeType() == CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)
quickFixOperations.append(wrapCString);
return quickFixOperations;
}
......@@ -48,10 +48,6 @@ namespace CppTools {
namespace CppEditor {
namespace Internal {
class CPPEditor;
class CppQuickFixOperation;
typedef QSharedPointer<CppQuickFixOperation> CppQuickFixOperationPtr;
class CppQuickFixOperation: public TextEditor::QuickFixOperation
{
Q_DISABLE_COPY(CppQuickFixOperation)
......@@ -112,7 +108,7 @@ private:
CPlusPlus::AST *_topLevelNode;
};
class CppQuickFixCollector: public TextEditor::IQuickFixCollector
class CppQuickFixCollector: public TextEditor::QuickFixCollector
{
Q_OBJECT
......@@ -120,22 +116,8 @@ public:
CppQuickFixCollector();
virtual ~CppQuickFixCollector();
QList<TextEditor::QuickFixOperation::Ptr> quickFixes() const { return _quickFixes; }
virtual TextEditor::ITextEditable *editor() const;
virtual int startPosition() const;
virtual bool supportsEditor(TextEditor::ITextEditable *editor);
virtual bool triggersCompletion(TextEditor::ITextEditable *editor);
virtual int startCompletion(TextEditor::ITextEditable *editor);
virtual void completions(QList<TextEditor::CompletionItem> *completions);
virtual void complete(const TextEditor::CompletionItem &item);
virtual void cleanup();
private:
CppTools::CppModelManagerInterface *_modelManager;
TextEditor::ITextEditable *_editable;
CPPEditor *_editor;
QList<TextEditor::QuickFixOperation::Ptr> _quickFixes;
virtual TextEditor::QuickFixState *initializeCompletion(TextEditor::ITextEditable *editable);
virtual QList<TextEditor::QuickFixOperation::Ptr> quickFixOperations(TextEditor::BaseTextEditor *editor) const;
};
} // end of namespace Internal
......
......@@ -36,6 +36,7 @@
#include <QtCore/QDebug>
using TextEditor::QuickFixOperation;
using TextEditor::QuickFixCollector;
QuickFixOperation::QuickFixOperation(TextEditor::BaseTextEditor *editor)
: _editor(editor)
......@@ -166,3 +167,85 @@ void QuickFixOperation::perform()
createChangeSet();
apply();
}
QuickFixCollector::QuickFixCollector()
: _editable(0)
{ }
QuickFixCollector::~QuickFixCollector()
{ }
TextEditor::ITextEditable *QuickFixCollector::editor() const
{ return _editable; }
int QuickFixCollector::startPosition() const
{ return _editable->position(); }
bool QuickFixCollector::supportsEditor(TextEditor::ITextEditable *)
{ return true; }
bool QuickFixCollector::triggersCompletion(TextEditor::ITextEditable *)
{ return false; }
int QuickFixCollector::startCompletion(TextEditor::ITextEditable *editable)
{
Q_ASSERT(editable != 0);
_editable = editable;
if (TextEditor::QuickFixState *state = initializeCompletion(editable)) {
TextEditor::BaseTextEditor *editor = qobject_cast<TextEditor::BaseTextEditor *>(editable->widget());
Q_ASSERT(editor != 0);
const QList<TextEditor::QuickFixOperation::Ptr> quickFixOperations = this->quickFixOperations(editor);
QMap<int, QList<TextEditor::QuickFixOperation::Ptr> > matchedOps;
foreach (TextEditor::QuickFixOperation::Ptr op, quickFixOperations) {
op->setTextCursor(editor->textCursor());
int priority = op->match(state);
if (priority != -1)
matchedOps[priority].append(op);
}
QMapIterator<int, QList<TextEditor::QuickFixOperation::Ptr> > it(matchedOps);
it.toBack();
if (it.hasPrevious()) {
it.previous();
_quickFixes = it.value();
}
delete state;
if (! _quickFixes.isEmpty())
return editable->position();
}
return -1;
}
void QuickFixCollector::completions(QList<TextEditor::CompletionItem> *quickFixItems)
{
for (int i = 0; i < _quickFixes.size(); ++i) {
TextEditor::QuickFixOperation::Ptr op = _quickFixes.at(i);
TextEditor::CompletionItem item(this);
item.text = op->description();
item.data = QVariant::fromValue(i);
quickFixItems->append(item);
}
}
void QuickFixCollector::complete(const TextEditor::CompletionItem &item)
{
const int index = item.data.toInt();
if (index < _quickFixes.size()) {
TextEditor::QuickFixOperation::Ptr quickFix = _quickFixes.at(index);
quickFix->perform();
}
}
void QuickFixCollector::cleanup()
{
_quickFixes.clear();
}
......@@ -31,6 +31,7 @@
#define TEXTEDITORQUICKFIX_H
#include "texteditor_global.h"
#include "icompletioncollector.h"
#include <utils/changeset.h>
#include <QtCore/QSharedPointer>
......@@ -111,6 +112,34 @@ private:
Utils::ChangeSet _changeSet;
};
class TEXTEDITOR_EXPORT QuickFixCollector: public TextEditor::IQuickFixCollector
{
Q_OBJECT
public:
QuickFixCollector();
virtual ~QuickFixCollector();
QList<TextEditor::QuickFixOperation::Ptr> quickFixes() const { return _quickFixes; }
virtual TextEditor::ITextEditable *editor() const;
virtual int startPosition() const;
virtual bool supportsEditor(TextEditor::ITextEditable *editor);
virtual bool triggersCompletion(TextEditor::ITextEditable *editor);
virtual int startCompletion(TextEditor::ITextEditable *editor);
virtual void completions(QList<TextEditor::CompletionItem> *completions);
virtual void complete(const TextEditor::CompletionItem &item);
virtual void cleanup();
virtual TextEditor::QuickFixState *initializeCompletion(TextEditor::ITextEditable *editable) = 0;
virtual QList<TextEditor::QuickFixOperation::Ptr> quickFixOperations(TextEditor::BaseTextEditor *editor) const = 0;
private:
TextEditor::ITextEditable *_editable;
QList<TextEditor::QuickFixOperation::Ptr> _quickFixes;
};
} // end of namespace TextEditor
#endif // TEXTEDITORQUICKFIX_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment