aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Format/ContinuationIndenter.cpp
diff options
context:
space:
mode:
authorGedare Bloom <gedare@rtems.org>2024-07-24 20:47:11 -0600
committerGitHub <noreply@github.com>2024-07-24 19:47:11 -0700
commitccae7b461be339e717d02f99ac857cf0bc7d17fc (patch)
tree6f3cf4629836a7fd4814b33db06f7e49febb7e9f /clang/lib/Format/ContinuationIndenter.cpp
parent7e7a9069d4240d2ae619cb50eba09f948c537ce3 (diff)
downloadllvm-ccae7b461be339e717d02f99ac857cf0bc7d17fc.zip
llvm-ccae7b461be339e717d02f99ac857cf0bc7d17fc.tar.gz
llvm-ccae7b461be339e717d02f99ac857cf0bc7d17fc.tar.bz2
[clang-format] Improve BlockIndent at ColumnLimit (#93140)
Fixes #55731 The reported formatting problems were related to ignoring deep nesting of "simple" functions (causing #54808) and to allowing the trailing annotation to become separated from the closing parens, which allowed a break to occur between the closing parens and the trailing annotation. The fix for the nesting of "simple" functions is to detect them more carefully. "Simple" was defined in a comment as being a single non-expression argument. I tried to stay as close to the original intent of the implementation while fixing the various bad formatting reports. In the process of fixing these bugs, some latent bugs were discovered related to how JavaScript Template Strings are handled. Those are also fixed here. --------- Co-authored-by: Owen Pan <owenpiano@gmail.com>
Diffstat (limited to 'clang/lib/Format/ContinuationIndenter.cpp')
-rw-r--r--clang/lib/Format/ContinuationIndenter.cpp38
1 files changed, 35 insertions, 3 deletions
diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp
index b073604..df86a77 100644
--- a/clang/lib/Format/ContinuationIndenter.cpp
+++ b/clang/lib/Format/ContinuationIndenter.cpp
@@ -803,6 +803,37 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
return !Tok.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while,
tok::kw_switch);
};
+ auto IsFunctionCallParen = [](const FormatToken &Tok) {
+ return Tok.is(tok::l_paren) && Tok.ParameterCount > 0 && Tok.Previous &&
+ Tok.Previous->is(tok::identifier);
+ };
+ const auto IsInTemplateString = [this](const FormatToken &Tok) {
+ if (!Style.isJavaScript())
+ return false;
+ for (const auto *Prev = &Tok; Prev; Prev = Prev->Previous) {
+ if (Prev->is(TT_TemplateString) && Prev->opensScope())
+ return true;
+ if (Prev->is(TT_TemplateString) && Prev->closesScope())
+ break;
+ }
+ return false;
+ };
+ // Identifies simple (no expression) one-argument function calls.
+ const auto IsSimpleFunction = [&](const FormatToken &Tok) {
+ if (!Tok.FakeLParens.empty() && Tok.FakeLParens.back() > prec::Unknown)
+ return false;
+ const auto *Previous = Tok.Previous;
+ if (!Previous || (!Previous->isOneOf(TT_FunctionDeclarationLParen,
+ TT_LambdaDefinitionLParen) &&
+ !IsFunctionCallParen(*Previous))) {
+ return true;
+ }
+ if (IsOpeningBracket(Tok) || IsInTemplateString(Tok))
+ return true;
+ const auto *Next = Tok.Next;
+ return !Next || Next->isMemberAccess() ||
+ Next->is(TT_FunctionDeclarationLParen) || IsFunctionCallParen(*Next);
+ };
if ((Style.AlignAfterOpenBracket == FormatStyle::BAS_AlwaysBreak ||
Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) &&
IsOpeningBracket(Previous) && State.Column > getNewLineColumn(State) &&
@@ -813,10 +844,10 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
// caaaaaaaaaaaall(
// caaaaaaaaaaaall(
// caaaaaaaaaaaaaaaaaaaaaaall(aaaaaaaaaaaaaa, aaaaaaaaa))));
- Current.FakeLParens.size() > 0 &&
- Current.FakeLParens.back() > prec::Unknown) {
+ !IsSimpleFunction(Current)) {
CurrentState.NoLineBreak = true;
}
+
if (Previous.is(TT_TemplateString) && Previous.opensScope())
CurrentState.NoLineBreak = true;
@@ -831,7 +862,8 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
Previous.isNot(TT_TableGenDAGArgOpenerToBreak) &&
!(Current.MacroParent && Previous.MacroParent) &&
(Current.isNot(TT_LineComment) ||
- Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen))) {
+ Previous.isOneOf(BK_BracedInit, TT_VerilogMultiLineListLParen)) &&
+ !IsInTemplateString(Current)) {
CurrentState.Indent = State.Column + Spaces;
CurrentState.IsAligned = true;
}