コード例 #1
0
        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))));
        }
コード例 #2
0
 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))));
 }
コード例 #3
0
        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());
        }
コード例 #4
0
 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))));
 }
コード例 #5
0
 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))));
 }
コード例 #6
0
        private StatementSyntax GenerateScalarVisit(
            ExpressionSyntax target,
            ExpressionSyntax source = null)
        {
            if (source == null)
            {
                source = target;
            }

            return
                (SyntaxFactory.ExpressionStatement(
                     SyntaxFactory.AssignmentExpression(
                         SyntaxKind.SimpleAssignmentExpression,
                         target,
                         SyntaxFactory.InvocationExpression(
                             SyntaxFactory.IdentifierName(VisitNullCheckedMethodName),
                             SyntaxHelper.ArgumentList(source)))));
        }
コード例 #7
0
        private MemberDeclarationSyntax GenerateInstanceProperty()
        {
            TypeSyntax comparerType = SyntaxFactory.ParseTypeName(GetEqualityComparerClassName(_className));

            // public static readonly ComparerType Instance = new ComparerType();
            return(SyntaxFactory.FieldDeclaration(
                       default(SyntaxList <AttributeListSyntax>),
                       SyntaxFactory.TokenList(
                           SyntaxFactory.Token(SyntaxKind.InternalKeyword),
                           SyntaxFactory.Token(SyntaxKind.StaticKeyword),
                           SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword)),
                       SyntaxFactory.VariableDeclaration(comparerType,
                                                         SyntaxFactory.SingletonSeparatedList(
                                                             SyntaxFactory.VariableDeclarator(
                                                                 SyntaxFactory.Identifier(InstancePropertyName),
                                                                 default(BracketedArgumentListSyntax),
                                                                 SyntaxFactory.EqualsValueClause(
                                                                     SyntaxFactory.ObjectCreationExpression(
                                                                         comparerType,
                                                                         SyntaxHelper.ArgumentList(),
                                                                         default(InitializerExpressionSyntax))))))));
        }
コード例 #8
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());
        }
コード例 #9
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))))
            });
        }