From f5ca7476b4ad7c64bb30efee1bb73b9d17554d92 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 00:38:11 +0000 Subject: [PATCH 1/2] Initial plan From 7de3b314f170144e83c0ee6b82e89cfe245a02d8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 10 Feb 2026 00:53:04 +0000 Subject: [PATCH 2/2] fix(adapter): address review feedback - fully-qualified types, member ordering, and code style Co-authored-by: JerrettDavis <2610199+JerrettDavis@users.noreply.github.com> --- .../Adapter/AdapterAttributes.cs | 2 +- .../Adapter/AdapterGenerator.cs | 47 +++++++++---------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/PatternKit.Generators.Abstractions/Adapter/AdapterAttributes.cs b/src/PatternKit.Generators.Abstractions/Adapter/AdapterAttributes.cs index f75afb7..72d6da4 100644 --- a/src/PatternKit.Generators.Abstractions/Adapter/AdapterAttributes.cs +++ b/src/PatternKit.Generators.Abstractions/Adapter/AdapterAttributes.cs @@ -76,7 +76,7 @@ public sealed class GenerateAdapterAttribute : Attribute /// /// First parameter must be the adaptee type /// Remaining parameters must match the target member's parameters -/// Return type must be compatible with the target member's return type +/// Return type must match the target member's return type exactly /// /// /// diff --git a/src/PatternKit.Generators/Adapter/AdapterGenerator.cs b/src/PatternKit.Generators/Adapter/AdapterGenerator.cs index 6f7fc05..97bd340 100644 --- a/src/PatternKit.Generators/Adapter/AdapterGenerator.cs +++ b/src/PatternKit.Generators/Adapter/AdapterGenerator.cs @@ -28,7 +28,7 @@ public sealed class AdapterGenerator : IIncrementalGenerator private const string DiagIdDuplicateMapping = "PKADP004"; private const string DiagIdSignatureMismatch = "PKADP005"; private const string DiagIdTypeNameConflict = "PKADP006"; - private const string DiagIdInvalidAdapteType = "PKADP007"; + private const string DiagIdInvalidAdapteeType = "PKADP007"; private const string DiagIdMapMethodNotStatic = "PKADP008"; private const string DiagIdEventsNotSupported = "PKADP009"; private const string DiagIdGenericMethodsNotSupported = "PKADP010"; @@ -85,7 +85,7 @@ public sealed class AdapterGenerator : IIncrementalGenerator isEnabledByDefault: true); private static readonly DiagnosticDescriptor InvalidAdapteeTypeDescriptor = new( - id: DiagIdInvalidAdapteType, + id: DiagIdInvalidAdapteeType, title: "Invalid adaptee type", messageFormat: "Adaptee type '{0}' must be a concrete class or struct", category: "PatternKit.Generators.Adapter", @@ -398,12 +398,11 @@ private List ValidateTargetMembers(INamedTypeSymbol targetType, Loca if (!processed.Add(type)) continue; - foreach (var member in type.GetMembers()) - { - // For abstract classes, only check abstract members - if (isAbstractClass && !member.IsAbstract) - continue; + var membersToCheck = type.GetMembers() + .Where(m => !isAbstractClass || m.IsAbstract); + foreach (var member in membersToCheck) + { // Check for events (not supported) if (member is IEventSymbol evt) { @@ -458,16 +457,13 @@ private List ValidateTargetMembers(INamedTypeSymbol targetType, Loca // Check for true overloaded methods (same name, different signatures) // Diamond inheritance (same signature from multiple paths) is OK - foreach (var kvp in methodSignatures) + foreach (var kvp in methodSignatures.Where(kvp => kvp.Value.Count > 1)) { - if (kvp.Value.Count > 1) - { - diagnostics.Add(Diagnostic.Create( - OverloadedMethodsNotSupportedDescriptor, - location, - targetType.Name, - kvp.Key)); - } + diagnostics.Add(Diagnostic.Create( + OverloadedMethodsNotSupportedDescriptor, + location, + targetType.Name, + kvp.Key)); } return diagnostics; @@ -560,12 +556,11 @@ private static List GetTargetMembers(INamedTypeSymbol targetType) if (!processed.Add(type)) continue; - foreach (var member in type.GetMembers()) - { - // For abstract classes, only include abstract members (must be overridden) - if (isAbstractClass && !member.IsAbstract) - continue; + var membersToProcess = type.GetMembers() + .Where(m => !isAbstractClass || m.IsAbstract); + foreach (var member in membersToProcess) + { // Include methods (not constructors), properties (not events - not supported) if (member is IMethodSymbol method && method.MethodKind == MethodKind.Ordinary) { @@ -577,7 +572,7 @@ private static List GetTargetMembers(INamedTypeSymbol targetType) else if (member is IPropertySymbol prop && !prop.IsIndexer) { // De-duplicate by name+type for properties - var sig = $"P:{prop.Name}:{prop.Type.ToDisplayString()}"; + var sig = $"P:{prop.Name}:{prop.Type.ToDisplayString(FullyQualifiedFormat)}"; if (seenSignatures.Add(sig)) members.Add(member); } @@ -597,15 +592,15 @@ private static List GetTargetMembers(INamedTypeSymbol targetType) } } - // Sort by name for deterministic output - return members.OrderBy(m => m.Name).ThenBy(m => m.ToDisplayString()).ToList(); + // Return in declaration order (members already added in traversal order) + return members; } private static string GetMemberSignature(IMethodSymbol method) { var paramSig = string.Join(",", method.Parameters.Select(p => - $"{p.RefKind}:{p.Type.ToDisplayString()}")); - return $"M:{method.Name}({paramSig}):{method.ReturnType.ToDisplayString()}"; + $"{p.RefKind}:{p.Type.ToDisplayString(FullyQualifiedFormat)}")); + return $"M:{method.Name}({paramSig}):{method.ReturnType.ToDisplayString(FullyQualifiedFormat)}"; } private static string? ValidateSignature(ISymbol targetMember, IMethodSymbol mapMethod, INamedTypeSymbol adapteeType)