Newer
Older
}
void QtStyleCodeFormatter::setIndentDeclarationBraces(bool onOff)
{
m_indentDeclarationBraces = onOff;
}
void QtStyleCodeFormatter::setIndentDeclarationMembers(bool onOff)
{
m_indentDeclarationMembers = onOff;
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
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
{
}
int QtStyleCodeFormatter::loadLexerState(const QTextBlock &block) const
{
}
void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedIndentDepth, int *paddingDepth, int *savedPaddingDepth) const
{
const State &parentState = state();
const Token &tk = currentToken();
const bool firstToken = (tokenIndex() == 0);
const bool lastToken = (tokenIndex() == tokenCount() - 1);
const int tokenPosition = column(tk.begin());
const int nextTokenPosition = lastToken ? tokenPosition + tk.length()
: column(tokenAt(tokenIndex() + 1).begin());
const int spaceOrNextTokenPosition = lastToken ? tokenPosition + tk.length() + 1
: nextTokenPosition;
if (shouldClearPaddingOnEnter(newState))
*paddingDepth = 0;
switch (newState) {
case namespace_start:
if (firstToken) {
*savedIndentDepth = tokenPosition;
*indentDepth = tokenPosition;
}
break;
case enum_start:
case class_start:
if (firstToken) {
*savedIndentDepth = tokenPosition;
*indentDepth = tokenPosition;
}
*paddingDepth = 2*m_indentSize;
break;
case template_param:
if (!lastToken)
*paddingDepth = nextTokenPosition-*indentDepth;
else {
if (*paddingDepth == 0)
*paddingDepth = 2*m_indentSize;
else
*paddingDepth += m_indentSize;
}
break;
case statement_with_condition:
case for_statement:
case switch_statement:
case if_statement:
case return_statement:
if (firstToken)
*indentDepth = *savedIndentDepth = tokenPosition;
*paddingDepth = 2*m_indentSize;
case declaration_start:
if (firstToken) {
*savedIndentDepth = tokenPosition;
*indentDepth = *savedIndentDepth;
}
// continuation indent in function bodies only, to not indent
// after the return type in "void\nfoo() {}"
for (int i = 0; state(i).type != topmost_intro; ++i) {
if (state(i).type == defun_open) {
*paddingDepth = 2*m_indentSize;
break;
}
}
break;
case arglist_open:
case condition_paren_open:
if (!lastToken)
*paddingDepth = nextTokenPosition-*indentDepth;
*paddingDepth += m_indentSize;
break;
case ternary_op:
if (!lastToken)
*paddingDepth = spaceOrNextTokenPosition-*indentDepth;
*paddingDepth += m_indentSize;
break;
case stream_op:
*paddingDepth = spaceOrNextTokenPosition-*indentDepth;
case stream_op_cont:
if (firstToken)
*savedPaddingDepth = *paddingDepth = spaceOrNextTokenPosition-*indentDepth;
// undo the continuation indent of the parent
*savedPaddingDepth = 0;
*paddingDepth = tokenPosition-*indentDepth;
*paddingDepth = m_indentSize - 2; // they'll get another 2 from member_init
break;
case member_init:
*paddingDepth += 2; // savedIndentDepth is the position of ':'
break;
case member_init_paren_open:
*paddingDepth += m_indentSize;
break;
case case_cont:
*indentDepth += m_indentSize;
break;
case class_open:
case enum_open:
case defun_open: {
// undo the continuation indent of the parent
*savedPaddingDepth = 0;
bool followedByData = (!lastToken && !tokenAt(tokenIndex() + 1).isComment());
if (followedByData)
*savedPaddingDepth = tokenPosition-*indentDepth;
*indentDepth += m_indentSize;
if (followedByData) {
*paddingDepth = nextTokenPosition-*indentDepth;
case substatement_open:
// undo parent continuation indent
*savedPaddingDepth = 0;
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;
if (!lastToken) {
if (parentState.type == initializer)
*savedPaddingDepth = tokenPosition-*indentDepth;
*paddingDepth = nextTokenPosition-*indentDepth;
} else {
// avoid existing continuation indents
if (parentState.type == initializer)
*savedPaddingDepth = state(1).savedPaddingDepth;
*paddingDepth = *savedPaddingDepth + m_indentSize;
break;
case block_open:
// case_cont already adds some indent, revert it for a block
if (parentState.type == case_cont && !m_indentSubstatementBraces)
*indentDepth = *savedIndentDepth = parentState.savedIndentDepth;
if (m_indentSubstatementStatements)
*indentDepth += m_indentSize;
break;
case condition_open:
// undo the continuation indent of the parent
*paddingDepth = parentState.savedPaddingDepth;
*savedPaddingDepth = *paddingDepth;
// fixed extra indent when continuing 'if (', but not for 'else if ('
if (nextTokenPosition-*indentDepth <= m_indentSize)
*paddingDepth = 2*m_indentSize;
*paddingDepth = nextTokenPosition-*indentDepth;
break;
case substatement:
// undo the continuation indent of the parent
*savedPaddingDepth = 0;
break;
case maybe_else: {
// set indent to outermost braceless savedIndent
int outermostBraceless = 0;
while (isBracelessState(state(outermostBraceless).type))
++outermostBraceless;
*indentDepth = state(outermostBraceless - 1).savedIndentDepth;
// this is where the else should go, if one appears - aligned to if_statement
*savedIndentDepth = state().savedIndentDepth;
} break;
case for_statement_paren_open:
*paddingDepth = nextTokenPosition - *indentDepth;
break;
case multiline_comment_start:
*indentDepth = tokenPosition + 2; // nextTokenPosition won't work
break;
case multiline_comment_cont:
*indentDepth = tokenPosition;
break;
case cpp_macro:
case cpp_macro_cont:
*indentDepth = m_indentSize;
break;
}
// ensure padding and indent are >= 0
*indentDepth = qMax(0, *indentDepth);
*savedIndentDepth = qMax(0, *savedIndentDepth);
*paddingDepth = qMax(0, *paddingDepth);
*savedPaddingDepth = qMax(0, *savedPaddingDepth);
void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, int lexerState, int *indentDepth, int *paddingDepth) const
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
{
State topState = state();
State previousState = state(1);
const bool topWasMaybeElse = (topState.type == maybe_else);
if (topWasMaybeElse) {
int outermostBraceless = 1;
while (state(outermostBraceless).type != invalid && isBracelessState(state(outermostBraceless).type))
++outermostBraceless;
topState = state(outermostBraceless);
previousState = state(outermostBraceless + 1);
}
// adjusting the indentDepth here instead of in enter() gives 'else if' the correct indentation
// ### could be moved?
if (topState.type == substatement)
*indentDepth += m_indentSize;
// keep user-adjusted indent in multiline comments
if (topState.type == multiline_comment_start
|| topState.type == multiline_comment_cont) {
if (!tokens.isEmpty()) {
*indentDepth = tokens.at(0).begin();
return;
}
}
const int kind = tokenAt(0).kind();
switch (kind) {
case T_POUND: *indentDepth = 0; break;
case T_COLON:
// ### ok for constructor initializer lists - what about ? and bitfields?
if (topState.type == expression && previousState.type == declaration_start) {
*paddingDepth = m_indentSize;
} else if (topState.type == ternary_op) {
if (*paddingDepth >= 2)
*paddingDepth -= 2;
else
*paddingDepth = 0;
}
break;
case T_LBRACE: {
if (topState.type == case_cont) {
*indentDepth = topState.savedIndentDepth;
if (m_indentSubstatementBraces)
*indentDepth += m_indentSize;
*paddingDepth = 0;
// function definition - argument list is expression state
} else if (topState.type == expression && previousState.type == declaration_start) {
*indentDepth = previousState.savedIndentDepth;
if (m_indentDeclarationBraces)
*indentDepth += m_indentSize;
*paddingDepth = 0;
} else if (topState.type == class_start) {
*indentDepth = topState.savedIndentDepth;
if (m_indentDeclarationBraces)
*indentDepth += m_indentSize;
*paddingDepth = 0;
} else if (topState.type == substatement) {
*indentDepth = topState.savedIndentDepth;
if (m_indentSubstatementBraces)
*indentDepth += m_indentSize;
*paddingDepth = 0;
} else if (topState.type != defun_open
&& topState.type != substatement_open
&& topState.type != brace_list_open
&& !topWasMaybeElse) {
*indentDepth = topState.savedIndentDepth;
*paddingDepth = 0;
}
break;
}
case T_RBRACE: {
if (topState.type == block_open && previousState.type == case_cont) {
*indentDepth = topState.savedIndentDepth;
*paddingDepth = topState.savedPaddingDepth;
break;
}
for (int i = 0; state(i).type != topmost_intro; ++i) {
const int type = state(i).type;
if (type == class_open
|| type == enum_open
|| type == defun_open) {
*indentDepth = state(i).savedIndentDepth;
if (m_indentDeclarationBraces)
*indentDepth += m_indentSize;
*paddingDepth = state(i).savedPaddingDepth;
break;
} else if (type == substatement_open
|| type == brace_list_open
|| type == block_open) {
*indentDepth = state(i).savedIndentDepth;
*paddingDepth = state(i).savedPaddingDepth;
break;
}
}
break;
}
// Disabled for now, see QTCREATORBUG-1825. It makes extending if conditions
// awkward: inserting a newline just before the ) shouldn't align to 'if'.
//case T_RPAREN:
// if (topState.type == condition_open) {
// *indentDepth = previousState.savedIndentDepth;
// }
// break;
case T_CASE: {
int lastSubstatementIndent = 0;
for (int i = 0; state(i).type != topmost_intro; ++i) {
const int type = state(i).type;
if (type == substatement_open) {
lastSubstatementIndent = state(i).savedIndentDepth;
} else if (type == switch_statement) {
*indentDepth = lastSubstatementIndent;
break;
} else if (type == case_cont) {
*indentDepth = state(i).savedIndentDepth;
break;
} else if (type == topmost_intro) {
break;
}
}
break;
case T_PUBLIC:
case T_PRIVATE:
case T_PROTECTED:
case T_Q_SIGNALS:
if (topState.type == class_open) {
if (tokenAt(1).is(T_COLON) || tokenAt(2).is(T_COLON))
*indentDepth = topState.savedIndentDepth;
}
break;
case T_ELSE:
if (topWasMaybeElse)
*indentDepth = state().savedIndentDepth; // topSavedIndent is actually the previous
break;
case T_LESS_LESS:
case T_GREATER_GREATER:
if (topState.type == stream_op || topState.type == stream_op_cont) {
if (*paddingDepth >= 3)
*paddingDepth -= 3; // to align << with <<
else
*paddingDepth = 0;
}
break;
case T_COMMENT:
case T_DOXY_COMMENT:
case T_CPP_COMMENT:
case T_CPP_DOXY_COMMENT:
// unindent the last line of a comment
if ((topState.type == multiline_comment_cont
|| topState.type == multiline_comment_start)
&& (kind == T_COMMENT || kind == T_DOXY_COMMENT)
&& (lexerState == Lexer::State_Default
|| tokens.size() != 1)) {
if (*indentDepth >= m_indentSize)
*indentDepth -= m_indentSize;
else
*indentDepth = 0;
case T_IDENTIFIER:
if (topState.type == substatement
|| topState.type == substatement_open
|| topState.type == case_cont
|| topState.type == block_open
|| topState.type == defun_open) {
if (tokens.size() > 1 && tokens.at(1).kind() == T_COLON) // label?
*indentDepth = 0;
}
break;
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
bool QtStyleCodeFormatter::shouldClearPaddingOnEnter(int state)
{
switch (state) {
case defun_open:
case class_start:
case class_open:
case enum_start:
case enum_open:
case namespace_start:
case namespace_open:
case template_start:
case if_statement:
case else_clause:
case for_statement:
case switch_statement:
case statement_with_condition:
case do_statement:
case return_statement:
case block_open:
case substatement_open:
case substatement:
return true;
}
return false;
}