public void IsOperatorEquals(string check, bool expected) { var testCode = @" namespace RoslynSandbox { using System; public class Foo { private int? bar1; private Nullable<int> bar2; private int bar3; private double? bar4; private string bar5; public Foo() { this.bar1 == this.bar1; } public int? Bar1 => this.bar1; } }"; testCode = testCode.AssertReplace("this.bar1 == this.bar1", check); var syntaxTree = CSharpSyntaxTree.ParseText(testCode); var compilation = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes()); var semanticModel = compilation.GetSemanticModel(syntaxTree); var binary = syntaxTree.FindBinaryExpression(check); var arg0 = semanticModel.GetSymbolSafe(binary.Left, CancellationToken.None); var arg1 = semanticModel.GetSymbolSafe(binary.Right, CancellationToken.None); Assert.AreEqual(expected, Equality.IsOperatorEquals(binary, semanticModel, CancellationToken.None, arg0, arg1)); Assert.AreEqual(expected, Equality.IsOperatorEquals(binary, semanticModel, CancellationToken.None, arg1, arg0)); }
private static bool CanFix(IfStatementSyntax ifStatement, SemanticModel semanticModel, CancellationToken cancellationToken, IParameterSymbol value, IFieldSymbol backingField, IPropertySymbol property) { foreach (var member in new ISymbol[] { backingField, property }) { if (Equality.IsOperatorEquals(ifStatement.Condition, semanticModel, cancellationToken, value, member) || Equality.IsObjectEquals(ifStatement.Condition, semanticModel, cancellationToken, value, member) || Equality.IsReferenceEquals(ifStatement.Condition, semanticModel, cancellationToken, value, member) || Equality.IsInstanceEquals(ifStatement.Condition, semanticModel, cancellationToken, value, member) || Equality.IsInstanceEquals(ifStatement.Condition, semanticModel, cancellationToken, member, value)) { return(true); } } return(false); }
private static void HandleInvocation(SyntaxNodeAnalysisContext context) { if (context.IsExcludedFromAnalysis()) { return; } var invocation = (InvocationExpressionSyntax)context.Node; var setter = invocation.FirstAncestorOrSelf <AccessorDeclarationSyntax>(); if (setter?.IsKind(SyntaxKind.SetAccessorDeclaration) != true) { return; } if (!IsFirstNotifyPropertyChange(invocation, context.SemanticModel, context.CancellationToken)) { return; } var propertyDeclaration = setter.FirstAncestorOrSelf <PropertyDeclarationSyntax>(); var property = context.SemanticModel.GetDeclaredSymbolSafe(propertyDeclaration, context.CancellationToken); if (!Property.TryGetBackingField(property, context.SemanticModel, context.CancellationToken, out IFieldSymbol backingField)) { return; } if (Property.TryFindValue(setter, context.SemanticModel, context.CancellationToken, out IParameterSymbol value)) { using (var pooledIfStatements = IfStatementWalker.Create(setter)) { foreach (var ifStatement in pooledIfStatements.Item.IfStatements) { if (ifStatement.SpanStart >= invocation.SpanStart) { continue; } foreach (var member in new ISymbol[] { backingField, property }) { if (Equality.IsOperatorEquals(ifStatement.Condition, context.SemanticModel, context.CancellationToken, value, member) || IsEqualsCheck(ifStatement.Condition, context.SemanticModel, context.CancellationToken, value, member)) { if (ifStatement.Statement.Span.Contains(invocation.Span)) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, invocation.FirstAncestorOrSelf <StatementSyntax>()?.GetLocation() ?? invocation.GetLocation())); } return; } if (Equality.IsOperatorNotEquals(ifStatement.Condition, context.SemanticModel, context.CancellationToken, value, member) || IsNegatedEqualsCheck(ifStatement.Condition, context.SemanticModel, context.CancellationToken, value, member)) { if (!ifStatement.Statement.Span.Contains(invocation.Span)) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, invocation.FirstAncestorOrSelf <StatementSyntax>()?.GetLocation() ?? invocation.GetLocation())); } return; } if (UsesValueAndMember(ifStatement, context.SemanticModel, context.CancellationToken, value, member)) { return; } } } } } context.ReportDiagnostic(Diagnostic.Create(Descriptor, invocation.FirstAncestorOrSelf <StatementSyntax>()?.GetLocation() ?? invocation.GetLocation())); }