From 74ed3e8a115d6a5eeaaf52e7f37eeb80d89c95c1 Mon Sep 17 00:00:00 2001 From: Christian Kamm <christian.d.kamm@nokia.com> Date: Tue, 6 Jul 2010 14:41:34 +0200 Subject: [PATCH] C++ indenter: Add more functions to manage the indenter state. --- src/plugins/cpptools/cppcodeformatter.cpp | 41 ++++++++++++++++++- src/plugins/cpptools/cppcodeformatter.h | 6 +++ .../codeformatter/tst_codeformatter.cpp | 6 +-- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp index 582293ff10c..89915daef5e 100644 --- a/src/plugins/cpptools/cppcodeformatter.cpp +++ b/src/plugins/cpptools/cppcodeformatter.cpp @@ -455,6 +455,8 @@ void CodeFormatter::updateStateUntil(const QTextBlock &endBlock) { QStack<State> previousState = initialState(); QTextBlock it = endBlock.document()->firstBlock(); + + // find the first block that needs recalculation for (; it.isValid() && it != endBlock; it = it.next()) { TextBlockUserData *userData = BaseTextDocumentLayout::userData(it); CppCodeFormatterData *cppData = static_cast<CppCodeFormatterData *>(userData->codeFormatterData()); @@ -469,10 +471,47 @@ void CodeFormatter::updateStateUntil(const QTextBlock &endBlock) previousState = cppData->m_endState; } + + if (it == endBlock) + return; + + // update everthing until endBlock for (; it.isValid() && it != endBlock; it = it.next()) { - //qDebug() << "recalc line" << it.blockNumber() + 1; recalculateStateAfter(it); } + + // invalidate everything below by marking the state in endBlock as invalid + TextBlockUserData *userData = BaseTextDocumentLayout::userData(endBlock); + CppCodeFormatterData *cppData = static_cast<CppCodeFormatterData *>(userData->codeFormatterData()); + if (cppData) + cppData->setBlockRevision(-1); +} + +void CodeFormatter::updateLineStateChange(const QTextBlock &block) +{ + if (!block.isValid()) + return; + + QStack<State> oldEndState; + + TextBlockUserData *userData = BaseTextDocumentLayout::userData(block); + CppCodeFormatterData *cppData = static_cast<CppCodeFormatterData *>(userData->codeFormatterData()); + if (cppData) + oldEndState = cppData->m_endState; + + recalculateStateAfter(block); + + if (oldEndState.isEmpty() || oldEndState != cppData->m_endState) { + // invalidate everything below by marking the next block's state as invalid + QTextBlock next = block.next(); + if (!next.isValid()) + return; + + userData = BaseTextDocumentLayout::userData(next); + cppData = static_cast<CppCodeFormatterData *>(userData->codeFormatterData()); + if (cppData) + cppData->setBlockRevision(-1); + } } CodeFormatter::State CodeFormatter::state(int belowTop) const diff --git a/src/plugins/cpptools/cppcodeformatter.h b/src/plugins/cpptools/cppcodeformatter.h index 2475603d4d0..4fee466086c 100644 --- a/src/plugins/cpptools/cppcodeformatter.h +++ b/src/plugins/cpptools/cppcodeformatter.h @@ -28,7 +28,13 @@ public: CodeFormatter(); virtual ~CodeFormatter(); + // updates all states up until block if necessary + // it is safe to call indentFor on block afterwards void updateStateUntil(const QTextBlock &block); + + // calculates the state change introduced by changing a single line + void updateLineStateChange(const QTextBlock &block); + int indentFor(const QTextBlock &block); void setTabSize(int tabSize); diff --git a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp index f604deee9c7..e8be0dcfb85 100644 --- a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp +++ b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp @@ -89,17 +89,17 @@ void checkIndent(QList<Line> data, int style = 0) formatter.setIndentDeclarationBraces(true); } - formatter.updateStateUntil(document.lastBlock()); - int i = 0; foreach (const Line &l, data) { + QTextBlock b = document.findBlockByLineNumber(i); if (l.expectedIndent != -1) { - int actualIndent = formatter.indentFor(document.findBlockByLineNumber(i)); + int actualIndent = formatter.indentFor(b); if (actualIndent != l.expectedIndent) { QFAIL(QString("Wrong indent in line %1 with text '%2', expected indent %3, got %4").arg( QString::number(i+1), l.line, QString::number(l.expectedIndent), QString::number(actualIndent)).toLatin1().constData()); } } + formatter.updateLineStateChange(b); ++i; } } -- GitLab