Repository: dotnet/roslyn
File: src/Features/Core/Portable/AddConstructorParametersFromMembers/AddConstructorParametersFromMembersCodeRefactoringProvider.AddConstructorParametersCodeAction.cs (C#)

Code before:
            {
                // For regular constructors, add assignment statements
                newConstructor = codeGenerator.AddStatements(newConstructor, CreateAssignStatements(_constructorCandidate), _info, cancellationToken)
                                                      .WithAdditionalAnnotations(Formatter.Annotation);

                var syntaxTree = constructor.SyntaxTree;
                var newRoot = syntaxTree.GetRoot(cancellationToken).ReplaceNode(constructor, newConstructor);

                // Make sure we get the document that contains the constructor we just updated
                var constructorDocument = _document.Project.GetDocument(syntaxTree);
                Contract.ThrowIfNull(constructorDocument);

                return constructorDocument.WithSyntaxRoot(newRoot).Project.Solution;
            }
            else
            {
                // For primary constructors, we need to:
                // 1. Update the primary constructor with new parameters
                // 2. Add initializers to the properties/fields
                var solution = await AddParametersAndInitializersToPrimaryConstructorAsync(
                    newConstructor, cancellationToken).ConfigureAwait(false);
                return solution;
            }
        }

        private bool IsPrimaryConstructor(IMethodSymbol constructor, CancellationToken cancellationToken)
        {
            // Check if the constructor syntax is a TypeDeclarationSyntax (primary constructor pattern)
            if (constructor.DeclaringSyntaxReferences.Length > 0)
            {
                var syntax = constructor.DeclaringSyntaxReferences[0].GetSyntax(cancellationToken);
                // Check language-agnostically by getting the syntax kind
                var syntaxFacts = _document.GetRequiredLanguageService<ISyntaxFactsService>();
                
                // In C#, primary constructors have their declaration on the type declaration itself
                // TypeDeclarationSyntax, RecordDeclarationSyntax etc
                // Regular constructors have ConstructorDeclarationSyntax
                // We can check if it's NOT a constructor declaration
                return !syntaxFacts.IsConstructorDeclaration(syntax);
            }
            return false;
        }

        private async Task<Solution> AddParametersAndInitializersToPrimaryConstructorAsync(
            SyntaxNode newConstructor,
            CancellationToken cancellationToken)
        {
            var solution = _document.Project.Solution;
            var solutionEditor = new SolutionEditor(solution);

            // First, update the primary constructor declaration with the new parameters

Review comment (suggestion):
@copilot add this as an extension to D:\github\roslyn\src\Workspaces\SharedUtilitiesAndExtensions\Compiler\Extensions\Symbols\IMethodSymbolExtensions.cs

it does not need ISyntaxFacts.  It just needs to not be implicit declared, and have a declaring syntax ref the same as its containing type.

Code after:

        private Solution AddParametersToRegularConstructor(SyntaxNode constructor, CancellationToken cancellationToken)
        {
            var codeGenerator = _document.GetRequiredLanguageService<ICodeGenerationService>();

            // For regular constructors, add assignment statements
            var newConstructor = GetNewConstructor(constructor, cancellationToken);
            newConstructor = codeGenerator
                .AddStatements(newConstructor, CreateAssignStatements(), _info, cancellationToken)
                .WithAdditionalAnnotations(Formatter.Annotation);

            var syntaxTree = constructor.SyntaxTree;
            var newRoot = syntaxTree.GetRoot(cancellationToken).ReplaceNode(constructor, newConstructor);

            // Make sure we get the document that contains the constructor we just updated
            var constructorDocument = _document.Project.GetDocument(syntaxTree);
            Contract.ThrowIfNull(constructorDocument);

            return constructorDocument.WithSyntaxRoot(newRoot).Project.Solution;
        }

        private async Task<Solution> AddParametersAndInitializersToPrimaryConstructorAsync(
            SyntaxNode constructor,
            CancellationToken cancellationToken)
        {
            // For primary constructors, we need to:
            //
            // 1. Add initializers to the properties/fields
            // 2. Update the primary constructor with new parameters
            //
            // We need to do it in this order so that we see the adjustment to the properties/fields when we're updating
            // the primary constructor that wraps them all.
            var newConstructor = GetNewConstructor(constructor, cancellationToken);

            var solution = _document.Project.Solution;
            var solutionEditor = new SolutionEditor(solution);

            // First, update the primary constructor declaration with the new parameters
            var oldConstructor = _document.GetRequiredLanguageService<ISymbolDeclarationService>()
                .GetDeclarations(Constructor)
                .Select(r => r.GetSyntax(cancellationToken))
                .First();

            var oldConstructorSyntaxTree = oldConstructor.SyntaxTree;

            foreach (var (parameter, member) in MissingParameters)
            {
                await AddInitializerToMemberAsync(
                    solutionEditor, member, parameter, cancellationToken).ConfigureAwait(false);
            }