Click here to Skip to main content
15,885,365 members
Articles / Programming Languages / C#

Calculating Metrics and Searching with a CodeDOM (Part 8)

Rate me:
Please Sign up or sign in to vote.
5.00/5 (7 votes)
6 Mar 2013CDDL7 min read 22K   682   10  
Calculating metrics on and searching a CodeDOM.
// The Nova Project by Ken Beckett.
// Copyright (C) 2007-2012 Inevitable Software, all rights reserved.
// Released under the Common Development and Distribution License, CDDL-1.0: http://opensource.org/licenses/cddl1.php
// Released under the Common Development and Distribution License, CDDL-1.0: http://opensource.org/licenses/cddl1.php

// This file contains test code that manually generates objects using the Nova.CodeDOM library.

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;

using Nova.CodeDOM;
using Nova.Utilities;
using Attribute = Nova.CodeDOM.Attribute;
using Label = Nova.CodeDOM.Label;
using ParameterModifier = Nova.CodeDOM.ParameterModifier;
using Switch = Nova.CodeDOM.Switch;

namespace Nova.Test
{
    /// <summary>
    /// Manual CodeObject tests.
    /// </summary>
    public class ManualTests
    {
        public static CodeObject GenerateSimpleTest(string testName, Project project)
        {
            // int x;
            // x = 1;
            // int y = x + 1;
            // x = y * 2;
            // const string t = "test";
            LocalDecl x, y;
            // Use a BlockDecl as a parent for multiple top-level statements
            CodeObject testCode = new BlockDecl(
                x = new LocalDecl("x", typeof(int)),
                new Assignment(x, 1),
                y = new LocalDecl("y", typeof(int), new Add(x, 1)),
                new Assignment(x, new Multiply(y, 2)),
                new LocalDecl("t", typeof(string), Modifiers.Const, "test")
                );
            return testCode;
        }

        public static CodeObject GenerateMethodTest(string testName, Project project)
        {
            // string CalculateGrade(string name, int score)
            // {
            //     string result = name;
            //     if (score < 70)
            //     {
            //         result += " FAILED";
            //         bool passed = false;
            //     }
            //     else
            //         result += " PASSED";
            //     return result;
            // }
            ParameterDecl name = new ParameterDecl("name", typeof(string));
            ParameterDecl score = new ParameterDecl("score", typeof(int));
            MethodDecl method = new MethodDecl("CalculateGrade", typeof(string), name, score);
            LocalDecl result = new LocalDecl("result", typeof(string), name);
            method.Add(result,
                new If(new LessThan(score, 70), new Block(new AddAssign(result, " FAILED"), new LocalDecl("passed", typeof(bool), false)),
                    new Else(new AddAssign(result, " PASSED"))), new Return(result));
            return method;
        }

