diff --git a/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.State.cs b/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.State.cs index 00c3c24af918..282036cd5b43 100644 --- a/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.State.cs +++ b/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.State.cs @@ -16,21 +16,28 @@ internal sealed class State( SyntaxNode contextNode, INamedTypeSymbol classOrStructType, ImmutableArray interfaceTypes, - SemanticModel model) : IImplementInterfaceInfo + SemanticModel model) { - public SyntaxNode ContextNode { get; } = contextNode; - public INamedTypeSymbol ClassOrStructType { get; } = classOrStructType; - public ImmutableArray InterfaceTypes { get; } = interfaceTypes; + public ImplementInterfaceInfo Info { get; private set; } = new() + { + ClassOrStructType = classOrStructType, + ContextNode = contextNode, + InterfaceTypes = interfaceTypes, + }; + + public SyntaxNode ContextNode => Info.ContextNode; + public INamedTypeSymbol ClassOrStructType => Info.ClassOrStructType; + public ImmutableArray InterfaceTypes => Info.InterfaceTypes; public SemanticModel Model { get; } = model; public readonly Document Document = document; // The members that are not implemented at all. - public ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented { get; private set; } = []; - public ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitOrImplicitImplementation { get; private set; } = []; + public ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented => Info.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented; + public ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitOrImplicitImplementation => Info.MembersWithoutExplicitOrImplicitImplementation; // The members that have no explicit implementation. - public ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitImplementation { get; private set; } = []; + public ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitImplementation => Info.MembersWithoutExplicitImplementation; public static State? Generate( AbstractImplementInterfaceService service, @@ -54,14 +61,23 @@ internal sealed class State( if (service.CanImplementImplicitly) { - state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented = state.ClassOrStructType.GetAllUnimplementedMembers( - interfaceTypes, includeMembersRequiringExplicitImplementation: false, cancellationToken); + state.Info = state.Info with + { + MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented = state.ClassOrStructType.GetAllUnimplementedMembers( + interfaceTypes, includeMembersRequiringExplicitImplementation: false, cancellationToken) + }; - state.MembersWithoutExplicitOrImplicitImplementation = state.ClassOrStructType.GetAllUnimplementedMembers( - interfaceTypes, includeMembersRequiringExplicitImplementation: true, cancellationToken); + state.Info = state.Info with + { + MembersWithoutExplicitOrImplicitImplementation = state.ClassOrStructType.GetAllUnimplementedMembers( + interfaceTypes, includeMembersRequiringExplicitImplementation: true, cancellationToken) + }; - state.MembersWithoutExplicitImplementation = state.ClassOrStructType.GetAllUnimplementedExplicitMembers( - interfaceTypes, cancellationToken); + state.Info = state.Info with + { + MembersWithoutExplicitImplementation = state.ClassOrStructType.GetAllUnimplementedExplicitMembers( + interfaceTypes, cancellationToken) + }; var allMembersImplemented = state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented.Length == 0; var allMembersImplementedExplicitly = state.MembersWithoutExplicitImplementation.Length == 0; @@ -71,8 +87,11 @@ internal sealed class State( else { // We put the members in this bucket so that the code fix title is "Implement Interface" - state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented = state.ClassOrStructType.GetAllUnimplementedExplicitMembers( - interfaceTypes, cancellationToken); + state.Info = state.Info with + { + MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented = state.ClassOrStructType.GetAllUnimplementedExplicitMembers( + interfaceTypes, cancellationToken) + }; var allMembersImplemented = state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented.Length == 0; return !allMembersImplemented ? state : null; diff --git a/src/Analyzers/Core/CodeFixes/ImplementInterface/IImplementInterfaceInfo.cs b/src/Analyzers/Core/CodeFixes/ImplementInterface/IImplementInterfaceInfo.cs index c687c79ded6c..0e6a734cf7c7 100644 --- a/src/Analyzers/Core/CodeFixes/ImplementInterface/IImplementInterfaceInfo.cs +++ b/src/Analyzers/Core/CodeFixes/ImplementInterface/IImplementInterfaceInfo.cs @@ -6,27 +6,27 @@ namespace Microsoft.CodeAnalysis.ImplementInterface; -internal interface IImplementInterfaceInfo +internal sealed record ImplementInterfaceInfo { /// /// The class or struct that is implementing the interface. /// - INamedTypeSymbol ClassOrStructType { get; } + public required INamedTypeSymbol ClassOrStructType { get; init; } /// /// The specific declaration node for that the interface implementations should be /// added to. /// - SyntaxNode ContextNode { get; } + public required SyntaxNode ContextNode { get; init; } /// /// Set of interfaces to implement. Normally a single interface (when a user invokes the code action on a single /// entry in the interface-list for a type). However, it may be multiple in the VB case where a user presses /// 'enter' at the end of the interfaces list, where we'll implement all the missing members for all listed interfaces. /// - ImmutableArray InterfaceTypes { get; } + public ImmutableArray InterfaceTypes { get; init; } - ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented { get; } - ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitOrImplicitImplementation { get; } - ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitImplementation { get; } + public ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented { get; init; } + public ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitOrImplicitImplementation { get; init; } + public ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitImplementation { get; init; } }