public static void AnalyzeLogicalAndExpression(SyntaxNodeAnalysisContext context, INamedTypeSymbol expressionType) { var logicalAndExpression = (BinaryExpressionSyntax)context.Node; if (logicalAndExpression.ContainsDiagnostics) { return; } ExpressionSyntax expression = SyntaxInfo.NullCheckExpressionInfo(logicalAndExpression.Left, allowedStyles: NullCheckStyles.NotEqualsToNull).Expression; if (expression == null) { return; } if (context.SemanticModel .GetTypeSymbol(expression, context.CancellationToken)? .IsReferenceType != true) { return; } ExpressionSyntax right = logicalAndExpression.Right?.WalkDownParentheses(); if (right == null) { return; } if (!ValidateRightExpression(right, context.SemanticModel, context.CancellationToken)) { return; } if (RefactoringUtility.ContainsOutArgumentWithLocal(right, context.SemanticModel, context.CancellationToken)) { return; } ExpressionSyntax expression2 = FindExpressionThatCanBeConditionallyAccessed(expression, right); if (expression2?.SpanContainsDirectives() != false) { return; } if (logicalAndExpression.IsInExpressionTree(expressionType, context.SemanticModel, context.CancellationToken)) { return; } context.ReportDiagnostic(DiagnosticDescriptors.UseConditionalAccess, logicalAndExpression); }
private static bool IsFixable( ExpressionSyntax left, ExpressionSyntax right, SyntaxKind binaryExpressionKind, SemanticModel semanticModel, CancellationToken cancellationToken) { NullCheckStyles allowedStyles = (binaryExpressionKind == SyntaxKind.LogicalAndExpression) ? NullCheckStyles.NotEqualsToNull : NullCheckStyles.EqualsToNull; NullCheckExpressionInfo nullCheck = SyntaxInfo.NullCheckExpressionInfo(left, allowedStyles: allowedStyles); ExpressionSyntax expression = nullCheck.Expression; if (expression == null) { return(false); } ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); if (typeSymbol == null) { return(false); } if (!typeSymbol.IsReferenceTypeOrNullableType()) { return(false); } if (right == null) { return(false); } if (!ValidateRightExpression(right, binaryExpressionKind, semanticModel, cancellationToken)) { return(false); } if (RefactoringUtility.ContainsOutArgumentWithLocal(right, semanticModel, cancellationToken)) { return(false); } ExpressionSyntax expression2 = FindExpressionThatCanBeConditionallyAccessed(expression, right, isNullable: !typeSymbol.IsReferenceType); return(expression2?.SpanContainsDirectives() == false); }
private static void Analyze( SyntaxNodeAnalysisContext context, ConditionalExpressionInfo conditionalExpressionInfo, ExpressionSyntax whenNull, ExpressionSyntax whenNotNull, SemanticModel semanticModel, CancellationToken cancellationToken) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(whenNotNull, cancellationToken); if (typeSymbol?.IsErrorType() == false && (typeSymbol.IsReferenceType || typeSymbol.IsValueType) && semanticModel.IsDefaultValue(typeSymbol, whenNull, cancellationToken) && !RefactoringUtility.ContainsOutArgumentWithLocal(whenNotNull, semanticModel, cancellationToken) && !conditionalExpressionInfo.ConditionalExpression.IsInExpressionTree(semanticModel, cancellationToken)) { context.ReportDiagnostic( DiagnosticDescriptors.UseConditionalAccessInsteadOfConditionalExpression, conditionalExpressionInfo.ConditionalExpression); } }