Beispiel #1
0
        public bool Compile()
        {
            // Check precondition: templateInfo must be known:
            if (this.templateInfo == null)
            {
                throw new InvalidOperationException("TemplateInfo property must be set before calling Compile method.");
            }

            // Template substitution fields:
            string        ns;
            string        classname;
            string        baseclassname;
            StringBuilder imports           = new StringBuilder();
            StringBuilder fields            = new StringBuilder();
            StringBuilder constructorparams = new StringBuilder();
            StringBuilder fieldinits        = new StringBuilder();
            StringBuilder generatebody      = new StringBuilder();
            StringBuilder scripts           = new StringBuilder();
            string        codeBehindFile    = null;

            // Retrieve codeTemplate directive:
            NameValueCollection ctdir = templateInfo.GetCodeTemplateDirective();
            // Retrieve class name information:
            ClassName cnb = new ClassName(ctdir["ClassName"] ?? StringUtils.ToIdentifier(templateInfo.TemplateFileInfo.Name));

            if (cnb.NameSpace == String.Empty)
            {
                cnb.NameSpace = GenerationLanguage.DefaultNameSpace;
            }

            // Retrieve base information:
            ns             = cnb.NameSpace;
            classname      = cnb.Name;
            baseclassname  = ctdir["Inherits"] ?? GenerationLanguage.DefaultBaseClass;
            codeBehindFile = templateInfo.FindFile(ctdir["CodeFile"]);

            foreach (NameValueCollection import in templateInfo.GetDirectives("Import"))
            {
                this.AppendImport(imports, import["Namespace"], import["Alias"]);
            }

            // Fill fields, fieldinits, constructorparams:
            foreach (NameValueCollection param in templateInfo.GetDirectives("Parameter"))
            {
                string n = param["Name"];
                string t = param["Type"] ?? "System.Object";

                fields.Append("\t\t");
                this.AppendField(fields, n, t);
                fieldinits.Append("\t\t\t");
                this.AppendFieldInitializer(fieldinits, n, t);
                this.AppendConstructorParam(constructorparams, n, t);
            }

            // Fill generatebody:
            bool writeLinePragma = Convert.ToBoolean(ctdir["LinePragmas"] ?? "True");

            foreach (ContentPart part in templateInfo.FileContent.Parts)
            {
                // Check for TemplateBody or Scriptlet:
                if (((TemplatePartTypes)part.Type != TemplatePartTypes.TemplateBody) && ((TemplatePartTypes)part.Type != TemplatePartTypes.Scriptlet))
                {
                    continue;
                }

                // Add line pragma begin:
                if (writeLinePragma)
                {
                    this.AppendLinePragmaBegin(generatebody, part.File.Filename, part.StartLine);
                }

                // Generate:
                if ((TemplatePartTypes)part.Type == TemplatePartTypes.TemplateBody)
                {
                    foreach (string line in LinesWithBreaks(part.Content))
                    {
                        string content = ToContent(this.LineToWriteCall(line));
                        //generatebody.Append("\t\t\t");
                        generatebody.Append(content);
                        generatebody.AppendLine();
                    }
                }
                else if ((TemplatePartTypes)part.Type == TemplatePartTypes.Scriptlet)
                {
                    foreach (string line in LinesWithBreaks(part.Content))
                    {
                        //generatebody.Append("\t\t\t");
                        generatebody.Append(line);
                    }
                    generatebody.AppendLine();
                }

                // Add line pragma end:
                if (writeLinePragma)
                {
                    this.AppendLinePragmaEnd(generatebody);
                }
            }

            // Fill scripts:
            foreach (ContentPart part in templateInfo.FileContent.FindPartsOfType(TemplatePartTypes.Script))
            {
                // Add line pragma begin:
                if (writeLinePragma)
                {
                    this.AppendLinePragmaBegin(scripts, part.File.Filename, part.StartLine);
                }

                // Append script:
                scripts.AppendLine(part.Content);
                scripts.AppendLine();

                // Add line pragma end:
                if (writeLinePragma)
                {
                    this.AppendLinePragmaEnd(scripts);
                }
            }

            // Build code:
            this.code = GetCodeTemplate();
            this.code = this.code.Replace("<%=templatefilename%>", templateInfo.TemplateFileInfo.FullName);
            this.code = this.code.Replace("<%=imports%>", imports.ToString());
            this.code = this.code.Replace("<%=namespace%>", ns);
            this.code = this.code.Replace("<%=classname%>", classname);
            this.code = this.code.Replace("<%=baseclassname%>", baseclassname);
            this.code = this.code.Replace("<%=fields%>", fields.ToString());
            this.code = this.code.Replace("<%=constructorparameters%>", constructorparams.ToString());
            this.code = this.code.Replace("<%=fieldinitialisations%>", fieldinits.ToString());
            this.code = this.code.Replace("<%=generatebody%>", generatebody.ToString());
            this.code = this.code.Replace("<%=scripts%>", scripts.ToString());

            // Save code file:
            string codeFile = templateInfo.TemplateFileInfo.FullName + ".gen";

            File.WriteAllText(codeFile, this.code);

            // Build assembly resolution path:
            List <string> referencepathlist = ((GenerationHost)templateInfo.Host).ReferencePath;

            referencepathlist.Add(templateInfo.TemplateFileInfo.Directory.FullName);
            referencepathlist.Add(templateInfo.TemplateFileInfo.Directory.FullName + "\\bin");
            string[] referencepath = referencepathlist.ToArray();

            // Collect references:
            List <string> references = new List <string>();

            references.Add(FileUtils.FindInPath(new FileInfo(typeof(Arebis.CodeGeneration.CodeTemplate).Assembly.Location).Name, referencepath));
            references.Add("System.dll");

            // Find references from settings:
            foreach (string path in templateInfo.Settings.GetValues("referenceassembly") ?? new string[0])
            {
                // Search for references:
                string fullpath = FileUtils.FindInPath(path, referencepath) ?? path;
                if (fullpath == null)
                {
                    continue;
                }

                // Add reference to references:
                if (references.Contains(fullpath) == false)
                {
                    references.Add(fullpath);
                }
            }

            // Find references from directives:
            foreach (NameValueCollection refer in templateInfo.GetDirectives("ReferenceAssembly"))
            {
                // Search for references:
                string path     = refer["Path"];
                string fullpath = FileUtils.FindInPath(path, referencepath) ?? path;
                if (fullpath == null)
                {
                    continue;
                }

                // Add reference to references:
                if (references.Contains(fullpath) == false)
                {
                    references.Add(fullpath);
                }
            }

            // Log references:
            foreach (string item in references)
            {
                templateInfo.Host.Log("Added reference \"{0}\".", item);
            }

            // Generate assembly filename:
            string assemblyFile =
                ctdir["AssemblyFile"] ??
                Path.Combine(Path.GetTempPath(), StringUtils.ToIdentifier(templateInfo.TemplateFileInfo.FullName) + ".dll");

            // Collect files to compile:
            List <string> codefiles = new List <string>();

            codefiles.Add(codeFile);
            if (codeBehindFile != null)
            {
                codefiles.Add(codeBehindFile);
            }
            foreach (NameValueCollection compileFileAttrs in templateInfo.GetDirectives("CompileFile"))
            {
                codefiles.Add(templateInfo.FindFile(compileFileAttrs["Path"]));
            }

            // Compile the template code:
            CodeDomProvider    provider = this.GetCodeDomProvider();
            CompilerParameters pars     = new CompilerParameters(references.ToArray(), assemblyFile, true);
            CompilerResults    results;

            pars.GenerateExecutable = false;
            pars.GenerateInMemory   = false;
            results = provider.CompileAssemblyFromFile(pars, codefiles.ToArray());

            // Delete the generated sourcefile:
            this.filesToDelete.Add(assemblyFile);
            this.filesToDelete.Add(assemblyFile.Replace(".dll", ".pdb"));
            if (Convert.ToBoolean(templateInfo.Settings["deletegeneratedsource"] ?? "True") == true)
            {
                this.filesToDelete.Add(codeFile);
            }

            // Check for compile errors & warnings:
            this.compilerErrors = new List <CompilerError>();
            foreach (CompilerError error in results.Errors)
            {
                compilerErrors.Add(error);
            }

            // Store compiled type & return success:
            if (results.Errors.HasErrors)
            {
                this.compiledType = null;
                return(false);
            }
            else
            {
                this.compiledType = results.CompiledAssembly.GetType(ns + "." + classname);
                return(true);
            }
        }
