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: