Ejemplo n.º 1
0
        /// <summary>
        /// Gets the parsed template code.
        /// </summary>
        /// <returns>The C# code created from the template functions.</returns>
        public static string ParseTemplateFileCSharp()
        {
            var sb = new StringBuilder(1000);
            string namespaces = "";

            // Get Designer version info
            string versionNumber;
            {
                Assembly designerAssembly = Assembly.GetAssembly(typeof(CompileHelper));
                versionNumber = designerAssembly.GetName().Version.ToString();
            }

            // Create namespace list
            for (int i = 0; i < Project.Instance.Namespaces.Count; i++)
            {
                if (Project.Instance.Namespaces[i].Trim().Length > 0)
                {
                    namespaces += "using " + Project.Instance.Namespaces[i] + ";\n";
                }
            }

            if (RandomiseTheNamespace)
            {
                NamespaceUsed = Project.Instance.ProjectNamespace + RandomNamespaceNumber++;
            }
            else
            {
                NamespaceUsed = Project.Instance.ProjectNamespace;
            }

            string versioningInfo =
                string.Format(
                    "[assembly: AssemblyVersion(\"{1}\")]{0}[assembly: AssemblyFileVersion(\"{1}\")]{0}[assembly: AssemblyInformationalVersion(\"{2}\")]{0}[assembly: AssemblyProduct(\"Compiled by ArchAngel Designer Version {2}\")]{0}",
                    Environment.NewLine, (string.IsNullOrEmpty(Project.Instance.Version) ? "0.0.0.0" : Project.Instance.Version),
                    versionNumber);

            sb.Append(@"
                    " + namespaces +
                      @"
                    using System.Reflection;
                    using System.Collections.Generic;
                    " +
                      versioningInfo + @"
                    namespace " + NamespaceUsed + @"
                    {");

            #region ScriptFunctionWrappers_String

            sb.Append(
                @"
                            public class ScriptFunctionWrapper : ArchAngel.Interfaces.ScriptFunctionWrapper
                            {
                        ");

            #region RunScriptFunction

            sb.Append(
                @"
                                private string GetParamTypeString(object[] parameters)
                                {
                                    StringBuilder sb = new StringBuilder(100);

                                    foreach (object parameter in parameters)
                                    {
                                        sb.Append(parameter.GetType().FullName + "","");
                                    }
                                    return sb.ToString().TrimEnd(',').Replace(""+"", ""."");
                                }

                                private static TemplateGen instance = new TemplateGen();

                                public override object RunScriptFunction(string functionName, ref object[] parameters)
                                {
                                    object result = null;

                                    switch (functionName)
                                    {
                       ");
            var functionComparer = new Comparers.FunctionComparer();
            Project.Instance.Functions.Sort(functionComparer);
            string prevFunctionName = "";

            for (int functionCounter = 0; functionCounter < Project.Instance.Functions.Count; functionCounter++)
            {
                FunctionInfo fi = Project.Instance.Functions[functionCounter];

                if (fi.IsExtensionMethod)
                    continue;

                DefaultValueFunction defaultValueFunction = Project.Instance.FindDefaultValueFunction(fi.Name,
                                                                                                              fi.Parameters);
                if (defaultValueFunction != null)
                    continue;

                //if (defaultValueFunction != null && !defaultValueFunction.UseCustomCode)
                //{
                //    continue;
                //}
                string unboxedString = "";
                string localVariables = "";
                string callee = "TemplateGen";

                if (fi.IsTemplateFunction)
                    callee = "instance";

                for (int i = 0; i < fi.Parameters.Count; i++)
                {
                    localVariables += string.Format("{0} {2}param{3}_{1} = ({0})parameters[{1}];",
                                                    Utility.GetDemangledGenericTypeName(fi.Parameters[i].DataType),
                                                    i, fi.Name, functionCounter);
                    if (i > 0)
                    {
                        unboxedString += ", ";
                    }
                    unboxedString += string.Format("{1} {2}param{3}_{0}", i, fi.Parameters[i].Modifiers, fi.Name, functionCounter);
                }
                // Check whether the function is overloaded - add inner switch if it is
                bool functionIsOverloaded = Project.Instance.FindFunctions(fi.Name).Count > 1;

                if (!functionIsOverloaded ||
                    !Utility.StringsAreEqual(prevFunctionName, Project.Instance.Functions[functionCounter].Name,
                                                          true))
                {
                    // This is the first function with this name
                    sb.AppendFormat("case \"{0}\":", fi.Name);

                    if (functionIsOverloaded)
                    {
                        sb.Append(@"
                                    switch (GetParamTypeString(parameters))
                                    {");
                    }
                }
                prevFunctionName = Project.Instance.Functions[functionCounter].Name;

                if (functionIsOverloaded)
                {
                    sb.AppendFormat("case \"{0}\":", GetParamTypeString(Project.Instance.Functions[functionCounter].Parameters));
                }
                if (fi.ReturnType != null && fi.ReturnType.FullName != "System.Void")
                {
                    sb.Append(@"
                                " + localVariables +
                              @"
                                result = " + callee + "." + fi.Name + @"(" + unboxedString +
                              @");
                                ");
                }
                else
                {
                    sb.Append(@"
                                " + localVariables + @"
                                " +
                              callee + "." + fi.Name + @"(" + unboxedString +
                              @");
                                result = null;
                                ");
                }
                for (int i = 0; i < fi.Parameters.Count; i++)
                {
                    sb.Append(string.Format("parameters[{0}] = {1}param{2}_{0};", i, fi.Name, functionCounter));
                }
                sb.Append(
                    @"
                                                break;
                                            ");
                if (functionIsOverloaded &&
                    (functionCounter == Project.Instance.Functions.Count - 1 ||
                     (functionCounter < Project.Instance.Functions.Count - 1 &&
                      Project.Instance.Functions[functionCounter].Name != Project.Instance.Functions[functionCounter + 1].Name)))
                {
                    // This is the last overloaded function with this name
                    //firstFuncWithName = true;
                    sb.Append(@"}
                                break;");
                }
            }

            #region Wrap calls to Dynamic Filenames

            foreach (OutputFile file in Project.Instance.GetAllFiles())
            {
                string paramString = string.IsNullOrEmpty(file.IteratorTypes)
                                        ? ""
                                        : string.Format("({0})parameters[0]", file.IteratorTypes);
                string[] parts = file.Name.Split('#');
                int numAdded = 0;

                for (int partCounter = 0; partCounter < parts.Length; partCounter++)
                {
                    if (partCounter % 2 == 1)
                    {
                        sb.AppendFormat(
                            @"
                            case ""DynamicFilenames.File_{0}_{1}"":
                                return TemplateGen.DynamicFilenames.File_{0}_{1}({2});
                            ",
                            file.Id, numAdded, paramString);
                        numAdded++;
                    }
                }
            }

            #endregion

            #region Wrap calls to Dynamic FolderNames

            foreach (OutputFolder folder in Project.Instance.GetAllFolders())
            {
                string paramString = folder.IteratorType == null
                                        ? ""
                                        : string.Format("({0})parameters[0]", folder.IteratorType.FullName);
                string[] parts = folder.Name.Split('#');
                int numAdded = 0;

                for (int partCounter = 0; partCounter < parts.Length; partCounter++)
                {
                    if (partCounter % 2 == 1)
                    {
                        sb.AppendFormat(
                            @"
                            case ""DynamicFolderNames.Folder_{0}_{1}"":
                                return TemplateGen.DynamicFolderNames.Folder_{0}_{1}({2});
                            ",
                            folder.Id, numAdded, paramString);
                        numAdded++;
                    }
                }
            }

            #endregion

            sb.Append(
                @"
                                            case ""InternalFunctions.MustSkipCurrentFile"":
                                                        return instance.SkipCurrentFile;
                                            case ""InternalFunctions.ResetSkipCurrentFile"":
                                                        instance.SkipCurrentFile = false;
                                                        return null;
                                            case ""InternalFunctions.GetCurrentFileName"":
                                                        return instance.CurrentFileName;
                                            case ""InternalFunctions.ResetCurrentFileName"":
                                                        instance.CurrentFileName = """";
                                                        return null;
                                            case ""InternalFunctions.SetGeneratedFileName"":
                                                        instance.GeneratedFileName = (string)parameters[0];
                                                        return null;
                                            case ""InternalFunctions.ClearTemplateCache"":
                                                        instance.ClearTemplateCache();
                                                        return null;
                                            default:
                                            throw new Exception(""Function not handled in RunScriptFunction:""+ functionName);
                                    }
                                    return result;
                                }
                        ");

            #endregion

            #region RunApiExtensionFunction

            sb.Append(
                @"
                                public override bool RunApiExtensionFunction(string functionName, out object result, ref object[] parameters)
                                {
                                    result = null;
                                    functionName = functionName.Replace(""."", ""_"");

                                    switch (functionName)
                                    {
                       ");

            prevFunctionName = "";

            foreach (ApiExtensionMethod extensionMethod in Project.Instance.ApiExtensions)
            {
                if (!extensionMethod.HasOverride)
                {
                    continue;
                }
                string unboxedString = "";
                string localVariables = "";

                var method = extensionMethod.ExtendedMethod;
                var parameters = method.GetParameters();
                for (int i = 0; i < parameters.Length; i++)
                {
                    localVariables += string.Format("{0} {2}param{1} = ({0})parameters[{1}];",
                                                    Utility.GetDemangledGenericTypeName(parameters[i].ParameterType),
                                                    i, method.Name);
                    if (i > 0)
                    {
                        unboxedString += ", ";
                    }
                    unboxedString += string.Format("{1} {2}param{0}", i, GetModifiers(parameters[i]), method.Name);
                }
                // Check whether the function is overloaded - add inner switch if it is
                bool functionIsOverloaded = Project.Instance.FindFunctions(method.Name).Count > 1;

                if (!Utility.StringsAreEqual(prevFunctionName, method.Name, true))
                {
                    // This is the first function with this name
                    sb.AppendFormat("case \"{0}\":", method.Name);

                    if (functionIsOverloaded)
                    {
                        sb.Append(@"
                                    switch (GetParamTypeString(parameters))
                                    {");
                    }
                }
                prevFunctionName = method.Name;

                if (functionIsOverloaded)
                {
                    sb.AppendFormat("case \"{0}\":", GetParamTypeString(parameters));
                }
                sb.Append( /*string.Format("case \"{0}\":", func.Name) +*/
                    @"
                                                " + localVariables +
                    @"
                                                result = ApiExtensionMethods." + GetApiExtensionMethodName(extensionMethod) + @"(" + unboxedString +
                    @");
                                                ");
                for (int i = 0; i < parameters.Length; i++)
                {
                    sb.Append(string.Format("parameters[{0}] = {1}param{0};", i, method.Name));
                }
                sb.Append(
                    @"
                                                return true;
                                            ");
            }

            sb.Append(
                @"
                                            default:
                                                return false;
                                    }
                                }
                        ");

            #endregion

            sb.Append(@"
                            }");

            #endregion

            #region LanguageAttribute

            sb.Append(
                @"
                    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true) ]
                    public class LanguageAttribute : Attribute
                    {
                        public LanguageAttribute(string language)
                        {
                            this.language = language;
                        }

                        protected string language;
                        public String Language
                        {
                            get
                            {
                                return this.language;
                            }
                        }

                        public override string ToString()
                        {
                            return language;
                        }
                    }
            ");

            #endregion

            InsertApiExtensionClass(sb, Project.Instance.ApiExtensions);

            // These need to go outside TemplateGen, as extension methods must be in a non-generic, static classes
            #region Extension Methods

            sb.Append(@"
            public static class TemplateGenExtensionMethods
            {
            ");

            foreach (var fi in Project.Instance.Functions)
            {
                if (fi.IsExtensionMethod == false) continue;

                /* Create Method Signature */
                sb.AppendLine("[Language(\"" + fi.TemplateReturnLanguage + "\")]");
                sb.AppendFormat("\t\t\tpublic static {0} {1}(", fi.ReturnType == null ? "void" : fi.ReturnType.FullName, fi.Name);
                // Create parameter list
                sb.Append(FormatParameters(fi.Parameters)).AppendLine(")");
                sb.AppendLine("\t\t\t{");
                sb.AppendLine(FormatFunctionBody(fi));
                sb.AppendLine("\t\t\t}");
            }

            sb.Append(@"
            }
            ");

            #endregion

            InsertVirtualProperties(sb, Project.Instance.UserOptions);
            //InsertDefaultValueFunctions(sb);

            InsertTemplateGenClass(sb);

            // Finish the namespace off
            sb.AppendLine(
            @"
            }
            ");

            // Fill the Line Number lookup objects with the information they need,
            // and remove debugging information.
            FillFunctionHashes();
            return ProcessLineCrossReferences(sb);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Sorts the functions into alphabetical order
 /// </summary>
 public void SortFunctions()
 {
     // Sort the functions
     Comparers.FunctionComparer comparer = new Comparers.FunctionComparer();
     Functions.Sort(comparer);
 }