PowerShell / PowerShell/PSScriptAnalyzer
PSUseConsistentIndentation double-indents attribute bodies that open a scriptblock (`[Attr({ … })]`)
Ninguém assumiu esta issue ainda.
- Linguagem predominante
- C#
- Estrelas
- 2.2k
- Forks
- 415
- Merge médio
- 13h 1min
- PRs com merge (30d)
- 2
Descrição
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)
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Direção de pesquisa
Comece executando a reprodução fornecida de Invoke-Formatter com PSUseConsistentIndentation habilitado; em seguida, rastreie o tratamento da indentação para a regra PSUseConsistentIndentation quando um atributo ou literal de tipo abre um scriptblock. Adicione um teste de regressão cobrindo [ArgumentCompleter({ ... })] e [ValidateScript({ ... })], verificando um nível de indentação do corpo e o })] de fechamento no nível do elemento de abertura.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- csharp, powershell
- Domínio
- tooling
- Tipo de issue
- Bug
- Dificuldade
- 3/5
- Tempo estimado
- 1-2 dias
- Status de atividade
- Ativa
- Clareza
- Claramente especificada
- Facilidade para iniciantes
- 70/100