Пример #1
0
        private StatementSyntax GenerateCollectionHashCodeContribution(
            string hashKindKey,
            ExpressionSyntax expression)
        {
            string collectionElementVariableName = _localVariableNameGenerator.GetNextCollectionElementVariableName();

            // From the type of the element (primitive, object, list, or dictionary), create
            // the appropriate hash generation code.
            string elementHashTypeKey = PropertyInfoDictionary.MakeElementKeyName(hashKindKey);

            StatementSyntax hashCodeContribution =
                GeneratePropertyHashCodeContribution(
                    elementHashTypeKey,
                    SyntaxFactory.IdentifierName(collectionElementVariableName));

            return(SyntaxFactory.IfStatement(
                       SyntaxHelper.IsNotNull(expression),
                       SyntaxFactory.Block(
                           SyntaxFactory.ForEachStatement(
                               SyntaxHelper.Var(),
                               collectionElementVariableName,
                               expression,
                               SyntaxFactory.Block(
                                   SyntaxFactory.ExpressionStatement(
                                       SyntaxFactory.AssignmentExpression(
                                           SyntaxKind.SimpleAssignmentExpression,
                                           SyntaxFactory.IdentifierName(GetHashCodeResultVariableName),
                                           SyntaxFactory.BinaryExpression(
                                               SyntaxKind.MultiplyExpression,
                                               SyntaxFactory.IdentifierName(GetHashCodeResultVariableName),
                                               SyntaxFactory.LiteralExpression(
                                                   SyntaxKind.NumericLiteralExpression,
                                                   SyntaxFactory.Literal(GetHashCodeCombiningValue))))),
                                   hashCodeContribution)))));
        }
Пример #2
0
        private StatementSyntax GenerateDictionaryHashCodeContribution(ExpressionSyntax expression)
        {
            string xorValueVariableName          = _localVariableNameGenerator.GetNextXorVariableName();
            string collectionElementVariableName = _localVariableNameGenerator.GetNextCollectionElementVariableName();

            return(SyntaxFactory.IfStatement(
                       SyntaxHelper.IsNotNull(expression),
                       SyntaxFactory.Block(
                           // int xor_0 = 0;
                           SyntaxFactory.LocalDeclarationStatement(
                               SyntaxFactory.VariableDeclaration(
                                   SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
                                   SyntaxFactory.SingletonSeparatedList(
                                       SyntaxFactory.VariableDeclarator(
                                           SyntaxFactory.Identifier(xorValueVariableName),
                                           default(BracketedArgumentListSyntax),
                                           SyntaxFactory.EqualsValueClause(
                                               SyntaxFactory.LiteralExpression(
                                                   SyntaxKind.NumericLiteralExpression,
                                                   SyntaxFactory.Literal(0)))))))
                           .WithLeadingTrivia(
                               SyntaxFactory.ParseLeadingTrivia(Resources.XorDictionaryComment)),

                           SyntaxFactory.ForEachStatement(
                               SyntaxHelper.Var(),
                               collectionElementVariableName,
                               expression,
                               SyntaxFactory.Block(
                                   // xor_0 ^= value_0.Key.GetHashCode();
                                   Xor(xorValueVariableName, collectionElementVariableName, KeyPropertyName),
                                   SyntaxFactory.IfStatement(
                                       SyntaxHelper.IsNotNull(
                                           SyntaxFactory.MemberAccessExpression(
                                               SyntaxKind.SimpleMemberAccessExpression,
                                               SyntaxFactory.IdentifierName(collectionElementVariableName),
                                               SyntaxFactory.IdentifierName(ValuePropertyName))),
                                       SyntaxFactory.Block(
                                           Xor(xorValueVariableName, collectionElementVariableName, ValuePropertyName))))),

                           SyntaxFactory.ExpressionStatement(
                               SyntaxFactory.AssignmentExpression(
                                   SyntaxKind.SimpleAssignmentExpression,
                                   SyntaxFactory.IdentifierName(GetHashCodeResultVariableName),
                                   SyntaxFactory.BinaryExpression(
                                       SyntaxKind.AddExpression,
                                       SyntaxFactory.ParenthesizedExpression(
                                           SyntaxFactory.BinaryExpression(
                                               SyntaxKind.MultiplyExpression,
                                               SyntaxFactory.IdentifierName(GetHashCodeResultVariableName),
                                               SyntaxFactory.LiteralExpression(
                                                   SyntaxKind.NumericLiteralExpression,
                                                   SyntaxFactory.Literal(GetHashCodeCombiningValue)))),
                                       SyntaxFactory.IdentifierName(xorValueVariableName)))))));
        }
