Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 12, 2025

Fix indentation of if statement after else on a separate line [WIP]

Problem

When an if statement appears on a different line from an else keyword, it should be indented like any other embedded statement, but currently it is not indented at all.

Root Cause

The issue has two parts:

  1. In IndentBlockFormattingRule.cs, the AddEmbeddedStatementsIndentationOperation method excludes all IfStatementSyntax from indentation when they are the statement of an ElseClauseSyntax, regardless of whether they are on the same line or different lines.
  2. In AnchorIndentationFormattingRule.cs, an anchor indentation operation is added for ALL StatementSyntax nodes (including IfStatementSyntax), which preserves the relative position of the if keyword and prevents it from being indented.

Changes Made

  • Understand the issue and locate the problematic code
  • Modified IndentBlockFormattingRule.cs to check if the if token is on the same line as the else token
  • If on the same line: skip indentation (existing behavior for else if)
  • If on different lines: add indent operation directly
  • Modified AnchorIndentationFormattingRule.cs to skip adding anchor operation for IfStatementSyntax when it's on a separate line from its else keyword
  • Added test FormatElseIfOnSeparateLines to validate the fix for separate lines
  • Added test FormatElseIfOnSameLineWithExtraSpaces to validate spacing normalization for same-line case
  • Added test FormatElseReturnOnSeparateLines (by @CyrusNajmabadi) to confirm indent mechanism works for other statement types
  • Updated WorkItem links to reference the correct issue if block not indented after else #16328
  • BLOCKED: Test for separate lines is still failing - investigating why anchor operation skip isn't working
  • Build and test the changes successfully
  • Run code review
  • Run codeql security check

Current Status

Test Results:

  • FormatElseIfOnSameLineWithExtraSpaces - PASSES: When else if (with extra spaces) is on the same line, it correctly formats to else if with a single space
  • FormatElseReturnOnSeparateLines - PASSES: Confirms indent mechanism works for other statement types (e.g., return)
  • FormatElseIfOnSeparateLines - FAILS: When else and if are on different lines, the if is not being indented

Investigation:
Found that AnchorIndentationFormattingRule adds an anchor operation for all statements (line 51-53), which preserves the relative position of the if keyword and prevents indentation. Added code to skip the anchor operation when there's a newline between else and if, but the test still fails. The logic appears correct but may not be executing as expected or there may be another source of anchor operations.

<issue_title>if block not indented after else</issue_title>

Version Used: 2.0.0.61213

if (true) { }
else
if (false) { }

should be auto-formatted (after typing } or explicitly formatting document) as

if (true) { }
else
    if (false) { }
Original prompt

This section details on the original issue you should resolve

<issue_title>if block not indented after else</issue_title>
<issue_description>Version Used: 2.0.0.61213

if (true) { }
else
if (false) { }

should be auto-formatted (after typing } or explicitly formatting document) as

if (true) { }
else
    if (false) { }
