From 7ae3fd5a10c584de0f0f0d1ff7761266eadc68d0 Mon Sep 17 00:00:00 2001 From: Christian Kamm <christian.d.kamm@nokia.com> Date: Wed, 7 Jul 2010 11:01:38 +0200 Subject: [PATCH] C++ indenter: Refactor to be independent of BaseTextDocumentLayout. Done-with: Thomas Hartmann --- src/plugins/cppeditor/cppeditor.cpp | 3 +- src/plugins/cpptools/cppcodeformatter.cpp | 156 ++++++++++-------- src/plugins/cpptools/cppcodeformatter.h | 30 +++- .../texteditor/basetextdocumentlayout.cpp | 5 - .../texteditor/basetextdocumentlayout.h | 7 - 5 files changed, 117 insertions(+), 84 deletions(-) diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index c21a5948d3c..cc4238013a0 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -1791,7 +1791,8 @@ void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs) void CPPEditor::setTabSettings(const TextEditor::TabSettings &ts) { - CppTools::CodeFormatter::invalidateCache(document()); + CppTools::QtStyleCodeFormatter formatter; + formatter.invalidateCache(document()); TextEditor::BaseTextEditor::setTabSettings(ts); } diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp index ac4d94faf9e..5d42edef6d0 100644 --- a/src/plugins/cpptools/cppcodeformatter.cpp +++ b/src/plugins/cpptools/cppcodeformatter.cpp @@ -10,33 +10,16 @@ #include <QtGui/QTextCursor> #include <QtGui/QTextBlock> -namespace CppTools { -namespace Internal { - class CppCodeFormatterData: public TextEditor::CodeFormatterData - { - public: - CppCodeFormatterData(int blockRevision, - const QStack<CodeFormatter::State> &beginState, - const QStack<CodeFormatter::State> &endState, - int indentDepth) - : CodeFormatterData(blockRevision) - , m_beginState(beginState) - , m_endState(endState) - , m_indentDepth(indentDepth) - {} - - QStack<CodeFormatter::State> m_beginState; - QStack<CodeFormatter::State> m_endState; - int m_indentDepth; - }; -} -} - using namespace CPlusPlus; using namespace CppTools; using namespace TextEditor; using namespace CppTools::Internal; +CodeFormatter::BlockData::BlockData() + : m_blockRevision(-1) +{ +} + CodeFormatter::CodeFormatter() : m_indentDepth(0) , m_tabSize(4) @@ -54,7 +37,7 @@ void CodeFormatter::setTabSize(int tabSize) void CodeFormatter::recalculateStateAfter(const QTextBlock &block) { - restoreBlockState(block.previous()); + restoreCurrentState(block.previous()); bool endedJoined = false; const int lexerState = tokenizeBlock(block, &endedJoined); @@ -420,14 +403,14 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block) if (topState == cpp_macro && endedJoined) turnInto(cpp_macro_cont); - storeBlockState(block); + saveCurrentState(block); } int CodeFormatter::indentFor(const QTextBlock &block) { // qDebug() << "indenting for" << block.blockNumber() + 1; - restoreBlockState(block.previous()); + restoreCurrentState(block.previous()); correctIndentation(block); return m_indentDepth; } @@ -439,18 +422,17 @@ void CodeFormatter::updateStateUntil(const QTextBlock &endBlock) // 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()); - if (!cppData) + BlockData blockData; + if (!loadBlockData(it, &blockData)) break; - if (cppData->blockRevision() != it.revision()) + if (blockData.m_blockRevision != it.revision()) break; - if (previousState != cppData->m_beginState) + if (previousState != blockData.m_beginState) break; - if (TextBlockUserData::lexerState(it) == -1) + if (loadLexerState(it) == -1) break; - previousState = cppData->m_endState; + previousState = blockData.m_endState; } if (it == endBlock) @@ -462,10 +444,10 @@ void CodeFormatter::updateStateUntil(const QTextBlock &endBlock) } // 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); + if (it.isValid()) { + BlockData invalidBlockData; + saveBlockData(&it, invalidBlockData); + } } void CodeFormatter::updateLineStateChange(const QTextBlock &block) @@ -473,26 +455,18 @@ 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; + BlockData blockData; + if (loadBlockData(block, &blockData) && blockData.m_blockRevision == block.revision()) + return; 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; + // 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); - } + saveBlockData(&next, BlockData()); } CodeFormatter::State CodeFormatter::state(int belowTop) const @@ -528,13 +502,10 @@ void CodeFormatter::invalidateCache(QTextDocument *document) if (!document) return; + BlockData invalidBlockData; QTextBlock it = document->firstBlock(); for (; it.isValid(); it = it.next()) { - TextBlockUserData *userData = BaseTextDocumentLayout::userData(it); - CppCodeFormatterData *cppData = static_cast<CppCodeFormatterData *>(userData->codeFormatterData()); - if (!cppData) - break; - cppData->setBlockRevision(-1); + saveBlockData(&it, invalidBlockData); } } @@ -795,25 +766,29 @@ void CodeFormatter::turnInto(int newState) enter(newState); } -void CodeFormatter::storeBlockState(const QTextBlock &block) +void CodeFormatter::saveCurrentState(const QTextBlock &block) { if (!block.isValid()) return; - TextBlockUserData *userData = BaseTextDocumentLayout::userData(block); - userData->setCodeFormatterData( - new CppCodeFormatterData(block.revision(), m_beginState, m_currentState, m_indentDepth)); + BlockData blockData; + blockData.m_blockRevision = block.revision(); + blockData.m_beginState = m_beginState; + blockData.m_endState = m_currentState; + blockData.m_indentDepth = m_indentDepth; + + QTextBlock saveableBlock(block); + saveBlockData(&saveableBlock, blockData); } -void CodeFormatter::restoreBlockState(const QTextBlock &block) +void CodeFormatter::restoreCurrentState(const QTextBlock &block) { if (block.isValid()) { - TextBlockUserData *userData = BaseTextDocumentLayout::userData(block); - CppCodeFormatterData *oldData = static_cast<CppCodeFormatterData *>(userData->codeFormatterData()); - if (oldData) { - m_currentState = oldData->m_endState; + BlockData blockData; + if (loadBlockData(block, &blockData)) { + m_indentDepth = blockData.m_indentDepth; + m_currentState = blockData.m_endState; m_beginState = m_currentState; - m_indentDepth = oldData->m_indentDepth; return; } } @@ -833,7 +808,7 @@ QStack<CodeFormatter::State> CodeFormatter::initialState() int CodeFormatter::tokenizeBlock(const QTextBlock &block, bool *endedJoined) { - int startState = TextBlockUserData::lexerState(block.previous()); + int startState = loadLexerState(block.previous()); if (block.blockNumber() == 0) startState = 0; Q_ASSERT(startState != -1); @@ -866,6 +841,17 @@ void CodeFormatter::dump() qDebug() << "Current indent depth:" << m_indentDepth; } + +namespace CppTools { +namespace Internal { + class CppCodeFormatterData: public TextEditor::CodeFormatterData + { + public: + CodeFormatter::BlockData m_data; + }; +} +} + QtStyleCodeFormatter::QtStyleCodeFormatter() : m_indentSize(4) , m_indentSubstatementBraces(false) @@ -900,6 +886,40 @@ void QtStyleCodeFormatter::setIndentDeclarationMembers(bool onOff) m_indentDeclarationMembers = onOff; } +void QtStyleCodeFormatter::saveBlockData(QTextBlock *block, const BlockData &data) const +{ + TextBlockUserData *userData = BaseTextDocumentLayout::userData(*block); + CppCodeFormatterData *cppData = static_cast<CppCodeFormatterData *>(userData->codeFormatterData()); + if (!cppData) { + cppData = new CppCodeFormatterData; + userData->setCodeFormatterData(cppData); + } + cppData->m_data = data; +} + +bool QtStyleCodeFormatter::loadBlockData(const QTextBlock &block, BlockData *data) const +{ + TextBlockUserData *userData = BaseTextDocumentLayout::testUserData(block); + if (!userData) + return false; + CppCodeFormatterData *cppData = static_cast<CppCodeFormatterData *>(userData->codeFormatterData()); + if (!cppData) + return false; + + *data = cppData->m_data; + return true; +} + +void QtStyleCodeFormatter::saveLexerState(QTextBlock *block, int state) const +{ + TextBlockUserData::setLexerState(*block, state); +} + +int QtStyleCodeFormatter::loadLexerState(const QTextBlock &block) const +{ + return TextBlockUserData::lexerState(block); +} + void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedIndentDepth) const { const State &parentState = state(); diff --git a/src/plugins/cpptools/cppcodeformatter.h b/src/plugins/cpptools/cppcodeformatter.h index 4fee466086c..18b02cea1bf 100644 --- a/src/plugins/cpptools/cppcodeformatter.h +++ b/src/plugins/cpptools/cppcodeformatter.h @@ -39,12 +39,30 @@ public: void setTabSize(int tabSize); - static void invalidateCache(QTextDocument *document); + void invalidateCache(QTextDocument *document); protected: virtual void onEnter(int newState, int *indentDepth, int *savedIndentDepth) const = 0; virtual void adjustIndent(const QList<CPlusPlus::Token> &tokens, int lexerState, int *indentDepth) const = 0; + class State; + class BlockData + { + public: + BlockData(); + + QStack<State> m_beginState; + QStack<State> m_endState; + int m_indentDepth; + int m_blockRevision; + }; + + virtual void saveBlockData(QTextBlock *block, const BlockData &data) const = 0; + virtual bool loadBlockData(const QTextBlock &block, BlockData *data) const = 0; + + virtual void saveLexerState(QTextBlock *block, int state) const = 0; + virtual int loadLexerState(const QTextBlock &block) const = 0; + protected: enum StateType { invalid = 0, @@ -146,8 +164,8 @@ protected: private: void recalculateStateAfter(const QTextBlock &block); - void storeBlockState(const QTextBlock &block); - void restoreBlockState(const QTextBlock &block); + void saveCurrentState(const QTextBlock &block); + void restoreCurrentState(const QTextBlock &block); QStringRef currentTokenText() const; @@ -201,6 +219,12 @@ protected: virtual void onEnter(int newState, int *indentDepth, int *savedIndentDepth) const; virtual void adjustIndent(const QList<CPlusPlus::Token> &tokens, int lexerState, int *indentDepth) const; + virtual void saveBlockData(QTextBlock *block, const BlockData &data) const; + virtual bool loadBlockData(const QTextBlock &block, BlockData *data) const; + + virtual void saveLexerState(QTextBlock *block, int state) const; + virtual int loadLexerState(const QTextBlock &block) const; + private: int m_indentSize; bool m_indentSubstatementBraces; diff --git a/src/plugins/texteditor/basetextdocumentlayout.cpp b/src/plugins/texteditor/basetextdocumentlayout.cpp index 871cab0e131..087eb09ccff 100644 --- a/src/plugins/texteditor/basetextdocumentlayout.cpp +++ b/src/plugins/texteditor/basetextdocumentlayout.cpp @@ -31,11 +31,6 @@ using namespace TextEditor; -CodeFormatterData::CodeFormatterData(int blockRevision) - : m_blockRevision(blockRevision) -{ -} - CodeFormatterData::~CodeFormatterData() { } diff --git a/src/plugins/texteditor/basetextdocumentlayout.h b/src/plugins/texteditor/basetextdocumentlayout.h index 76323c63841..d6fa481ec74 100644 --- a/src/plugins/texteditor/basetextdocumentlayout.h +++ b/src/plugins/texteditor/basetextdocumentlayout.h @@ -57,14 +57,7 @@ struct TEXTEDITOR_EXPORT Parenthesis class TEXTEDITOR_EXPORT CodeFormatterData { public: - CodeFormatterData(int blockRevision); virtual ~CodeFormatterData(); - - int blockRevision() const { return m_blockRevision; } - void setBlockRevision(int revision) { m_blockRevision = revision; } - -private: - int m_blockRevision; }; class TEXTEDITOR_EXPORT TextBlockUserData : public QTextBlockUserData -- GitLab