private static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context) { var conditionalExpression = (ConditionalExpressionSyntax)context.Node; if (context.Node.ContainsDiagnostics) { return; } if (context.Node.SpanContainsDirectives()) { return; } ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression); if (!info.Success) { return; } SyntaxKind trueKind = info.WhenTrue.Kind(); if (trueKind == SyntaxKind.TrueLiteralExpression) { if (context.SemanticModel.GetTypeInfo(info.WhenFalse, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression); } } else { SyntaxKind falseKind = info.WhenFalse.Kind(); if (falseKind == SyntaxKind.FalseLiteralExpression) { if (context.SemanticModel.GetTypeInfo(info.WhenTrue, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression); } } else if (trueKind == SyntaxKind.FalseLiteralExpression && falseKind == SyntaxKind.TrueLiteralExpression) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression); } } }
public static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context) { var conditionalExpression = (ConditionalExpressionSyntax)context.Node; if (context.Node.ContainsDiagnostics) { return; } if (context.Node.SpanContainsDirectives()) { return; } ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression); if (!info.Success) { return; } switch (info.WhenTrue.Kind()) { case SyntaxKind.TrueLiteralExpression: { if (info.WhenFalse.Kind() == SyntaxKind.FalseLiteralExpression) { context.ReportDiagnostic(DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression); } break; } case SyntaxKind.FalseLiteralExpression: { if (info.WhenFalse.Kind() == SyntaxKind.TrueLiteralExpression) { context.ReportDiagnostic(DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression); } break; } } }
public static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context) { var conditionalExpression = (ConditionalExpressionSyntax)context.Node; if (context.Node.ContainsDiagnostics) { return; } if (context.Node.SpanContainsDirectives()) { return; } ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression); if (!info.Success) { return; } SyntaxKind trueKind = info.WhenTrue.Kind(); if (trueKind == SyntaxKind.TrueLiteralExpression) { context.ReportDiagnostic(DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression); } else { SyntaxKind falseKind = info.WhenFalse.Kind(); if (falseKind == SyntaxKind.FalseLiteralExpression) { context.ReportDiagnostic(DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression); } else if (trueKind == SyntaxKind.FalseLiteralExpression && falseKind == SyntaxKind.TrueLiteralExpression) { context.ReportDiagnostic(DiagnosticDescriptors.SimplifyConditionalExpression, conditionalExpression); } } }
private static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context) { var conditionalExpression = (ConditionalExpressionSyntax)context.Node; if (conditionalExpression.ContainsDiagnostics) { return; } ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression, walkDownParentheses: false); if (!info.Success) { return; } if (info.Condition.Kind() == SyntaxKind.ParenthesizedExpression) { return; } DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.ParenthesizeConditionInConditionalExpression, info.Condition); }
private static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context) { var conditionalExpression = (ConditionalExpressionSyntax)context.Node; if (context.Node.ContainsDiagnostics) { return; } if (context.Node.SpanContainsDirectives()) { return; } ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression); if (!info.Success) { return; } SyntaxKind trueKind = info.WhenTrue.Kind(); SyntaxKind falseKind = info.WhenFalse.Kind(); if (trueKind == SyntaxKind.TrueLiteralExpression) { // a ? true : false >>> a // a ? true : b >>> a || b if (falseKind == SyntaxKind.FalseLiteralExpression || context.SemanticModel.GetTypeInfo(info.WhenFalse, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean) { Report(DiagnosticDescriptors.SimplifyConditionalExpression); } } else if (trueKind == SyntaxKind.FalseLiteralExpression) { /// a ? false : true >>> !a if (falseKind == SyntaxKind.TrueLiteralExpression) { Report(DiagnosticDescriptors.SimplifyConditionalExpression); } /// a ? false : b >>> !a && b else if (context.SemanticModel.GetTypeInfo(info.WhenFalse, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean) { Report(DiagnosticDescriptors.SimplifyConditionalExpression2); } } else if (falseKind == SyntaxKind.TrueLiteralExpression) { // a ? b : true >>> !a || b if (context.SemanticModel.GetTypeInfo(info.WhenTrue, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean) { Report(DiagnosticDescriptors.SimplifyConditionalExpression2); } } else if (falseKind == SyntaxKind.FalseLiteralExpression) { // a ? b : false >>> a && b if (context.SemanticModel.GetTypeInfo(info.WhenTrue, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean) { Report(DiagnosticDescriptors.SimplifyConditionalExpression); } } void Report(DiagnosticDescriptor descriptor) { DiagnosticHelpers.ReportDiagnosticIfNotSuppressed(context, descriptor, conditionalExpression); } }
public static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken) { ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression); ExpressionSyntax whenTrue = info.WhenTrue; ExpressionSyntax whenFalse = info.WhenFalse; SyntaxKind trueKind = whenTrue.Kind(); SyntaxKind falseKind = whenFalse.Kind(); ExpressionSyntax newNode = null; if (trueKind == SyntaxKind.TrueLiteralExpression) { if (falseKind == SyntaxKind.FalseLiteralExpression) { newNode = CreateNewNode(conditionalExpression, info.Condition); } else { SyntaxTriviaList trailingTrivia = info .QuestionToken .LeadingTrivia .AddRange(info.QuestionToken.TrailingTrivia) .AddRange(whenTrue.GetLeadingTrivia()) .EmptyIfWhitespace(); newNode = LogicalOrExpression( conditionalExpression.Condition.Parenthesize().AppendToTrailingTrivia(trailingTrivia), Token(info.ColonToken.LeadingTrivia, SyntaxKind.BarBarToken, info.ColonToken.TrailingTrivia), whenFalse.Parenthesize()); } } else if (falseKind == SyntaxKind.FalseLiteralExpression) { SyntaxTriviaList trailingTrivia = whenTrue .GetTrailingTrivia() .AddRange(info.ColonToken.LeadingTrivia) .AddRange(info.ColonToken.TrailingTrivia) .AddRange(whenFalse.GetLeadingTrivia()) .EmptyIfWhitespace() .AddRange(whenFalse.GetTrailingTrivia()); newNode = LogicalAndExpression( conditionalExpression.Condition.Parenthesize(), Token(info.QuestionToken.LeadingTrivia, SyntaxKind.AmpersandAmpersandToken, info.QuestionToken.TrailingTrivia), whenTrue.WithTrailingTrivia(trailingTrivia).Parenthesize()); } else if (trueKind == SyntaxKind.FalseLiteralExpression && falseKind == SyntaxKind.TrueLiteralExpression) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); newNode = CreateNewNode(conditionalExpression, Inverter.LogicallyNegate(info.Condition, semanticModel, cancellationToken)); } newNode = newNode.Parenthesize(); return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false)); }
public static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context) { if (context.Node.SpanContainsDirectives()) { return; } var conditionalExpression = (ConditionalExpressionSyntax)context.Node; ConditionalExpressionInfo conditionalExpressionInfo = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression); if (!conditionalExpressionInfo.Success) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(conditionalExpressionInfo.Condition, semanticModel: semanticModel, cancellationToken: cancellationToken); if (!nullCheck.Success) { return; } ExpressionSyntax whenNotNull = (nullCheck.IsCheckingNotNull) ? conditionalExpressionInfo.WhenTrue : conditionalExpressionInfo.WhenFalse; ExpressionSyntax whenNull = (nullCheck.IsCheckingNotNull) ? conditionalExpressionInfo.WhenFalse : conditionalExpressionInfo.WhenTrue; if (CSharpFactory.AreEquivalent(nullCheck.Expression, whenNotNull)) { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseCoalesceExpressionInsteadOfConditionalExpression) && semanticModel .GetTypeSymbol(nullCheck.Expression, cancellationToken)? .IsReferenceTypeOrNullableType() == true) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseCoalesceExpressionInsteadOfConditionalExpression, conditionalExpression); } } else if (whenNotNull.IsKind( SyntaxKind.SimpleMemberAccessExpression, SyntaxKind.ElementAccessExpression, SyntaxKind.ConditionalAccessExpression, SyntaxKind.InvocationExpression)) { ExpressionSyntax expression = UseConditionalAccessAnalyzer.FindExpressionThatCanBeConditionallyAccessed( nullCheck.Expression, whenNotNull, semanticModel, cancellationToken); if (expression == null) { return; } ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(nullCheck.Expression, cancellationToken); if (typeSymbol == null) { return; } if (typeSymbol.IsReferenceType) { Analyze(context, conditionalExpressionInfo, whenNull, whenNotNull, semanticModel, cancellationToken); } else if (typeSymbol.IsNullableType()) { if (expression.IsParentKind(SyntaxKind.SimpleMemberAccessExpression)) { var memberAccessExpression = (MemberAccessExpressionSyntax)expression.Parent; if (!memberAccessExpression.IsParentKind(SyntaxKind.InvocationExpression) && (memberAccessExpression.Name as IdentifierNameSyntax)?.Identifier.ValueText == "Value") { if (memberAccessExpression == whenNotNull) { if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseCoalesceExpressionInsteadOfConditionalExpression)) { DiagnosticHelpers.ReportDiagnostic( context, DiagnosticDescriptors.UseCoalesceExpressionInsteadOfConditionalExpression, conditionalExpression); } } else { Analyze(context, conditionalExpressionInfo, whenNull, whenNotNull, semanticModel, cancellationToken); } } } } } else if (!context.IsAnalyzerSuppressed(DiagnosticDescriptors.UseConditionalAccessInsteadOfConditionalExpression) && whenNotNull.IsKind(SyntaxKind.CastExpression) && whenNull.IsKind(SyntaxKind.NullLiteralExpression, SyntaxKind.DefaultLiteralExpression)) { var castExpression = (CastExpressionSyntax)whenNotNull; if (castExpression.Type.IsKind(SyntaxKind.NullableType) && castExpression.Expression.IsKind(SyntaxKind.InvocationExpression, SyntaxKind.SimpleMemberAccessExpression, SyntaxKind.ElementAccessExpression)) { ExpressionSyntax expression = UseConditionalAccessAnalyzer.FindExpressionThatCanBeConditionallyAccessed( nullCheck.Expression, castExpression.Expression, isNullable: true, semanticModel, cancellationToken); if (expression != null) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(nullCheck.Expression, cancellationToken); if (typeSymbol?.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticDescriptors.UseConditionalAccessInsteadOfConditionalExpression, conditionalExpression); } } } } }
public static bool CanRefactor(ConditionalExpressionSyntax conditionalExpression) { return(SyntaxInfo.ConditionalExpressionInfo(conditionalExpression).Success); }
public static async Task <Document> RefactorAsync( Document document, ConditionalExpressionSyntax conditionalExpression, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false); ConditionalExpressionInfo conditionalExpressionInfo = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression); NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(conditionalExpressionInfo.Condition, semanticModel: semanticModel, cancellationToken: cancellationToken); ExpressionSyntax whenNotNull = (nullCheck.IsCheckingNotNull) ? conditionalExpressionInfo.WhenTrue : conditionalExpressionInfo.WhenFalse; ExpressionSyntax whenNull = (nullCheck.IsCheckingNotNull) ? conditionalExpressionInfo.WhenFalse : conditionalExpressionInfo.WhenTrue; ExpressionSyntax expression = UseConditionalAccessAnalyzer.FindExpressionThatCanBeConditionallyAccessed(nullCheck.Expression, whenNotNull); bool coalesce = false; ExpressionSyntax newNode = null; if (CSharpFactory.AreEquivalent(nullCheck.Expression, whenNotNull)) { newNode = nullCheck.Expression; coalesce = true; } else if (semanticModel .GetTypeSymbol(nullCheck.Expression, cancellationToken) .IsNullableType()) { if (expression.IsParentKind(SyntaxKind.SimpleMemberAccessExpression)) { var memberAccessExpression = (MemberAccessExpressionSyntax)expression.Parent; if (!memberAccessExpression.IsParentKind(SyntaxKind.InvocationExpression) && (memberAccessExpression.Name as IdentifierNameSyntax)?.Identifier.ValueText == "Value") { if (memberAccessExpression == whenNotNull) { newNode = nullCheck.Expression; coalesce = true; } else { newNode = ParseExpression($"{expression}?{whenNotNull.ToString().Substring(memberAccessExpression.Span.End - whenNotNull.SpanStart)}"); } } } } if (newNode == null) { newNode = ParseExpression(whenNotNull.ToString().Insert(expression.Span.End - whenNotNull.SpanStart, "?")); } if (coalesce || !semanticModel.GetTypeSymbol(whenNotNull, cancellationToken).IsReferenceType) { newNode = CoalesceExpression(newNode.Parenthesize(), whenNull.Parenthesize()); } newNode = newNode .WithTriviaFrom(conditionalExpression) .Parenthesize(); return(await document.ReplaceNodeAsync(conditionalExpression, newNode, cancellationToken).ConfigureAwait(false)); }
private static void AnalyzeConditionalExpression(SyntaxNodeAnalysisContext context) { if (context.Node.ContainsDiagnostics) { return; } if (context.Node.SpanContainsDirectives()) { return; } var conditionalExpression = (ConditionalExpressionSyntax)context.Node; ConditionalExpressionInfo info = SyntaxInfo.ConditionalExpressionInfo(conditionalExpression); if (!info.Success) { return; } SyntaxKind trueKind = info.WhenTrue.Kind(); SyntaxKind falseKind = info.WhenFalse.Kind(); if (trueKind == SyntaxKind.TrueLiteralExpression) { // a ? true : false >>> a // a ? true : b >>> a || b if (falseKind == SyntaxKind.FalseLiteralExpression || (falseKind != SyntaxKind.ThrowExpression && context.SemanticModel.GetTypeInfo(info.WhenFalse, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean)) { ReportDiagnostic(); } } else if (trueKind == SyntaxKind.FalseLiteralExpression) { /// a ? false : true >>> !a if (falseKind == SyntaxKind.TrueLiteralExpression) { ReportDiagnostic(); } /// a ? false : b >>> !a && b else if (falseKind != SyntaxKind.ThrowExpression && !AnalyzerOptions.DoNotSimplifyConditionalExpressionWhenConditionIsInverted.IsEnabled(context) && context.SemanticModel.GetTypeInfo(info.WhenFalse, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.SimplifyConditionalExpression, conditionalExpression, AnalyzerOptions.DoNotSimplifyConditionalExpressionWhenConditionIsInverted); } } else if (falseKind == SyntaxKind.TrueLiteralExpression) { // a ? b : true >>> !a || b if (trueKind != SyntaxKind.ThrowExpression && !AnalyzerOptions.DoNotSimplifyConditionalExpressionWhenConditionIsInverted.IsEnabled(context) && context.SemanticModel.GetTypeInfo(info.WhenTrue, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean) { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.SimplifyConditionalExpression, conditionalExpression, AnalyzerOptions.DoNotSimplifyConditionalExpressionWhenConditionIsInverted); } } else if (falseKind == SyntaxKind.FalseLiteralExpression) { // a ? b : false >>> a && b if (trueKind != SyntaxKind.ThrowExpression && context.SemanticModel.GetTypeInfo(info.WhenTrue, context.CancellationToken).ConvertedType?.SpecialType == SpecialType.System_Boolean) { ReportDiagnostic(); } } void ReportDiagnostic() { DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.SimplifyConditionalExpression, conditionalExpression); } }