Commit 7ae3fd5a authored by Christian Kamm's avatar Christian Kamm
Browse files

C++ indenter: Refactor to be independent of BaseTextDocumentLayout.

Done-with: Thomas Hartmann
parent 486b23b8
......@@ -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);
}
......
......@@ -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();
......
......@@ -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;
......
......@@ -31,11 +31,6 @@
using namespace TextEditor;
CodeFormatterData::CodeFormatterData(int blockRevision)
: m_blockRevision(blockRevision)
{
}
CodeFormatterData::~CodeFormatterData()
{
}
......
......@@ -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
......
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