Пример #3
0
        private StatementSyntax[] GenerateArrayVisit(
            int arrayRank,
            int nestingLevel,
            ExpressionSyntax arrayValuedExpression)
        {
            ExpressionSyntax loopLimitExpression;

            if (nestingLevel == 0)
            {
                // node.Locations.Count
                loopLimitExpression = SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    arrayValuedExpression,
                    SyntaxFactory.IdentifierName(CountPropertyName));
            }
            else
            {
                // value_0.Count
                loopLimitExpression = SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    SyntaxFactory.IdentifierName(
                        LocalVariableNameGenerator.GetCollectionElementVariableName(nestingLevel - 1)),
                    SyntaxFactory.IdentifierName(CountPropertyName));
            }

            var statements = new List <StatementSyntax>();

            if (nestingLevel < arrayRank)
            {
                // We're not yet at the innermost level, so we need another for loop.
                string loopVariableName         = LocalVariableNameGenerator.GetLoopIndexVariableName(nestingLevel);
                string outerLoopVariableName    = LocalVariableNameGenerator.GetLoopIndexVariableName(nestingLevel - 1);
                string arrayElementVariableName = LocalVariableNameGenerator.GetCollectionElementVariableName(nestingLevel - 1);

                // For every level except the outermost, we need to get an array element and test whether
                // it's null.
                if (nestingLevel > 0)
                {
                    // var value_0 = node.Locations[index_0];
                    statements.Add(
                        SyntaxFactory.LocalDeclarationStatement(
                            SyntaxFactory.VariableDeclaration(
                                SyntaxHelper.Var(),
                                SyntaxFactory.SingletonSeparatedList(
                                    SyntaxFactory.VariableDeclarator(
                                        SyntaxFactory.Identifier(arrayElementVariableName),
                                        default(BracketedArgumentListSyntax),
                                        SyntaxFactory.EqualsValueClause(
                                            SyntaxFactory.ElementAccessExpression(
                                                arrayValuedExpression,
                                                SyntaxFactory.BracketedArgumentList(
                                                    SyntaxFactory.SingletonSeparatedList(
                                                        SyntaxFactory.Argument(
                                                            SyntaxFactory.IdentifierName(outerLoopVariableName)))))))))));
                }

                // for
                ForStatementSyntax forStatement = SyntaxFactory.ForStatement(
                    // (index_0 = 0;
                    SyntaxFactory.VariableDeclaration(
                        SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
                        SyntaxFactory.SingletonSeparatedList(
                            SyntaxFactory.VariableDeclarator(loopVariableName)
                            .WithInitializer(
                                SyntaxFactory.EqualsValueClause(SyntaxFactory.LiteralExpression(
                                                                    SyntaxKind.NumericLiteralExpression,
                                                                    SyntaxFactory.Literal(0)))))),
                    default(SeparatedSyntaxList <ExpressionSyntax>),
                    // index_0 < value_0.Count;
                    SyntaxFactory.BinaryExpression(
                        SyntaxKind.LessThanExpression,
                        SyntaxFactory.IdentifierName(loopVariableName),
                        loopLimitExpression),
                    // ++index_0)
                    SyntaxFactory.SingletonSeparatedList <ExpressionSyntax>(
                        SyntaxFactory.PrefixUnaryExpression(
                            SyntaxKind.PreIncrementExpression,
                            SyntaxFactory.IdentifierName(loopVariableName))),
                    // { ... }
                    SyntaxFactory.Block(
                        GenerateArrayVisit(arrayRank, nestingLevel + 1, arrayValuedExpression)));

                if (nestingLevel > 0)
                {
                    statements.Add(
                        SyntaxFactory.IfStatement(
                            SyntaxHelper.IsNotNull(arrayElementVariableName),
                            SyntaxFactory.Block(
                                forStatement)));
                }
                else
                {
                    statements.Add(forStatement);
                }
            }
            else
            {
                string loopVariableName = LocalVariableNameGenerator.GetLoopIndexVariableName(nestingLevel - 1);

                // We're in the body of the innermost loop over array elements. This is
                // where we do the assignment. For arrays of rank 1, the assignment is
                // to an element of the property itself. For arrays of rank > 1, the
                // assignment is to an array element of a temporary variable representing
                // one of the elements of the property.
                ElementAccessExpressionSyntax elementAccessExpression;
                if (arrayRank == 1)
                {
                    // node.Location[index_0]
                    elementAccessExpression =
                        SyntaxFactory.ElementAccessExpression(
                            arrayValuedExpression,
                            SyntaxFactory.BracketedArgumentList(
                                SyntaxFactory.SingletonSeparatedList(
                                    SyntaxFactory.Argument(
                                        SyntaxFactory.IdentifierName(loopVariableName)))));
                }
                else
                {
                    string arrayElementVariableName = LocalVariableNameGenerator.GetCollectionElementVariableName(nestingLevel - 2);

                    // value_0[index_1]
                    elementAccessExpression =
                        SyntaxFactory.ElementAccessExpression(
                            SyntaxFactory.IdentifierName(arrayElementVariableName),
                            SyntaxFactory.BracketedArgumentList(
                                SyntaxFactory.SingletonSeparatedList(
                                    SyntaxFactory.Argument(
                                        SyntaxFactory.IdentifierName(loopVariableName)))));
                }

                statements.Add(
                    SyntaxFactory.ExpressionStatement(
                        SyntaxFactory.AssignmentExpression(
                            SyntaxKind.SimpleAssignmentExpression,
                            elementAccessExpression,
                            SyntaxFactory.InvocationExpression(
                                SyntaxFactory.IdentifierName(VisitNullCheckedMethodName),
                                SyntaxHelper.ArgumentList(elementAccessExpression)))));
            }

            return(statements.ToArray());
        }
