diff options
author | Roberto Raggi <roberto.raggi@nokia.com> | 2009-11-13 16:14:26 +0100 |
---|---|---|
committer | Roberto Raggi <roberto.raggi@nokia.com> | 2009-11-13 16:14:38 +0100 |
commit | c13b8697d2ab5f2d3b901ae75156cf7cebe55a10 (patch) | |
tree | a95a61d53037afc82711ccb3c58209db6cab3c08 /src/plugins/cpptools/cpptoolseditorsupport.cpp | |
parent | e35a754dc9e9e31937415d2106095bbbfa099e71 (diff) | |
download | qt-creator-c13b8697d2ab5f2d3b901ae75156cf7cebe55a10.tar.gz |
Introduced the quick fix engine
Diffstat (limited to 'src/plugins/cpptools/cpptoolseditorsupport.cpp')
-rw-r--r-- | src/plugins/cpptools/cpptoolseditorsupport.cpp | 315 |
1 files changed, 0 insertions, 315 deletions
diff --git a/src/plugins/cpptools/cpptoolseditorsupport.cpp b/src/plugins/cpptools/cpptoolseditorsupport.cpp index 90811aad5a..c9c3e367a6 100644 --- a/src/plugins/cpptools/cpptoolseditorsupport.cpp +++ b/src/plugins/cpptools/cpptoolseditorsupport.cpp @@ -44,273 +44,6 @@ using namespace CppTools::Internal; using namespace CPlusPlus; -namespace { - -enum { - DEFAULT_QUICKFIX_INTERVAL = 500 -}; - -class QuickFixMark: public TextEditor::ITextMark -{ - QIcon _icon; - -public: - QuickFixMark(QObject *parent) - : TextEditor::ITextMark(parent), - _icon(QLatin1String(":/core/images/redo.png")) // ### FIXME - { } - - virtual ~QuickFixMark() - { } - - virtual QIcon icon() const - { return _icon; } - - virtual void updateLineNumber(int) - { } - - virtual void updateBlock(const QTextBlock &) - { } - - virtual void removedFromEditor() - { } - - virtual void documentClosing() - { } -}; - -class ReplaceCast: public QuickFixOperation -{ - CastExpressionAST *_castExpression; - -public: - ReplaceCast(CastExpressionAST *node, Document::Ptr doc, const Snapshot &snapshot) - : QuickFixOperation(doc, snapshot), - _castExpression(node) - { } - - virtual QString description() const - { return QLatin1String("Rewrite old C-style cast"); } - - virtual void apply(QTextCursor tc) - { - setTextCursor(tc); - - tc.beginEditBlock(); - - QTextCursor beginOfCast = cursor(_castExpression->lparen_token); - QTextCursor endOfCast = cursor(_castExpression->rparen_token); - QTextCursor beginOfExpr = moveAtStartOfToken(_castExpression->expression->firstToken()); - QTextCursor endOfExpr = moveAtEndOfToken(_castExpression->expression->lastToken() - 1); - - beginOfCast.insertText(QLatin1String("reinterpret_cast<")); - endOfCast.insertText(QLatin1String(">")); - - beginOfExpr.insertText(QLatin1String("(")); - endOfExpr.insertText(QLatin1String(")")); - - tc.endEditBlock(); - } -}; - -class RewriteConditional: public QuickFixOperation -{ - QString _source; - BinaryExpressionAST *_binaryExpression; - -public: - RewriteConditional(const QString &source, BinaryExpressionAST *node, - Document::Ptr doc, const Snapshot &snapshot) - : QuickFixOperation(doc, snapshot), - _source(source), - _binaryExpression(node) - { } - - virtual QString description() const - { return QString::fromUtf8("Rewrite conditional (%1)").arg(_source.simplified()); } - - virtual void apply(QTextCursor tc) - { - setTextCursor(tc); - - tc.beginEditBlock(); - - UnaryExpressionAST *left_unary_expr = _binaryExpression->left_expression->asUnaryExpression(); - UnaryExpressionAST *right_unary_expr = _binaryExpression->right_expression->asUnaryExpression(); - - QTextCursor left_not_op = cursor(left_unary_expr->unary_op_token); - QTextCursor right_not_op = cursor(right_unary_expr->unary_op_token); - QTextCursor log_and_op = cursor(_binaryExpression->binary_op_token); - - QTextCursor begin_of_expr = moveAtStartOfToken(_binaryExpression->firstToken()); - QTextCursor end_of_expr = moveAtEndOfToken(_binaryExpression->lastToken() - 1); - - left_not_op.removeSelectedText(); - right_not_op.removeSelectedText(); - log_and_op.insertText(QLatin1String("||")); - begin_of_expr.insertText(QLatin1String("!(")); - end_of_expr.insertText(QLatin1String(")")); - - tc.endEditBlock(); - } -}; -class CheckDocument: protected ASTVisitor -{ - QTextCursor _textCursor; - Document::Ptr _doc; - Snapshot _snapshot; - unsigned _line; - unsigned _column; - QList<QuickFixOperationPtr> _quickFixes; - -public: - CheckDocument(Document::Ptr doc, Snapshot snapshot) - : ASTVisitor(doc->control()), _doc(doc), _snapshot(snapshot), - _line(0), _column(0) - { } - - QList<QuickFixOperationPtr> operator()(QTextCursor tc) - { - _quickFixes.clear(); - _textCursor = tc; - _line = tc.blockNumber() + 1; - _column = tc.columnNumber() + 1; - accept(_doc->translationUnit()->ast()); - return _quickFixes; - } - -protected: - using ASTVisitor::visit; - - bool checkPosition(AST *ast) const - { - unsigned startLine, startColumn; - unsigned endLine, endColumn; - - getTokenStartPosition(ast->firstToken(), &startLine, &startColumn); - getTokenEndPosition(ast->lastToken() - 1, &endLine, &endColumn); - - if (_line < startLine || (_line == startLine && _column < startColumn)) - return false; - else if (_line > endLine || (_line == endLine && _column >= endColumn)) - return false; - - return true; - } - - QTextCursor moveAtStartOfToken(unsigned index) const - { - unsigned line, col; - getTokenStartPosition(index, &line, &col); - QTextCursor tc = _textCursor; - tc.setPosition(tc.document()->findBlockByNumber(line - 1).position() + col - 1); - return tc; - } - - QTextCursor moveAtEndOfToken(unsigned index) const - { - const Token &tk = tokenAt(index); - - unsigned line, col; - getTokenStartPosition(index, &line, &col); - QTextCursor tc = _textCursor; - tc.setPosition(tc.document()->findBlockByNumber(line - 1).position() + col + tk.f.length - 1); - return tc; - } - - virtual bool visit(BinaryExpressionAST *ast) - { - if (ast->left_expression && ast->right_expression && tokenKind(ast->binary_op_token) == T_AMPER_AMPER && - checkPosition(ast)) { - UnaryExpressionAST *left_unary_expr = ast->left_expression->asUnaryExpression(); - UnaryExpressionAST *right_unary_expr = ast->right_expression->asUnaryExpression(); - if (left_unary_expr && left_unary_expr->expression && tokenKind(left_unary_expr->unary_op_token) == T_NOT && - right_unary_expr && right_unary_expr->expression && tokenKind(right_unary_expr->unary_op_token) == T_NOT) { - // replace !a && !b with !(a || b) - QTextCursor beg = moveAtStartOfToken(ast->firstToken()); - QTextCursor end = moveAtEndOfToken(ast->lastToken() - 1); - beg.setPosition(end.position(), QTextCursor::KeepAnchor); - QString source = beg.selectedText(); - - QuickFixOperationPtr op(new RewriteConditional(source, ast, _doc, _snapshot)); - _quickFixes.append(op); - return true; - } - } - - return true; - } - - virtual bool visit(CastExpressionAST *ast) - { - if (! checkPosition(ast)) - return true; - - if (ast->type_id && ast->lparen_token && ast->rparen_token && ast->expression) { - QuickFixOperationPtr op(new ReplaceCast(ast, _doc, _snapshot)); - _quickFixes.append(op); - } - - return true; - } -}; - -} // end of anonymous namespace - -QuickFixOperation::QuickFixOperation(CPlusPlus::Document::Ptr doc, const CPlusPlus::Snapshot &snapshot) - : _doc(doc), _snapshot(snapshot) -{ } - -QuickFixOperation::~QuickFixOperation() -{ } - -QTextCursor QuickFixOperation::textCursor() const -{ return _textCursor; } - -void QuickFixOperation::setTextCursor(const QTextCursor &tc) -{ _textCursor = tc; } - -const CPlusPlus::Token &QuickFixOperation::tokenAt(unsigned index) const -{ return _doc->translationUnit()->tokenAt(index); } - -void QuickFixOperation::getTokenStartPosition(unsigned index, unsigned *line, unsigned *column) const -{ _doc->translationUnit()->getPosition(tokenAt(index).begin(), line, column); } - -void QuickFixOperation::getTokenEndPosition(unsigned index, unsigned *line, unsigned *column) const -{ _doc->translationUnit()->getPosition(tokenAt(index).end(), line, column); } - -QTextCursor QuickFixOperation::cursor(unsigned index) const -{ - const Token &tk = tokenAt(index); - - unsigned line, col; - getTokenStartPosition(index, &line, &col); - QTextCursor tc = _textCursor; - tc.setPosition(tc.document()->findBlockByNumber(line - 1).position() + col - 1); - tc.setPosition(tc.position() + tk.f.length, QTextCursor::KeepAnchor); - return tc; -} - -QTextCursor QuickFixOperation::moveAtStartOfToken(unsigned index) const -{ - unsigned line, col; - getTokenStartPosition(index, &line, &col); - QTextCursor tc = _textCursor; - tc.setPosition(tc.document()->findBlockByNumber(line - 1).position() + col - 1); - return tc; -} - -QTextCursor QuickFixOperation::moveAtEndOfToken(unsigned index) const -{ - const Token &tk = tokenAt(index); - - unsigned line, col; - getTokenStartPosition(index, &line, &col); - QTextCursor tc = _textCursor; - tc.setPosition(tc.document()->findBlockByNumber(line - 1).position() + col + tk.f.length - 1); - return tc; -} - CppEditorSupport::CppEditorSupport(CppModelManager *modelManager) : QObject(modelManager), _modelManager(modelManager), @@ -320,14 +53,6 @@ CppEditorSupport::CppEditorSupport(CppModelManager *modelManager) _updateDocumentTimer->setSingleShot(true); _updateDocumentTimer->setInterval(_updateDocumentInterval); connect(_updateDocumentTimer, SIGNAL(timeout()), this, SLOT(updateDocumentNow())); - _quickFixMark = new QuickFixMark(this); - - _quickFixTimer = new QTimer(this); - _quickFixTimer->setSingleShot(true); - _quickFixTimer->setInterval(DEFAULT_QUICKFIX_INTERVAL); -#ifdef QTCREATOR_WITH_QUICKFIX - connect(_quickFixTimer, SIGNAL(timeout()), this, SLOT(checkDocumentNow())); -#endif } CppEditorSupport::~CppEditorSupport() @@ -344,12 +69,6 @@ void CppEditorSupport::setTextEditor(TextEditor::ITextEditor *textEditor) return; connect(_textEditor, SIGNAL(contentsChanged()), this, SIGNAL(contentsChanged())); - -#ifdef QTCREATOR_WITH_QUICKFIX - connect(qobject_cast<TextEditor::BaseTextEditor *>(_textEditor->widget()), SIGNAL(cursorPositionChanged()), - this, SLOT(checkDocument())); -#endif - connect(this, SIGNAL(contentsChanged()), this, SLOT(updateDocument())); updateDocument(); @@ -396,37 +115,3 @@ void CppEditorSupport::updateDocumentNow() } } -void CppEditorSupport::checkDocument() -{ - _quickFixTimer->start(DEFAULT_QUICKFIX_INTERVAL); -} - -void CppEditorSupport::checkDocumentNow() -{ - _textEditor->markableInterface()->removeMark(_quickFixMark); - _quickFixes.clear(); - - TextEditor::BaseTextEditor *ed = - qobject_cast<TextEditor::BaseTextEditor *>(_textEditor->widget()); - - Snapshot snapshot = _modelManager->snapshot(); - const QString plainText = contents(); - const QString fileName = _textEditor->file()->fileName(); - const QByteArray preprocessedCode = snapshot.preprocessedCode(plainText, fileName); - - if (Document::Ptr doc = snapshot.documentFromSource(preprocessedCode, fileName)) { - doc->parse(); - - CheckDocument checkDocument(doc, snapshot); - QList<QuickFixOperationPtr> quickFixes = checkDocument(ed->textCursor()); - if (! quickFixes.isEmpty()) { - int line, col; - ed->convertPosition(ed->position(), &line, &col); - - _textEditor->markableInterface()->addMark(_quickFixMark, line); - _quickFixes = quickFixes; - } - } -} - - |