|
// 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.Composition;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.ReplaceConditionalWithStatements;
namespace Microsoft.CodeAnalysis.CSharp.ReplaceConditionalWithStatements;
[ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = PredefinedCodeRefactoringProviderNames.ReplaceConditionalWithStatements), Shared]
internal class CSharpReplaceConditionalWithStatementsCodeRefactoringProvider :
AbstractReplaceConditionalWithStatementsCodeRefactoringProvider<
ExpressionSyntax,
ConditionalExpressionSyntax,
StatementSyntax,
LocalDeclarationStatementSyntax,
ArgumentSyntax,
BaseArgumentListSyntax,
VariableDeclaratorSyntax,
VariableDeclaratorSyntax,
EqualsValueClauseSyntax>
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public CSharpReplaceConditionalWithStatementsCodeRefactoringProvider()
{
}
protected override bool CanRewriteLocalDeclarationStatement(LocalDeclarationStatementSyntax localDeclarationStatement)
{
// A using local decl must have an initializer, so we can't rewrite this to no longer have one.
if (localDeclarationStatement.UsingKeyword != default)
return false;
// ref local variables must have an initializer, so we can't rewrite this to no longer have one.
if (localDeclarationStatement.Declaration.Type is RefTypeSyntax)
return false;
return true;
}
protected override bool HasSingleVariable(
LocalDeclarationStatementSyntax localDeclarationStatement,
[NotNullWhen(true)] out VariableDeclaratorSyntax? variable)
{
if (localDeclarationStatement.Declaration.Variables.Count == 1)
{
variable = localDeclarationStatement.Declaration.Variables[0];
return true;
}
variable = null;
return false;
}
protected override LocalDeclarationStatementSyntax GetUpdatedLocalDeclarationStatement(
SyntaxGenerator generator,
LocalDeclarationStatementSyntax localDeclarationStatement,
ILocalSymbol symbol)
{
// If we have `var x = a ? b : c;`
// then we have to replace `var` with the actual type of the local when breaking this into multiple statements.
var type = localDeclarationStatement.Declaration.Type;
if (type.IsVar)
{
localDeclarationStatement = localDeclarationStatement.ReplaceNode(
type, symbol.Type.GenerateTypeSyntax(allowVar: false).WithTriviaFrom(type));
}
var variable = localDeclarationStatement.Declaration.Variables[0];
return localDeclarationStatement.ReplaceNode(
variable,
variable.WithInitializer(null).WithIdentifier(variable.Identifier.WithTrailingTrivia()));
}
}
|