diff options
author | Christian Kamm <christian.d.kamm@nokia.com> | 2011-09-07 13:30:48 +0200 |
---|---|---|
committer | Christian Kamm <christian.d.kamm@nokia.com> | 2011-09-14 11:02:45 +0200 |
commit | 16b4a6fe733b9973311ae19c6ecc90b1a6c53f36 (patch) | |
tree | bcc70f823600c6aef5a820cff6df3e6af44701db /src | |
parent | bbc48690e85adbe5ea8a5ffe14d5ba26fc7a3b7c (diff) | |
download | qt-creator-16b4a6fe733b9973311ae19c6ecc90b1a6c53f36.tar.gz |
QmlJS indenter: Fix labelled statements and break/continue with label.
Also do some cleanup to make handling of substatements nicer.
Change-Id: I78773fc81d9b0058fa97c5cef393cca34b7fd885
Reviewed-on: http://codereview.qt-project.org/4413
Reviewed-by: Thomas Hartmann <Thomas.Hartmann@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/qmljs/qmljscodeformatter.cpp | 34 | ||||
-rw-r--r-- | src/libs/qmljs/qmljscodeformatter.h | 5 | ||||
-rw-r--r-- | src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp | 50 |
3 files changed, 72 insertions, 17 deletions
diff --git a/src/libs/qmljs/qmljscodeformatter.cpp b/src/libs/qmljs/qmljscodeformatter.cpp index eb7e61642d..b02075e4f8 100644 --- a/src/libs/qmljs/qmljscodeformatter.cpp +++ b/src/libs/qmljs/qmljscodeformatter.cpp @@ -252,6 +252,12 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block) default: enter(expression); continue; // really? identifier and more tokens might already be gone } break; + case expression_or_label: + switch (kind) { + case Colon: turnInto(labelled_statement); break; + default: enter(expression); continue; + } break; + case expression: if (tryInsideExpression()) break; @@ -346,6 +352,12 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block) case RightBrace: leave(true); break; } break; + case labelled_statement: + if (tryStatement()) + break; + leave(true); // error recovery + break; + case substatement: // prefer substatement_open over block_open if (kind != LeftBrace) { @@ -426,7 +438,11 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block) case RightParenthesis: leave(); leave(true); break; } break; - break; + case breakcontinue_statement: + switch (kind) { + case Identifier: leave(true); break; + default: leave(true); continue; // try again + } break; case case_start: switch (kind) { @@ -466,11 +482,22 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block) int topState = m_currentState.top().type; + // if there's no colon on the same line, it's not a label + if (topState == expression_or_label) + enter(expression); + // if not followed by an identifier on the same line, it's done + else if (topState == breakcontinue_statement) + leave(true); + + topState = m_currentState.top().type; + + // some states might be continued on the next line if (topState == expression || topState == expression_or_objectdefinition || topState == objectliteral_assignment) { enter(expression_maybe_continuation); } + // multi-line comment start? if (topState != multiline_comment_start && topState != multiline_comment_cont && (lexerState & Scanner::MultiLineMask) == Scanner::MultiLineComment) { @@ -680,7 +707,6 @@ bool CodeFormatter::tryStatement() case Break: case Continue: enter(breakcontinue_statement); - leave(true); return true; case Throw: enter(throw_statement); @@ -717,7 +743,10 @@ bool CodeFormatter::tryStatement() enter(jsblock_open); return true; case Identifier: + enter(expression_or_label); + return true; case Delimiter: + case Var: case PlusPlus: case MinusMinus: case Import: @@ -755,7 +784,6 @@ bool CodeFormatter::isExpressionEndState(int type) const type == objectdefinition_open || type == if_statement || type == else_clause || - type == do_statement || type == jsblock_open || type == substatement_open || type == bracket_open || diff --git a/src/libs/qmljs/qmljscodeformatter.h b/src/libs/qmljs/qmljscodeformatter.h index bd2e9228d5..4a1f372a6d 100644 --- a/src/libs/qmljs/qmljscodeformatter.h +++ b/src/libs/qmljs/qmljscodeformatter.h @@ -133,6 +133,7 @@ public: // must be public to make Q_GADGET introspection work expression_continuation, // at the end of the line, when the next line definitely is a continuation expression_maybe_continuation, // at the end of the line, when the next line may be an expression expression_or_objectdefinition, // after a binding starting with an identifier ("x: foo") + expression_or_label, // when expecting a statement and getting an identifier paren_open, // opening ( in expression bracket_open, // opening [ in expression @@ -148,7 +149,7 @@ public: // must be public to make Q_GADGET introspection work jsblock_open, empty_statement, // for a ';', will be popped directly - breakcontinue_statement, // for continue/break, will be popped directly + breakcontinue_statement, // for continue/break, may be followed by identifier if_statement, // After 'if' maybe_else, // after the first substatement in an if @@ -160,6 +161,8 @@ public: // must be public to make Q_GADGET introspection work substatement, // The first line after a conditional or loop construct. substatement_open, // The brace that opens a substatement block. + labelled_statement, // after a label + return_statement, // After 'return' throw_statement, // After 'throw' diff --git a/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp b/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp index a85a25685e..4b809d89ee 100644 --- a/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp +++ b/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp @@ -128,15 +128,29 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd *indentDepth = tokenPosition; break; + case expression_or_label: + if (*indentDepth == tokenPosition) + *indentDepth += 2*m_indentSize; + else + *indentDepth = tokenPosition; + break; + case expression: - // expression_or_objectdefinition has already consumed the first token - // ternary already adjusts indents nicely - if (parentState.type != expression_or_objectdefinition - && parentState.type != binding_assignment - && parentState.type != ternary_op) { - *indentDepth += 2 * m_indentSize; + if (*indentDepth == tokenPosition) { + // expression_or_objectdefinition doesn't want the indent + // expression_or_label already has it + // ternary already adjusts indents nicely + if (parentState.type != expression_or_objectdefinition + && parentState.type != expression_or_label + && parentState.type != binding_assignment + && parentState.type != ternary_op) { + *indentDepth += 2*m_indentSize; + } } - if (!firstToken && parentState.type != expression_or_objectdefinition) { + // expression_or_objectdefinition and expression_or_label have already consumed the first token + else if (parentState.type != expression_or_objectdefinition + && parentState.type != expression_or_label + && parentState.type != ternary_op) { *indentDepth = tokenPosition; } break; @@ -204,11 +218,18 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd *indentDepth = *savedIndentDepth + m_indentSize; break; + case substatement: + *indentDepth += m_indentSize; + break; + case objectliteral_open: if (parentState.type == expression || parentState.type == objectliteral_assignment) { // undo the continuation indent of the expression - *indentDepth = parentState.savedIndentDepth; + if (state(1).type == expression_or_label) + *indentDepth = state(1).savedIndentDepth; + else + *indentDepth = parentState.savedIndentDepth; *savedIndentDepth = *indentDepth; } *indentDepth += m_indentSize; @@ -224,6 +245,14 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd *savedIndentDepth = tokenPosition; // ### continuation *indentDepth = *savedIndentDepth; // + 2*m_indentSize; + // special case for 'else if' + if (!firstToken + && newState == if_statement + && parentState.type == substatement + && state(1).type == else_clause) { + *indentDepth = state(1).savedIndentDepth; + *savedIndentDepth = *indentDepth; + } break; case maybe_else: { @@ -270,11 +299,6 @@ void QtStyleCodeFormatter::adjustIndent(const QList<Token> &tokens, int lexerSta State topState = state(); State previousState = state(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) { |