PowerShell / PowerShell/PSScriptAnalyzer

PSUseConsistentIndentation double-indents attribute bodies that open a scriptblock (`[Attr({ … })]`)

Đang mở
#2,216 2 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Ngôn ngữ chính
C#
Star
2.2k
Fork
414
Merge trung bình
13 giờ 1 phút
Pull request đã merge (30 ngày)
2

Mô tả

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 (same LParen+XCurly double 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 .where and .foreach methods is incorrect" (adjacent-opener family)

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu bằng cách chạy bản tái hiện Invoke-Formatter được cung cấp với PSUseConsistentIndentation được bật, sau đó lần theo cách xử lý thụt lề cho quy tắc PSUseConsistentIndentation khi một thuộc tính hoặc literal kiểu mở một scriptblock. Thêm một bài kiểm thử hồi quy bao quát [ArgumentCompleter({ ... })] và [ValidateScript({ ... })], xác minh một cấp độ thụt lề cho phần thân và })] đóng ở cấp độ của phần mở.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
csharp, powershell
Lĩnh vực
tooling
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
70/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.