public void IsOperatorNotEquals(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.IsOperatorNotEquals(binary, semanticModel, CancellationToken.None, arg0, arg1));
            Assert.AreEqual(expected, Equality.IsOperatorNotEquals(binary, semanticModel, CancellationToken.None, arg1, arg0));
        }
예제 #2
0
        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()));
        }