        /// <summary>
        /// Manually generate code objects that replicate the code in FullTest.cs.
        /// </summary>
        public static CodeUnit GenerateFullTest(string testName, Project project)
        {
            CodeUnit codeUnit = project.CreateCodeUnit(testName);

            codeUnit.Add(new Comment("The Nova Project by Ken Beckett.\nCopyright (C) 2007-2012 Inevitable Software, all rights reserved."),
                new Comment("This file contains test code for the Nova.CodeDOM library - it's not designed to be\nexecuted, only parsed and resolved."),
                new PragmaWarningDirective(PragmaWarningAction.Disable) { EOLComment = "disable warnings for this file"},
                new UnDefSymbol("JUST_TESTING") { EOLComment = "undefine symbol" },
                new DefineSymbol("UNDOCUMENTED") { EOLComment = "define symbol" });

            codeUnit.Add(
                new UsingDirective(project.ParseName("System")),
                new UsingDirective(project.ParseName("System.Collections")),
                new UsingDirective(project.ParseName("System.Collections.Generic")),
                new UsingDirective(project.ParseName("System.ComponentModel")),
                new UsingDirective(project.ParseName("System.Diagnostics")),
                new UsingDirective(project.ParseName("System.Reflection")),
                new UsingDirective(project.ParseName("Nova.CodeDOM"))
                );
            Alias win_alias = new Alias("Win", project.ParseName("System.Windows")) { EOLComment = "namespace alias" }; codeUnit.Add(win_alias);
            Alias app_alias = new Alias("App", project.ParseName("System.Windows.Application")) { EOLComment = "type alias" }; codeUnit.Add(app_alias);
            Alias attribute_alias = new Alias("Attribute", project.ParseName("System.Attribute")); codeUnit.Add(attribute_alias);

            codeUnit.Add(new Attribute(AttributeTarget.Assembly, new Call(new Dot(project.ParseName("System.Reflection"),
                ConstructorRef.Find(typeof(AssemblyInformationalVersionAttribute), typeof(string))), "0.9")) { EOLComment = "global attribute" });


            // namespace Test.Full
            NamespaceDecl @namespace = new NamespaceDecl(project.ParseName("Test.Full"));
            codeUnit.Add(@namespace);
            @namespace.Add(new UsingDirective(project.ParseName("System.Runtime.InteropServices")));


            // class CustomAttribute
            ClassDecl classCustomAttribute = new ClassDecl("CustomAttribute", Modifiers.None, typeof(Attribute)) { DocComment = new DocSummary("\nThis is a custom attribute.\n") };
            PropertyDecl customAttribute_Message = new PropertyDecl("Message", typeof(string), Modifiers.Public) { Getter = new GetterDecl(new Return(new Literal(null))), Setter = new SetterDecl(), IsSingleLine = true };
            PropertyDecl customAttribute_Value = new PropertyDecl("Value", typeof(int), Modifiers.Public) { Getter = new GetterDecl(new Return(0)), Setter = new SetterDecl(), IsSingleLine = true };
            classCustomAttribute.Add(customAttribute_Message, customAttribute_Value);
            classCustomAttribute.AttachAnnotation(new Attribute(ConstructorRef.Find(typeof(AttributeUsageAttribute), typeof(AttributeTargets)),
                new Dot(typeof(AttributeTargets), EnumMemberRef.Find(typeof(AttributeTargets), "All"))));
            @namespace.Add(classCustomAttribute);


            // public enum TestEnum
            EnumDecl TestEnum = new EnumDecl("TestEnum", Modifiers.Public, typeof(byte)) { Comment = "This is a top-level enum declaration" };
            @namespace.Add(TestEnum);
            //testEnum.AttachAnnotation(new Attribute(typeof(FlagsAttribute)));
            TestEnum.IsBitFlags = true;  // This is the easy way to add the Flags attribute
            TestEnum.Add("Zero");
            EnumMemberDecl testEnum_One = new EnumMemberDecl("One", 1) { EOLComment = "EOL comment" };
            testEnum_One.AttachAnnotation(new IfDirective(true));
            testEnum_One.AttachAnnotation(new EndIfDirective(), AnnotationFlags.IsPostfix);
            EnumMemberDecl testEnum_Two = new EnumMemberDecl("Two") { EOLComment = "EOL comment" };
            testEnum_Two.AttachAnnotation(new IfDirective(true));
            testEnum_Two.AttachComment("Regular comment");
            testEnum_Two.AttachAnnotation(new Attribute(ConstructorRef.Find(typeof(DescriptionAttribute), typeof(string)), "two"));
            testEnum_Two.AttachAnnotation(new ElseDirective { SkippedText = "Too," }, AnnotationFlags.IsPostfix);
            testEnum_Two.AttachAnnotation(new EndIfDirective(), AnnotationFlags.IsPostfix);
            EnumMemberDecl testEnum_Four = new EnumMemberDecl("Four", 4);
            TestEnum.Add(testEnum_One, testEnum_Two, testEnum_Four);


            // public class TestClass : ArrayList, IDisposable
            ClassDecl TestClass = new ClassDecl("TestClass", Modifiers.Public) { DocComment = new DocSummary("\nThis is a class.\n") };
            TestClass.AddBaseTypes(new TypeRef(typeof(ArrayList), true), typeof(IDisposable));
            TestClass.AttachAnnotation(new Attribute(new Call(ConstructorRef.Find(classCustomAttribute), new Assignment(customAttribute_Message, "test"),
                new Assignment(customAttribute_Value, 3))) { EOLComment = "class attribute" });
            TestClass.AttachAnnotation(new IfDirective(true));
            TestClass.AttachAnnotation(new ElseDirective { SkippedText = "class TestClass" }, AnnotationFlags.IsInfix1);
            TestClass.AttachAnnotation(new EndIfDirective(), AnnotationFlags.IsInfix1);
            @namespace.Add(TestClass);


            // ENUMS

            TestClass.Add(new Comment("ENUMS"));

            // enum E1
            EnumDecl enumE1 = new EnumDecl("E1") { Comment = "This is a nested enum declaration" };
            enumE1.Add("One", 1);
            EnumMemberDecl enumE1_two = new EnumMemberDecl("Two", 2);
            enumE1.Add(enumE1_two);
            TestClass.Add(enumE1);

            // enum SingleEnum
            EnumDecl enumSingleEnum = new EnumDecl("SingleEnum");
            enumSingleEnum.Add("LonelyValue");
            TestClass.Add(enumSingleEnum);


            // CONSTANTS & FIELDS

            TestClass.Add(new Comment("CONSTANTS & FIELDS"));
            FieldDecl _maxItems = new FieldDecl("MaxItems", typeof(int), Modifiers.Public | Modifiers.Const, 100);
            TestClass.Add(_maxItems);
            FieldDecl _test = new FieldDecl("_test", typeof(string), Modifiers.Private) { NewLines = 1 };
            _test.AttachAnnotation(new Attribute(ConstructorRef.Find(typeof(ObsoleteAttribute), typeof(string)), "don't use") { EOLComment = "field attribute" });
            TestClass.Add(_test);
            FieldDecl _instance = new FieldDecl("_instance", TestClass, Modifiers.Private | Modifiers.Static); TestClass.Add(_instance);
            FieldDecl _2darray = new FieldDecl("_2darray", typeof(double[,]), Modifiers.Private); TestClass.Add(_2darray);
            MultiFieldDecl mfd = new MultiFieldDecl(typeof(int), Modifiers.Private, "_a", "_b"); TestClass.Add(mfd);
            FieldDecl _c = new FieldDecl("_c", typeof(int), Modifiers.Private, 0);
            FieldDecl _d = new FieldDecl("_d", typeof(int));
            TestClass.Add(new MultiFieldDecl(_c, _d));
            FieldDecl E = new FieldDecl("E", typeof(int), Modifiers.Private | Modifiers.Const, _maxItems); TestClass.Add(E);
            FieldDecl _testEnum = new FieldDecl("_testEnum", TestEnum, Modifiers.Private, new Dot(TestEnum, testEnum_Four)); TestClass.Add(_testEnum);


            // CONSTRUCTORS & DESTRUCTORS

            TestClass.Add(new Comment("CONSTRUCTORS & DESTRUCTORS"));
            TestClass.Add(
                new ConstructorDecl(Modifiers.Static)
                    {
                        Comment = "Static constructor",
                        Body =
                            {
                                new Assignment(_instance, new NewObject(TestClass.GetConstructor())),
                                new Call(new Dot(_instance, MethodRef.Find(typeof(ArrayList), "Add", typeof(object))), new Literal(null)) { EOLComment = "base method call" }
                            }
                    }
                );

            TestClass.Add(
                new DocSummary("\nDoc comment with missing language element.\n"),
                new Comment("private int field;") { NewLines = 1, NoSpaceAfterDelimiter = true }
                );

            ConstructorDecl TestClass_ctor1;
            {
                BaseInitializer ctor1_baseInitializer = new BaseInitializer(ConstructorRef.Find(typeof(ArrayList)));
                ctor1_baseInitializer.AttachComment("infix", AnnotationFlags.IsInfix1 | AnnotationFlags.NoSpace);
                TestClass_ctor1 = new ConstructorDecl(Modifiers.Public)
                                      {
                                          Initializer = ctor1_baseInitializer,
                                          DocComment = new DocComment(new DocSummary("Default constructor"), "\ntest")
                                      };
                TestClass.Add(TestClass_ctor1);
            }

            ConstructorDecl TestClass_ctor2;
            {
                ParameterDecl ctor2_param = new ParameterDecl("test", typeof(string));
                TestClass_ctor2 = new ConstructorDecl(Modifiers.Public, ctor2_param)
                                      {
                                          Initializer = new ThisInitializer(TestClass_ctor1),
                                          DocComment = new DocComment(new DocSummary("\nConstructor w/parameter.\n"), new DocParam(ctor2_param, "Test parameter."))
                                      };
                TestClass.Add(TestClass_ctor2);
            }

            Literal thisParameter = new Literal("test");
            TestClass.Add(
                new ConstructorDecl(Modifiers.Public, new ParameterDecl("test", typeof(int)))
                    {
                        EOLComment = "EOL comment on ConstructorDecl",
                        Initializer = new ThisInitializer(TestClass_ctor2, thisParameter) { Comment = "Comment on ConstructorInitializer", EOLComment = "EOL comment on ConstructorInitializer" }
                    },
                new DestructorDecl { Comment = "Destructor" },
                new MethodDecl("Dispose", typeof(void), Modifiers.Public)  // IDisposable implementation
                );


            // PROPERTIES

            TestClass.Add(new Comment("PROPERTIES"));
            SymbolicRef _testRef = _test.CreateRef();
            _testRef.AttachAnnotation(new Comment("inline") { IsFirstOnLine = false }, AnnotationFlags.NoSpace);
            GetterDecl get_Test = new GetterDecl(new Return(_testRef)) { Body = { EOLComment = "getter" } };
            SetterDecl set_Test = new SetterDecl(Modifiers.Protected) { Body = { EOLComment = "setter" } };
            set_Test.AttachAnnotation(new Attribute(classCustomAttribute));
            set_Test.Add(new Assignment(_test, set_Test.ValueParameter) { EOLComment = "EOL comment" });
            PropertyDecl TestClass_Test = new PropertyDecl("Test", typeof(string), Modifiers.Public)
                                     {
                                         Getter = get_Test,
                                         Setter = set_Test,
                                         DocComment = new DocComment(new DocSummary("\nTest property.\n"), new DocValue("This is a test value."))
                                     };
            TestClass_Test.AttachAnnotation(new Attribute(classCustomAttribute) { EOLComment = "property attribute" });
            TestClass.Add(TestClass_Test);


            // INDEXERS

            TestClass.Add(new Comment("INDEXERS"));
            ParameterDecl ip1 = new ParameterDecl("p1", typeof(int));
            ParameterDecl ip2 = new ParameterDecl("p2", typeof(int));
            GetterDecl get_Item = new GetterDecl(new Return(new Index(_2darray, ip1, ip2)));
            SetterDecl set_Item = new SetterDecl(Modifiers.Private);
            set_Item.AttachAnnotation(new Attribute(classCustomAttribute));
            set_Item.Add(new Assignment(new Index(_2darray, ip1, ip2), set_Item.ValueParameter));
            IndexerDecl indexer = new IndexerDecl(typeof(double), Modifiers.Public, ip1, ip2)
                              {
                                  Getter = get_Item,
                                  Setter = set_Item,
                                  DocComment = new DocComment(new DocSummary("\nThis is an indexer.\n"),
                                      new DocParam(ip1, "First parameter ", new DocC(ip1), "."),
                                      new DocParam(ip2, "Second parameter ", new DocParamRef(ip2), "."),
                                      new DocReturns("Double result."))
                              };
            indexer.AttachAnnotation(new Attribute(classCustomAttribute) { EOLComment = "indexer attribute" });
            TestClass.Add(indexer);


            // Forward declarations for methods:

            MethodDecl methodVoid1 = new MethodDecl("MethodVoid1", typeof(void), Modifiers.Static) { EOLComment = "No parameters, empty body, static" };
            methodVoid1.AttachComment("infix", AnnotationFlags.IsInfix1 | AnnotationFlags.NoSpace);

            MethodDecl methodVoid2;
            {
                ParameterDecl p1 = new ParameterDecl("p1", typeof(double));
                ParameterDecl p2 = new ParameterDecl("p2", typeof(double));
                methodVoid2 = new MethodDecl("MethodVoid2", typeof(void), Modifiers.New, p1, p2) { EOLComment = "Two parameters" };
                methodVoid2.Add(new Return { EOLComment = "Return with no value" });
            }

            MethodDecl methodUIntULong;
            {
                ParameterDecl p1 = new ParameterDecl("p1", typeof(uint));
                ParameterDecl p2 = new ParameterDecl("p2", typeof(ulong));
                methodUIntULong = new MethodDecl("MethodUIntULong", typeof(void), p1, p2);
            }

            MethodDecl methodString;
            {
                ParameterDecl p1 = new ParameterDecl("p1", typeof(string), ParameterModifier.Ref);
                ParameterDecl p2 = new ParameterDecl("p2", typeof(double), ParameterModifier.Out) { IsFirstOnLine = true };
                methodString = new MethodDecl("MethodString", typeof(string), p1, p2) { EOLComment = "Two parameters" };
                methodString.Add(new Assignment(p2, 0), new Return(p1));
            }

            GenericMethodDecl methodGeneric;
            {
                TypeParameter U = new TypeParameter("U");
                TypeParameter T = new TypeParameter("T");
                ParameterDecl u = new ParameterDecl("u", U);
                methodGeneric = new GenericMethodDecl("MethodGeneric", T, u) { EOLComment = "EOL comment on GenericMethodDecl" };
                methodGeneric.AttachAnnotation(new DocComment(new DocSummary("\nGeneric method.\n"), new DocTypeParam(T, "Type parameter T."),
                    new DocTypeParam(U, "Type parameter U."), new DocParam(u, "Parameter u."), new DocReturns("Result T.")));
                methodGeneric.AddTypeParameters(T, U);
                methodGeneric.AddConstraintClauses(new ConstraintClause(T, new TypeConstraint(U)) { IsFirstOnLine = true, EOLComment = "EOL comment on 1st constraint" },
                    new ConstraintClause(U, new ClassConstraint()) { IsFirstOnLine = true, EOLComment = "EOL comment on 2nd constraint" });
                methodGeneric.Add(new Return(new Conditional(new Equal(u, new Literal(null)),
                    new DefaultValue(T), new Cast(T, u))));
            }

            GenericMethodDecl methodGeneric2;
            {
                TypeParameter T = new TypeParameter("T");
                ParameterDecl obj = new ParameterDecl("obj", T);
                methodGeneric2 = new GenericMethodDecl("MethodGeneric2", new TypeRef(T, 1), Modifiers.New, obj);
                methodGeneric2.AddTypeParameters(T);
                methodGeneric2.Add(new Return(new NewArray(T, 1)));
            }

            Namespace namespace_System = project.FindNamespace("System");
            TypeRefBase type_Console = TypeRef.Find(namespace_System, "Console");
            TypeRefBase methodRef_WriteLine = MethodRef.Find(type_Console, "WriteLine", typeof(string));

            MethodDecl methodInt;
            {
                ParameterDecl pa = new ParameterDecl("pa", typeof(int[]), ParameterModifier.Params);
                methodInt = new MethodDecl("MethodInt", typeof(int), pa) { EOLComment = "One parameter" };
                pa.AttachComment("inline", AnnotationFlags.NoSpace);
                methodInt.Add(new Return(new Multiply(new Index(pa, 0), -1)) { EOLComment = "Return a value" });

                LocalDecl result = new LocalDecl("result", typeof(int), new Call(methodInt, 10));
                LocalDecl list = new LocalDecl("list", typeof(List<int>), new NewObject(typeof(List<int>)));
                LocalDecl bx = new LocalDecl("b", typeof(bool), new LessThanEqual(new BitwiseAnd(result, new Literal("0x80", true)), 3));
                LocalDecl ox = new LocalDecl("o", typeof(object), new Index(list, 0));

                TypeParameterRef ListT = new TypeParameterRef(typeof(List<>).GetGenericArguments()[0]);
                methodInt.AttachAnnotation(new DocComment(
                    new DocSummary("\nTest method with ", new DocB("one"), " parameter.\nThe ", new DocParamRef(pa), " parameter is an ", new DocI("optional"), " list of ",
                        new DocC(typeof(int)), ".\nUse standard XML escapes to embed chars such as: < & >", new DocPara("2nd paragraph"), "\n",
                        new DocSee(new Dot(typeof(string), MethodRef.Find(typeof(string), "IndexOf"))), new DocSeeAlso(new Call(methodString, new Ref(typeof(string)), new Out(typeof(double)))),
                        "\nGenerics can be referenced like ", new DocSee(new TypeRef(typeof(List<>), ListT)), ".\n"),
                    new DocParam(pa, ""), new DocReturns("The result."),
                    new DocException(project.ParseName("System.Exception"), "Thrown when..."),
                    new DocPermission(project.ParseName("System.Security.PermissionSet"), "Everyone can access this method."),
                    new DocRemarks("\nThis is the remarks section.\n", new DocSee(new Call(new Dot(project.ParseName("System.Threading.Monitor"),
                        MethodRef.Find(typeof(Monitor), "Enter", typeof(object), typeof(bool))), typeof(object), new Ref(typeof(bool)))),
                        "\nHere is a list:", new DocList("bullet", new DocListHeader(new DocListTerm("Header Term"), new DocListDescription("Header Description")),
                            new DocListItem(new DocListTerm("Term 1"), new DocListDescription("Description 1.")), new DocListItem(new DocListTerm("Term 2"), new DocListDescription("Description 2."))),
                        "\n"),
                    new DocExample("This example shows how to call the ", new DocSee(methodInt), " method.",
                        new DocCode(new BlockDecl(
                            result, list, bx, ox,
                            new LocalDecl("i", typeof(int), new Call(methodGeneric.CreateRef(typeof(int), typeof(object)), ox)),
                            new LocalDecl("s", typeof(string), "<&>"),
                            new If(bx, new If(new GreaterThan(result, 0), new Call(Dot.Create(type_Console, methodRef_WriteLine), "")))
                            )), "\n")
                    ));
            }

            MethodDecl methodIterator;
            {
                methodIterator = new MethodDecl("GetEnumerator", typeof(IEnumerator<int>), Modifiers.Public) { EOLComment = "Iterator" };
                methodIterator.Add(new YieldReturn(1), new YieldReturn(2), new YieldBreak());
            }

            StructDecl testStruct = new StructDecl("TestStruct", Modifiers.Public) { DocComment = new DocSummary("\nThis is a top-level struct\n") };


            // DELEGATES

            TestClass.Add(new Comment("DELEGATES"));
            DelegateDecl del_VoidNoParms = new DelegateDecl("VoidNoParms", typeof(void)); TestClass.Add(del_VoidNoParms);
            DelegateDecl del_VoidString = new DelegateDecl("VoidString", typeof(void), Modifiers.Public, new ParameterDecl("msg", typeof(string))); TestClass.Add(del_VoidString);
            DelegateDecl del_VoidTwoParms = new DelegateDecl("VoidTwoParms", typeof(void), Modifiers.Public, new ParameterDecl("p1", typeof(double)),
                new ParameterDecl("p2", typeof(double))); TestClass.Add(del_VoidTwoParms);
            DelegateDecl del_StringTwoParms = new DelegateDecl("StringTwoParms", typeof(string), Modifiers.Public, new ParameterDecl("p1", typeof(string), ParameterModifier.Ref),
                new ParameterDecl("p2", typeof(double), ParameterModifier.Out)); TestClass.Add(del_StringTwoParms);

            TypeParameter dT = new TypeParameter("T");
            DelegateDecl del_GenericIntParamsT = new DelegateDecl("GenericIntParamsT", typeof(int), Modifiers.Private, dT);
            del_GenericIntParamsT.AddConstraintClauses(new ConstraintClause(dT, new StructConstraint()));
            del_GenericIntParamsT.AddParameter(new ParameterDecl("p1", dT.CreateArrayRef(1), ParameterModifier.Params));
            TestClass.Add(del_GenericIntParamsT);

            PropertyInfo propertyInfo_Length = typeof(string[]).GetProperty("Length");
            FieldDecl _del1 = new FieldDecl("_del1", del_VoidNoParms, Modifiers.Private, new NewObject(del_VoidNoParms, Dot.Create(type_Console, methodRef_WriteLine))); TestClass.Add(_del1);
            FieldDecl _del2 = new FieldDecl("_del2", del_VoidTwoParms, Modifiers.Private, new Dot(_instance, methodVoid2)); TestClass.Add(_del2);
            FieldDecl _del3 = new FieldDecl("_del3", del_StringTwoParms, Modifiers.Private, new Dot(_instance, methodString)); TestClass.Add(_del3);
            FieldDecl _del4 = new FieldDecl("_del4", del_GenericIntParamsT.CreateRef(typeof(int)), Modifiers.Private,
                new Dot(_instance, methodInt)); TestClass.Add(_del4);
            FieldDecl _adel1 = new FieldDecl("_adel1", del_VoidNoParms, Modifiers.Private,
                new AnonymousMethod(new LocalDecl("i", typeof(int), 2), null)); TestClass.Add(_adel1);
            ParameterDecl aip1 = new ParameterDecl("ai", typeof(int[]));
            FieldDecl _adel2 = new FieldDecl("_adel2", del_GenericIntParamsT.CreateRef(typeof(int)), Modifiers.Private,
                new AnonymousMethod(new Return(new Dot(aip1, propertyInfo_Length)), aip1) { IsSingleLine = false, EOLComment = "EOL comment" }); TestClass.Add(_adel2);

            FieldDecl WriteLine = new FieldDecl("WriteLine", del_VoidString, Modifiers.Public | Modifiers.Static, new NewObject(del_VoidString, Dot.Create(type_Console, methodRef_WriteLine))) { NewLines = 2 };
            TestClass.Add(WriteLine);

            MethodDecl MethodWithDelegateParameter1 = new MethodDecl("MethodWithDelegateParameter", typeof(void), Modifiers.Private | Modifiers.Static);
            {
                TestClass.Add(MethodWithDelegateParameter1);
                ParameterDecl del = new ParameterDecl("del", del_VoidNoParms);
                MethodWithDelegateParameter1.AddParameters(new ParameterDecl("s", typeof(string)), del);
                MethodWithDelegateParameter1.Add(new Call(del));
            }
            MethodDecl MethodWithDelegateParameter2 = new MethodDecl("MethodWithDelegateParameter", typeof(void), Modifiers.Private | Modifiers.Static) { NewLines = 1 };
            {
                TestClass.Add(MethodWithDelegateParameter2);
                ParameterDecl del = new ParameterDecl("del", del_VoidTwoParms);
                MethodWithDelegateParameter2.AddParameters(new ParameterDecl("s", typeof(string)), del);
                MethodWithDelegateParameter2.Add(new Call(del, new Literal("1.0", true), new Literal("2.0", true)));
            }
            MethodDecl MethodWithDelegateParameter3 = new MethodDecl("MethodWithDelegateParameter3", typeof(string), Modifiers.Private | Modifiers.Static) { NewLines = 1 };
            {
                TestClass.Add(MethodWithDelegateParameter3);
                ParameterDecl ps = new ParameterDecl("s", typeof(string));
                ParameterDecl del = new ParameterDecl("del", del_GenericIntParamsT.CreateRef(typeof(int)));
                MethodWithDelegateParameter3.AddParameters(ps, del);
                MethodWithDelegateParameter3.Add(new Return(new Add(ps, new Call(del, 1, 2))));
            }
            MethodDecl MethodWithDelegateParameter4 = new MethodDecl("MethodWithDelegateParameter4", typeof(string), Modifiers.Private | Modifiers.Static) { NewLines = 1 };
            {
                TestClass.Add(MethodWithDelegateParameter4);
                ParameterDecl del = new ParameterDecl("del", typeof(Func<IEnumerable<double>, string>));
                MethodWithDelegateParameter4.AddParameters(new ParameterDecl("s", typeof(string)), del);
                MethodWithDelegateParameter4.Add(new Return(new Literal(null)));
            }

            GenericMethodDecl method_Generic = new GenericMethodDecl("Generic", typeof(void), Modifiers.Public, new TypeParameter("T")) { NewLines = 1 };

            {
                MethodDecl TestDelegates = new MethodDecl("TestDelegates", typeof(void), Modifiers.Public) { NewLines = 1 };
                TestClass.Add(TestDelegates);
                TestDelegates.Add(
                    new Call(MethodWithDelegateParameter1, "1a", new AnonymousMethod(new Call(Dot.Create(type_Console, methodRef_WriteLine)))),
                    new Call(MethodWithDelegateParameter1, "1b", Dot.Create(type_Console, methodRef_WriteLine)),
                    new Call(MethodWithDelegateParameter1, "1c", method_Generic.CreateRef(typeof(int)))
                    );

                {
                    ParameterDecl pa = new ParameterDecl("a", typeof(double));
                    ParameterDecl pb = new ParameterDecl("b", typeof(double));
                    TestDelegates.Add(new Call(MethodWithDelegateParameter2, "2a", new AnonymousMethod(new Assignment(pa, pb), pa, pb)) { NewLines = 2 });
                }

                TestDelegates.Add(new Call(MethodWithDelegateParameter3, "3a", new AnonymousMethod(new Return(1), null)) { NewLines = 2 });
                {
                    ParameterDecl ai = new ParameterDecl("ai", typeof(int[]));
                    TestDelegates.Add(new Call(MethodWithDelegateParameter3, "3b", new AnonymousMethod(new Return(new Dot(ai, propertyInfo_Length)), ai)));
                }

                MethodInfo methodInfo_Concat = TypeUtil.GetMethod(typeof(string), "Concat", typeof(IEnumerable<>));
                TestDelegates.Add(new Call(MethodWithDelegateParameter4, "4a", new Dot(typeof(string), new MethodRef(methodInfo_Concat, typeof(double)))) { NewLines = 2 });

                LocalDecl dela;
                {
                    ParameterDecl ps1 = new ParameterDecl("s1", typeof(double));
                    ParameterDecl ps2 = new ParameterDecl("s2", typeof(double));
                    MethodInfo methodInfo_Concat_object_object = TypeUtil.GetMethod(typeof(string), "Concat", typeof(object), typeof(object));
                    dela = new LocalDecl("dela", typeof(Action<double, double>),
                        new AnonymousMethod(new Call(new Dot(typeof(string), new MethodRef(methodInfo_Concat_object_object)), ps1, ps2), ps1, ps2)) { NewLines = 2 };
                    TestDelegates.Add(dela);
                }
                TestDelegates.Add(new Call(MethodWithDelegateParameter1, "1a", new NewObject(del_VoidTwoParms, dela)));

                TestDelegates.Add(new LocalDecl("func1b", typeof(Func<int[], int>), methodInt) { NewLines = 2 });
            }
            TestClass.Add(method_Generic);


            // EVENTS

            TestClass.Add(new Comment("EVENTS"));
            MultiFieldDecl multiEvents = new MultiFieldDecl(del_VoidNoParms, Modifiers.Event) { NewLines = 2, EOLComment = "field-like events" };
            FieldDecl _event1 = new FieldDecl("_event1", del_VoidNoParms, new Literal(null));
            multiEvents.Add(_event1);
            multiEvents.Add("_event2", methodVoid1);
            TestClass.Add(multiEvents);

            AdderDecl add_Event2 = new AdderDecl { Body = { EOLComment = "adder" } };
            add_Event2.AttachAnnotation(new Attribute(classCustomAttribute));
            add_Event2.Add(new AddAssign(_event1, add_Event2.ValueParameter));
            RemoverDecl remove_Event2 = new RemoverDecl { Body = { EOLComment = "remover" } };
            remove_Event2.Add(new SubtractAssign(_event1, add_Event2.ValueParameter));
            EventDecl event2 = new EventDecl("Event2", del_VoidNoParms) { Adder = add_Event2, Remover = remove_Event2, Comment = "This is an event" };
            event2.AttachAnnotation(new Attribute(classCustomAttribute) { EOLComment = "event attribute" });
            TestClass.Add(event2);


            // OPERATOR OVERLOADING

            TestClass.Add(new Comment("OPERATOR OVERLOADING"));
            OperatorDecl op_positive = new OperatorDecl(Add.ParseToken, typeof(int), Modifiers.Public | Modifiers.Static,
                new Return(0), new ParameterDecl("p", TestClass)) { NewLines = 2, IsSingleLine = true, Body = { EOLComment = "unary" } }; TestClass.Add(op_positive);
            OperatorDecl op_add = new OperatorDecl(Add.ParseToken, typeof(int), Modifiers.Public | Modifiers.Static,
                new Return(0), new ParameterDecl("left", TestClass), new ParameterDecl("right", typeof(int))) { IsSingleLine = true, Body = { EOLComment = "binary" } }; TestClass.Add(op_add);
            ConversionOperatorDecl op_iconv = new ConversionOperatorDecl(typeof(string), Modifiers.Public | Modifiers.Static | Modifiers.Implicit,
                new Return(new Literal(null)), new ParameterDecl("p", TestClass)) { IsSingleLine = true, Body = { EOLComment = "implicit conversion" } }; TestClass.Add(op_iconv);
            ConversionOperatorDecl op_econv = new ConversionOperatorDecl(typeof(double), Modifiers.Public | Modifiers.Static | Modifiers.Explicit,
                new Return(0), new ParameterDecl("p", TestClass)) { IsSingleLine = true, Body = { EOLComment = "explicit conversion" } }; TestClass.Add(op_econv);

            MethodDecl OperatorOverloading = new MethodDecl("OperatorOverloading", typeof(void), Modifiers.Public | Modifiers.Static);
            {
                SymbolicRef dateTime_Now = PropertyRef.Find(typeof(DateTime), "Now");
                LocalDecl dt1 = new LocalDecl("dt1", typeof(DateTime), Dot.Create(typeof(DateTime), dateTime_Now));
                LocalDecl diff = new LocalDecl("diff", typeof(TimeSpan), new Subtract(Dot.Create(typeof(DateTime), dateTime_Now), dt1).ResolveOverload());
                OperatorOverloading.Add(dt1, diff, new AddAssign(dt1, diff).ResolveOverload(), new Call(new Dot(dt1, MethodRef.Find(typeof(DateTime), "ToString"))));
                LocalDecl t = new LocalDecl("t", TestClass, new NewObject(TestClass));
                LocalDecl _i = new LocalDecl("i", typeof(int), new Add(t, 5).ResolveOverload());
                LocalDecl _s = new LocalDecl("s", typeof(string), new Add(new Add(t, " "), t));
                OperatorOverloading.Add(t, _i, _s, new Call(new Dot(typeof(int), MethodRef.Find(typeof(int), "Parse", typeof(string))), t),
                    new LocalDecl("d", typeof(double), new Cast(typeof(double), t).ResolveOverload()));
            }
            TestClass.Add(OperatorOverloading);


            // void MethodTest()
            MethodDecl MethodTest = new MethodDecl("MethodTest", typeof(void)) { Comment = "Main Testing Method" };
            {
                MethodTest.AttachAnnotation(new Attribute(new Call(ConstructorRef.Find(typeof(ConditionalAttribute), typeof(string)), "DEBUG"),
                    new Call(ConstructorRef.Find(typeof(ConditionalAttribute), typeof(string)), "TRACE") { IsFirstOnLine = true }) { EOLComment = "method attributes" });
                MethodTest.AttachAnnotation(new Attribute(ConstructorRef.Find(typeof(ObsoleteAttribute), typeof(string), typeof(bool)),
                    "Use new method", true));

                MethodTest.Add(new Comment("----- TYPES -----\n(using Variables and Literals to test)"));

                LocalDecl uo = new LocalDecl("uo", typeof(object)) { NewLines = 2, EOLComment = "uninitialized" }; MethodTest.Add(uo);
                LocalDecl o = new LocalDecl("o", typeof(object), new Literal(null)) { EOLComment = "null Literal" }; MethodTest.Add(o);
                LocalDecl b1 = new LocalDecl("b1", typeof(bool), true) { EOLComment = "true Literal" }; MethodTest.Add(b1);
                LocalDecl b2 = new LocalDecl("b2", typeof(bool), false) { EOLComment = "false Literal" }; MethodTest.Add(b2);
                LocalDecl b = new LocalDecl("b", typeof(byte), 255); MethodTest.Add(b);
                LocalDecl sb = new LocalDecl("sb", typeof(sbyte), -128); MethodTest.Add(sb);
                LocalDecl s = new LocalDecl("s", typeof(short), -32768); MethodTest.Add(s);
                LocalDecl us = new LocalDecl("us", typeof(ushort), 65535); MethodTest.Add(us);
                LocalDecl i = new LocalDecl("i", typeof(int), -2147483648); MethodTest.Add(i);
                LocalDecl ui = new LocalDecl("ui", typeof(uint), 4294967295); MethodTest.Add(ui);
#pragma warning disable 78
                LocalDecl l = new LocalDecl("l", typeof(long), new Literal("-9223372036854775808l", true)); MethodTest.Add(l);
#pragma warning restore 78
                LocalDecl ul = new LocalDecl("ul", typeof(ulong), new Literal("18446744073709551615L", true)); MethodTest.Add(ul);
                LocalDecl f1 = new LocalDecl("f1", typeof(float), new Literal("3.4e38f", true)); MethodTest.Add(f1);
                LocalDecl f2 = new LocalDecl("f2", typeof(float), new Literal("-1.5e-45F", true)); MethodTest.Add(f2);
                LocalDecl d1 = new LocalDecl("d1", typeof(double), new Literal("1.7e308d", true)); MethodTest.Add(d1);
                LocalDecl d2 = new LocalDecl("d2", typeof(double), new Literal("-5.0e-324D", true)); MethodTest.Add(d2);
                LocalDecl NegativeInfinity = new LocalDecl("NegativeInfinity", typeof(double), new Divide(new Literal("-1.0", true), new Literal("0.0", true))); MethodTest.Add(NegativeInfinity);
                LocalDecl PositiveInfinity = new LocalDecl("PositiveInfinity", typeof(double), new Divide(new Literal("1.0", true), new Literal("0.0", true))); MethodTest.Add(PositiveInfinity);
                LocalDecl NaN = new LocalDecl("NaN", typeof(double), new Divide(new Literal("0.0", true), new Literal("0.0", true))); MethodTest.Add(NaN);
                LocalDecl m = new LocalDecl("m", typeof(decimal), 1000000m); MethodTest.Add(m);
                LocalDecl c1 = new LocalDecl("c1", typeof(char), 'a'); MethodTest.Add(c1);
                LocalDecl c2 = new LocalDecl("c2", typeof(char), new Literal(@"'\\'", true)); MethodTest.Add(c2);
                LocalDecl s1 = new LocalDecl("s1", typeof(string), new Literal(null)); MethodTest.Add(s1);
                LocalDecl s2 = new LocalDecl("s2", typeof(string), @"\\"); MethodTest.Add(s2);
                LocalDecl s3 = new LocalDecl("s3", typeof(string), "test"); MethodTest.Add(s3);

                MethodTest.Add(new Comment("enums"));
                LocalDecl e1 = new LocalDecl("e1", enumE1, new Cast(enumE1, 0)); MethodTest.Add(e1);
                LocalDecl e2 = new LocalDecl("e2", enumE1, new Dot(enumE1, enumE1_two)); MethodTest.Add(e2);
                MethodTest.Add(new LocalDecl("e3", TestEnum, new BitwiseOr(new BitwiseOr(new Dot(TestEnum, testEnum_One), new Dot(TestEnum, testEnum_Two)), _testEnum)));

                MethodTest.Add(new Comment("Arrays (simple)"));
                LocalDecl ia = new LocalDecl("ia", typeof(int[]),
                    new Initializer(1, 2, 3, new Add(i, 2))); MethodTest.Add(ia);
                LocalDecl cha = new LocalDecl("cha", typeof(char[]), new Initializer(' ', new Literal(@"'\''", true), new Literal(@"'\""'", true),
                    new Literal(@"'\n'", true), new Literal(@"'\xffff'", true), new Cast(typeof(char), new Add(c1, 2)))); MethodTest.Add(cha);
                LocalDecl sa = new LocalDecl("sa", typeof(string[]), new Initializer("one", "two", new Add(s3, "val"))); MethodTest.Add(sa);
                NewArray new_ia2 = new NewArray(typeof(int), 2) { Initializer = new Initializer(1, 2) };
                LocalDecl ia2 = new LocalDecl("ia2", typeof(int[]), new_ia2); MethodTest.Add(ia2);

                MethodTest.Add(new Comment("Multi-dimensional Arrays"));
                LocalDecl dax2 = new LocalDecl("dax2", typeof(double[,]),
                    new Initializer(new Initializer(1, 2), new Initializer(3, 4))); MethodTest.Add(dax2);
                NewArray new_dax2b = new NewArray(typeof(double), 2, 2) { Initializer = new Initializer(new Initializer(1, 2), new Initializer(3, 4)) };
                LocalDecl dax2b = new LocalDecl("dax2b", typeof(double[,]), new_dax2b); MethodTest.Add(dax2b);

                MethodTest.Add(new Comment("Jagged Arrays"));
                NewArray ijax2_1 = new NewArray(typeof(int), null) { Initializer = new Initializer(1) };
                NewArray ijax2_2 = new NewArray(typeof(int), 2) { Initializer = new Initializer(21, 22) };
                LocalDecl ijax2 = new LocalDecl("ijax2", typeof(int[][]), new NewArray(typeof(int[]), 2) { Initializer = new Initializer(ijax2_1, ijax2_2) });
                MethodTest.Add(ijax2);
                Namespace namespace_Test = project.FindNamespace("Test");
                Namespace namespace_TestFull = @namespace.Namespace;
                LocalDecl ijau = new LocalDecl("ijau", Dot.Create(namespace_Test, namespace_TestFull, TestClass.CreateArrayRef(1, 1)),
                    new NewArray(Dot.Create(namespace_Test, namespace_TestFull, TestClass.CreateArrayRef(1)), 1));
                MethodTest.Add(ijau);
                NewArray ijax3_1 = new NewArray(typeof(int), null, null) { Initializer = new Initializer(new Initializer(1), new Initializer(2)) };
                LocalDecl ijax3 = new LocalDecl("ijax3", typeof(int[][,]), new NewArray(typeof(int[][,])) { Initializer = new Initializer(ijax3_1) });
                MethodTest.Add(ijax3);

                MethodTest.Add(new Comment("Generic Types"));
                Namespace namespace_Collections = (Namespace)namespace_System.Find("Collections");
                Namespace namespace_Generic = (Namespace)namespace_Collections.Find("Generic");
                LocalDecl li = new LocalDecl("li", Dot.Create(namespace_System, namespace_Collections, namespace_Generic, typeof(List<int>)),
                    new NewObject(typeof(List<int>))); MethodTest.Add(li);
                LocalDecl lli = new LocalDecl("lli", typeof(List<List<int>>), new NewObject(typeof(List<List<int>>))); MethodTest.Add(lli);

                MethodTest.Add(new Comment("Nullable Types"));
                LocalDecl ni = new LocalDecl("ni", typeof(int?), new Cast(typeof(int?), i)); MethodTest.Add(ni);
                LocalDecl ndt = new LocalDecl("ndt", TypeRef.CreateNullable(new Dot(namespace_System, typeof(DateTime))), new NewObject(TypeRef.CreateNullable(new Dot(namespace_System, typeof(DateTime))))); MethodTest.Add(ndt);
                LocalDecl ni2 = new LocalDecl("ni2", typeof(int?), new Literal(null)); MethodTest.Add(ni2);
                LocalDecl ns = new LocalDecl("ns", TypeRef.CreateNullable(Dot.Create(namespace_Test, namespace_TestFull, testStruct)),
                    new Literal(null)); MethodTest.Add(ns);

                MethodTest.Add(new Comment("const"));
                LocalDecl ci = new LocalDecl("ci", typeof(int), Modifiers.Const, -1); MethodTest.Add(ci);
                LocalDecl cl = new LocalDecl("cl", typeof(long), Modifiers.Const, new Add(E, ci)); MethodTest.Add(cl);
                LocalDecl cui = new LocalDecl("cui", typeof(uint), Modifiers.Const, 1); MethodTest.Add(cui);
                LocalDecl csum = new LocalDecl("csum", typeof(long), new Add(cui, ci)); MethodTest.Add(csum);

                LocalDecl cs1 = new LocalDecl("cs1", typeof(string), Modifiers.Const, @" This string has a \n\""linefeed\"" in it   "); MethodTest.Add(cs1);
                LocalDecl cs2 = new LocalDecl("cs2", typeof(string), Modifiers.Const, new Literal(@"@""LF esc: \n, double quote: """"""", true)); MethodTest.Add(cs2);
                LocalDecl cs3 = new LocalDecl("cs3", typeof(string), Modifiers.Const, @"Escapes: \\\'\""\0\a\b\f\n\r\t\v\x0a\x7f\u2425\U0010FFFF"); MethodTest.Add(cs3);
                LocalDecl cs4 = new LocalDecl("cs4", typeof(string), Modifiers.Const, new Add(cs2, cs3)); MethodTest.Add(cs4);
                LocalDecl test = new LocalDecl("test", typeof(string), new Add(new Add(cs4, " "), cl)); MethodTest.Add(test);

                MethodTest.Add(new Comment("Use of namespace and type aliases"));
                TypeRefBase win_ClipBoard = TypeRef.Find(win_alias, "Clipboard");
                MethodTest.Add(new Call(Dot.Create(win_alias, win_ClipBoard, MethodRef.Find(win_ClipBoard, "Clear"))));
                SymbolicRef app_Current = PropertyRef.Find(app_alias, "Current");
                MethodTest.Add(new Call(Dot.Create(app_alias, app_Current, MethodRef.Find(app_Current.EvaluateType(), "ToString"))));
                MethodTest.Add(new LocalDecl("app", app_alias, new NewObject(app_alias)));

                MethodTest.Add(new Comment("Hex literals"),
                    new Assignment(b, new Literal("0xff", true)),
                    new Assignment(sb, new Literal("0x7f", true)),
                    new Assignment(s, new Literal("0x7FFF", true)),
                    new Assignment(us, new Literal("0xFFFF", true)),
                    new Assignment(i, new Literal("0x7fffffff", true)),
                    new Assignment(ui, new Literal("0xffffffff", true)),
                    new Assignment(l, new Literal("0x7fffffffffffffff", true)),
                    new Assignment(ul, new Literal("0xffffffffffffffff", true)),
                    new Assignment(c1, new Cast(typeof(char), new Literal("0x0041", true))));

                MethodTest.Add(new Comment("----- OPERATORS -----"));

                MethodTest.Add(new Comment("UNARY OPERATORS"),
                    new Assignment(b1, new Not(b2)) { NewLines = 2, EOLComment = "Not" },
                    new Assignment(i, new Complement(i)) { EOLComment = "Complement" },
                    new Assignment(i, new Positive(i)) { EOLComment = "Positive" },
                    new Assignment(i, new Negative(i)) { EOLComment = "Negative" },
                    new Increment(i) { EOLComment = "Increment" },
                    new Decrement(i) { EOLComment = "Decrement" },
                    new PostIncrement(i) { EOLComment = "PostIncrement" },
                    new PostDecrement(i) { EOLComment = "PostDecrement" },
                    new Assignment(b, new Cast(typeof(byte), i)) { EOLComment = "Cast" }
                    );

                MethodTest.Add(new Comment("BINARY OPERATORS"),
                    new Assignment(i, 1) { NewLines = 2, EOLComment = "Assignment" },
                    new Assignment(i, new Add(i, 1)) { EOLComment = "Add" },
                    new Assignment(i, new Subtract(i, 1)) { EOLComment = "Subtract" },
                    new Assignment(i, new Multiply(i, 1)) { EOLComment = "Multiply" },
                    new Assignment(i, new Divide(i, 1)) { EOLComment = "Divide" },
                    new Assignment(i, new Mod(i, 1)) { EOLComment = "Mod" },
                    new Assignment(i, new BitwiseAnd(i, 1)) { EOLComment = "BitwiseAnd" },
                    new Assignment(i, new BitwiseOr(i, 1)) { EOLComment = "BitwiseOr" },
                    new Assignment(i, new BitwiseXor(i, 1)) { EOLComment = "BitwiseXor" },
                    new Assignment(b1, new And(b1, b2)) { EOLComment = "And" },
                    new Assignment(b1, new Or(b1, b2)) { EOLComment = "Or" },
                    new Assignment(b1, new Equal(i, 1)) { EOLComment = "Equal" },
                    new Assignment(b1, new NotEqual(i, 1)) { EOLComment = "NotEqual" },
                    new Assignment(b1, new LessThan(i, 1)) { EOLComment = "LessThan" },
                    new Assignment(b1, new GreaterThan(i, 1)) { EOLComment = "GreaterThan" },
                    new Assignment(b1, new LessThanEqual(i, 1)) { EOLComment = "LessThanEqual" },
                    new Assignment(b1, new GreaterThanEqual(i, 1)) { EOLComment = "GreaterThanEqual" },
                    new Assignment(i, new LeftShift(i, 1)) { EOLComment = "LeftShift" },
                    new Assignment(i, new RightShift(i, 1)) { EOLComment = "RightShift" },
                    new AddAssign(i, 1) { EOLComment = "AddAssign" },
                    new SubtractAssign(i, 1) { EOLComment = "SubtractAssign" },
                    new MultiplyAssign(i, 1) { EOLComment = "MultiplyAssign" },
                    new DivideAssign(i, 1) { EOLComment = "DivideAssign" },
                    new ModAssign(i, 1) { EOLComment = "ModAssign" },
                    new BitwiseAndAssign(i, 1) { EOLComment = "BitwiseAndAssign" },
                    new BitwiseOrAssign(i, 1) { EOLComment = "BitwiseOrAssign" },
                    new BitwiseXorAssign(i, 1) { EOLComment = "BitwiseXorAssign" },
                    new LeftShiftAssign(i, 1) { EOLComment = "LeftShiftAssign" },
                    new RightShiftAssign(i, 1) { EOLComment = "RightShiftAssign" },
                    new Assignment(s1, new IfNullThen(s2, "")) { EOLComment = "IfNullThen" }
                    );

                MethodTest.Add(new Comment("OTHER OPERATORS"),
                    new Call(methodVoid1) { NewLines = 2, EOLComment = "Call (static)" },
                    new Call(new Dot(_instance, methodVoid2), 1, 2) { EOLComment = "Call (instance)" },
                    new Assignment(new Index(ia, 0), 0) { EOLComment = "Index" },
                    new Assignment(o, new Conditional(b1, new NewObject(new TypeRef(typeof(Dictionary<,>), typeof(int), typeof(string))), new Literal(null))) { EOLComment = "Conditional" },
                    new Assignment(s1, new Call(new Dot(new Cast(typeof(object), o) { HasParens = true },
                        MethodRef.Find(typeof(object), "ToString")))) { EOLComment = "Dot" },
                    new Assignment(s1, new As(o, typeof(string))) { EOLComment = "As" },
                    new Assignment(b1, new Is(o, typeof(int))) { EOLComment = "Is" },
                    new LocalDecl("t", typeof(Type), new TypeOf(typeof(Dictionary<,>))) { EOLComment = "TypeOf" },
                    new Assignment(i, new SizeOf(typeof(int))) { EOLComment = "SizeOf" },
                    new Assignment(i, new Checked(new Increment(i))) { EOLComment = "Checked" },
                    new Assignment(i, new Unchecked(new Increment(i))) { EOLComment = "Unchecked" },
                    new Assignment(i, new NewObject(typeof(int))) { EOLComment = "New simple type" },
                    new Assignment(o, new NewObject(Dot.Create(namespace_Test, namespace_TestFull, TestClass_ctor2), "test")) { EOLComment = "New class" },
                    new Assignment(o, new NewObject(testStruct)) { EOLComment = "New struct" }
                    );
                {
                    TypeRefBase type_PlatformID = TypeRef.Find(namespace_System, "PlatformID");
                    MethodTest.Add(new LocalDecl("p", type_PlatformID, Lookup.Create(codeUnit.GlobalAlias,
                        namespace_System, type_PlatformID, FieldRef.Find(type_PlatformID, "Win32NT"))) { EOLComment = "Lookup" });
                }

                MethodTest.Add(new Comment("This can be used to test loading of private types from referenced assemblies"));
                MethodTest.Add(new Comment("System.Web.DataAccess.SqlConnectionHelper h;") { NewLines = 1, NoSpaceAfterDelimiter = true });

                MethodTest.Add(new Comment("----- EXPRESSIONS -----"));
                MethodTest.Add(new Comment("(see above for Variables & Literals, including const, null, true, false)") { NewLines = 1 });

                MethodTest.Add(new Comment("Compound Variable Declarations"));
                LocalDecl mi1 = new LocalDecl("mi1", typeof(int));
                LocalDecl mi2 = new LocalDecl("mi2", typeof(int), 2) { EOLComment = "Number 2" };
                LocalDecl mi3 = new LocalDecl("mi3", typeof(int)) { IsFirstOnLine = true, EOLComment = "Third one" };
                MethodTest.Add(new MultiLocalDecl(mi1, mi2, mi3));

                MethodTest.Add(new Comment("Parenthesis Usage"),
                    new Assignment(b1, new Or(new And(b1, b2), new GreaterThan(i, 0))) { EOLComment = "Nested parens" },
                    new Assignment(i, new Subtract(i, new Add(1, 2))) { EOLComment = "Necessary parens" },
                    new Assignment(i, new Negative(new Add(i, 1))) { EOLComment = "Unary operator w/necessary parens" },
                    new Assignment(i, new Add(new Add(new Add(i, 1) { HasParens = true }, 2) { HasParens = true }, 3)) { EOLComment = "Unnecessary parens: ((i + 1) + 2) + 3" },
                    new Assignment(i, new Add(new Add(i, 1) { HasParens = true }, new Add(2, 3))) { EOLComment = "Necessary parens: (i + 1) + (2 + 3)" },
                    new Assignment(i, new Add(i, new Add(1, new Add(2, 3)))) { EOLComment = "Necessary parens: i + (1 + (2 + 3))" }
                    );

                BlockDecl block = new BlockDecl { Comment = "Stand-alone code block", Body = { InfixEOLComment = "Infix EOL comment" } };
                block.Add(new Comment("This & Base usage"),
                    new Assignment(o, new ThisRef()) { EOLComment = "this" },
                    new Call(new Dot(new ThisRef(), methodVoid2), 1, 2) { EOLComment = "this scope" },
                    new Assignment(d1, new Index(new ThisRef(), 0, 0)) { EOLComment = "this indexer" },
                    new Call(new Dot(new BaseRef(), MethodRef.Find(typeof(object), "GetType"))) { EOLComment = "base scope" },
                    new Assignment(o, new Index(new BaseRef(), 0)) { EOLComment = "base indexer" }
                    );
                MethodTest.Add(block);

                MethodTest.Add(new Comment("Multiple statements on the same line"),
                    new Assignment(s3, s1),
                    new Assignment(s1, s2) { NewLines = 0 },
                    new Assignment(s2, s3) { NewLines = 0, EOLComment = "Swap s1 and s2" }
                    );

                MethodTest.Add(new Comment("----- STATEMENTS -----"));

                MethodTest.Add(new Comment("IF"),
                    new If(new Equal(i, 1), new Comment("empty")) { Comment = "empty statement" },
                    new If(new Equal(i, 1), new Assignment(i, 2)) { Comment = "single statement" },
                    new If(new Equal(i, 2), new Assignment(i, 1)) { Comment = "single statement, same line", IsSingleLine = true, Body = { EOLComment = "single line 'if'" } }
                    );
                {
                    If @if = new If(new Equal(i, 1), new Block(new Assignment(i, 2), new Assignment(b1, true)) { InfixEOLComment = "K&R style" }) { Comment = "block" }; MethodTest.Add(@if);
                    @if.Body.IsFirstOnLine = false;
                }

                MethodTest.Add(new Comment("IF / ELSE"),
                    new If(new Equal(i, 1), new Else()) { Comment = "empty statement" },
                    new If(new Equal(i, 1), new Assignment(i, 2), new Else(new Assignment(i, 1))) { Comment = "single statement" },
                    new If(new Equal(i, 1), new Block(new Assignment(i, 2), new Assignment(b1, true)),
                        new Else(new Block(new Assignment(i, 1), new Assignment(b1, true)))) { Comment = "block" }
                    );

                MethodTest.Add(new Comment("IF / ELSE CHAINING"),
                    new If(new Equal(i, 1), new Else(new If(new Equal(i, 2), new Block(new Assignment(i, 1), new Assignment(b1, true)),
                        new Else(new If(new Equal(i, 3), new Assignment(i, 2), new Else(new Assignment(i, 0))) { EOLComment = "if EOL comment" }) { EOLComment = "else EOL comment" }) { Comment = "if comment" }) { Comment = "else comment" }) { Comment = "WITHOUT else-if chaining" },
                    new If(new Equal(i, 1), new ElseIf(new Equal(i, 2), new Block(new Assignment(i, 1), new Assignment(b1, true)),
                        new ElseIf(new Equal(i, 3), new Assignment(i, 2), new Else(new Assignment(i, 0))) { EOLComment = "else-if EOL comment" }) { Comment = "else-if comment" }) { Comment = "WITH else-if chaining" });

                MethodTest.Add(new Comment("SWITCH / CASE / DEFAULT"),
                    new Switch(i) { Comment = "empty switch" },
                    new Switch(i, new Case(1, new Block(new Assignment(b1, true), new Break()))) { Comment = "single case" }
                    );
                {
                    LocalDecl a;
                    MethodTest.Add(new Switch(i,
                        new Case(1) { EOLComment = "empty case fall-through" },
                        new Case(2, new Block(new Comment("Comment inside brace-less block"), new Assignment(b1, true), new Break())),
                        new Case(3, new Block(a = new LocalDecl("a", typeof(int), i),
                            new If(new Equal(a, 1), new Break()), new Assignment(b2, true), new Break()) { HasBraces = true, Comment = "Comment outside block after header" }) { Comment = "This case has braces for scope" },
                        new Default(new Block(new Assignment(b1, new Assignment(b2, false)), new Break())) { Comment = "This is the default case" }) { Comment = "multiple case, default" });
                }

                {
                    MethodTest.Add(new Comment("GOTO"));
                    Label label1 = new Label("Label1") { NewLines = 2, EOLComment = "first label" };
                    Label label2 = new Label("Label2") { EOLComment = "another label" };
                    MethodTest.Add(label1, label2);
                    Case case1 = new Case(1); case1.Add(new Goto(label1) { EOLComment = "goto label" });
                    Case case2 = new Case(2); case2.Add(new Goto(new Cast(typeof(int), new Multiply(new Literal("1L", true), 2))) { EOLComment = "goto case" });
                    Default @default = new Default(new Break());
                    Case case3 = new Case(3); case3.Add(new Goto(@default) { EOLComment = "goto default" });
                    MethodTest.Add(new Switch(i, case1, case2, case3, @default));
                }

                MethodTest.Add(new Comment("WHILE"),
                    new While(new LessThan(i, 100), null) { Comment = "null body" },
                    new While(new LessThan(i, 100)) { Comment = "empty statement" },
                    new While(new LessThan(i, 100), new Increment(i)) { Comment = "single statement" },
                    new While(new LessThan(i, 100), new Block(new Increment(i), new Continue())) { Comment = "block" },
                    new While(null, true, new Block(new Increment(i), new If(new GreaterThan(i, 100), new Break()) { IsSingleLine = true })) { Comment = "do infinite loop" }
                    );

                MethodTest.Add(new Comment("DO / WHILE"),
                    new While(new LessThan(i, 100), true) { Comment = "empty statement" },
                    new While(new LessThan(i, 100), true, new Increment(i)) { Comment = "single statement" },
                    new While(new LessThan(i, 100), true, new Block(new Increment(i), new Assignment(b1, true))) { Comment = "block" }
                    );

                MethodTest.Add(new Comment("FOR"));
                {
                    For @for = new For(new Assignment(i, 0), new LessThan(i, 100), null, null) { Comment = "null body" };
                    @for.AttachComment("infix", AnnotationFlags.IsInfix3 | AnnotationFlags.NoSpace);
                    MethodTest.Add(@for);
                    MethodTest.Add(new For(new Assignment(i, 0), new LessThan(i, 100), new Increment(i)) { Comment = "empty statement" });
                    LocalDecl i1 = new LocalDecl("i1", typeof(int), 0);
                    LocalDecl i2 = new LocalDecl("i2", typeof(int), 0);
                    @for = new For(new MultiLocalDecl(i1, i2), new LessThan(i1, 100), new Increment(i1), new AddAssign(i, i1)) { Comment = "single statement" };
                    @for.Iterations.Add(new Decrement(i2));
                    MethodTest.Add(@for);
                    @for = new For(new Assignment(i, 0), new LessThan(i, 100), new Increment(i),
                        new Block(new AddAssign(l, i), new Assignment(b1, true))) { Comment = "block" };
                    @for.Initializations.Add(new Assignment(l, 0));
                    @for.Iterations.Add(new Decrement(l));
                    MethodTest.Add(@for);
                    MethodTest.Add(new For(null, null, null, new Break()) { Comment = "do infinite loop" });
                }
                {
                    LocalDecl v2, v3;
                    MethodTest.Add(new Comment("FOREACH"),
                        new ForEach(new LocalDecl("v", typeof(int)), ia) { Comment = "empty statement" },
                        new ForEach(v2 = new LocalDecl("v", typeof(int)), ia, new AddAssign(i, v2)) { Comment = "single statement" },
                        new ForEach(v3 = new LocalDecl("v", typeof(int)), ia, new Block(new AddAssign(i, v3), new Assignment(b1, true))) { Comment = "block" }
                        );
                }

                MethodTest.Add(new Comment("----- EXCEPTIONS -----"));
                {
                    Finally @finally = new Finally(new Assignment(b2, true)) { EOLComment = "finally" };
                    Catch catch1 = new Catch(typeof(OverflowException), new Throw { EOLComment = "re-throw" }) { EOLComment = "catch w/o variable" };
                    LocalDecl ex = new LocalDecl("ex", typeof(StackOverflowException));
                    Catch catch2 = new Catch(ex, new Throw(ex) { EOLComment = "new throw" }) { EOLComment = "catch w/variable" };
                    Catch catch3 = new Catch { EOLComment = "catch all exceptions" };
                    MethodTest.Add(new Try(new Increment(i), @finally, catch1, catch2, catch3) { NewLines = 2, EOLComment = "try" });
                }

                MethodTest.Add(new Using(_instance) { HasBraces = true, EOLComment = "expression", NewLines = 2 });
                MethodTest.Add(new Using(new LocalDecl("obj", Dot.Create(namespace_Test, namespace_TestFull, TestClass),
                    new NewObject(TestClass_ctor1))) { HasBraces = true, EOLComment = "local variable" });
                {
                    LocalDecl obj1 = new LocalDecl("obj1", TestClass, new NewObject(TestClass_ctor1));
                    LocalDecl obj2 = new LocalDecl("obj2", TestClass, new NewObject(TestClass_ctor1));
                    MethodTest.Add(new Using(new MultiLocalDecl(obj1, obj2)) { HasBraces = true, EOLComment = "multiple variables" });
                }
                {
                    Using obj3 = new Using(new LocalDecl("obj3", TestClass, new NewObject(TestClass_ctor1))) { HasBraces = true, EOLComment = " and only have braces on the inner-most block)" };
                    Using obj2 = new Using(new LocalDecl("obj2", TestClass, new NewObject(TestClass_ctor1)), obj3) { EOLComment = "(should display at the same indent level," };
                    MethodTest.Add(new Using(new LocalDecl("obj1", TestClass, new NewObject(TestClass_ctor1)), obj2) { EOLComment = "multiple nested usings" });
                }

                MethodTest.Add(new Comment("----- LOCK -----"),
                    new Lock(o) { Comment = "empty statement" },
                    new Lock(o, new Increment(i)) { Comment = "single statement" },
                    new Lock(o, new Block(new Increment(i), new Assignment(b1, true))) { Comment = "block" }
                    );

                Ref refs3 = new Ref(s3);
                refs3.AttachAnnotation(new Comment("inline,") { IsFirstOnLine = false });
                MethodTest.Add(new Comment("----- METHODS -----"),
                    new Assignment(i, new Call(methodInt, 1)) { NewLines = 2 },
                    new If(new Equal(new Call(methodString, refs3, new Out(d1)), new Literal(null)),
                        new Assignment(i, new Call(methodGeneric.CreateRef(typeof(int), typeof(object)), o))),
                    new Assignment(ia, new Call(methodGeneric2, i)),
                    new Call(methodUIntULong, new Add(new Literal("1u", true), 1), new Subtract(new Literal("1ul", true), 1)),
                    new Call(methodUIntULong, new Add(ui, 1), new Subtract(ul, 1))
                    );

                MethodTest.Add(new Call(new Dot(typeof(decimal), MethodRef.Find(typeof(decimal), "Round", typeof(decimal))), new Conditional(b1, ci, new Literal("100m", true))) { NewLines = 2 });
                TypeRefBase string_Format = MethodRef.Find(typeof(string), "Format", typeof(string), typeof(object[]));
                SymbolicRef int_MaxValue = FieldRef.Find(typeof(int), "MaxValue");
                MethodTest.Add(
                    new Call(Dot.Create(typeof(string), string_Format), "{0} {1}", 1, Dot.Create(typeof(int), int_MaxValue)),
                    new Call(Dot.Create(typeof(string), string_Format), "{0} {1} {2} {3}", 1, Dot.Create(typeof(int), int_MaxValue),
                        new Literal("2d", true), new Literal("3f", true)),
                    new Call(Dot.Create(typeof(string), string_Format), new Literal(@"""""", true)),
                    new Call(new Dot(li, MethodRef.Find(typeof(List<int>), "Add", typeof(int))), 1)
                    );

                MethodTest.Add(
                    new Call(_del1) { NewLines = 2 },
                    new Assignment(s1, new Call(_del3, new Ref(s2), new Out(d1))),
                    new Assignment(i, new Call(_del4, 1)),
                    new AddAssign(_del1, methodVoid1)
                    );

                MethodTest.Add(new Comment("----- PROPERTIES -----"),
                    new Assignment(s1, TestClass_Test) { NewLines = 2 },
                    new Assignment(TestClass_Test, s1)
                    );

                MethodTest.Add(new Comment("----- INDEXERS -----"),
                    new Assignment(d1, new Index(_instance, 0, 0)) { NewLines = 2 },
                    new Assignment(new Index(_instance, 0, 0), d1)
                    );

                MethodTest.Add(new Comment("----- EVENTS -----"),
                    new AddAssign(event2, methodVoid1) { NewLines = 2 }
                    );

                MethodTest.Add(new Comment("----- COMMENTS -----"));
                MethodTest.Add(new Comment("This is an independent comment that is split...\n\nacross 3 lines."));
                {
                    Assignment assign = new Assignment(i, 1) { IsFirstOnLine = true, EOLComment = "This EOL comment is associated with the statement on the left", NewLines = 2 };
                    assign.AttachComment("This comment is associated with the statement below");
                    assign.AttachComment("This is a separate comment associated with the statement below, and\nit spans two lines.");
                    MethodTest.Add(assign);
                    And and = new And(b1, b2) { EOLComment = "embedded comment" };
                    MethodTest.Add(new Assignment(b1, new Or(and, new Not(new GreaterThan(i, 0)))) { NewLines = 2, EOLComment = "EOL comment" });
                }

                {
                    If @if = new If(new And(new And(new NotEqual(s, new Literal(null)) { IsFirstOnLine = true, EOLComment = "EOL on !=" },
                        new GreaterThan(new Dot(new ThisRef(), PropertyRef.Find(TestClass, "Capacity")), 0)) { IsFirstOnLine = true, EOLComment = "EOL on '&&' #1" },
                        new Dot(Dot.Create(namespace_System, type_Console), PropertyRef.Find(type_Console, "CursorVisible")) { PostfixComment = "Postfix comment", EOLComment = "EOL on '&&' #2" })) { IsEndFirstOnLine = true, NewLines = 2 };

                    Or or = new Or(
                        new And(new LocalRef(b1) { IsFirstOnLine = true, EOLComment = "EOL on b1" },
                            new GreaterThan(new Cast(typeof(long), Dot.Create(namespace_System, type_Console, PropertyRef.Find(type_Console, "BufferWidth"))) { IsFirstOnLine = true, EOLComment = "EOL on cast" }, 0) { EOLComment = "EOL on '>'", PostfixComment = "Postfix comment on '>'" }
                            ) { IsFirstOnLine = true, IsEndFirstOnLine = true, EOLComment = "EOL on '&&'" },
                        new Not(new LessThan(i, new Literal(0) { EOLComment = "EOL on '0'" }) { IsEndFirstOnLine = true }) { IsFirstOnLine = true, EOLComment = "EOL on '!'" }) { IsEndFirstOnLine = true };
                    or.AttachComment("EOL on ||", AnnotationFlags.IsInfix1, CommentFlags.EOL);
                    Assignment assign = new Assignment(b1, or);

                    LocalDecl objs = new LocalDecl("objs", typeof(object[]), new NewArray(typeof(object[]))
                        {
                            Initializer = new Initializer(new Dot(new ThisRef(), PropertyRef.Find(TestClass, "Capacity")) { EOLComment = "1st" },
                                new Cast(typeof(long), Dot.Create(type_Console, PropertyRef.Find(type_Console, "BufferWidth"))) { EOLComment = "2nd" },
                                new Or(new And(b1, b2), new Equal(i, 0)) { EOLComment = "3rd" },
                                new LocalRef(s) { EOLComment = "4th" }) { IsSingleLine = false }
                        });

                    MultiLocalDecl multi = new MultiLocalDecl(
                        new LocalDecl("i1", typeof(int), 1) { EOLComment = "1" },
                        new LocalDecl("i2", typeof(int), 2) { IsFirstOnLine = true, EOLComment = "2" },
                        new LocalDecl("i3", typeof(int), new Cast(typeof(int), Dot.Create(type_Console, PropertyRef.Find(type_Console, "BufferWidth")))) { IsFirstOnLine = true, EOLComment = "3" });

                    @if.Add(assign, objs, multi);
                    MethodTest.Add(@if);
                }


                MethodTest.Add(new Comment("There is a triple blank line after this comment..."));
                MethodTest.Add(new Comment("Block comment Line 1\n   Line 2", CommentFlags.Block) { NewLines = 4 });
                MethodTest.Add(new Comment("Block comment Line 1\n   Line 2\n   Line 3\n", CommentFlags.Block) { NewLines = 1 });

                MethodTest.Add(new Comment("TODO: This is a 'to-do' comment", CommentFlags.TODO));


                MethodTest.Add(new Comment("----- COMPILER DIRECTIVES -----"),
                    new RegionDirective("/* COMPILER DIRECTIVES */"),
                    new Comment("See top of file for #define/#undef examples, since they can only legally appear there"),
                    new IfDirective(new Or(new Or(new And(new And(new DirectiveSymbolRef("TEST1"),
                        new DirectiveSymbolRef("TEST2")), new DirectiveSymbolRef("TEST3")),
                        new Not(new DirectiveSymbolRef("TEST4"))), new And(new Equal(new DirectiveSymbolRef("TEST5"), true),
                            new NotEqual(new DirectiveSymbolRef("TEST6"), false)))) { NewLines = 2, EOLComment = "comment" },
                    new IfDirective(new DirectiveSymbolRef("TEST1"))
                        {
                            NewLines = 2,
                            SkippedText = "// This 'code' will not be compiled:\nIt's not actually code, but that doesn't matter.",
                            EOLComment = "conditional compilation"
                        },
                    new ElIfDirective(new DirectiveSymbolRef("TEST2")) { SkippedText = "This text won't be compiled.", EOLComment = "elif" },
                    new ElseDirective { EOLComment = "else" },
                    new WarningDirective("Warning message!") { NewLines = 2 },
                    //new ErrorDirective("Error message!"),
                    new Comment("#error Error message!") { HasNoIndentation = true, NoSpaceAfterDelimiter = true, NewLines = 1 },
                    new LineDirective(999, @"""C:\path\test.cs""") { EOLComment = "comment" },
                    new LineDirective(LineDirectiveType.Hidden) { EOLComment = "comment" },
                    new LineDirective(LineDirectiveType.Default) { EOLComment = "comment" },
                    new EndIfDirective { EOLComment = "endif", NewLines = 2 },
                    new EndIfDirective { NewLines = 2 }
                    );

                {
                    Literal one = new Literal("one") { IsFirstOnLine = true, Comment = "Regular comment" };
                    Literal two = new Literal("two") { IsFirstOnLine = true, Comment = "Regular comment", EOLComment = "EOL comment" };
                    two.AttachAnnotation(new ElseDirective(), true);
                    two.AttachAnnotation(new IfDirective(false) { SkippedText = "\"too\"," }, true);
                    two.AttachAnnotation(new EndIfDirective(), AnnotationFlags.IsPostfix);
                    two.AttachAnnotation(new IfDirective(false) { SkippedText = "\"three\"" }, AnnotationFlags.IsPostfix);
                    two.AttachAnnotation(new EndIfDirective(), AnnotationFlags.IsPostfix);
                    MethodTest.Add(new LocalDecl("cds", typeof(string[]), new Initializer(one, two) { IsSingleLine = false, InfixEOLComment = "EOL comment" }) { NewLines = 2 });
                }

                MethodTest.Add(
                    new PragmaWarningDirective(PragmaWarningAction.Disable) { NewLines = 2, EOLComment = "comment" },
                    new PragmaWarningDirective(PragmaWarningAction.Restore) { EOLComment = "comment" },
                    new PragmaWarningDirective(PragmaWarningAction.Disable, 78, 219, 1691) { EOLComment = "comment" },
                    new PragmaWarningDirective(PragmaWarningAction.Restore, 78, 219, 1691) { EOLComment = "comment" },
                    new PragmaWarningDirective(PragmaWarningAction.Disable),
                    new PragmaChecksumDirective("\"test.cs\"", "\"{00000000-0000-0000-0000-000000000000}\"", "\"01234567\"") { NewLines = 2, EOLComment = "comment" },
                    new EndRegionDirective("/* COMPILER DIRECTIVES */")
                    );
            }
            TestClass.Add(MethodTest);


            TestClass.Add(new Comment("----- OTHER METHODS -----"),
                methodVoid1, methodVoid2, methodUIntULong, methodInt, methodString, methodGeneric, methodGeneric2, methodIterator);


            MethodDecl removeDirectory = new MethodDecl("RemoveDirectory", typeof(bool), Modifiers.Static | Modifiers.Extern,
                (CodeObject)null, new ParameterDecl("name", typeof(string))) { EOLComment = "extern - no body" };
            Attribute dll_attr = new Attribute(ConstructorRef.Find(typeof(DllImportAttribute), typeof(string)), "kernel32",
                new Assignment(FieldRef.Find(typeof(DllImportAttribute), "SetLastError"), true), new Assignment(FieldRef.Find(typeof(DllImportAttribute), "ExactSpelling"), true));
            removeDirectory.AttachAnnotation(dll_attr);
            TestClass.Add(removeDirectory);


            {
                ParameterDecl px = new ParameterDecl("x", typeof(double), ParameterModifier.Ref);
                MethodDecl aMethod = new MethodDecl("AMethod", typeof(void), px) { EOLComment = "parameter attributes" };
                px.AttachAnnotation(new Attribute(typeof(InAttribute), typeof(OutAttribute)));
                TestClass.Add(aMethod);
            }


            // NESTED, GENERIC INTERFACE
            InterfaceDecl interface1;
            MethodDecl interface1_Method;
            PropertyDecl interface1_Property;
            IndexerDecl interface1_Indexer;
            EventDecl interface1_Event;
            {
                TypeParameter T = new TypeParameter("T");
                interface1 = new InterfaceDecl("InnerInterface", Modifiers.None, T) { Comment = "This is a nested, generic interface" };
                interface1_Method = new MethodDecl("Method", typeof(void), (CodeObject)null);
                interface1.Add(interface1_Method);
                interface1_Property = new PropertyDecl("Property", typeof(string)) { NewLines = 1, Getter = new GetterDecl(null), Setter = new SetterDecl(null) };
                interface1.Add(interface1_Property);
                interface1_Indexer = new IndexerDecl(T, new ParameterDecl("i", T)) { NewLines = 1, Getter = new GetterDecl(null) };
                interface1.Add(interface1_Indexer);
                interface1_Event = new EventDecl("Event", del_VoidNoParms) { NewLines = 1 };
                interface1.Add(interface1_Event);
                TestClass.Add(interface1);
            }

            // NESTED, GENERIC CLASS
            ClassDecl InnerClass;
            {
                TypeParameter T = new TypeParameter("T");
                TypeParameter U = new TypeParameter("U");
                InnerClass = new ClassDecl("InnerClass", Modifiers.None, T, U)
                    {
                        DocComment = new DocComment(new DocSummary("\nThis is a nested, generic class.\n"), new DocTypeParam(T, "Type parameter T."), new DocTypeParam(U, "Type parameter U.")),
                        EOLComment = "EOL comment on ClassDecl"
                    };
                InnerClass.AddBaseTypes(new TypeRef(interface1, T) { IsFirstOnLine = true, Comment = "Comment on base-type list", EOLComment = "EOL comment on base type/interface" });
                InnerClass.AddConstraintClauses(new ConstraintClause(T, new StructConstraint()) { IsFirstOnLine = true, Comment = "Comment on constraints" },
                    new ConstraintClause(U, new TypeConstraint(TestClass), new NewConstraint { EOLComment = "EOL comment on constraints" }));
                InnerClass.Add(new FieldDecl("t", T, Modifiers.Protected));
                InnerClass.Add(new FieldDecl("u", U, Modifiers.Public));
                FieldDecl c1_p = new FieldDecl("p", interface1.CreateRef(T), Modifiers.Public); InnerClass.Add(c1_p);
                TypeRef c1_instance_Type = InnerClass.CreateRef(typeof(int), TestClass);
                FieldDecl c1_instance = new FieldDecl("_instance", c1_instance_Type, Modifiers.Private | Modifiers.Static | Modifiers.ReadOnly); InnerClass.Add(c1_instance);

                ClassDecl c1_Inner2;
                GenericMethodDecl c1_Inner2Generic;
                {
                    TypeParameter V = new TypeParameter("V");
                    c1_Inner2 = new ClassDecl("Inner2", Modifiers.Private, V) { DocComment = new DocComment(new DocSummary("\nNested, generic type, with generic method referencing parent type parameters.\n"), new DocTypeParam(V, "Type parameter V.")) };
                    c1_Inner2.AddConstraintClauses(new ConstraintClause(V, new TypeConstraint(typeof(IComparable))));
                    TypeParameter W = new TypeParameter("W");
                    c1_Inner2Generic = new GenericMethodDecl("Inner2Generic", typeof(string), Modifiers.Public, W);
                    c1_Inner2Generic.AddConstraintClauses(new ConstraintClause(W, new TypeConstraint(U)));
                    {
                        ParameterDecl t = new ParameterDecl("t", T);
                        ParameterDecl u = new ParameterDecl("u", U);
                        ParameterDecl v = new ParameterDecl("v", V);
                        ParameterDecl w = new ParameterDecl("w", W);
                        c1_Inner2Generic.AddParameters(t, u, v, w);
                        c1_Inner2Generic.Add(new Return(new Add(new Add(new Add(new Call(new Dot(t, MethodRef.Find(typeof(object), "ToString"))), u), v), w)));
                        c1_Inner2Generic.DocComment = new DocComment(new DocSummary("\nInner2Generic test method.\nThis method has generic parameter ", new DocTypeParamRef(W), ".\n"),
                            new DocTypeParam(W, "Type parameter W."), new DocParam(t, "Parameter t."), new DocParam(u, "Parameter u."), new DocParam(v, "Parameter v."), new DocParam(w, "Parameter w."),
                            new DocReturns("String result."));
                    }
                }
                c1_Inner2.Add(c1_Inner2Generic);

                FieldDecl c1_inner2 = new FieldDecl("_inner2", c1_Inner2.CreateRef(typeof(long)), Modifiers.Private); InnerClass.Add(c1_inner2);

                InnerClass.Add(new ConstructorDecl(Modifiers.Static)
                    {
                        Comment = "Static constructor",
                        Body =
                            {
                                new Assignment(c1_instance, new NewObject(InnerClass.CreateRef(typeof(int), TestClass))),
                                new LocalDecl("t1", typeof(Type), new Call(new Dot(new Cast(interface1, c1_instance), MethodRef.Find(c1_instance_Type, "GetType")))),
                                new LocalDecl("t2", typeof(Type), new Call(new Dot(new Cast(typeof(IList), new NewObject(new TypeRef(typeof(List<>), T))), MethodRef.Find(c1_instance_Type, "GetType")))),
                                new Assignment(new Dot(c1_instance, FieldRef.Find(c1_instance_Type, "_inner2")), new NewObject(new Dot(new TypeRef(InnerClass, typeof(int), TestClass), new TypeRef(c1_Inner2, typeof(long))))),
                                new LocalDecl("s", typeof(string), new Call(Dot.Create(c1_instance, c1_inner2, c1_Inner2Generic), 1, new Dot(TestClass, _instance), new Literal("2L", true), new Dot(TestClass, _instance)))
                            }
                    });

                InnerClass.Add(new Comment("Explicit interface implementations"));
                InnerClass.Add(new MethodDecl(new Dot(interface1.CreateRef(T), interface1_Method), typeof(void)) { IsSingleLine = true });
                InnerClass.Add(new PropertyDecl(new Dot(interface1.CreateRef(T), interface1_Property), typeof(string)) { NewLines = 1, Getter = new GetterDecl(new Return("")), Setter = new SetterDecl(), IsSingleLine = true });
                InnerClass.Add(new IndexerDecl(new Dot(interface1.CreateRef(T), interface1_Indexer), T, new ParameterDecl("i", T)) { NewLines = 1, Getter = new GetterDecl(new Return(new DefaultValue(T))), IsSingleLine = true });
                InnerClass.Add(new EventDecl(new Dot(interface1.CreateRef(T), interface1_Event), del_VoidNoParms) { NewLines = 1, Adder = new AdderDecl(), Remover = new RemoverDecl(), IsSingleLine = true });

                InnerClass.Add(c1_Inner2);

                TestClass.Add(InnerClass);
            }


            // public struct InnerStruct<T>
            {
                TypeParameter typeParameterT = new TypeParameter("T");
                StructDecl struct1 = new StructDecl("InnerStruct", Modifiers.Public, typeParameterT);
                struct1.AttachAnnotation(new DocComment(
                    new DocSummary("\nThis is a nested struct, generic on ", new DocTypeParamRef(typeParameterT), ".\n"),
                    new DocTypeParam(typeParameterT, "Type parameter.")));
                TestClass.Add(struct1);
            }


            // class InnerDerived : InnerClass<DateTime, TestClass>
            ClassDecl InnerDerived = new ClassDecl("InnerDerived", Modifiers.None, new TypeRef(InnerClass, typeof(DateTime), TestClass));
            SymbolicRef inner_t = FieldRef.Find(InnerClass, "t");
            InnerDerived.Add(new MethodDecl("Method", typeof(void), new LocalDecl("v", typeof(int), new Dot(inner_t, PropertyRef.Find(typeof(DateTime), "Hour")))));
            TestClass.Add(InnerDerived);


            // class TestCollection<TItem> : List<TItem>
            ClassDecl TestCollection;
            {
                TypeParameter TItem = new TypeParameter("TItem");
                TestCollection = new ClassDecl("TestCollection", Modifiers.None, TItem) { IsEndFirstOnLine = false };
                TestCollection.AddBaseTypes(new TypeRef(typeof(List<>), TItem));
                TestClass.Add(TestCollection);
            }
            MethodDecl CollectionMethod = new MethodDecl("CollectionMethod", typeof(void), new ParameterDecl("list", new TypeRef(typeof(List<>), TestClass))) { NewLines = 1 };
            TestClass.Add(CollectionMethod);
            MethodDecl testGenericCollection = new MethodDecl("TestGenericCollection", typeof(void)) { NewLines = 1 };
            LocalDecl collection = new LocalDecl("collection", new TypeRef(TestCollection, TestClass), new NewObject(new TypeRef(TestCollection, TestClass)));
            testGenericCollection.Add(collection, new Call(CollectionMethod, collection));
            TestClass.Add(testGenericCollection);


            // public class TestBase<T>
            ClassDecl TestBaseT;
            PropertyDecl TestBaseT_Property;
            {
                TypeParameter T = new TypeParameter("T");
                TestBaseT = new ClassDecl("TestBase", Modifiers.Public, T);
                FieldDecl t = new FieldDecl("t", T, Modifiers.Private, new DefaultValue(T));
                TestBaseT_Property = new PropertyDecl("Property", T, Modifiers.Public) { Getter = new GetterDecl(new Return(t)), IsSingleLine = true, NewLines = 1 };
                TestBaseT.Add(t, TestBaseT_Property);
                TestClass.Add(TestBaseT);
            }
            // public class InnerTest : TestBase<TestClass>
            ClassDecl InnerTest;
            {
                InnerTest = new ClassDecl("InnerTest", Modifiers.Public, TestBaseT.CreateRef(TestClass)) { NewLines = 1 };
                MethodDecl Test = new MethodDecl("Test", typeof(void), Modifiers.Public, new LocalDecl("s1", typeof(string), new Dot(TestBaseT_Property, TestClass_Test)));
                InnerTest.Add(Test);
                TestClass.Add(InnerTest);
            }


            // public interface ITestInterface : IComparable
            @namespace.Add(new InterfaceDecl("ITestInterface", Modifiers.Public, typeof(IComparable)) { Comment = "This is a top-level interface" });


            // public struct TestStruct
            //StructDecl @struct = new StructDecl("TestStruct", Modifiers.Public);  // Moved up for forward reference
            @namespace.Add(testStruct);


            return codeUnit;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)


Written By
Software Developer (Senior)
United States United States
I've been writing software since the late 70's, currently focusing mainly on C#.NET. I also like to travel around the world, and I own a Chocolate Factory (sadly, none of my employees are oompa loompas).

Comments and Discussions