File: src\Analyzers\CSharp\CodeFixes\GenerateConstructor\GenerateConstructorCodeFixProvider.cs
Web Access
Project: src\src\CodeStyle\CSharp\CodeFixes\Microsoft.CodeAnalysis.CSharp.CodeStyle.Fixes.csproj (Microsoft.CodeAnalysis.CSharp.CodeStyle.Fixes)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CodeFixes.GenerateMember;
using Microsoft.CodeAnalysis.CodeGeneration;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.GenerateMember.GenerateConstructor;
using Microsoft.CodeAnalysis.Shared.Extensions;
 
namespace Microsoft.CodeAnalysis.CSharp.GenerateConstructor;
 
/// <summary>
/// This <see cref="CodeFixProvider"/> gives users a way to generate constructors for an existing
/// type when a user tries to 'new' up an instance of that type with a set of parameter that does
/// not match any existing constructor.  i.e. it is the equivalent of 'Generate-Method' but for
/// constructors.  Parameters for the constructor will be picked in a manner similar to Generate-
/// Method.  However, this type will also attempt to hook up those parameters to existing fields
/// and properties, or pass them to a this/base constructor if available.
/// 
/// Importantly, this type is not responsible for generating constructors for a type based on 
/// the user selecting some fields/properties of that type.  Nor is it responsible for generating
/// derived class constructors for all unmatched base class constructors in a type hierarchy.
/// </summary>
[ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.GenerateConstructor), Shared]
[ExtensionOrder(After = PredefinedCodeFixProviderNames.FullyQualify)]
[method: ImportingConstructor]
[method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
internal sealed class GenerateConstructorCodeFixProvider() : AbstractGenerateMemberCodeFixProvider
{
    public override ImmutableArray<string> FixableDiagnosticIds => GenerateConstructorDiagnosticIds.AllDiagnosticIds;
 
    protected override Task<ImmutableArray<CodeAction>> GetCodeActionsAsync(
        Document document, SyntaxNode node, CancellationToken cancellationToken)
    {
        var service = document.GetLanguageService<IGenerateConstructorService>();
        return service.GenerateConstructorAsync(document, node, cancellationToken);
    }
 
    protected override bool IsCandidate(SyntaxNode node, SyntaxToken token, Diagnostic diagnostic)
    {
        return node is BaseObjectCreationExpressionSyntax or
               ConstructorInitializerSyntax or
               AttributeSyntax;
    }
 
    protected override SyntaxNode GetTargetNode(SyntaxNode node)
    {
        switch (node)
        {
            case ObjectCreationExpressionSyntax objectCreationNode:
                return objectCreationNode.Type.GetRightmostName();
            case AttributeSyntax attributeNode:
                return attributeNode.Name;
        }
 
        return node;
    }
}