The problem was that the LevelIndentTracker remembered
the indentation level of previous deeper levels when
leaving a scope. Afterwards, when it entered again a
deeper level, it blindly reused the previous
indentation level. In case the --lines option was used
such that the previous deeper level was not formatted,
that previous level was whatever happened to be there
in the source code. The formatter simply believed it.
This is fixed by letting the LevelIndentTracker forget
the previous deeper levels when stepping out of them
(=> change in LevelIndentTracker::nextLine()).
Note that this used to be the case until LLVM 14.0.6,
but was changed in https://reviews.llvm.org/D129064
(#56352) to fix a crash. Our commit here essentially
reverts that crash fix. It was incorrect/incomplete.
Fixes#58464.
Fixes#59178.
Fixes#62799.
Differential Revision: https://reviews.llvm.org/D151047
adjustToUnmodifiedLine: The code does something only for non-PP-directives.
This is now reflected by putting the if-check to the top. This also ensures
that the assert() there is executed only if IndentForLevel is actually
accessed.
getIndent(): assert valid index into IndentForLevel.
Added explanation regarding the intention of IndentForLevel.
Differential Revision: https://reviews.llvm.org/D155094
If the first token of an annotated line already has a computed Newlines,
reuse it to avoid potential overlapping whitespace replacements before
preprocessor branching directives.
Fixes#62892.
Differential Revision: https://reviews.llvm.org/D151954
After https://reviews.llvm.org/D151954 we've noticed some issues w/
clang-format behavior, as outlined in
https://github.com/llvm/llvm-project/issues/63170.
Valid C/C++ files, that were previously accepted, are now rejected by
clang-format, emitting the message:
"The new replacement overlaps with an existing replacement."
This reverts commit 4b9764959dc4b8783e18747c1742ab164e4bc4ee and
d2627cf88d2553a4c2e850430bdb908a4b7d2e52, which depends on it.
Reviewed By: phosek
Differential Revision: https://reviews.llvm.org/D152473
This reverts commit 4b9764959dc4b8783e18747c1742ab164e4bc4ee.
Reverting since this causes clang-formtat to incorrectly fall into an
error path yet return a zero exit code despite not formatting the file
at all.
See https://github.com/llvm/llvm-project/issues/63170
Adds an option KeepEmptyLinesAtEOF to keep empty lines (up to
MaxEmptyLinesToKeep) before EOF. This remedies the probably unintentional
change in behavior introduced in 3d3ea84a4f8f, which started to always
remove empty lines before EOF.
Fixes#56054.
Fixes#63150.
Differential Revision: https://reviews.llvm.org/D152305
If the first token of an annotated line is finalized, reuse its
NewlinesBefore value to avoid potential overlapping whitespace
replacements before preprocessor branching directives.
Fixes#62892.
Differential Revision: https://reviews.llvm.org/D151954
The problem was that the LevelIndentTracker remembered
the indentation level of previous deeper levels when
leaving a scope. Afterwards, when it entered again a
deeper level, it blindly reused the the previous
indentation level. In case of the --lines option
configured such that the previous deeper level was not
formatted, that previous level was whatever happened
to be there in the source code. The formatter simply
believed it.
This is fixed by letting the LevelIndentTracker forget
the previous deeper levels when stepping out of them
(=> change in LevelIndentTracker::nextLine()).
Note that this used to be the case until LLVM 14.0.6,
but was changed in
https://github.com/llvm/llvm-project/issues/56352 to
fix a crash. Our commit here essentially reverts that
crash fix. It seemed to have been incorrect. The proper
fix is to set the AnnotedLine::Level of joined lines
correctly (=> change in LineJoiner::join()).
See
https://github.com/llvm/llvm-project/issues/59178#issuecomment-1542637781
for some more details.
Fixes#58464.
Fixes#59178.
Differential Revision: https://reviews.llvm.org/D151047
When in ColumnLimit 0, the formatter looks for MustBreakBefore in the
line in order to check if a line is allowed to be merged onto one line.
However, since MustBreakBefore is really a property of the gap between
the token and the one previously, I belive the check is erroneous in
checking all the tokens in a line, since whether the previous line ended
with a forced line break should have no effect on whether the current
line is allowed to merge with the next one.
This patch changes the check to skip the first token in
`LineJoiner.containsMustBreak`.
This patch also changes a test, which is not ideal, but I believe the
test also suffered from this bug. The test case in question sets
AllowShortFunctionsOnASingleLine to "Empty", but the empty function in
said test case isn't merged to a single line, because of the very same
bug this patch fixes.
Fixes https://github.com/llvm/llvm-project/issues/62721
Reviewed By: HazardyKnusperkeks, owenpan, MyDeveloperDay
Differential Revision: https://reviews.llvm.org/D150614
The previous version set the indentation directly using IndentForLevel,
however, this has a few caveats, namely:
* IndentForLevel applies to all scopes of the entire program being
formatted, but this indentation should only be adjusted for scopes
of namespaces.
* The method it used only set the correct indent amount if one wasn't
already set for a given level, meaning it didn't work correctly if
anything with indentation preceded a namespace keyword. This
includes preprocessing directives if using IndentPPDirectives.
This patch instead reduces the Level of all lines within namespaces
which are compacted by CompactNamespaces. This means they will get
correct indentation using the normal process.
Fixes https://github.com/llvm/llvm-project/issues/60843
Reviewed By: owenpan, MyDeveloperDay, HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D144296
Add configuration to specify macros.
Macros will be expanded, and the code will be parsed and annotated
in the expanded state. In a second step, the formatting decisions
in the annotated expanded code will be reconstructed onto the
original unexpanded macro call.
Eventually, this will allow to remove special-case code for
various macro options we accumulated over the years in favor of
one principled mechanism.
Differential Revision: https://reviews.llvm.org/D144170
For example, use 'Next' instead of 'Next != nullptr',
and '!Next' instead of 'Next == nullptr'.
Differential Revision: https://reviews.llvm.org/D144355
This solves the issue where a case statement inside a macro greedily
adds preprocessor lines such as #include to the macro even if they
are not a part of the macro to begin with.
Fixes#58214.
Differential Revision: https://reviews.llvm.org/D135422
When the opening brace of a control statement block is wrapped, we
must check the previous line to determine whether to try to merge
the block.
Fixes#38639.
Fixes#48007.
Fixes#57421.
Differential Revision: https://reviews.llvm.org/D133093
Now things inside hierarchies like modules and interfaces are
indented. When the module header spans multiple lines, all except the
first line are indented as continuations. We added the property
`IsContinuation` to mark lines that should be indented this way.
In order that the colons inside square brackets don't get labeled as
`TT_ObjCMethodExpr`, we added a check to only use this type when the
language is not Verilog.
Differential Revision: https://reviews.llvm.org/D128712
With D117142, we would now format
```
struct A {
#define A
void f() { a(); }
#endif
};
```
into
```
struct A {
#ifdef A
void f() {
a();
}
#endif
};
```
because we were looking for the record lbrace without skipping preprocess lines.
Fixes https://github.com/llvm/llvm-project/issues/54901.
Reviewed By: curdeius, owenpan
Differential Revision: https://reviews.llvm.org/D123737
[clang-format] Indent import statements in JavaScript.
Take for example this piece of code found at
<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import>.
```
for (const link of document.querySelectorAll("nav > a")) {
link.addEventListener("click", e => {
e.preventDefault();
import('/modules/my-module.js')
.then(module => {
module.loadPageInto(main);
})
.catch(err => {
main.textContent = err.message;
});
});
}
```
Previously the import line would be unindented, looking like this.
```
for (const link of document.querySelectorAll("nav > a")) {
link.addEventListener("click", e => {
e.preventDefault();
import('/modules/my-module.js')
.then(module => {
module.loadPageInto(main);
})
.catch(err => {
main.textContent = err.message;
});
});
}
```
Actually we were going to fix this along with fixing Verilog import
statements. But the patch got too big.
Reviewed By: MyDeveloperDay, curdeius
Differential Revision: https://reviews.llvm.org/D121906
Fixes https://github.com/llvm/llvm-project/issues/54147.
When handling `AllowShortFunctionsOnASingleLine`, we were searching for the last line with a smaller level than the current line. The search was incorrect when the first line had the same level as the current one. This led to an unsatisfied assumption about the existence of a brace (non-comment token).
Reviewed By: HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D120902
Fixes https://github.com/llvm/llvm-project/issues/24781.
Fixes https://github.com/llvm/llvm-project/issues/38160.
This patch splits `TT_RecordLBrace` for classes/enums/structs/unions (and other records, e.g. interfaces) and uses the brace type to avoid the error-prone scanning for record token.
The mentioned bugs were provoked by the scanning being too limited (and so not considering `const` or `constexpr`, or other qualifiers, on an anonymous struct variable declaration).
Moreover, the proposed solution is more efficient as we parse tokens once only (scanning being parsing too).
Reviewed By: MyDeveloperDay, HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D119785
Fixes https://github.com/llvm/llvm-project/issues/53758.
Braces in loops and in `if` statements with leading (block) comments were formatted according to `BraceWrapping.AfterFunction` and not `AllowShortBlocksOnASingleLine`/`AllowShortLoopsOnASingleLine`/`AllowShortIfStatementsOnASingleLine`.
Previously, the code:
```
while (true) {
f();
}
/*comment*/ while (true) {
f();
}
```
was incorrectly formatted to:
```
while (true) {
f();
}
/*comment*/ while (true) { f(); }
```
when using config:
```
BasedOnStyle: LLVM
BreakBeforeBraces: Custom
BraceWrapping:
AfterFunction: false
AllowShortBlocksOnASingleLine: false
AllowShortLoopsOnASingleLine: false
```
and it was (correctly but by chance) formatted to:
```
while (true) {
f();
}
/*comment*/ while (true) {
f();
}
```
when using enabling brace wrapping after functions:
```
BasedOnStyle: LLVM
BreakBeforeBraces: Custom
BraceWrapping:
AfterFunction: true
AllowShortBlocksOnASingleLine: false
AllowShortLoopsOnASingleLine: false
```
Reviewed By: MyDeveloperDay, HazardyKnusperkeks, owenpan
Differential Revision: https://reviews.llvm.org/D119649
* Give I[1] and I[-1] a name:
- Easier to understand
- Easier to debug (since you don't go through operator[] everytime)
* TheLine->First != TheLine->Last follows since last is a l brace and
first isn't.
* Factor the check for is(tok::l_brace) out.
* Drop else after return.
Differential Revision: https://reviews.llvm.org/D115060
Fixes https://github.com/llvm/llvm-project/issues/53430.
Initially, I had a quick and dirty approach, but it led to a myriad of special cases handling comments (that may add unwrapped lines).
So I added TT_RecordLBrace type annotations and it seems like a much nicer solution.
I think that in the future it will allow us to clean up some convoluted code that detects records.
Reviewed By: MyDeveloperDay, HazardyKnusperkeks
Differential Revision: https://reviews.llvm.org/D118337