public static CodeCompileUnit TestDirectiveCompileUnit()
        {
            CodeCompileUnit     compileUnit      = new CodeCompileUnit();
            CodeNamespace       codeNamespace    = new CodeNamespace("Test.Namespace");
            CodeTypeDeclaration classDeclaration = new CodeTypeDeclaration("TestClass")
            {
                IsClass = true
            };

            classDeclaration.SetAccessibilityLevel(AccessibilityLevel.Public);

            var method = new CodeMemberMethod()
            {
                Name       = "Method",
                Attributes = MemberAttributes.Public | MemberAttributes.Final
            };

            compileUnit.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Compile unit region"));
            compileUnit.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null));

            classDeclaration.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Class region"));
            classDeclaration.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null));

            var field1 = new CodeMemberField(Types.Int, "a");
            var field2 = new CodeMemberField(Types.Int, "b");

            field1.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Fields region"));
            field2.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null));

            method.Statements.Add(
                new CodeAssignStatement(
                    FieldReferenceExpression.Default("a"),
                    FieldReferenceExpression.Default("b"))
            {
                StartDirectives =
                {
                    new CodeRegionDirective(CodeRegionMode.Start, "region a"),
                    new CodeRegionDirective(CodeRegionMode.Start, "region b")
                }
            });
            method.Statements.Add(
                new CodeMethodReturnStatement(
                    FieldReferenceExpression.Default("a"))
            {
                EndDirectives =
                {
                    new CodeRegionDirective(CodeRegionMode.End, null),
                    new CodeRegionDirective(CodeRegionMode.End, null)
                }
            });

            compileUnit.Namespaces.Add(codeNamespace);
            codeNamespace.Types.Add(classDeclaration);
            classDeclaration.Members.Add(field1);
            classDeclaration.Members.Add(field2);
            classDeclaration.Members.Add(method);
            return(compileUnit);
        }
        public static CodeCompileUnit TestSimpleClassCompileUnit()
        {
            CodeCommentStatement docComment = new CodeCommentStatement("this is a doc comment", true);
            CodeCommentStatement comment    = new CodeCommentStatement("this is a comment", false);

            CodeCompileUnit     compileUnit      = new CodeCompileUnit();
            CodeNamespace       codeNamespace    = new CodeNamespace("Test.Namespace");
            CodeTypeDeclaration classDeclaration = new CodeTypeDeclaration("TestClass")
            {
                IsClass = true
            };

            classDeclaration.TypeAttributes =
                (classDeclaration.TypeAttributes & ~TypeAttributes.VisibilityMask) | TypeAttributes.NotPublic;

            var field1 = new CodeMemberField(typeof(int), "count");

            field1.Attributes = (field1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private;
            var field2 = new CodeMemberField(typeof(int), "increment");

            field2.Attributes = (field2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.FamilyAndAssembly;

            classDeclaration.Members.Add(field1);
            classDeclaration.Members.Add(field2);

            var prop1 = new CodeMemberProperty()
            {
                Name       = "Prop",
                HasGet     = true,
                HasSet     = true,
                Type       = Types.Int,
                Attributes = MemberAttributes.Public | MemberAttributes.Final
            };
            var prop2 = new CodeMemberProperty()
            {
                Name       = "Prop2",
                HasSet     = true,
                Type       = Types.Int,
                Attributes = MemberAttributes.Public
            };

            prop1.GetStatements.Add(new CodeMethodReturnStatement(FieldReferenceExpression.Default("increment")));
            prop1.SetStatements.Add(
                new CodeAssignStatement(FieldReferenceExpression.Default("increment"),
                                        new CodePropertySetValueReferenceExpression()));
            prop2.SetStatements.Add(new CodeThrowExceptionStatement(
                                        new CodeObjectCreateExpression(new CodeTypeReference("Exception"))));

            classDeclaration.Members.Add(prop1);
            classDeclaration.Members.Add(prop2);

            var constructor = new CodeConstructor();

            constructor.Attributes = (constructor.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Family;

            constructor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "count"));
            constructor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "increment"));

            constructor.Statements.Add(new CodeAssignStatement(
                                           FieldReferenceExpression.This("count"),
                                           new CodeArgumentReferenceExpression("count")));
            constructor.Statements.Add(new CodeAssignStatement(
                                           FieldReferenceExpression.This("increment"),
                                           new CodeArgumentReferenceExpression("increment")));

            classDeclaration.Members.Add(constructor);
            classDeclaration.Attributes = (classDeclaration.Attributes & ~MemberAttributes.AccessMask) |
                                          MemberAttributes.FamilyOrAssembly;

            var method = new CodeMemberMethod()
            {
                Name       = "IncrementAndGet",
                ReturnType = Types.Int,
                Attributes = MemberAttributes.FamilyOrAssembly | MemberAttributes.Final
            };

            method.Statements.Add(comment);
            method.Statements.Add(
                new CodeOperationAssignmentStatement(
                    FieldReferenceExpression.Default("count"),
                    CodeBinaryOperatorTypeMore.Add,
                    FieldReferenceExpression.Default("increment")).AsAssignStatement());
            method.Statements.Add(new CodeMethodReturnStatement(FieldReferenceExpression.Default("count")));

            classDeclaration.Members.Add(method);

            codeNamespace.Types.Add(classDeclaration);
            compileUnit.Namespaces.Add(codeNamespace);

            codeNamespace.Comments.Add(comment);
            codeNamespace.Comments.Add(docComment);

            classDeclaration.Comments.Add(docComment);
            classDeclaration.Comments.Add(docComment);

            method.Comments.Add(comment);

            return(compileUnit);
        }
        public static CodeCompileUnit TestSimpleStructCompileUnit()
        {
            CodeCompileUnit     compileUnit      = new CodeCompileUnit();
            CodeNamespace       codeNamespace    = new CodeNamespace("Test.Namespace");
            CodeTypeDeclaration classDeclaration = new CodeTypeDeclaration("TestClass")
            {
                IsStruct = true
            };

            classDeclaration.TypeAttributes =
                (classDeclaration.TypeAttributes & ~TypeAttributes.VisibilityMask) | TypeAttributes.NotPublic;

            var field1 = new CodeMemberField(typeof(int), "count");

            field1.Attributes = (field1.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private;
            var field2 = new CodeMemberField(typeof(int), "increment");

            field2.Attributes = (field2.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private;

            classDeclaration.Members.Add(field1);
            classDeclaration.Members.Add(field2);

            var constructor = new CodeConstructor();

            constructor.Attributes = (constructor.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public;

            constructor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "count"));
            constructor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "increment"));

            constructor.Statements.Add(new CodeAssignStatement(
                                           FieldReferenceExpression.This("count"),
                                           new CodeArgumentReferenceExpression("count")));
            constructor.Statements.Add(new CodeAssignStatement(
                                           FieldReferenceExpression.This("increment"),
                                           new CodeArgumentReferenceExpression("increment")));

            classDeclaration.Members.Add(constructor);
            classDeclaration.Attributes = (classDeclaration.Attributes & ~MemberAttributes.AccessMask) |
                                          MemberAttributes.Assembly;

            var method = new CodeMemberMethod()
            {
                Name       = "IncrementAndGet",
                ReturnType = Types.Int,
                Attributes = MemberAttributes.Assembly | MemberAttributes.Final
            };

            method.Statements.Add(
                new CodeOperationAssignmentStatement(
                    FieldReferenceExpression.Default("count"),
                    CodeBinaryOperatorTypeMore.Add,
                    FieldReferenceExpression.Default("increment")).AsAssignStatement());
            method.Statements.Add(new CodeMethodReturnStatement(FieldReferenceExpression.Default("count")));

            classDeclaration.Members.Add(method);

            codeNamespace.Types.Add(classDeclaration);
            compileUnit.Namespaces.Add(codeNamespace);

            return(compileUnit);
        }