diff --git a/docs/en-US/about_Type_Signatures.help.md b/docs/en-US/about_Type_Signatures.help.md index 6674adb..4093088 100644 --- a/docs/en-US/about_Type_Signatures.help.md +++ b/docs/en-US/about_Type_Signatures.help.md @@ -26,6 +26,8 @@ Type signatures are a custom query language built into PowerShell type expressio * [Generic Parameters (`T`, `TT`, and `TM`)](#generic-parameters-t-tt-and-tm) * [`primitive`](#primitive) * [`interface`](#interface) +* [`abstract`](#abstract) +* [`concrete`](#concrete) * [`number`](#number) * [`decoration`, `hasattr`](#decoration-hasattr) * [`generic`](#generic) @@ -2508,6 +2510,230 @@ void Example(int value); +## `abstract` + +([Back to Top](#keywords)) + +Matches only abstract types. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +```powershell +Find-Member -ParameterType { [abstract] } +``` + +
+ + + +Signature + +
+ +:x: + + + +```csharp +void Example(IDisposable disposable); +``` + +
+ +:x: + + + +```csharp +void Example(object obj); +``` + +
+ +:x: + + + +```csharp +void Example(int value); +``` + +
+ +:x: + + + +```csharp +void Example(T value); +``` + +
+ +:heavy_check_mark: + + + +```csharp +void Example(FileSystemInfo value); +``` + +
+ +:heavy_check_mark: + + + +```csharp +void Example(FileInfo value); +``` + +
+ +## `concrete` + +([Back to Top](#keywords)) + +Matches only concrete types. No abstract classes, interfaces, or generic parameters. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +```powershell +Find-Member -ParameterType { [abstract] } +``` + +
+ + + +Signature + +
+ +:x: + + + +```csharp +void Example(IDisposable disposable); +``` + +
+ +:heavy_check_mark: + + + +```csharp +void Example(object obj); +``` + +
+ +:heavy_check_mark: + + + +```csharp +void Example(int value); +``` + +
+ +:x: + + + +```csharp +void Example(T value); +``` + +
+ +:x: + + + +```csharp +void Example(FileSystemInfo value); +``` + +
+ +:heavy_check_mark: + + + +```csharp +void Example(FileInfo value); +``` + +
+ ## `number` ([Back to Top](#keywords)) diff --git a/src/ClassExplorer/Signatures/ClassificationKind.cs b/src/ClassExplorer/Signatures/ClassificationKind.cs index ab1926b..4361f3a 100644 --- a/src/ClassExplorer/Signatures/ClassificationKind.cs +++ b/src/ClassExplorer/Signatures/ClassificationKind.cs @@ -25,6 +25,8 @@ internal enum ClassificationKind Primitive = 1 << 8, - Pointer = 1 << 9, + Abstract = 1 << 9, + + Concrete = 1 << 10, } } diff --git a/src/ClassExplorer/Signatures/Keywords.cs b/src/ClassExplorer/Signatures/Keywords.cs index fb8d311..8d8c5d1 100644 --- a/src/ClassExplorer/Signatures/Keywords.cs +++ b/src/ClassExplorer/Signatures/Keywords.cs @@ -27,6 +27,8 @@ internal static class Keywords public const string @enum = "enum"; public const string referencetype = "referencetype"; public const string @interface = "interface"; + public const string @abstract = "abstract"; + public const string concrete = "concrete"; public const string primitive = "primitive"; public const string pointer = "pointer"; public const string any = "any"; diff --git a/src/ClassExplorer/Signatures/SignatureParser.cs b/src/ClassExplorer/Signatures/SignatureParser.cs index 9ccbd16..25766d9 100644 --- a/src/ClassExplorer/Signatures/SignatureParser.cs +++ b/src/ClassExplorer/Signatures/SignatureParser.cs @@ -220,6 +220,8 @@ public ITypeSignature ParseDefinition( Keywords.@enum => new TypeClassification(ClassificationKind.Enum), Keywords.referencetype => new TypeClassification(ClassificationKind.ReferenceType), Keywords.@interface => new TypeClassification(ClassificationKind.Interface), + Keywords.@abstract => new TypeClassification(ClassificationKind.Abstract), + Keywords.concrete => new TypeClassification(ClassificationKind.Concrete), Keywords.primitive => new TypeClassification(ClassificationKind.Primitive), Keywords.any => new AnySignature(), Keywords.generic => Consume(ParseGeneric(args, typeName), out argsConsumed), diff --git a/src/ClassExplorer/Signatures/TypeClassification.cs b/src/ClassExplorer/Signatures/TypeClassification.cs index 92bd1e5..4f18e04 100644 --- a/src/ClassExplorer/Signatures/TypeClassification.cs +++ b/src/ClassExplorer/Signatures/TypeClassification.cs @@ -55,11 +55,42 @@ public override bool IsMatch(Type type) return false; } - if ((Kind & ClassificationKind.Pointer) != 0 && !type.IsPointer) + if ((Kind & ClassificationKind.Abstract) != 0 && (!type.IsAbstract || type.IsInterface)) { return false; } + if ((Kind & ClassificationKind.Concrete) != 0 && !IsConcrete(type)) + { + return false; + } + + return true; + } + + private static bool IsConcrete(Type type) + { + if (type is not { IsAbstract: false, IsInterface: false, IsGenericParameter: false }) + { + return false; + } + + if (type.IsGenericType) + { + foreach (Type genericArg in type.GetGenericArguments()) + { + if (!IsConcrete(genericArg)) + { + return false; + } + } + } + + if (type.HasElementType) + { + return IsConcrete(type.GetElementType()!); + } + return true; } diff --git a/tools/Signatures.yaml b/tools/Signatures.yaml index 6ae2da6..34cbb67 100644 --- a/tools/Signatures.yaml +++ b/tools/Signatures.yaml @@ -434,6 +434,42 @@ keywords: - match: false sig: void Example(int value); + - header: "`abstract`" + description: Matches only abstract types. + examples: + - syntax: Find-Member -ParameterType { [abstract] } + signatures: + - match: false + sig: void Example(IDisposable disposable); + - match: false + sig: void Example(object obj); + - match: false + sig: void Example(int value); + - match: false + sig: void Example(T value); + - match: true + sig: void Example(FileSystemInfo value); + - match: true + sig: void Example(FileInfo value); + + - header: "`concrete`" + description: Matches only concrete types. No abstract classes, interfaces, or generic parameters. + examples: + - syntax: Find-Member -ParameterType { [abstract] } + signatures: + - match: false + sig: void Example(IDisposable disposable); + - match: true + sig: void Example(object obj); + - match: true + sig: void Example(int value); + - match: false + sig: void Example(T value); + - match: false + sig: void Example(FileSystemInfo value); + - match: true + sig: void Example(FileInfo value); + - header: "`number`" description: Matches a hard coded list of types representing numbers. examples: