diff --git a/src/Analyzers/CSharp/Analysis/SimplifyCoalesceExpressionAnalyzer.cs b/src/Analyzers/CSharp/Analysis/SimplifyCoalesceExpressionAnalyzer.cs index 8b86898c2c..8b79310cd9 100644 --- a/src/Analyzers/CSharp/Analysis/SimplifyCoalesceExpressionAnalyzer.cs +++ b/src/Analyzers/CSharp/Analysis/SimplifyCoalesceExpressionAnalyzer.cs @@ -94,7 +94,7 @@ private static BinaryExpressionPart GetRedundantPart( return BinaryExpressionPart.Left; case SyntaxKind.DefaultExpression: { - if (IsDefaultOfReferenceType((DefaultExpressionSyntax)left, semanticModel, cancellationToken)) + if (IsDefaultOfReferenceOrNullableType((DefaultExpressionSyntax)left, semanticModel, cancellationToken)) return BinaryExpressionPart.Left; break; @@ -129,10 +129,12 @@ private static BinaryExpressionPart GetRedundantPart( switch (rightKind) { case SyntaxKind.NullLiteralExpression: - return BinaryExpressionPart.Right; + { + return BinaryExpressionPart.Right; + } case SyntaxKind.DefaultExpression: { - if (IsDefaultOfReferenceType((DefaultExpressionSyntax)right, semanticModel, cancellationToken)) + if (IsDefaultOfReferenceOrNullableType((DefaultExpressionSyntax)right, semanticModel, cancellationToken)) return BinaryExpressionPart.Right; break; @@ -148,12 +150,15 @@ private static BinaryExpressionPart GetRedundantPart( return BinaryExpressionPart.None; } - private static bool IsDefaultOfReferenceType(DefaultExpressionSyntax defaultExpression, SemanticModel semanticModel, CancellationToken cancellationToken) + private static bool IsDefaultOfReferenceOrNullableType(DefaultExpressionSyntax defaultExpression, SemanticModel semanticModel, CancellationToken cancellationToken) { TypeSyntax type = defaultExpression.Type; if (type != null) { + if (type.IsKind(SyntaxKind.NullableType)) + return true; + ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken); if (typeSymbol?.IsErrorType() == false diff --git a/src/Tests/Analyzers.Tests/RCS1143SimplifyCoalesceExpressionTests.cs b/src/Tests/Analyzers.Tests/RCS1143SimplifyCoalesceExpressionTests.cs new file mode 100644 index 0000000000..c5ed5247d7 --- /dev/null +++ b/src/Tests/Analyzers.Tests/RCS1143SimplifyCoalesceExpressionTests.cs @@ -0,0 +1,50 @@ +// Copyright (c) Josef Pihrt. All rights reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Diagnostics; +using Roslynator.CSharp.CodeFixes; +using Xunit; + +namespace Roslynator.CSharp.Analysis.Tests +{ + public class RCS1143SimplifyCoalesceExpressionTests : AbstractCSharpFixVerifier + { + public override DiagnosticDescriptor Descriptor { get; } = DiagnosticDescriptors.SimplifyCoalesceExpression; + + public override DiagnosticAnalyzer Analyzer { get; } = new SimplifyCoalesceExpressionAnalyzer(); + + public override CodeFixProvider FixProvider { get; } = new BinaryExpressionCodeFixProvider(); + + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.SimplifyCoalesceExpression)] + public async Task Test_DefaultOfNullableType() + { + await VerifyDiagnosticAndFixAsync(@" +class C +{ + void M() + { + C x = null; + + int? y = x?.M2() [|?? default(int?)|]; + } + + int M2() => default; +} +", @" +class C +{ + void M() + { + C x = null; + + int? y = x?.M2(); + } + + int M2() => default; +} +"); + } + } +}