PowerShell / PowerShell/PSScriptAnalyzer
PSUseConsistentIndentation double-indents attribute bodies that open a scriptblock (`[Attr({ … })]`)
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- C#
- Sterne
- 2.2k
- Forks
- 414
- Ø Merge
- 13 Std. 1 Min.
- Gemergte PRs (30 T.)
- 2
Beschreibung
Prerequisites
- I have read the documentation and my issue is not covered there.
- I have searched the existing issues and my issue is not already reported.
Summary
PSUseConsistentIndentation (and therefore Invoke-Formatter) double-indents the body of an attribute that opens a scriptblock, e.g. [ArgumentCompleter({...})]. The body gets IndentationSize * 2 and the closing })] gets IndentationSize * 1.
This looks like the same root cause as #2159 (hashtable inside a method call: the LParen and the AtCurly each add an indentation level). Here the two adjacent openers are ( and { from a type/attribute literal instead of @{, so [AttributeName({ hits it too. #2159 was fixed on main by #2173 ("only the last unclosed opener on a line affects indentation"), but neither that fix nor #2159 covers the attribute form, and it is still broken in the latest release 1.25.0.
Steps to reproduce
$code = @'
[ArgumentCompleter({
Param($commandName, $parameterName)
$validKeys = @('a', 'b')
$validKeys | Where-Object { $_ } | ForEach-Object { "$_=" }
})]
'@
$settings = @{
IncludeRules = @('PSUseConsistentIndentation')
Rules = @{
PSUseConsistentIndentation = @{
Enable = $true
IndentationSize = 4
Kind = 'tab'
}
}
}
Invoke-Formatter -ScriptDefinition $code -Settings $settings
Expected behavior
One level of indentation for the body, matching the opener line, and the closing })] at the opener's level:
[ArgumentCompleter({
Param($commandName, $parameterName)
$validKeys = @('a', 'b')
$validKeys | Where-Object { $_ } | ForEach-Object { "$_=" }
})]
Actual behavior
Two levels for the body and one level for the closing })]:
[ArgumentCompleter({
Param($commandName, $parameterName)
$validKeys = @('a', 'b')
$validKeys | Where-Object { $_ } | ForEach-Object { "$_=" }
})]
The same happens with spaces (Kind = 'space', IndentationSize = 4) and with NewLineAfterOpenBrace/PSPlaceOpenBrace not involved at all — PSUseConsistentIndentation alone is enough.
It also affects other attribute forms that open a scriptblock, e.g.
[ValidateScript({
$_ -gt 0
})]
and the buggy output is not idempotent in a harmless way: because the opener line itself is not re-indented, re-running the formatter keeps the body at the wrong level, and any tool that re-applies formatting sees a permanent diff.
Environment
PSVersion: 7.6.6
PSEdition: Core
OS: Windows 11 (26100)
PSScriptAnalyzer: 1.25.0
Also reproduced with PSScriptAnalyzer 1.24.0 (bundled with ms-vscode.powershell 2025.4.0) and with Windows PowerShell 5.1 / 26100 (Desktop edition), so it is not host- or edition-specific.
Related
- #2159 —
PSUseConsistentIndentation: Hashtable inside method call gets double-indented (sameLParen+XCurlydouble count; fixed by #2173) - #2173 — the fix that pops the level when an opener is not the last unclosed opener on the line; it does not catch the attribute opening
({ - #1168 — "Formatting
.whereand.foreachmethods is incorrect" (adjacent-opener family)
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne damit, die bereitgestellte Invoke-Formatter-Reproduktion mit aktivierter PSUseConsistentIndentation auszuführen; verfolge dann die Behandlung der Einrückung für die Regel PSUseConsistentIndentation, wenn ein Attribut oder ein Typ-Literal einen Scriptblock öffnet. Füge einen Regressionstest hinzu, der [ArgumentCompleter({ ... })] und [ValidateScript({ ... })] abdeckt und eine Einrückungsebene im Body sowie das schließende })] auf der Ebene des öffnenden Elements überprüft.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- csharp, powershell
- Bereich
- tooling
- Issue-Typ
- Bug
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Aktiv
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 70/100