MethodDeclaration CreateGetHashCodeMethod(ValueObjectDescriptor valueObject)
        {
            var hashCodes = from fd in valueObject.FieldDeclarations
                            from f in fd.Fields
                            select(Expression) new InvocationExpression(
                new MemberReferenceExpression(
                    new MemberReferenceExpression(new ThisReferenceExpression(), f.Name),
                    "GetHashCode"
                    )
                );

            return(new MethodDeclaration
            {
                TypeReference = new TypeReference("global::System.Int32"),
                Modifier = Modifiers.Public | Modifiers.Override,
                Name = "GetHashCode",
                Body = new BlockStatement
                {
                    Children = new List <INode>
                    {
                        new ReturnStatement(hashCodes.Aggregate((c1, c2) => new BinaryOperatorExpression(c1, BinaryOperatorType.ExclusiveOr, c2)))
                    }
                }
            });
        }
 NamespaceDeclaration CreateNamespace(ValueObjectDescriptor valueObject, NamespaceDeclaration originalNamespace)
 {
     var ns = new NamespaceDeclaration(originalNamespace.Name);
     ns.Children.AddRange(originalNamespace.Children.OfType<UsingDeclaration>());
     ns.Children.Add(CreatePartialClass(valueObject));
     return ns;
 }
 OperatorDeclaration CreateInequalityOperator(ValueObjectDescriptor valueObject)
 {
     return(new OperatorDeclaration
     {
         OverloadableOperator = OverloadableOperatorType.InEquality,
         TypeReference = new TypeReference("global::System.Boolean"),
         Modifier = Modifiers.Public | Modifiers.Static,
         Parameters = new List <ParameterDeclarationExpression>
         {
             new ParameterDeclarationExpression(new TypeReference(valueObject.TypeDeclaration.Name), "x"),
             new ParameterDeclarationExpression(new TypeReference(valueObject.TypeDeclaration.Name), "y"),
         },
         Body = new BlockStatement
         {
             Children = new List <INode>
             {
                 new ReturnStatement(
                     new UnaryOperatorExpression(
                         new ParenthesizedExpression(
                             new BinaryOperatorExpression(
                                 new IdentifierExpression("x"),
                                 BinaryOperatorType.Equality,
                                 new IdentifierExpression("y")
                                 )
                             ),
                         UnaryOperatorType.Not
                         )
                     )
             }
         }
     });
 }
 IEnumerable <ParameterDeclarationExpression> CreateConstructorParameters(ValueObjectDescriptor valueObject)
 {
     return
         (from fd in valueObject.FieldDeclarations
          from f in fd.Fields
          select new ParameterDeclarationExpression(fd.TypeReference, f.Name));
 }
        NamespaceDeclaration CreateNamespace(ValueObjectDescriptor valueObject, NamespaceDeclaration originalNamespace)
        {
            var ns = new NamespaceDeclaration(originalNamespace.Name);

            ns.Children.AddRange(originalNamespace.Children.OfType <UsingDeclaration>());
            ns.Children.Add(CreatePartialClass(valueObject));
            return(ns);
        }
 OperatorDeclaration CreateEqualityOperator(ValueObjectDescriptor valueObject)
 {
     return(new OperatorDeclaration
     {
         OverloadableOperator = OverloadableOperatorType.Equality,
         TypeReference = new TypeReference("global::System.Boolean"),
         Modifier = Modifiers.Public | Modifiers.Static,
         Parameters = new List <ParameterDeclarationExpression>
         {
             new ParameterDeclarationExpression(new TypeReference(valueObject.TypeDeclaration.Name), "x"),
             new ParameterDeclarationExpression(new TypeReference(valueObject.TypeDeclaration.Name), "y"),
         },
         Body = new BlockStatement
         {
             Children = new List <INode>
             {
                 new IfElseStatement(
                     new InvocationExpression(
                         new MemberReferenceExpression(new TypeReferenceExpression(new TypeReference("global::System.Object")), "ReferenceEquals"),
                         new List <Expression> {
                     new IdentifierExpression("x"), new IdentifierExpression("y")
                 }
                         ),
                     new ReturnStatement(new PrimitiveExpression(true))
                     ),
                 new IfElseStatement(
                     new InvocationExpression(
                         new MemberReferenceExpression(new TypeReferenceExpression(new TypeReference("global::System.Object")), "ReferenceEquals"),
                         new List <Expression> {
                     new IdentifierExpression("x"), new PrimitiveExpression(null)
                 }
                         ),
                     new ReturnStatement(new PrimitiveExpression(false))
                     ),
                 new IfElseStatement(
                     new InvocationExpression(
                         new MemberReferenceExpression(new TypeReferenceExpression(new TypeReference("global::System.Object")), "ReferenceEquals"),
                         new List <Expression> {
                     new IdentifierExpression("y"), new PrimitiveExpression(null)
                 }
                         ),
                     new ReturnStatement(new PrimitiveExpression(false))
                     ),
                 new ReturnStatement(
                     new InvocationExpression(
                         new MemberReferenceExpression(
                             new IdentifierExpression("x"), "Equals"
                             ),
                         new List <Expression> {
                     new IdentifierExpression("y")
                 }
                         )
                     )
             }
         }
     });
 }
        MethodDeclaration CreateEqualsMethod(ValueObjectDescriptor valueObject)
        {
            var tests = from fd in valueObject.FieldDeclarations
                        from f in fd.Fields
                        select new BinaryOperatorExpression(
                new MemberReferenceExpression(new ThisReferenceExpression(), f.Name),
                BinaryOperatorType.Equality,
                new MemberReferenceExpression(new IdentifierExpression("typed"), f.Name)
                );
            var test = tests.Aggregate((t1, t2) => new BinaryOperatorExpression(t1, BinaryOperatorType.LogicalAnd, t2));

            return(new MethodDeclaration
            {
                Modifier = Modifiers.Public | Modifiers.Override,
                TypeReference = new TypeReference("global::System.Boolean"),
                Name = "Equals",
                Parameters = new List <ParameterDeclarationExpression> {
                    new ParameterDeclarationExpression(new TypeReference("global::System.Object"), "obj")
                },
                Body = new BlockStatement
                {
                    Children = new List <INode>
                    {
                        // var typed = obj as <ValueObjectType>;
                        new LocalVariableDeclaration(new VariableDeclaration(
                                                         "typed",
                                                         new CastExpression(
                                                             new TypeReference(valueObject.TypeDeclaration.Name),
                                                             new IdentifierExpression("obj"),
                                                             CastType.TryCast
                                                             ),
                                                         new TypeReference(valueObject.TypeDeclaration.Name)
                                                         )),

                        // if (Object.ReferenceEquals(typed, null)) return false;
                        new IfElseStatement(new InvocationExpression(
                                                new MemberReferenceExpression(new TypeReferenceExpression(new TypeReference("global::System.Object")), "ReferenceEquals"),
                                                new List <Expression>
                        {
                            new IdentifierExpression("typed"),
                            new PrimitiveExpression(null)
                        }
                                                ), new ReturnStatement(new PrimitiveExpression(false))),

                        new ReturnStatement(test)
                    }
                }
            });
        }
 INode CreatePartialClass(ValueObjectDescriptor valueObject)
 {
     var partialClass = new TypeDeclaration(
         valueObject.TypeDeclaration.Modifier,
         new List<AttributeSection>()
     );
     partialClass.Name = valueObject.TypeDeclaration.Name;
     partialClass.Children.Add(CreateConstructor(valueObject));
     partialClass.Children.AddRange(CreateProperties(valueObject));
     partialClass.Children.Add(CreateEqualsMethod(valueObject));
     partialClass.Children.Add(CreateGetHashCodeMethod(valueObject));
     partialClass.Children.Add(CreateEqualityOperator(valueObject));
     partialClass.Children.Add(CreateInequalityOperator(valueObject));
     return partialClass;
 }
        INode CreatePartialClass(ValueObjectDescriptor valueObject)
        {
            var partialClass = new TypeDeclaration(
                valueObject.TypeDeclaration.Modifier,
                new List <AttributeSection>()
                );

            partialClass.Name = valueObject.TypeDeclaration.Name;
            partialClass.Children.Add(CreateConstructor(valueObject));
            partialClass.Children.AddRange(CreateProperties(valueObject));
            partialClass.Children.Add(CreateEqualsMethod(valueObject));
            partialClass.Children.Add(CreateGetHashCodeMethod(valueObject));
            partialClass.Children.Add(CreateEqualityOperator(valueObject));
            partialClass.Children.Add(CreateInequalityOperator(valueObject));
            return(partialClass);
        }
        public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
        {
            var previous = currentInfo;

            if (typeDeclaration.Type == ClassType.Class)
            {
                var isValueObject = typeDeclaration.BaseTypes.Any(t => t.Type == "IValueObject");
                if (isValueObject)
                {
                    currentInfo = new ValueObjectDescriptor(typeDeclaration);
                    ValueObjectInfos.Add(currentInfo);
                }
            }
            
            var result = base.VisitTypeDeclaration(typeDeclaration, data);
            currentInfo = previous;
            return result;
        }
 IEnumerable <PropertyDeclaration> CreateProperties(ValueObjectDescriptor valueObject)
 {
     return(from fd in valueObject.FieldDeclarations
            from f in fd.Fields
            select new PropertyDeclaration(Modifiers.Public, new List <AttributeSection>(), PropertyNameFromField(f), new List <ParameterDeclarationExpression>())
     {
         TypeReference = fd.TypeReference,
         GetRegion = new PropertyGetRegion(new BlockStatement {
             Children = new List <INode>
             {
                 new ReturnStatement(new MemberReferenceExpression(
                                         new ThisReferenceExpression(),
                                         f.Name
                                         ))
             }
         }, new List <AttributeSection>())
     });
 }
