diff options
Diffstat (limited to 'lib/Format')
-rw-r--r-- | lib/Format/ContinuationIndenter.cpp | 4 | ||||
-rw-r--r-- | lib/Format/TokenAnnotator.cpp | 12 | ||||
-rw-r--r-- | lib/Format/WhitespaceManager.cpp | 60 |
3 files changed, 61 insertions, 15 deletions
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp index ae1af753bf46..387923031f85 100644 --- a/lib/Format/ContinuationIndenter.cpp +++ b/lib/Format/ContinuationIndenter.cpp @@ -1036,8 +1036,8 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State, State.Stack.back().NestedBlockIndent); if (Current.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare)) { if (Current.opensBlockOrBlockTypeList(Style)) { - NewIndent = State.Stack.back().NestedBlockIndent + Style.IndentWidth; - NewIndent = std::min(State.Column + 2, NewIndent); + NewIndent = Style.IndentWidth + + std::min(State.Column, State.Stack.back().NestedBlockIndent); } else { NewIndent = State.Stack.back().LastSpace + Style.ContinuationIndentWidth; } diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index 2af931cdf1ba..7ce699cf14a1 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -135,8 +135,11 @@ private: if (Left->is(TT_OverloadedOperatorLParen)) { Contexts.back().IsExpression = false; } else if (Style.Language == FormatStyle::LK_JavaScript && - Line.startsWith(Keywords.kw_type, tok::identifier)) { + (Line.startsWith(Keywords.kw_type, tok::identifier) || + Line.startsWith(tok::kw_export, Keywords.kw_type, + tok::identifier))) { // type X = (...); + // export type X = (...); Contexts.back().IsExpression = false; } else if (Left->Previous && (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype, @@ -979,9 +982,12 @@ private: void modifyContext(const FormatToken &Current) { if (Current.getPrecedence() == prec::Assignment && !Line.First->isOneOf(tok::kw_template, tok::kw_using, tok::kw_return) && - // Type aliases use `type X = ...;` in TypeScript. + // Type aliases use `type X = ...;` in TypeScript and can be exported + // using `export type ...`. !(Style.Language == FormatStyle::LK_JavaScript && - Line.startsWith(Keywords.kw_type, tok::identifier)) && + (Line.startsWith(Keywords.kw_type, tok::identifier) || + Line.startsWith(tok::kw_export, Keywords.kw_type, + tok::identifier))) && (!Current.Previous || Current.Previous->isNot(tok::kw_operator))) { Contexts.back().IsExpression = true; if (!Line.startsWith(TT_UnaryOperator)) { diff --git a/lib/Format/WhitespaceManager.cpp b/lib/Format/WhitespaceManager.cpp index 3b6311d15487..4b4fd13145fb 100644 --- a/lib/Format/WhitespaceManager.cpp +++ b/lib/Format/WhitespaceManager.cpp @@ -100,18 +100,56 @@ void WhitespaceManager::calculateLineBreakInformation() { Changes[0].PreviousEndOfTokenColumn = 0; Change *LastOutsideTokenChange = &Changes[0]; for (unsigned i = 1, e = Changes.size(); i != e; ++i) { - unsigned OriginalWhitespaceStart = - SourceMgr.getFileOffset(Changes[i].OriginalWhitespaceRange.getBegin()); - unsigned PreviousOriginalWhitespaceEnd = SourceMgr.getFileOffset( - Changes[i - 1].OriginalWhitespaceRange.getEnd()); - Changes[i - 1].TokenLength = OriginalWhitespaceStart - - PreviousOriginalWhitespaceEnd + - Changes[i].PreviousLinePostfix.size() + - Changes[i - 1].CurrentLinePrefix.size(); + SourceLocation OriginalWhitespaceStart = + Changes[i].OriginalWhitespaceRange.getBegin(); + SourceLocation PreviousOriginalWhitespaceEnd = + Changes[i - 1].OriginalWhitespaceRange.getEnd(); + unsigned OriginalWhitespaceStartOffset = + SourceMgr.getFileOffset(OriginalWhitespaceStart); + unsigned PreviousOriginalWhitespaceEndOffset = + SourceMgr.getFileOffset(PreviousOriginalWhitespaceEnd); + assert(PreviousOriginalWhitespaceEndOffset <= + OriginalWhitespaceStartOffset); + const char *const PreviousOriginalWhitespaceEndData = + SourceMgr.getCharacterData(PreviousOriginalWhitespaceEnd); + StringRef Text(PreviousOriginalWhitespaceEndData, + SourceMgr.getCharacterData(OriginalWhitespaceStart) - + PreviousOriginalWhitespaceEndData); + // Usually consecutive changes would occur in consecutive tokens. This is + // not the case however when analyzing some preprocessor runs of the + // annotated lines. For example, in this code: + // + // #if A // line 1 + // int i = 1; + // #else B // line 2 + // int i = 2; + // #endif // line 3 + // + // one of the runs will produce the sequence of lines marked with line 1, 2 + // and 3. So the two consecutive whitespace changes just before '// line 2' + // and before '#endif // line 3' span multiple lines and tokens: + // + // #else B{change X}[// line 2 + // int i = 2; + // ]{change Y}#endif // line 3 + // + // For this reason, if the text between consecutive changes spans multiple + // newlines, the token length must be adjusted to the end of the original + // line of the token. + auto NewlinePos = Text.find_first_of('\n'); + if (NewlinePos == StringRef::npos) { + Changes[i - 1].TokenLength = OriginalWhitespaceStartOffset - + PreviousOriginalWhitespaceEndOffset + + Changes[i].PreviousLinePostfix.size() + + Changes[i - 1].CurrentLinePrefix.size(); + } else { + Changes[i - 1].TokenLength = + NewlinePos + Changes[i - 1].CurrentLinePrefix.size(); + } // If there are multiple changes in this token, sum up all the changes until // the end of the line. - if (Changes[i - 1].IsInsideToken) + if (Changes[i - 1].IsInsideToken && Changes[i - 1].NewlinesBefore == 0) LastOutsideTokenChange->TokenLength += Changes[i - 1].TokenLength + Changes[i - 1].Spaces; else @@ -434,7 +472,9 @@ void WhitespaceManager::alignTrailingComments() { continue; unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn; - unsigned ChangeMaxColumn = Style.ColumnLimit - Changes[i].TokenLength; + unsigned ChangeMaxColumn = Style.ColumnLimit >= Changes[i].TokenLength + ? Style.ColumnLimit - Changes[i].TokenLength + : ChangeMinColumn; // If we don't create a replacement for this change, we have to consider // it to be immovable. |