|
// 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.Threading;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeGeneration;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp.UseExpressionBody;
internal sealed class UseExpressionBodyForMethodsHelper :
UseExpressionBodyHelper<MethodDeclarationSyntax>
{
public static readonly UseExpressionBodyForMethodsHelper Instance = new();
private UseExpressionBodyForMethodsHelper()
: base(IDEDiagnosticIds.UseExpressionBodyForMethodsDiagnosticId,
EnforceOnBuildValues.UseExpressionBodyForMethods,
new LocalizableResourceString(nameof(CSharpAnalyzersResources.Use_expression_body_for_method), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)),
new LocalizableResourceString(nameof(CSharpAnalyzersResources.Use_block_body_for_method), CSharpAnalyzersResources.ResourceManager, typeof(CSharpAnalyzersResources)),
CSharpCodeStyleOptions.PreferExpressionBodiedMethods,
[SyntaxKind.MethodDeclaration])
{
}
public override CodeStyleOption2<ExpressionBodyPreference> GetExpressionBodyPreference(CSharpCodeGenerationOptions options)
=> options.PreferExpressionBodiedMethods;
protected override BlockSyntax? GetBody(MethodDeclarationSyntax declaration)
=> declaration.Body;
protected override ArrowExpressionClauseSyntax? GetExpressionBody(MethodDeclarationSyntax declaration)
=> declaration.ExpressionBody;
protected override SyntaxToken GetSemicolonToken(MethodDeclarationSyntax declaration)
=> declaration.SemicolonToken;
protected override MethodDeclarationSyntax WithSemicolonToken(MethodDeclarationSyntax declaration, SyntaxToken token)
=> declaration.WithSemicolonToken(token);
protected override MethodDeclarationSyntax WithExpressionBody(MethodDeclarationSyntax declaration, ArrowExpressionClauseSyntax? expressionBody)
=> declaration.WithExpressionBody(expressionBody);
protected override MethodDeclarationSyntax WithBody(MethodDeclarationSyntax declaration, BlockSyntax? body)
=> declaration.WithBody(body);
protected override bool CreateReturnStatementForExpression(
SemanticModel semanticModel, MethodDeclarationSyntax declaration, CancellationToken cancellationToken)
{
if (declaration.Modifiers.Any(SyntaxKind.AsyncKeyword))
{
// if it's 'async TaskLike' (where TaskLike is non-generic) we do *not* want to
// create a return statement. This is just the 'async' version of a 'void' method.
var method = semanticModel.GetDeclaredSymbol(declaration, cancellationToken);
return method is { ReturnType: INamedTypeSymbol { Arity: not 0 } };
}
return !declaration.ReturnType.IsVoid();
}
}
|