public CodeCompileUnit Compile(TypeSafeDataUnit dataUnit)
        {
            var compileUnit = new CodeCompileUnit();

            compileUnit.UserData.Add(Strings.CompileUnitUserDataKey, dataUnit.FileName);

            CompilerUtil.WriteHeader(compileUnit);

            var ns = new CodeNamespace(Namespace);

            compileUnit.Namespaces.Add(ns);

            var className = CompilerUtil.GetSafeName(dataUnit.ClassName, false, false);

            if (className != dataUnit.ClassName)
            {
                TSLog.LogWarning(LogCategory.Compile,
                                 string.Format("Class name was modified to conform to C# standards ({0} -> {1})", dataUnit.ClassName, className));
            }

            var container = CompilerUtil.CreateStaticType(className);

            CompilerUtil.AddTypeSafeTag(container);

            PopulateClass(dataUnit, container);

            ns.Types.Add(container);
            return(compileUnit);
        }
        private void WriteFolder(CodeTypeDeclaration type, ResourceFolder folder)
        {
            ResourceCompilerUtil.WriteResources(type, folder);

            foreach (var f in folder.Folders)
            {
                var c = CompilerUtil.CreateStaticType(CompilerUtil.GetSafeName(f.Name));
                WriteFolder(c, f);

                type.Members.Add(c);
            }

            ResourceCompilerUtil.CreateGetContentsMethod(type);
            ResourceCompilerUtil.CreateGetContentsRecursiveMethod(type, folder);

            ResourceCompilerUtil.WriteGetContentsGenericMethod(type);
            ResourceCompilerUtil.WriteGetContentsRecursiveGenericMethod(type);

            ResourceCompilerUtil.WriteUnloadAllMethod(type);
            ResourceCompilerUtil.WriteUnloadAllRecursiveMethod(type);
        }
        public static void CreateGetContentsRecursiveMethod(CodeTypeDeclaration type, ResourceFolder folder)
        {
            var cache = new CodeMemberField(GetIResourceIListType(), RecursiveLookupCacheName)
            {
                Attributes = MemberAttributes.Static | MemberAttributes.Private
            };

            type.Members.Add(cache);

            var method = new CodeMemberMethod
            {
                Attributes = MemberAttributes.Static | MemberAttributes.Public,
                Name       = Strings.GetResourcesRecursiveMethodName,
                ReturnType = GetIResourceIListType()
            };

            method.Comments.AddRange(CompilerUtil.CreateDocsComment(Strings.GetContentsRecursiveCommentSummary,
                                                                    Strings.GetContentsRecursiveCommentReturns));

            method.Statements.Add(
                new CodeConditionStatement(
                    new CodeBinaryOperatorExpression(
                        new CodeFieldReferenceExpression(null, RecursiveLookupCacheName),
                        CodeBinaryOperatorType.IdentityInequality,
                        new CodePrimitiveExpression(null)
                        ),
                    new CodeMethodReturnStatement(new CodeFieldReferenceExpression(null, RecursiveLookupCacheName))));

            // Create list
            method.Statements.Add(new CodeVariableDeclarationStatement(GetIResourceListType(), "tmp",
                                                                       new CodeObjectCreateExpression(GetIResourceListType())));

            // Add any resources from this folder
            method.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("tmp"), "AddRange",
                                                                 new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(null, Strings.GetResourcesMethodName))));

            // Add any resources from subfolders
            foreach (var f in folder.Folders)
            {
                var name = CompilerUtil.GetSafeName(f.Name, true);

                // Skip if this folder hasn't been added to the type for some reason
                if (!CompilerUtil.IsDuplicate(name, type))
                {
                    continue;
                }

                // Add any resources from this folder
                method.Statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("tmp"),
                                                                     "AddRange",
                                                                     new CodeMethodInvokeExpression(
                                                                         new CodeMethodReferenceExpression(new CodeSnippetExpression(name),
                                                                                                           Strings.GetResourcesRecursiveMethodName))));
            }

            method.Statements.Add(
                new CodeAssignStatement(new CodeFieldReferenceExpression(null, RecursiveLookupCacheName),
                                        new CodeVariableReferenceExpression("tmp")));

            method.Statements.Add(
                new CodeMethodReturnStatement(new CodeFieldReferenceExpression(null, RecursiveLookupCacheName)));

            type.Members.Add(method);
        }