private StatementSyntax GenerateEqualityEqualsComparison(
            string propertyName,
            ExpressionSyntax left,
            ExpressionSyntax right)
        {
            string typeName = _propertyInfoDictionary[propertyName].TypeName;

            // if (!(TypeName.ValueComparer.Equals(left.Prop, right.Prop))
            //
            // We choose this form, rather than using the convenience method
            //
            //      if (left.Prop.ValueEquals(right.Prop))
            //
            // because the comparer method takes care of the null check.
            return(SyntaxFactory.IfStatement(
                       SyntaxFactory.PrefixUnaryExpression(
                           SyntaxKind.LogicalNotExpression,
                           SyntaxFactory.InvocationExpression(
                               SyntaxFactory.MemberAccessExpression(
                                   SyntaxKind.SimpleMemberAccessExpression,
                                   SyntaxFactory.MemberAccessExpression(
                                       SyntaxKind.SimpleMemberAccessExpression,
                                       SyntaxFactory.ParseTypeName(typeName),
                                       SyntaxFactory.IdentifierName(ValueComparerPropertyName)),
                                   SyntaxFactory.IdentifierName(WellKnownMethodNames.EqualsMethod)),
                               SyntaxHelper.ArgumentList(left, right))),
                       SyntaxFactory.Block(SyntaxHelper.Return(false))));
        }
        private StatementSyntax MakeCollectionEqualsTest(
            string comparisonKindKey,
            ExpressionSyntax left,
            ExpressionSyntax right)
        {
            return(SyntaxFactory.IfStatement(
                       // if (!Object.ReferenceEquals(Prop, other.Prop))
                       SyntaxHelper.AreDifferentObjects(left, right),
                       SyntaxFactory.Block(
                           // if (Prop == null || other.Prop == null)
                           SyntaxFactory.IfStatement(
                               SyntaxFactory.BinaryExpression(
                                   SyntaxKind.LogicalOrExpression,
                                   SyntaxHelper.IsNull(left),
                                   SyntaxHelper.IsNull(right)),
                               SyntaxFactory.Block(SyntaxHelper.Return(false))),

                           // if (Prop.Count != other.Prop.Count)
                           SyntaxFactory.IfStatement(
                               SyntaxFactory.BinaryExpression(
                                   SyntaxKind.NotEqualsExpression,
                                   SyntaxFactory.MemberAccessExpression(
                                       SyntaxKind.SimpleMemberAccessExpression,
                                       left,
                                       SyntaxFactory.IdentifierName(CountPropertyName)),
                                   SyntaxFactory.MemberAccessExpression(
                                       SyntaxKind.SimpleMemberAccessExpression,
                                       right,
                                       SyntaxFactory.IdentifierName(CountPropertyName))),
                               SyntaxFactory.Block(SyntaxHelper.Return(false))),

                           CollectionIndexLoop(comparisonKindKey, left, right)
                           )));
        }
 private StatementSyntax GeneratorOperatorEqualsComparison(ExpressionSyntax left, ExpressionSyntax right)
 {
     return(SyntaxFactory.IfStatement(
                SyntaxFactory.BinaryExpression(
                    SyntaxKind.NotEqualsExpression,
                    left,
                    right),
                SyntaxFactory.Block(SyntaxHelper.Return(false))));
 }
 private IfStatementSyntax GenerateReferenceEqualityTest()
 {
     return(SyntaxFactory.IfStatement(
                SyntaxFactory.InvocationExpression(
                    SyntaxFactory.IdentifierName(WellKnownMethodNames.ReferenceEqualsMethod),
                    SyntaxHelper.ArgumentList(
                        SyntaxFactory.IdentifierName(FirstEqualsAgumentName),
                        SyntaxFactory.IdentifierName(SecondEqualsArgumentName))),
                SyntaxFactory.Block(
                    SyntaxHelper.Return(true))));
 }
        private StatementSyntax[] GenerateGetHashCodeBody()
        {
            var statements = new List <StatementSyntax>();

            statements.Add(SyntaxFactory.IfStatement(
                               SyntaxFactory.InvocationExpression(
                                   SyntaxFactory.IdentifierName(WellKnownMethodNames.ReferenceEqualsMethod),
                                   SyntaxHelper.ArgumentList(
                                       SyntaxFactory.IdentifierName(GetHashCodeArgumentName),
                                       SyntaxHelper.Null())),
                               SyntaxFactory.Block(
                                   SyntaxHelper.Return(0))));

            statements.Add(SyntaxFactory.LocalDeclarationStatement(
                               SyntaxFactory.VariableDeclaration(
                                   SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
                                   SyntaxFactory.SingletonSeparatedList(
                                       SyntaxFactory.VariableDeclarator(
                                           SyntaxFactory.Identifier(GetHashCodeResultVariableName),
                                           default(BracketedArgumentListSyntax),
                                           SyntaxFactory.EqualsValueClause(
                                               SyntaxFactory.LiteralExpression(
                                                   SyntaxKind.NumericLiteralExpression,
                                                   SyntaxFactory.Literal(GetHashCodeSeedValue))))))));

            string[] propertyNames = _propertyInfoDictionary.GetPropertyNames();
            if (propertyNames.Any())
            {
                var uncheckedStatements = new List <StatementSyntax>();
                foreach (var propertyName in propertyNames)
                {
                    uncheckedStatements.Add(
                        GeneratePropertyHashCodeContribution(
                            propertyName,
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                SyntaxFactory.IdentifierName(GetHashCodeArgumentName),
                                SyntaxFactory.IdentifierName(propertyName))));
                }

                statements.Add(SyntaxFactory.CheckedStatement(
                                   SyntaxKind.UncheckedStatement,
                                   SyntaxFactory.Block(uncheckedStatements)));
            }

            statements.Add(SyntaxFactory.ReturnStatement(
                               SyntaxFactory.IdentifierName(GetHashCodeResultVariableName)));

            return(statements.ToArray());
        }
 private StatementSyntax GenerateObjectEqualsComparison(ExpressionSyntax left, ExpressionSyntax right)
 {
     // if (!(Object.Equals(left.Prop, right.Prop))
     return(SyntaxFactory.IfStatement(
                SyntaxFactory.PrefixUnaryExpression(
                    SyntaxKind.LogicalNotExpression,
                    SyntaxFactory.InvocationExpression(
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            SyntaxFactory.IdentifierName(WellKnownTypeNames.Object),
                            SyntaxFactory.IdentifierName(WellKnownMethodNames.EqualsMethod)),
                        SyntaxHelper.ArgumentList(left, right))),
                SyntaxFactory.Block(SyntaxHelper.Return(false))));
 }
 private IfStatementSyntax NullCheckTest()
 {
     return(SyntaxFactory.IfStatement(
                SyntaxFactory.BinaryExpression(
                    SyntaxKind.LogicalOrExpression,
                    SyntaxFactory.InvocationExpression(
                        SyntaxFactory.IdentifierName(WellKnownMethodNames.ReferenceEqualsMethod),
                        SyntaxHelper.ArgumentList(
                            SyntaxFactory.IdentifierName(FirstEqualsAgumentName),
                            SyntaxHelper.Null())),
                    SyntaxFactory.InvocationExpression(
                        SyntaxFactory.IdentifierName(WellKnownMethodNames.ReferenceEqualsMethod),
                        SyntaxHelper.ArgumentList(
                            SyntaxFactory.IdentifierName(SecondEqualsArgumentName),
                            SyntaxHelper.Null()))),
                SyntaxFactory.Block(
                    SyntaxHelper.Return(false))));
 }
        private IList <StatementSyntax> GeneratePropertyComparisons()
        {
            var statements = new List <StatementSyntax>();

            foreach (string propertyName in _propertyInfoDictionary.GetPropertyNames())
            {
                statements.Add(
                    GeneratePropertyComparison(
                        propertyName,
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            SyntaxFactory.IdentifierName(FirstEqualsAgumentName),
                            SyntaxFactory.IdentifierName(propertyName)),
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            SyntaxFactory.IdentifierName(SecondEqualsArgumentName),
                            SyntaxFactory.IdentifierName(propertyName))));
            }

            // All comparisons succeeded.
            statements.Add(SyntaxHelper.Return(true));

            return(statements);
        }
        private IfStatementSyntax MakeDictionaryEqualsTest(
            string propertyInfoKey,
            ExpressionSyntax left,
            ExpressionSyntax right)
        {
            string dictionaryElementVariableName = _localVariableNameGenerator.GetNextCollectionElementVariableName();
            string otherPropertyVariableName     = _localVariableNameGenerator.GetNextCollectionElementVariableName();

            // Construct the key into the PropertyInfoDictionary so we can look up how
            // dictionary elements are to be compared.
            string     valuePropertyInfoKey = PropertyInfoDictionary.MakeDictionaryItemKeyName(propertyInfoKey);
            TypeSyntax dictionaryValueType  = _propertyInfoDictionary[valuePropertyInfoKey].Type;

            return(SyntaxFactory.IfStatement(
                       // if (!Object.ReferenceEquals(left, right))
                       SyntaxHelper.AreDifferentObjects(left, right),
                       SyntaxFactory.Block(
                           // if (left == null || right == null || left.Count != right.Count)
                           SyntaxFactory.IfStatement(
                               SyntaxFactory.BinaryExpression(
                                   SyntaxKind.LogicalOrExpression,
                                   SyntaxHelper.IsNull(left),
                                   SyntaxFactory.BinaryExpression(
                                       SyntaxKind.LogicalOrExpression,
                                       SyntaxHelper.IsNull(right),
                                       SyntaxFactory.BinaryExpression(
                                           SyntaxKind.NotEqualsExpression,
                                           SyntaxFactory.MemberAccessExpression(
                                               SyntaxKind.SimpleMemberAccessExpression,
                                               left,
                                               SyntaxFactory.IdentifierName(CountPropertyName)),
                                           SyntaxFactory.MemberAccessExpression(
                                               SyntaxKind.SimpleMemberAccessExpression,
                                               right,
                                               SyntaxFactory.IdentifierName(CountPropertyName))))),
                               // return false;
                               SyntaxFactory.Block(SyntaxHelper.Return(false))),
                           // foreach (var value_0 in left)
                           SyntaxFactory.ForEachStatement(
                               SyntaxHelper.Var(),
                               dictionaryElementVariableName,
                               left,
                               SyntaxFactory.Block(
                                   // var value_1;
                                   SyntaxFactory.LocalDeclarationStatement(
                                       default(SyntaxTokenList), // modifiers
                                       SyntaxFactory.VariableDeclaration(
                                           dictionaryValueType,
                                           SyntaxFactory.SingletonSeparatedList(
                                               SyntaxFactory.VariableDeclarator(otherPropertyVariableName)))),
                                   // if (!right.TryGetValue(value_0.Key, out value_1))
                                   SyntaxFactory.IfStatement(
                                       SyntaxFactory.PrefixUnaryExpression(
                                           SyntaxKind.LogicalNotExpression,
                                           SyntaxFactory.InvocationExpression(
                                               SyntaxFactory.MemberAccessExpression(
                                                   SyntaxKind.SimpleMemberAccessExpression,
                                                   right,
                                                   SyntaxFactory.IdentifierName("TryGetValue")),
                                               SyntaxFactory.ArgumentList(
                                                   SyntaxFactory.SeparatedList(
                                                       new ArgumentSyntax[]
            {
                SyntaxFactory.Argument(
                    SyntaxFactory.MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        SyntaxFactory.IdentifierName(dictionaryElementVariableName),
                        SyntaxFactory.IdentifierName(KeyPropertyName))),
                SyntaxFactory.Argument(
                    default(NameColonSyntax),
                    SyntaxFactory.Token(SyntaxKind.OutKeyword),
                    SyntaxFactory.IdentifierName(otherPropertyVariableName))
            })))),
                                       // return false;
                                       SyntaxFactory.Block(SyntaxHelper.Return(false))),

                                   GeneratePropertyComparison(
                                       valuePropertyInfoKey,
                                       SyntaxFactory.MemberAccessExpression(
                                           SyntaxKind.SimpleMemberAccessExpression,
                                           SyntaxFactory.IdentifierName(dictionaryElementVariableName),
                                           SyntaxFactory.IdentifierName(ValuePropertyName)),
                                       SyntaxFactory.IdentifierName(otherPropertyVariableName)))))));
        }