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)