Пример #4
0
        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)))))));
        }
Пример #5
0
        private StatementSyntax[] GenerateDictionaryVisit(int arrayRank, string propertyName)
        {
            const string KeyVariableName   = "key";
            const string KeysVariableName  = "keys";
            const string KeysPropertyName  = "Keys";
            const string ValueVariableName = "value";

            ExpressionSyntax dictionaryValue =
                SyntaxFactory.ElementAccessExpression(
                    SyntaxFactory.MemberAccessExpression(
                        SyntaxKind.SimpleMemberAccessExpression,
                        SyntaxFactory.IdentifierName(NodeParameterName),
                        SyntaxFactory.IdentifierName(propertyName)),
                    SyntaxFactory.BracketedArgumentList(
                        SyntaxFactory.SingletonSeparatedList(
                            SyntaxFactory.Argument(
                                SyntaxFactory.IdentifierName(KeyVariableName)))));

            // The code to visit an individual dictionary element depends on whether the
            // elements are scalar values or arrays.
            StatementSyntax[] dictionaryElementVisitStatements;

            if (arrayRank == 0)
            {
                dictionaryElementVisitStatements = new StatementSyntax[]
                {
                    GenerateScalarVisit(dictionaryValue, SyntaxFactory.IdentifierName(ValueVariableName))
                };
            }
            else
            {
                ExpressionSyntax arrayValuedExpression =
                    SyntaxFactory.ElementAccessExpression(
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            SyntaxFactory.IdentifierName(NodeParameterName),
                            SyntaxFactory.IdentifierName(propertyName)),
                        SyntaxFactory.BracketedArgumentList(
                            SyntaxFactory.SingletonSeparatedList(
                                SyntaxFactory.Argument(
                                    SyntaxFactory.IdentifierName(KeyVariableName)))));

                dictionaryElementVisitStatements = GenerateArrayVisit(
                    arrayRank,
                    nestingLevel: 0,
                    arrayValuedExpression: arrayValuedExpression);
            }

            return(new StatementSyntax[]
            {
                // var keys = node.PropertyName.Keys.ToArray();
                SyntaxFactory.LocalDeclarationStatement(
                    SyntaxFactory.VariableDeclaration(
                        SyntaxHelper.Var(),
                        SyntaxFactory.SingletonSeparatedList(
                            SyntaxFactory.VariableDeclarator(
                                SyntaxFactory.Identifier(KeysVariableName),
                                default(BracketedArgumentListSyntax),
                                SyntaxFactory.EqualsValueClause(
                                    SyntaxFactory.InvocationExpression(
                                        SyntaxFactory.MemberAccessExpression(
                                            SyntaxKind.SimpleMemberAccessExpression,
                                            SyntaxFactory.MemberAccessExpression(
                                                SyntaxKind.SimpleMemberAccessExpression,
                                                SyntaxFactory.MemberAccessExpression(
                                                    SyntaxKind.SimpleMemberAccessExpression,
                                                    SyntaxFactory.IdentifierName(NodeParameterName),
                                                    SyntaxFactory.IdentifierName(propertyName)),
                                                SyntaxFactory.IdentifierName(KeysPropertyName)),
                                            SyntaxFactory.IdentifierName(ToArrayMethodName)),
                                        SyntaxHelper.ArgumentList())))))),

                // foreach (var key in keys)
                SyntaxFactory.ForEachStatement(
                    SyntaxHelper.Var(),
                    KeyVariableName,
                    SyntaxFactory.IdentifierName(KeysVariableName),
                    SyntaxFactory.Block(
                        SyntaxFactory.LocalDeclarationStatement(
                            SyntaxFactory.VariableDeclaration(
                                SyntaxHelper.Var(),
                                SyntaxFactory.SingletonSeparatedList(
                                    SyntaxFactory.VariableDeclarator(
                                        SyntaxFactory.Identifier(ValueVariableName),
                                        default(BracketedArgumentListSyntax),
                                        SyntaxFactory.EqualsValueClause(dictionaryValue))))),
                        SyntaxFactory.IfStatement(
                            SyntaxHelper.IsNotNull(ValueVariableName),
                            SyntaxFactory.Block(dictionaryElementVisitStatements))))
            });
        }