Newer
Older
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
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 int tokenPosition = column(tk.begin());
const bool firstToken = (tokenIndex() == 0);
const bool lastToken = (tokenIndex() == tokenCount() - 1);
int nextTokenStart = 0;
if (!lastToken)
nextTokenStart = column(tokenAt(tokenIndex() + 1).begin());
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 = tokenPosition-*indentDepth + tk.length();
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 = tokenPosition-*indentDepth + 1;
*paddingDepth += m_indentSize;
break;
case ternary_op:
if (!lastToken)
*paddingDepth = tokenPosition-*indentDepth + tk.length() + 1;
*paddingDepth += m_indentSize;
break;
case stream_op:
*paddingDepth = tokenPosition-*indentDepth + tk.length() + 1;
case stream_op_cont:
if (firstToken)
*savedPaddingDepth = *paddingDepth = tokenPosition-*indentDepth + tk.length() + 1;
// 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 = column(tokenAt(tokenIndex() + 1).begin()) - *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 = nextTokenStart-*indentDepth;
} else {
// avoid existing continuation indents
if (parentState.type == initializer)
*savedPaddingDepth = state(1).savedPaddingDepth;
*paddingDepth = *savedPaddingDepth + m_indentSize;
break;
case block_open:
if (parentState.type != case_cont)
*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 (tokenPosition <= *indentDepth + m_indentSize)
*paddingDepth = 2*m_indentSize;
*paddingDepth = tokenPosition-*indentDepth + 1;
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 = tokenPosition + 1 - *indentDepth;
break;
case multiline_comment_start:
*indentDepth = tokenPosition + 2;
break;
case multiline_comment_cont:
*indentDepth = tokenPosition;
break;
case cpp_macro:
case cpp_macro_cont:
*indentDepth = m_indentSize;
break;
}
}
void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, int lexerState, int *indentDepth, int *paddingDepth) const
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
{
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) {
*paddingDepth -= 2;
}
break;
case T_LBRACE: {
if (topState.type == case_cont) {
*indentDepth = topState.savedIndentDepth;
*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 = previousState.savedIndentDepth;
*paddingDepth = previousState.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;
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
case T_DEFAULT:
case T_CASE:
for (int i = 0; state(i).type != topmost_intro; ++i) {
const int type = state(i).type;
if (type == switch_statement || 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)
*paddingDepth -= 3; // to align << with <<
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)) {
*indentDepth -= m_indentSize;
}
break;
}
}
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
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;
}