Skip to content

Commit d136325

Browse files
Fix positional parameter binding for FilterScript (#5)
* Allow FilterScript to be a positional argument - Change Find-Member and Find-Type to allow either FilterScript or Name to be in position 0 based on type. (e.g. Find-Type { $_.Name } or Find-Type Name) - Add tests for positional binding. - Remove a method in TypeArgumentCompleter that was left in by mistake and isn't used. * Fix argument completer for Find-Type Added the argument completer back onto Find-Type and fixed the bad test for type name validation.
1 parent c38c911 commit d136325

File tree

9 files changed

+108
-32
lines changed

9 files changed

+108
-32
lines changed

docs/en-US/Find-Member.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ Find properties, methods, fields, etc that fit specific criteria.
1212

1313
## SYNTAX
1414

15+
### ByFilter (Default)
16+
17+
```powershell
18+
Find-Member [-ParameterType <Type>] [-ReturnType <Type>] [-IncludeSpecialName] [-MemberType <MemberTypes>]
19+
[-Static] [-Instance] [-Abstract] [-Virtual] [[-FilterScript] <ScriptBlock>] [-Name <String>] [-Force]
20+
[-RegularExpression] [-InputObject <PSObject>]
21+
```
22+
23+
### ByName
24+
1525
```powershell
1626
Find-Member [-ParameterType <Type>] [-ReturnType <Type>] [-IncludeSpecialName] [-MemberType <MemberTypes>]
1727
[-Static] [-Instance] [-Abstract] [-Virtual] [-FilterScript <ScriptBlock>] [[-Name] <String>] [-Force]
@@ -144,10 +154,20 @@ Specifies a ScriptBlock to invoke as a filter. The variable "$_" or "$PSItem" co
144154
145155
```yaml
146156
Type: ScriptBlock
147-
Parameter Sets: (All)
157+
Parameter Sets: ByFilter
158+
Aliases:
159+
160+
Required: False
161+
Position: 0
162+
Default value: None
163+
Accept pipeline input: False
164+
Accept wildcard characters: False
165+
166+
Type: ScriptBlock
167+
Parameter Sets: ByName
148168
Aliases:
149169

150-
Required: True
170+
Required: False
151171
Position: Named
152172
Default value: None
153173
Accept pipeline input: False
@@ -241,14 +261,24 @@ Specifies the member name to match.
241261
242262
```yaml
243263
Type: String
244-
Parameter Sets: (All)
264+
Parameter Sets: ByName
245265
Aliases:
246266

247267
Required: False
248268
Position: 0
249269
Default value: None
250270
Accept pipeline input: False
251271
Accept wildcard characters: True
272+
273+
Type: String
274+
Parameter Sets: ByFilter
275+
Aliases:
276+
277+
Required: False
278+
Position: Named
279+
Default value: None
280+
Accept pipeline input: False
281+
Accept wildcard characters: True
252282
```
253283
254284
### -ParameterType

docs/en-US/Find-Type.md

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,19 @@ Find .NET classes in the AppDomain.
1212

1313
## SYNTAX
1414

15+
### ByFilter (Default)
16+
17+
```powershell
18+
Find-Type [[-Namespace] <String>] [-FullName <String>] [-InheritsType <Type>] [-ImplementsInterface <Type>]
19+
[-Abstract] [-Interface] [-ValueType] [[-FilterScript] <ScriptBlock>] [-Name <String>] [-Force]
20+
[-RegularExpression] [-InputObject <PSObject>]
21+
```
22+
23+
### ByName
24+
1525
```powershell
1626
Find-Type [[-Namespace] <String>] [-FullName <String>] [-InheritsType <Type>] [-ImplementsInterface <Type>]
17-
[[-Name] <String>] [-Abstract] [-Interface] [-ValueType] [-FilterScript <ScriptBlock>] [-Force]
27+
[-Abstract] [-Interface] [-ValueType] [-FilterScript <ScriptBlock>] [[-Name] <String>] [-Force]
1828
[-RegularExpression] [-InputObject <PSObject>]
1929
```
2030

@@ -73,10 +83,20 @@ Specifies a ScriptBlock to invoke as a filter. The variable "$_" or "$PSItem" co
7383

7484
```yaml
7585
Type: ScriptBlock
76-
Parameter Sets: (All)
86+
Parameter Sets: ByFilter
87+
Aliases:
88+
89+
Required: False
90+
Position: 0
91+
Default value: None
92+
Accept pipeline input: False
93+
Accept wildcard characters: False
94+
95+
Type: ScriptBlock
96+
Parameter Sets: ByName
7797
Aliases:
7898

79-
Required: True
99+
Required: False
80100
Position: Named
81101
Default value: None
82102
Accept pipeline input: False
@@ -169,14 +189,24 @@ Specifies the name of the type to match. For example, the name of the type "Syst
169189
170190
```yaml
171191
Type: String
172-
Parameter Sets: (All)
192+
Parameter Sets: ByName
173193
Aliases:
174194

175195
Required: False
176196
Position: 0
177197
Default value: None
178198
Accept pipeline input: False
179199
Accept wildcard characters: True
200+
201+
Type: String
202+
Parameter Sets: ByFilter
203+
Aliases:
204+
205+
Required: False
206+
Position: Named
207+
Default value: None
208+
Accept pipeline input: False
209+
Accept wildcard characters: True
180210
```
181211
182212
### -Namespace

module/ClassExplorer.psd1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
RootModule = 'ClassExplorer.psm1'
1313

1414
# Version number of this module.
15-
ModuleVersion = '1.0.0'
15+
ModuleVersion = '1.0.1'
1616

1717
# Supported PSEditions
1818
CompatiblePSEditions = 'Desktop', 'Core'
@@ -88,7 +88,7 @@ PrivateData = @{
8888
# IconUri = ''
8989

9090
# ReleaseNotes of this module
91-
# ReleaseNotes = ''
91+
ReleaseNotes = '- Fix positional binding of FilterScript for Find-Member and Find-Type.'
9292

9393
} # End of PSData hashtable
9494

src/ClassExplorer/Commands/FindMemberCommand.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace ClassExplorer.Commands
1111
/// The Find-Member cmdlet searches the current AppDomain for matching members.
1212
/// </summary>
1313
[OutputType(typeof(MemberInfo))]
14-
[Cmdlet(VerbsCommon.Find, "Member")]
14+
[Cmdlet(VerbsCommon.Find, "Member", DefaultParameterSetName = "ByFilter")]
1515
public class FindMemberCommand : FindReflectionObjectCommandBase<MemberInfo>
1616
{
1717
private BindingFlags _flags;

src/ClassExplorer/Commands/FindReflectionObjectCommandBase.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@ public abstract class FindReflectionObjectCommandBase<TMemberType> : Cmdlet
1717
/// <summary>
1818
/// Gets or sets a ScriptBlock to invoke as a predicate filter.
1919
/// </summary>
20-
[Parameter]
20+
[Parameter(Position = 0, ParameterSetName="ByFilter")]
21+
[Parameter(ParameterSetName="ByName")]
2122
[ValidateNotNull]
2223
public virtual ScriptBlock FilterScript { get; set; }
2324

2425
/// <summary>
2526
/// Gets or sets the name to match.
2627
/// </summary>
27-
[Parameter(Position = 0)]
28+
[Parameter(Position = 0, ParameterSetName="ByName")]
29+
[Parameter(ParameterSetName="ByFilter")]
2830
[SupportsWildcards]
2931
[ValidateNotNullOrEmpty]
3032
public virtual string Name { get; set; }

src/ClassExplorer/Commands/FindTypeCommand.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace ClassExplorer.Commands
1212
/// The FindType cmdlet searches the AppDomain for matching types.
1313
/// </summary>
1414
[OutputType(typeof(Type))]
15-
[Cmdlet(VerbsCommon.Find, "Type")]
15+
[Cmdlet(VerbsCommon.Find, "Type", DefaultParameterSetName = "ByFilter")]
1616
public class FindTypeCommand : FindReflectionObjectCommandBase<Type>
1717
{
1818
/// <summary>
@@ -23,6 +23,16 @@ public class FindTypeCommand : FindReflectionObjectCommandBase<Type>
2323
[SupportsWildcards]
2424
public string Namespace { get; set; }
2525

26+
/// <summary>
27+
/// Gets or sets the type name to match.
28+
/// </summary>
29+
[Parameter(Position = 0, ParameterSetName = "ByName")]
30+
[Parameter(ParameterSetName = "ByFilter")]
31+
[ValidateNotNullOrEmpty]
32+
[SupportsWildcards]
33+
[ArgumentCompleter(typeof(TypeNameArgumentCompleter))]
34+
public override string Name { get; set; }
35+
2636
/// <summary>
2737
/// Gets or sets the full type name to match.
2838
/// </summary>
@@ -48,16 +58,6 @@ public class FindTypeCommand : FindReflectionObjectCommandBase<Type>
4858
[ArgumentCompleter(typeof(TypeArgumentCompleter))]
4959
public Type ImplementsInterface { get; set; }
5060

51-
/// <summary>
52-
/// Gets or sets the type name to match.
53-
/// </summary>
54-
[Parameter(Position = 0, ParameterSetName = "ByName")]
55-
[Parameter(ParameterSetName = "__AllParameterSets")]
56-
[ValidateNotNullOrEmpty]
57-
[SupportsWildcards]
58-
[ArgumentCompleter(typeof(TypeNameArgumentCompleter))]
59-
public override string Name { get; set; }
60-
6161
/// <summary>
6262
/// Gets or sets a value indicating whether to only match abstract classes.
6363
/// </summary>

src/ClassExplorer/TypeArgumentCompleter.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,6 @@ public IEnumerable<CompletionResult> CompleteArgument(
4444
return GetTypesForCompletion(wordToComplete).Select(NewResult);
4545
}
4646

47-
private static bool CompletionTypeFilter(Type m, object filterCriteria)
48-
{
49-
return m.IsPublic &&
50-
filterCriteria is string wordToComplete
51-
? m.Name.StartsWith(wordToComplete, StringComparison.InvariantCultureIgnoreCase)
52-
: false;
53-
}
54-
5547
private static CompletionResult NewResult(Type type)
5648
{
5749
return new CompletionResult(

test/Completion.Tests.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Describe 'Completion tests' {
2020
$results = complete 'Find-Type -Name Toke'
2121

2222
$results.CompletionMatches | ShouldAll { $_.CompletionText.StartsWith('Token') }
23+
$results.CompletionMatches | Should -Not -BeNullOrEmpty
2324
}
2425
It 'can complete type full names' {
2526
$results = complete 'Find-Member -ReturnType Ast'

test/Find-Type.Tests.ps1

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,27 @@ Describe 'Find-Type tests' {
1818
Get-Item . | Find-Type | Should -Be ([System.IO.DirectoryInfo])
1919
}
2020
}
21+
22+
Context 'Positional parameter binding' {
23+
It 'accepts a scriptblock in position 0' {
24+
Find-Type { $_.Name -eq 'runspace' } | Should -Be ([runspace])
25+
}
26+
27+
It 'accepts a name in position 0' {
28+
Find-Type RunspaceMode | Should -Be ([System.Management.Automation.RunspaceMode])
29+
}
30+
31+
It 'accepts both a name and a script block as named parameters in the same command' {
32+
Find-Type -Name Runspace* -FilterScript { $_.IsAbstract } |
33+
ShouldAny { $_ -eq [runspace] }
34+
}
35+
36+
It 'accepts namespace at position 1' {
37+
Find-Type PowerShell* System.Management.Automation.Runspaces |
38+
Should -Be ([System.Management.Automation.Runspaces.PowerShellProcessInstance])
39+
}
40+
}
41+
2142
It 'can find all types' {
2243
$result = Find-Type | Measure-Object
2344

@@ -30,7 +51,7 @@ Describe 'Find-Type tests' {
3051
$result | Should -Be ([powershell])
3152
}
3253
It 'matches by name' {
33-
Find-Type runspace | Should -Be ([runspace])
54+
Find-Type RunspaceMode | Should -Be ([System.Management.Automation.RunspaceMode])
3455
}
3556
It 'matches by namespace' {
3657
Find-Type -Namespace System.Timers | ShouldAll { $_.Namespace -eq 'System.Timers' }

0 commit comments

Comments
 (0)