private static bool HaveSameTarget([NotNull] IOperation leftOperation, [NotNull] IOperation rightOperation, [NotNull] NullCheckScanner scanner) { IOperation innerRightOperation = SkipNullableValueProperty(rightOperation, scanner.NullableHasValueProperty); return(OperationEqualityComparer.Default.Equals(leftOperation, innerRightOperation)); }
private void AnalyzeBinaryOperator(OperationAnalysisContext context, [NotNull] NullCheckScanner scanner) { var binaryOperator = (IBinaryOperation)context.Operation; NullCheckScanResult?scanResult = scanner.ScanBinaryOperator(binaryOperator); ReportForScanResult(scanResult, context.ReportDiagnostic); }
private void AnalyzeIsPattern(OperationAnalysisContext context, [NotNull] NullCheckScanner scanner) { var isPattern = (IIsPatternOperation)context.Operation; NullCheckScanResult?scanResult = scanner.ScanIsPattern(isPattern); ReportForScanResult(scanResult, context.ReportDiagnostic); }
private void AnalyzePropertyReference(OperationAnalysisContext context, [NotNull] NullCheckScanner scanner) { var propertyReference = (IPropertyReferenceOperation)context.Operation; NullCheckScanResult?scanResult = scanner.ScanPropertyReference(propertyReference); ReportForScanResult(scanResult, context.ReportDiagnostic); }
private static void AnalyzeBinaryOperator(OperationAnalysisContext context, [NotNull] NullCheckScanner scanner) { var binaryOperator = (IBinaryOperation)context.Operation; if (DoReportForNullableComparison(binaryOperator, scanner)) { context.ReportDiagnostic(Diagnostic.Create(NullableComparisonRule, binaryOperator.Syntax.GetLocation())); } }
private static void RegisterCompilationStart([NotNull] CompilationStartAnalysisContext startContext) { var scanner = new NullCheckScanner(startContext.Compilation); startContext.RegisterOperationAction(context => AnalyzePropertyReferenceAction(context, scanner), OperationKind.PropertyReference); startContext.RegisterOperationAction(context => AnalyzeBinaryOperatorAction(context, scanner), OperationKind.BinaryOperator); }
public override void Initialize([NotNull] AnalysisContext context) { context.EnableConcurrentExecution(); context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.RegisterCompilationStartAction(startContext => { var scanner = new NullCheckScanner(startContext.Compilation); RegisterForOperations(startContext, scanner); }); }
private void RegisterForOperations([NotNull] CompilationStartAnalysisContext startContext, [NotNull] NullCheckScanner scanner) { startContext.RegisterOperationAction(context => context.SkipInvalid(_ => AnalyzePropertyReference(context, scanner)), OperationKind.PropertyReference); startContext.RegisterOperationAction(context => context.SkipInvalid(_ => AnalyzeInvocation(context, scanner)), OperationKind.Invocation); startContext.RegisterOperationAction(context => context.SkipInvalid(_ => AnalyzeIsPattern(context, scanner)), OperationKind.IsPattern); startContext.RegisterOperationAction(context => context.SkipInvalid(_ => AnalyzeBinaryOperator(context, scanner)), OperationKind.BinaryOperator); }
private static bool DoReportForNullableComparison([NotNull] IBinaryOperation binaryOperator, [NotNull] NullCheckScanner scanner) { if (IsLogicalAnd(binaryOperator)) { IOperation leftTarget = TryGetTargetInNotNullCheck(binaryOperator.LeftOperand, scanner); if (leftTarget != null && !(leftTarget is IInvocationOperation)) { if (DoReportForMatchingRightOperandInNullableComparison(binaryOperator.RightOperand, scanner, leftTarget)) { return(true); } } } return(false); }
private static bool DoReportForMatchingRightOperandInNullableComparison([NotNull] IOperation rightOperand, [NotNull] NullCheckScanner scanner, [NotNull] IOperation leftTarget) { if (rightOperand is IBinaryOperation rightOperation && NumericComparisonOperators.Contains(rightOperation.OperatorKind)) { if (HaveSameTarget(leftTarget, rightOperation.LeftOperand, scanner) || HaveSameTarget(leftTarget, rightOperation.RightOperand, scanner)) { if (!IsEqualityComparisonWithNullableType(rightOperation)) { return(true); } } } return(false); }
private static void AnalyzePropertyReference(OperationAnalysisContext context, [NotNull] NullCheckScanner scanner) { var propertyReference = (IPropertyReferenceOperation)context.Operation; NullCheckScanResult?scanResult = scanner.ScanPropertyReference(propertyReference); if (scanResult != null && scanResult.Value.Method == NullCheckMethod.NullableHasValueMethod) { if (propertyReference.Parent is IBinaryOperation binaryOperator && DoReportForNullableComparison(binaryOperator, scanner)) { return; } context.ReportDiagnostic(Diagnostic.Create(NullableHasValueRule, propertyReference.Syntax.GetLocation())); } }
public NullCheckVisitor([NotNull] NullCheckScanner scanner) { Guard.NotNull(scanner, nameof(scanner)); this.scanner = scanner; }
private static IOperation TryGetTargetInNotNullCheck([NotNull] IOperation operation, [NotNull] NullCheckScanner scanner) { IOperation targetOperation = SkipNotOperators(operation); var visitor = new NullCheckVisitor(scanner); visitor.Visit(targetOperation); return(visitor.ScanResult != null && visitor.ScanResult.Value.Operand == NullCheckOperand.IsNotNull ? visitor.ScanResult.Value.Target : null); }