summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools/cppcodeformatter.cpp
diff options
context:
space:
mode:
authorChristian Kamm <christian.d.kamm@nokia.com>2010-07-05 12:56:37 +0200
committerChristian Kamm <christian.d.kamm@nokia.com>2010-07-05 13:49:12 +0200
commit19db6c98267d6afd4e27d727d5582541947ec43b (patch)
treedb7dea90189f53a63968f8cbc7064ea255978611 /src/plugins/cpptools/cppcodeformatter.cpp
parent3100fc0b7edc7670ac9a95a2715b80a6d4a3be21 (diff)
downloadqt-creator-19db6c98267d6afd4e27d727d5582541947ec43b.tar.gz
C++ indenter: Make building custom styles easier, fix style issues.
Keep more information by using enter() instead of turnInto() when moving from a *_start to *_open.
Diffstat (limited to 'src/plugins/cpptools/cppcodeformatter.cpp')
-rw-r--r--src/plugins/cpptools/cppcodeformatter.cpp172
1 files changed, 118 insertions, 54 deletions
diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp
index 1bfb0a574a..7028157c1b 100644
--- a/src/plugins/cpptools/cppcodeformatter.cpp
+++ b/src/plugins/cpptools/cppcodeformatter.cpp
@@ -38,8 +38,7 @@ using namespace TextEditor;
using namespace CppTools::Internal;
CodeFormatter::CodeFormatter()
- : m_document(0)
- , m_indentDepth(0)
+ : m_indentDepth(0)
{
}
@@ -47,11 +46,6 @@ CodeFormatter::~CodeFormatter()
{
}
-void CodeFormatter::setDocument(QTextDocument *document)
-{
- m_document = document;
-}
-
void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
{
restoreBlockState(block.previous());
@@ -59,6 +53,7 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
bool endedJoined = false;
const int lexerState = tokenizeBlock(block, &endedJoined);
m_tokenIndex = 0;
+ m_newStates.clear();
if (tokenAt(0).kind() == T_POUND) {
enter(cpp_macro_start);
@@ -84,7 +79,8 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
case namespace_start:
switch (kind) {
- case T_LBRACE: turnInto(namespace_open); break;
+ case T_LBRACE: enter(namespace_open); break;
+ case T_RBRACE: leave(); break;
} break;
case namespace_open:
@@ -92,7 +88,7 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
break;
switch (kind) {
case T_NAMESPACE: enter(namespace_start); break;
- case T_RBRACE: leave(); break;
+ case T_RBRACE: leave(); continue; // always nested in namespace_start
case T_STRUCT:
case T_UNION:
case T_CLASS: enter(class_start); break;
@@ -103,14 +99,14 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
case class_start:
switch (kind) {
case T_SEMICOLON: leave(); break;
- case T_LBRACE: turnInto(class_open); break;
+ case T_LBRACE: enter(class_open); break;
} break;
case class_open:
if (tryDeclaration())
break;
switch (kind) {
- case T_RBRACE: leave(); break;
+ case T_RBRACE: leave(); continue; // always nested in class_start
case T_STRUCT:
case T_UNION:
case T_CLASS: enter(class_start); break;
@@ -121,13 +117,19 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
case enum_start:
switch (kind) {
case T_SEMICOLON: leave(); break;
- case T_LBRACE: turnInto(brace_list_open); break;
+ case T_LBRACE: enter(enum_open); break;
+ } break;
+
+ case enum_open:
+ switch (kind) {
+ case T_RBRACE: leave(); continue; // always nested in enum_start
+ case T_LBRACE: enter(brace_list_open); break;
} break;
case brace_list_open:
switch (kind) {
case T_RBRACE: leave(); break;
- case T_LBRACE: enter(brace_list_open); break; // ### Other, nested brace list?
+ case T_LBRACE: enter(brace_list_open); break;
} break;
case using_start:
@@ -156,10 +158,11 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
if (tryExpression(true))
break;
switch (kind) {
+ case T_RBRACE:
case T_SEMICOLON: leave(true); break;
case T_EQUAL: enter(initializer); break;
- case T_LBRACE: turnInto(defun_open); break;
- case T_COLON: turnInto(member_init_open); break;
+ case T_LBRACE: enter(defun_open); break;
+ case T_COLON: enter(member_init_open); break;
case T_OPERATOR: enter(operator_declaration); break;
} break;
@@ -211,14 +214,14 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
case member_init_open:
switch (kind) {
case T_LBRACE: turnInto(defun_open); break;
- case T_SEMICOLON: leave(); break; // ### so we don't break completely if it's a bitfield or ternary
+ case T_SEMICOLON: leave(); continue; // so we don't break completely if it's a bitfield or ternary
} break;
case defun_open:
if (tryStatement())
break;
switch (kind) {
- case T_RBRACE: leave(); break;
+ case T_RBRACE: leave(); continue; // always nested in declaration_start
} break;
case switch_statement:
@@ -437,9 +440,6 @@ int CodeFormatter::indentFor(const QTextBlock &block)
{
// qDebug() << "indenting for" << block.blockNumber() + 1;
- Q_ASSERT(m_document);
- Q_ASSERT(m_document == block.document());
-
requireStatesUntil(block);
correctIndentation(block);
return m_indentDepth;
@@ -448,7 +448,7 @@ int CodeFormatter::indentFor(const QTextBlock &block)
void CodeFormatter::requireStatesUntil(const QTextBlock &endBlock)
{
QStack<State> previousState = initialState();
- QTextBlock it = m_document->firstBlock();
+ QTextBlock it = endBlock.document()->firstBlock();
for (; it.isValid() && it != endBlock; it = it.next()) {
TextBlockUserData *userData = BaseTextDocumentLayout::userData(it);
CppCodeFormatterData *cppData = static_cast<CppCodeFormatterData *>(userData->codeFormatterData());
@@ -478,14 +478,19 @@ CodeFormatter::State CodeFormatter::state(int belowTop) const
return State();
}
+const QVector<CodeFormatter::State> &CodeFormatter::newStatesThisLine() const
+{
+ return m_newStates;
+}
+
int CodeFormatter::tokenIndex() const
{
return m_tokenIndex;
}
-int CodeFormatter::tokenIndexFromEnd() const
+int CodeFormatter::tokenCount() const
{
- return m_tokens.size() - 1 - m_tokenIndex;
+ return m_tokens.size();
}
const CPlusPlus::Token &CodeFormatter::currentToken() const
@@ -493,9 +498,12 @@ const CPlusPlus::Token &CodeFormatter::currentToken() const
return m_currentToken;
}
-void CodeFormatter::invalidateCache()
+void CodeFormatter::invalidateCache(QTextDocument *document)
{
- QTextBlock it = m_document->firstBlock();
+ if (!document)
+ return;
+
+ QTextBlock it = document->firstBlock();
for (; it.isValid(); it = it.next()) {
TextBlockUserData *userData = BaseTextDocumentLayout::userData(it);
CppCodeFormatterData *cppData = static_cast<CppCodeFormatterData *>(userData->codeFormatterData());
@@ -509,7 +517,9 @@ void CodeFormatter::enter(int newState)
{
int savedIndentDepth = m_indentDepth;
onEnter(newState, &m_indentDepth, &savedIndentDepth);
- m_currentState.push(State(newState, savedIndentDepth));
+ State s(newState, savedIndentDepth);
+ m_currentState.push(s);
+ m_newStates.push(s);
}
void CodeFormatter::leave(bool statementDone)
@@ -518,6 +528,9 @@ void CodeFormatter::leave(bool statementDone)
if (m_currentState.top().type == topmost_intro)
return;
+ if (m_newStates.size() > 0)
+ m_newStates.pop();
+
// restore indent depth
State poppedState = m_currentState.pop();
m_indentDepth = poppedState.savedIndentDepth;
@@ -794,24 +807,36 @@ void CodeFormatter::dump()
QtStyleCodeFormatter::QtStyleCodeFormatter()
: m_indentSize(4)
- , m_style(QtStyle)
+ , m_indentSubstatementBraces(false)
+ , m_indentSubstatementStatements(true)
+ , m_indentDeclarationBraces(false)
+ , m_indentDeclarationMembers(true)
{
}
void QtStyleCodeFormatter::setIndentSize(int size)
{
- if (size != m_indentSize) {
- m_indentSize = size;
- invalidateCache();
- }
+ m_indentSize = size;
}
-void QtStyleCodeFormatter::setCompoundStyle(CompoundStyle style)
+void QtStyleCodeFormatter::setIndentSubstatementBraces(bool onOff)
{
- if (style != m_style) {
- m_style = style;
- invalidateCache();
- }
+ m_indentSubstatementBraces = onOff;
+}
+
+void QtStyleCodeFormatter::setIndentSubstatementStatements(bool onOff)
+{
+ m_indentSubstatementStatements = onOff;
+}
+
+void QtStyleCodeFormatter::setIndentDeclarationBraces(bool onOff)
+{
+ m_indentDeclarationBraces = onOff;
+}
+
+void QtStyleCodeFormatter::setIndentDeclarationMembers(bool onOff)
+{
+ m_indentDeclarationMembers = onOff;
}
void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedIndentDepth) const
@@ -820,7 +845,7 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
const Token &tk = currentToken();
const int tokenPosition = tk.begin();
const bool firstToken = (tokenIndex() == 0);
- const bool lastToken = (tokenIndexFromEnd() == 0);
+ const bool lastToken = (tokenIndex() == tokenCount() - 1);
switch (newState) {
case namespace_start:
@@ -874,28 +899,58 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
break;
case member_init_open:
+ // undo the continuation indent of the parent
+ *savedIndentDepth = parentState.savedIndentDepth;
+
if (firstToken)
*indentDepth = tokenPosition + tk.length() + 1;
else
- *indentDepth += m_indentSize;
+ *indentDepth = *savedIndentDepth + m_indentSize;
break;
- case defun_open:
- case class_open:
case case_cont:
*indentDepth += m_indentSize;
break;
- case substatement_open:
- if (m_style == WhitesmithsStyle)
- break;
- if (parentState.type != switch_statement)
+ case class_open:
+ case enum_open:
+ case defun_open:
+ // undo the continuation indent of the parent
+ *savedIndentDepth = parentState.savedIndentDepth;
+
+ if (firstToken)
+ *savedIndentDepth = tokenPosition;
+
+ *indentDepth = *savedIndentDepth;
+
+ if (m_indentDeclarationMembers)
*indentDepth += m_indentSize;
break;
+ case substatement_open:
+ if (firstToken) {
+ *savedIndentDepth = tokenPosition;
+ *indentDepth = *savedIndentDepth;
+ } else if (m_indentSubstatementBraces && !m_indentSubstatementStatements) {
+ // ### The preceding check is quite arbitrary.
+ // It actually needs another flag to determine whether the closing curly
+ // should be indented or not
+ *indentDepth = *savedIndentDepth += m_indentSize;
+ }
+
+ if (m_indentSubstatementStatements) {
+ if (parentState.type != switch_statement)
+ *indentDepth += m_indentSize;
+ }
+ break;
+
case brace_list_open:
if (parentState.type != initializer)
*indentDepth = parentState.savedIndentDepth + m_indentSize;
+ else if (lastToken) {
+ *savedIndentDepth = state(1).savedIndentDepth;
+ *indentDepth = *savedIndentDepth + m_indentSize;
+ }
break;
case block_open:
@@ -919,9 +974,6 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
// undo the continuation indent of the parent
*indentDepth = parentState.savedIndentDepth;
*savedIndentDepth = *indentDepth;
- // these styles want to indent braces
- if (m_style == GnuStyle || m_style == WhitesmithsStyle)
- *savedIndentDepth += m_indentSize;
break;
case maybe_else: {
@@ -998,16 +1050,27 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
}
break;
case T_LBRACE: {
- // function definition - argument list is expression state
- if (topState.type == case_cont)
+ if (topState.type == case_cont) {
*indentDepth = topState.savedIndentDepth;
- else if (topState.type == expression && previousState.type == declaration_start)
+ // function definition - argument list is expression state
+ } else if (topState.type == expression && previousState.type == declaration_start) {
*indentDepth = previousState.savedIndentDepth;
- else if (topState.type != defun_open
- && topState.type != substatement_open
+ if (m_indentDeclarationBraces)
+ *indentDepth += m_indentSize;
+ } else if (topState.type == class_start) {
+ *indentDepth = topState.savedIndentDepth;
+ if (m_indentDeclarationBraces)
+ *indentDepth += m_indentSize;
+ } else if (topState.type == substatement) {
+ *indentDepth = topState.savedIndentDepth;
+ if (m_indentSubstatementBraces)
+ *indentDepth += m_indentSize;
+ } else if (topState.type != defun_open
&& topState.type != block_open
- && !topWasMaybeElse)
+ && !topWasMaybeElse) {
*indentDepth = topState.savedIndentDepth;
+ }
+
break;
}
case T_RBRACE: {
@@ -1022,7 +1085,8 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
|| type == class_open
|| type == brace_list_open
|| type == namespace_open
- || type == block_open) {
+ || type == block_open
+ || type == enum_open) {
*indentDepth = state(i).savedIndentDepth;
break;
}