Skip to content
Snippets Groups Projects
Commit bcf50a0a authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Generalized the quickfix collector.

parent 3d81ae85
No related branches found
No related tags found
No related merge requests found
......@@ -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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment