WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@liamjpeters
Copy link
Contributor

@liamjpeters liamjpeters commented Nov 4, 2025

PR Summary

UseConsistentWhitespace's CheckInnerBrace breaks braced member access ($a.{Prop}) by inserting whitespace after the opening and before the closing curly brace ($a.{ Prop }). The inner content of the braces must match the referenced property name exactly. No formatting of the inner content should occur.

Unlike the variable curly-brace format, ${a}, which is tokenised as a variable, no special tokenisation happens for this bracing.

Disclaimer: I don't know the correct names for things

PR introduces a new function, GetBracedMemberAccessRanges(), in TokenOperations.cs, which walks the token list looking for the shape of a braced member access:

  • One of these tokens:
    • TokenKind.Variable
    • TokenKind.Identifier
    • TokenKind.StringLiteral
    • TokenKind.StringExpandable
    • TokenKind.HereStringLiteral
    • TokenKind.HereStringExpandable
    • TokenKind.RParen
    • TokenKind.RCurly
    • TokenKind.RBracket
  • Optional inline comments(but no whitespace, new lines, line continuations)
  • Dot (or QuestionDot on PS7+) Token.
  • Optional inline comments, whitespace, new lines, line continuations
  • Left Curly Brace
  • Inner content
  • Matched Right Curly Brace

The function returns a list of int pairs which represent a range from the startoffset of a LCurly to the endoffset of a RCurly. Formatting within these ranges could break braced member access.

In UseConsistentWhitespace when checking for inner brace violations in FindInnerBraceViolations(), call the function to get the ranges to exclude. Skip whitespace checking for braces within any range (inclusive).

Fixes #2066

When asking copilot to look this over, it told me I could instead have used the AST, looking for MemberExpressionAst who's Member started with a { and ended with a }. I could then infer the offsets of the braces. I could explore that if it's a more desirable/correct solution.

PR Checklist

Copy link
Collaborator

@bergmeister bergmeister left a comment

Choose a reason for hiding this comment

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

Thanks for all the work and detail. Word of warning, getting edge cases in UseConsistent rule is hard, just expect some potential regressions but you've added plenty new test cases, which should overall make it better and be a change for the better. those regressions are often just found with a new release as so many people use PSSA in so many different ways

Copy link
Member

@andyleejordan andyleejordan left a comment

Choose a reason for hiding this comment

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

Thanks!

node = rcurlyNode.Next;
}

return ranges;
Copy link
Member

Choose a reason for hiding this comment

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

Man this looked fun to implement, good job!

@andyleejordan andyleejordan merged commit 7d2b8ae into PowerShell:main Dec 3, 2025
4 checks passed
@liamjpeters liamjpeters deleted the #2066UseConsistentWhitespaceInnerBraceIssue branch December 3, 2025 17:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Formatting breaks pattern needed for null-conditonal operators by adding spaces

3 participants