PowerShell icon indicating copy to clipboard operation
PowerShell copied to clipboard

Allow HiddenAttribute to decorate classes and exclude from type completion

Open yotsuda opened this issue 1 month ago • 4 comments

PR Summary

Allow HiddenAttribute to be applied to classes and exclude hidden classes from type name completion.

PR Context

Fixes #18914

The HiddenAttribute can be applied to properties, methods, and other members to hide them from tab completion and Get-Member, but could not be applied to classes themselves. This PR extends the attribute to support classes and ensures hidden classes are excluded from type name completion.

Before this fix:

[Hidden]  // Error: Not valid on this declaration type
public class InternalHelperClass { }

After this fix:

[Hidden]  // Now works - class is hidden from completion
public class InternalHelperClass { }

var obj = new InternalHelperClass();  // Can still instantiate explicitly
[Internal<Tab>]  // Does NOT suggest InternalHelperClass

PR Checklist

Description

Implementation

1. Extended HiddenAttribute target (Attributes.cs)

  • Added AttributeTargets.Class to AttributeUsage

2. Added IsHidden property to TypeDefinitionAst (ast.cs)

  • Cached property following the same pattern as PropertyMemberAst.IsHidden
  • Uses GetReflectionAttributeType() for attribute checking

3. Filtered hidden classes from type completion (CompletionCompleters.cs)

  • PowerShell-defined types: Filter using !ast.IsHidden
  • C#-defined types: Filter using type.IsDefined(typeof(HiddenAttribute), false)

Files Changed

  • src/System.Management.Automation/engine/Attributes.cs - Extended AttributeUsage
  • src/System.Management.Automation/engine/parser/ast.cs - Added IsHidden property
  • src/System.Management.Automation/engine/CommandCompletion/CompletionCompleters.cs - Filter hidden types
  • test/powershell/Language/Classes/Scripting.Classes.BasicParsing.Tests.ps1 - Added tests

Testing

Test Coverage

Added 3 comprehensive test cases:

  1. Instance creation - Verifies hidden classes can be instantiated
  2. Attribute presence - Validates attribute is correctly applied
  3. Type completion exclusion - Confirms hidden classes don't appear in tab completion

Results

Describing HiddenAttribute on Class Test
  [+] Should be able to create an instance of hidden class 7ms
  [+] HiddenAttribute should be present on the class 14ms
  [+] Hidden class should not appear in type name completion 142ms

Tests Passed: 327, Failed: 0, Skipped: 11, Pending: 13, Inconclusive: 0

Additional Notes

  • No breaking changes - only adds new functionality
  • Consistent with existing HiddenAttribute behavior for members
  • Performance: Attribute check is cached to avoid repeated reflection calls
  • Useful for hiding internal helper classes in modules

yotsuda avatar Nov 23 '25 13:11 yotsuda

@MartinGC94 Please review.

iSazonov avatar Nov 24 '25 05:11 iSazonov

It seems fine but I don't see a test for hiding PowerShell classes from tabcompletion: TabExpansion2 '[hidden()] class Test1{} [Test1'

This uses the AST so it's handled differently than C# classes are.

MartinGC94 avatar Nov 24 '25 21:11 MartinGC94

@MartinGC94 Thank you for the insightful review! You're absolutely right - the [hidden()] syntax wasn't available for PowerShell classes (missing type accelerator), and there were no tests for the AST-based scenario you mentioned.

I've added the following in a5344fed4:

  1. Hidden type accelerator - Registered HiddenAttribute in CoreTypes to enable [hidden()] syntax for PowerShell classes, consistent with other attributes like [Parameter()]

  2. Comprehensive tests - Including your specific scenario [hidden()] class Test1{} [Test1, plus regression tests to ensure visible classes still appear in completion

All tests pass (332 passed).

yotsuda avatar Nov 25 '25 14:11 yotsuda

This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. Maintainer, please provide feedback and/or mark it as Waiting on Author