```</issue_description>

<agent_instructions>@copilot see if you can figure out where this is happening.  The rule should be this.  If 'if' is on the same line as the preceding 'else', then we should force a single space between them.  If it's not on the same line, it should be like any embedded statement in the 'else' and should be indented one level.

presumably we're just checking if the 'else' has an embedded 'if' and just bailing out, instead of handling the individual cases smartly.</agent_instructions>

## Comments on the Issue (you are @copilot in this section)

<comments>
<comment_new><author>@Pilchie</author><body>
Interesting.  We don't touch the indentation of the `if` at all, no matter where it is.

Related to https://github.com/dotnet/roslyn/issues/12315</body></comment_new>
</comments>

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix indentation for if block after else Fix indentation of if statement after else on separate line Nov 12, 2025
Copilot AI requested a review from CyrusNajmabadi November 12, 2025 12:39
Copilot finished work on behalf of CyrusNajmabadi November 12, 2025 12:39
if (false) { }
}
}
""");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot add a test that demonstrates that if we start with else if ... (where the else/if are on the same line) that the if is moved one space after the else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added test FormatElseIfOnSameLineWithExtraSpaces that verifies when else if (with multiple spaces) is on the same line, it formats to else if with a single space. The test passes. (ceaa90b)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Your fix doesn't seem to have worked. I have debugged through it and i can see that it is appropriate getting hit and appropriately calling AddEmbeddedStatementsIndentationOperation(list, elseClause.Statement);. However, we still don't actually see the if-statement get indented.

I've added another test that shows that this does work properly with another statement kind (like a 'return statement'). Figure out what other code there must be somewhere in the formatting engine that is causing us to still not move the 'if' statement. Perhaps it's some sort of suppression. Or something else entirely. It's very strange.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've traced through the code and confirmed the indent operation is being added via AddIndentBlockOperation(list, firstToken, lastToken, TextSpan.FromBounds(...)). The return statement test passes, confirming the mechanism works for other statement types.

For IfStatementSyntax specifically, I suspect there may be:

  1. An anchor/alignment operation being added elsewhere that overrides the indent
  2. The IfStatementSyntax node being processed after the ElseClauseSyntax and adding a conflicting operation
  3. Some special handling in the formatting engine's operation resolution

Could you point me to where in the formatting engine I should look for how indent operations are resolved/applied, or if there's specific handling for IfStatementSyntax that might be interfering?

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
@CyrusNajmabadi CyrusNajmabadi marked this pull request as ready for review November 12, 2025 12:58
@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner November 12, 2025 12:58
Copilot AI requested a review from CyrusNajmabadi November 12, 2025 12:59
Copilot finished work on behalf of CyrusNajmabadi November 12, 2025 12:59
}
""");

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/12286")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot update the links to be #16328

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated both WorkItem attributes to reference the correct issue #16328 (c665e40)

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Copilot AI requested a review from CyrusNajmabadi November 12, 2025 13:06
Copilot finished work on behalf of CyrusNajmabadi November 12, 2025 13:06
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Copilot finished work on behalf of CyrusNajmabadi November 12, 2025 15:51
if (!lastToken.IsMissing)
{
AddIndentBlockOperation(list, firstToken, lastToken, TextSpan.FromBounds(firstToken.FullSpan.Start, lastToken.FullSpan.End));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot inlining had no effect. The original call here was correct as it was calling into the overload of AddEmbeddedStatementsIndentationOperation that takes a statement as the second operation.

In terms of finding the issue, can you look around in the sibling files of this rule and see if there are any suspect behaviors around IfStatementSyntax, ElseClauseSyntax, IfKeyword, ElseKeyword, etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found the issue! AnchorIndentationFormattingRule adds an anchor indentation operation for ALL StatementSyntax nodes (lines 51-53), which preserves the if keyword's position and prevents the indent operation from taking effect.

I added a check to skip the anchor operation when an IfStatementSyntax is on a separate line from its else keyword (889d7e7), but the test still fails. The logic looks correct - it checks for newline trivia and returns early to skip adding the anchor. However, the if is still not being indented.

Could there be another source adding an anchor operation, or is there something about how anchor and indent operations interact that I'm missing?

…if on separate lines

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Copilot AI requested a review from CyrusNajmabadi November 12, 2025 16:53
Copilot finished work on behalf of CyrusNajmabadi November 12, 2025 16:53
@CyrusNajmabadi CyrusNajmabadi enabled auto-merge (rebase) November 12, 2025 18:35
auto-merge was automatically disabled November 12, 2025 20:16

Rebase failed

@CyrusNajmabadi CyrusNajmabadi merged commit 5b20f50 into main Nov 12, 2025
26 checks passed
@CyrusNajmabadi CyrusNajmabadi deleted the copilot/fix-indent-after-else branch November 12, 2025 20:17
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

if block not indented after else

3 participants