Beispiel #2
0
        public bool Compile()
        {
            // Check precondition: templateInfo must be known:
            if (this.templateInfo == null)
            {
                throw new InvalidOperationException("TemplateInfo property must be set before calling Compile method.");
            }

            // Retrieve codeTemplate directive:
            NameValueCollection ctdir = templateInfo.GetCodeTemplateDirective();

            // Save code file:
            string codeFile = templateInfo.TemplateFileInfo.FullName + ".gen";

            File.WriteAllText(codeFile, CreateCode());

            ClassName cnb            = GetClassName(ctdir);
            string    ns             = cnb.NameSpace;
            string    classname      = cnb.Name;
            string    codeBehindFile = templateInfo.FindFile(ctdir["CodeFile"]);

            // Build assembly resolution path:
            List <string> referencepathlist = ((GenerationHost)templateInfo.Host).ReferencePath;

            referencepathlist.Add(templateInfo.TemplateFileInfo.Directory.FullName);
            referencepathlist.Add(templateInfo.TemplateFileInfo.Directory.FullName + "\\bin");
            string[] referencepath = referencepathlist.ToArray();

            // Collect references:
            List <string> references = new List <string>();

            references.Add(FileUtils.FindInPath(new FileInfo(typeof(Arebis.CodeGeneration.CodeTemplate).Assembly.Location).Name, referencepath));
            references.Add("System.dll");

            // Find references from settings:
            foreach (string path in templateInfo.Settings.GetValues("referenceassembly") ?? new string[0])
            {
                // Search for references:
                string fullpath = FileUtils.FindInPath(path, referencepath) ?? path;
                if (fullpath == null)
                {
                    continue;
                }

                // Add reference to references:
                if (references.Contains(fullpath) == false)
                {
                    references.Add(fullpath);
                }
            }

            // Find references from directives:
            foreach (NameValueCollection refer in templateInfo.GetDirectives("ReferenceAssembly"))
            {
                // Search for references:
                string path     = refer["Path"];
                string fullpath = FileUtils.FindInPath(path, referencepath) ?? path;
                if (fullpath == null)
                {
                    continue;
                }

                // Add reference to references:
                if (references.Contains(fullpath) == false)
                {
                    references.Add(fullpath);
                }
            }

            // Log references:
            foreach (string item in references)
            {
                templateInfo.Host.Log("Added reference \"{0}\".", item);
            }

            // Generate assembly filename:
            string assemblyFile =
                ctdir["AssemblyFile"] ??
                Path.Combine(Path.GetTempPath(), StringUtils.ToIdentifier(templateInfo.TemplateFileInfo.FullName) + ".dll");

            // Collect files to compile:
            List <string> codefiles = new List <string>();

            codefiles.Add(codeFile);
            if (codeBehindFile != null)
            {
                codefiles.Add(codeBehindFile);
            }
            foreach (NameValueCollection compileFileAttrs in templateInfo.GetDirectives("CompileFile"))
            {
                codefiles.Add(templateInfo.FindFile(compileFileAttrs["Path"]));
            }

            // Compile the template code:
            CodeDomProvider    provider = this.GetCodeDomProvider();
            CompilerParameters pars     = new CompilerParameters(references.ToArray(), assemblyFile, true);
            CompilerResults    results;

            pars.GenerateExecutable = false;
            pars.GenerateInMemory   = false;
            results = provider.CompileAssemblyFromFile(pars, codefiles.ToArray());

            // Delete the generated sourcefile:
            this.filesToDelete.Add(assemblyFile);
            this.filesToDelete.Add(assemblyFile.Replace(".dll", ".pdb"));
            if (Convert.ToBoolean(templateInfo.Settings["deletegeneratedsource"] ?? "True") == true)
            {
                this.filesToDelete.Add(codeFile);
            }

            // Check for compile errors & warnings:
            this.compilerErrors = new List <CompilerError>();
            foreach (CompilerError error in results.Errors)
            {
                compilerErrors.Add(error);
            }

            // Store compiled type & return success:
            if (results.Errors.HasErrors)
            {
                this.compiledType = null;
                return(false);
            }
            else
            {
                this.compiledType = results.CompiledAssembly.GetType(ns + "." + classname);
                return(true);
            }
        }