| File: src\roslyn\src\Analyzers\CSharp\CodeFixes\AssignOutParameters\AssignOutParametersAboveReturnCodeFixProvider.cs | Web Access |
| Project: src\roslyn\src\Features\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.Features.csproj (Microsoft.CodeAnalysis.CSharp.Features) |
// 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. using System; using System.Collections.Immutable; using System.Composition; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Shared.Extensions; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.AssignOutParameters; [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.AssignOutParametersAboveReturn), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] internal sealed class AssignOutParametersAboveReturnCodeFixProvider() : AbstractAssignOutParametersCodeFixProvider { protected override void TryRegisterFix(CodeFixContext context, Document document, SyntaxNode container, SyntaxNode location) { RegisterCodeFix(context, CSharpCodeFixesResources.Assign_out_parameters, nameof(CSharpCodeFixesResources.Assign_out_parameters)); } protected override void AssignOutParameters( SyntaxEditor editor, SyntaxNode container, MultiDictionary<SyntaxNode, (SyntaxNode exprOrStatement, ImmutableArray<IParameterSymbol> unassignedParameters)>.ValueSet values, CancellationToken cancellationToken) { foreach (var (exprOrStatement, unassignedParameters) in values) { var statements = GenerateAssignmentStatements(editor.Generator, unassignedParameters); AddAssignmentStatements(editor, exprOrStatement, statements); } } private static void AddAssignmentStatements( SyntaxEditor editor, SyntaxNode exprOrStatement, ImmutableArray<SyntaxNode> statements) { var generator = editor.Generator; if (exprOrStatement is LocalFunctionStatementSyntax { ExpressionBody: { } localFunctionExpressionBody }) { // Expression-bodied local functions report CS0177 on the method name instead of the expression. // Reassign exprOrStatement so the code fix implementation works as it does for other expression-bodied // members. exprOrStatement = localFunctionExpressionBody.Expression; } var parent = exprOrStatement.GetRequiredParent(); if (parent.IsEmbeddedStatementOwner()) { var newBody = SyntaxFactory.Block(statements.Add(exprOrStatement).Cast<StatementSyntax>()); editor.ReplaceNode(exprOrStatement, newBody); editor.ReplaceNode( exprOrStatement.GetRequiredParent(), (c, _) => c.WithAdditionalAnnotations(Formatter.Annotation)); } else if (parent is BlockSyntax or SwitchSectionSyntax) { editor.InsertBefore(exprOrStatement, statements); } else if (parent is ArrowExpressionClauseSyntax) { statements = statements.Add(generator.ReturnStatement(exprOrStatement)); editor.ReplaceNode( parent.GetRequiredParent(), generator.WithStatements(parent.GetRequiredParent(), statements)); } else { var lambda = (LambdaExpressionSyntax)parent; var newBody = SyntaxFactory.Block(statements.Add(generator.ReturnStatement(exprOrStatement)).Cast<StatementSyntax>()); editor.ReplaceNode( lambda, lambda.WithBody(newBody) .WithAdditionalAnnotations(Formatter.Annotation)); } } }