Beispiel #12
0
        public override object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
        {
            var previous = currentInfo;

            if (typeDeclaration.Type == ClassType.Class)
            {
                var isValueObject = typeDeclaration.BaseTypes.Any(t => t.Type == "IValueObject");
                if (isValueObject)
                {
                    currentInfo = new ValueObjectDescriptor(typeDeclaration);
                    ValueObjectInfos.Add(currentInfo);
                }
            }

            var result = base.VisitTypeDeclaration(typeDeclaration, data);

            currentInfo = previous;
            return(result);
        }
 ConstructorDeclaration CreateConstructor(ValueObjectDescriptor valueObject)
 {
     return(new ConstructorDeclaration(
                valueObject.TypeDeclaration.Name,
                Modifiers.Public,
                CreateConstructorParameters(valueObject).ToList(),
                new List <AttributeSection>()
                )
     {
         Body = new BlockStatement
         {
             Children = (from fd in valueObject.FieldDeclarations
                         from f in fd.Fields
                         // this.[field] = [parameter];
                         select(INode) new ExpressionStatement(new AssignmentExpression(
                                                                   new MemberReferenceExpression(new ThisReferenceExpression(), f.Name),
                                                                   AssignmentOperatorType.Assign,
                                                                   new IdentifierExpression(f.Name)
                                                                   ))).ToList()
         }
     });
 }
 IEnumerable<ParameterDeclarationExpression> CreateConstructorParameters(ValueObjectDescriptor valueObject)
 {
     return
         from fd in valueObject.FieldDeclarations
         from f in fd.Fields
         select new ParameterDeclarationExpression(fd.TypeReference, f.Name);
 }
        MethodDeclaration CreateEqualsMethod(ValueObjectDescriptor valueObject)
        {
            var tests = from fd in valueObject.FieldDeclarations
                        from f in fd.Fields
                        select new BinaryOperatorExpression(
                            new MemberReferenceExpression(new ThisReferenceExpression(), f.Name),
                            BinaryOperatorType.Equality,
                            new MemberReferenceExpression(new IdentifierExpression("typed"), f.Name)
                        );
            var test = tests.Aggregate((t1, t2) => new BinaryOperatorExpression(t1, BinaryOperatorType.LogicalAnd, t2));

            return new MethodDeclaration
            {
                Modifier = Modifiers.Public | Modifiers.Override,
                TypeReference = new TypeReference("global::System.Boolean"),
                Name = "Equals",
                Parameters = new List<ParameterDeclarationExpression> { new ParameterDeclarationExpression(new TypeReference("global::System.Object"), "obj") },
                Body = new BlockStatement
                {
                    Children = new List<INode>
                    {
                        // var typed = obj as <ValueObjectType>;
                        new LocalVariableDeclaration(new VariableDeclaration(
                            "typed", 
                            new CastExpression(
                                new TypeReference(valueObject.TypeDeclaration.Name), 
                                new IdentifierExpression("obj"), 
                                CastType.TryCast
                            ),
                            new TypeReference(valueObject.TypeDeclaration.Name)
                        )),
                        
                        // if (Object.ReferenceEquals(typed, null)) return false;
                        new IfElseStatement(new InvocationExpression(
                            new MemberReferenceExpression(new TypeReferenceExpression(new TypeReference("global::System.Object")), "ReferenceEquals"),
                            new List<Expression>
                            {
                                new IdentifierExpression("typed"),
                                new PrimitiveExpression(null) 
                            }
                        ), new ReturnStatement(new PrimitiveExpression(false))),

                        new ReturnStatement(test)
                    }
                    
                }
            };
        }
        MethodDeclaration CreateGetHashCodeMethod(ValueObjectDescriptor valueObject)
        {
            var hashCodes = from fd in valueObject.FieldDeclarations
                            from f in fd.Fields
                            select (Expression)new InvocationExpression(
                                new MemberReferenceExpression(
                                    new MemberReferenceExpression(new ThisReferenceExpression(), f.Name),
                                    "GetHashCode"
                                )
                            );

            return new MethodDeclaration
            {
                TypeReference = new TypeReference("global::System.Int32"),
                Modifier = Modifiers.Public | Modifiers.Override,
                Name = "GetHashCode",
                Body = new BlockStatement
                {
                    Children = new List<INode>
                    {
                        new ReturnStatement(hashCodes.Aggregate((c1,c2) => new BinaryOperatorExpression(c1, BinaryOperatorType.ExclusiveOr, c2)))
                    }
                }
            };
        }
 OperatorDeclaration CreateEqualityOperator(ValueObjectDescriptor valueObject)
 {
     return new OperatorDeclaration
     {
         OverloadableOperator = OverloadableOperatorType.Equality,
         TypeReference = new TypeReference("global::System.Boolean"),
         Modifier = Modifiers.Public | Modifiers.Static,
         Parameters = new List<ParameterDeclarationExpression>
         {
             new ParameterDeclarationExpression(new TypeReference(valueObject.TypeDeclaration.Name), "x"),
             new ParameterDeclarationExpression(new TypeReference(valueObject.TypeDeclaration.Name), "y"),
         },
         Body = new BlockStatement
         {
             Children = new List<INode>
             {
                 new IfElseStatement(
                     new InvocationExpression(
                         new MemberReferenceExpression(new TypeReferenceExpression(new TypeReference("global::System.Object")), "ReferenceEquals"),
                         new List<Expression> {new IdentifierExpression("x"), new IdentifierExpression("y")}
                     ),
                     new ReturnStatement(new PrimitiveExpression(true))
                 ),
                 new IfElseStatement(
                     new InvocationExpression(
                         new MemberReferenceExpression(new TypeReferenceExpression(new TypeReference("global::System.Object")), "ReferenceEquals"),
                         new List<Expression> {new IdentifierExpression("x"), new PrimitiveExpression(null)}
                     ),
                     new ReturnStatement(new PrimitiveExpression(false))
                 ),
                 new IfElseStatement(
                     new InvocationExpression(
                         new MemberReferenceExpression(new TypeReferenceExpression(new TypeReference("global::System.Object")), "ReferenceEquals"),
                         new List<Expression> {new IdentifierExpression("y"), new PrimitiveExpression(null)}
                     ),
                     new ReturnStatement(new PrimitiveExpression(false))
                 ),
                 new ReturnStatement(
                     new InvocationExpression(
                         new MemberReferenceExpression(
                             new IdentifierExpression("x"), "Equals"
                         ),
                         new List<Expression> {new IdentifierExpression("y")}
                     )
                 )
             }
         }
     };
 }
 OperatorDeclaration CreateInequalityOperator(ValueObjectDescriptor valueObject)
 {
     return new OperatorDeclaration
     {
         OverloadableOperator = OverloadableOperatorType.InEquality,
         TypeReference = new TypeReference("global::System.Boolean"),
         Modifier = Modifiers.Public | Modifiers.Static,
         Parameters = new List<ParameterDeclarationExpression>
         {
             new ParameterDeclarationExpression(new TypeReference(valueObject.TypeDeclaration.Name), "x"),
             new ParameterDeclarationExpression(new TypeReference(valueObject.TypeDeclaration.Name), "y"),
         },
         Body = new BlockStatement
         {
             Children = new List<INode>
             {
                 new ReturnStatement(
                     new UnaryOperatorExpression(
                         new ParenthesizedExpression(
                             new BinaryOperatorExpression(
                                 new IdentifierExpression("x"), 
                                 BinaryOperatorType.Equality, 
                                 new IdentifierExpression("y")
                             )
                         ),
                         UnaryOperatorType.Not
                     )
                 )
             }
         }
     };
 }
 ConstructorDeclaration CreateConstructor(ValueObjectDescriptor valueObject)
 {
     return new ConstructorDeclaration(
         valueObject.TypeDeclaration.Name,
         Modifiers.Public,
         CreateConstructorParameters(valueObject).ToList(),
         new List<AttributeSection>()
     )
     {
         Body = new BlockStatement
         {
             Children = (from fd in valueObject.FieldDeclarations
                         from f in fd.Fields
                         // this.[field] = [parameter];
                         select (INode)new ExpressionStatement(new AssignmentExpression(
                             new MemberReferenceExpression(new ThisReferenceExpression(), f.Name),
                             AssignmentOperatorType.Assign,
                             new IdentifierExpression(f.Name)
                         ))).ToList()
         }
     };
 }
 IEnumerable<PropertyDeclaration> CreateProperties(ValueObjectDescriptor valueObject)
 {
     return from fd in valueObject.FieldDeclarations
            from f in fd.Fields
            select new PropertyDeclaration(Modifiers.Public, new List<AttributeSection>(), PropertyNameFromField(f), new List<ParameterDeclarationExpression>())
            {
                TypeReference = fd.TypeReference,
                GetRegion = new PropertyGetRegion(new BlockStatement {
                    Children = new List<INode> 
                    {
                        new ReturnStatement(new MemberReferenceExpression(
                            new ThisReferenceExpression(),
                            f.Name
                        ))
                    }
                }, new List<AttributeSection>())
            };
 }