public void AnalyzeObjectCreationOperation(OperationAnalysisContext context) { var operation = (IObjectCreationOperation)context.Operation; var type = operation.Type as INamedTypeSymbol; if (type?.OriginalDefinition == null) { return; } if (operation.Constructor == null) { return; } if (HashSetSymbols.Any(t => type.OriginalDefinition.IsEqualTo(t))) { if (operation.Constructor.Parameters.Any(arg => arg.Type.IsEqualTo(IEqualityComparerSymbol?.Construct(type.TypeArguments[0])))) { return; } if (IsStruct(type.TypeArguments[0]) && HasDefaultEqualsOrHashCodeImplementations(type.TypeArguments[0])) { context.ReportDiagnostic(s_rule2, operation); } } }
public void AnalyzeInvocationOperation(OperationAnalysisContext context) { var operation = (IInvocationOperation)context.Operation; if (operation.TargetMethod.Name == nameof(ValueType.GetHashCode)) { var actualType = operation.Children.FirstOrDefault()?.GetActualType(); if (actualType == null) { return; } if (IsStruct(actualType) && HasDefaultEqualsOrHashCodeImplementations(actualType)) { context.ReportDiagnostic(s_rule, operation); } } else if (operation.TargetMethod.Name == nameof(ValueType.Equals)) { var actualType = operation.Children.FirstOrDefault()?.GetActualType(); if (actualType == null) { return; } if (IsStruct(actualType) && HasDefaultEqualsOrHashCodeImplementations(actualType)) { context.ReportDiagnostic(s_rule, operation); } } else if (IsImmutableCreateMethod(operation.TargetMethod)) { var type = operation.TargetMethod.TypeArguments[0]; if (IsStruct(type) && HasDefaultEqualsOrHashCodeImplementations(type)) { if (operation.TargetMethod.ContainingType.IsEqualTo(ImmutableSortedDictionarySymbol)) { if (operation.TargetMethod.Parameters.Any(arg => arg.Type.IsEqualTo(IComparerSymbol?.Construct(type)))) { return; } } else { if (operation.TargetMethod.Parameters.Any(arg => arg.Type.IsEqualTo(IEqualityComparerSymbol?.Construct(type)))) { return; } } context.ReportDiagnostic(s_rule2, operation); } } bool IsImmutableCreateMethod(IMethodSymbol methodSymbol) { var names = new[] { "Create", "CreateBuilder", "CreateRange", }; var builderTypes = new[] { ImmutableDictionarySymbol, ImmutableHashSetSymbol, ImmutableSortedDictionarySymbol, }; return(methodSymbol.Arity >= 1 && names.Contains(methodSymbol.Name, StringComparer.Ordinal) && builderTypes.Any(type => type.IsEqualTo(methodSymbol.ContainingType.OriginalDefinition))); } }