コード例 #1
0
        //public const string TemplateFileExtension = ".ate";

        //ToDo Move this to a config file in a project folder
        //public static List<string> AutoTemplateExtensions = new List<string> { "*.cs", "*.sln", "*.csproj", "*.html", "*.js", "*.ts", "*.json", "*.cshtml", "*.wsd", "*.puml", "*.project", "*.java" , "*.sql" , "*.yaml", "*.xml", "*.yml", "*.md", "*.txt", "*.name"};

        internal static void Compile(CompileContext CompileContext, FileInfo FileInfo)
        {
            var FileName = FileInfo.Name;


            if (FileName.StartsWithTags(Template.Tags, "inject ", out var Tag))
            {
                var InjectionName = FileName.Substring(Tag.Key.Length + 7);
                InjectionName = InjectionName.Substring(0, InjectionName.IndexOf(Tag.Value));
                var CodeSegment = CompileContext.Template.FindOrCreateCodeSegment(InjectionName);
                CodeSegment.Code = FileInfo.ReadAllText();
            }
            else if (FileName.ContainsTags(Template.Tags, "ignore"))
            {
                //Do nothing
            }
            else
            {
                var PreviousTopSegment = CompileContext.Stack.Peek();
                Text.Compile(CompileContext, FileName);

                var FileSegment = new FileSegment();
                FileSegment.SourceFile = FileInfo;
                var TopSegment = CompileContext.Stack.Peek();

                TopSegment.Segments.Add(FileSegment);
                FileSegment.Class = TopSegment.Class;

                if (FileName.ContainsTags(Template.Tags, "no overwrite"))
                {
                    FileSegment.OverWrite = false;
                }
                else
                {
                    FileSegment.OverWrite = true;
                }

                if (FileInfo.Name.FitsMasks(CompileContext.Template.CompileMasks.ToList()))
                {
                    CompileContext.Stack.Push(FileSegment);
                    Text.Compile(CompileContext, System.IO.File.ReadAllText(FileInfo.FullName));
                }

                while (CompileContext.Stack.Peek() != PreviousTopSegment)
                {
                    CompileContext.Stack.Pop();
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Adds text and enum segments to Context
        /// </summary>
        /// <param name="CompileContext"></param>
        /// <param name="SourceText"></param>
        internal static void Compile(CompileContext CompileContext, string SourceText)
        {
            var bits = SourceText.Split(Template.Tags.Values.ToArray(), StringSplitOptions.None);

            foreach (var bit in bits)
            {
                string StaticText;
                string Code;
                //string Name;
                var TopSegment = CompileContext.Stack.Peek();

                int Opening = bit.IndexOfTags(Template.Tags, out var Tag);
                if (Opening > -1)
                {
                    StaticText = bit.Substring(0, Opening);
                    Code       = bit.Substring(Opening + Tag.Key.Length);
                    Code       = Code.Trim();
                    if (Code.IndexOf(Tag.Key) >= 0)
                    {
                        throw new Exception("template syntax error in " + SourceText + " at position " + SourceText.IndexOf(bit) + ": " + bit);
                    }
                    //Name = "M" + Guid.NewGuid().ToString().Replace("-", "");
                }
                else
                {
                    StaticText = bit;
                    Code       = "";
                    //Name = "";
                }

                StaticText = StaticText.Replace("App_FullCodeName", "App.FullCodeName");

                Code = Code.Replace("ʢ", "(");
                Code = Code.Replace("ʡ", ")");
                Code = Code.Replace("ℴ", ".");


                if (Code.Length > 9 && Code.Substring(0, 9) == "for each ")
                {
                    var ListSegment = new ListSegment();
                    //ListSegment.MethodName = Name;
                    ListSegment.StaticText = StaticText;

                    Code = Code.Substring(9);
                    var Alias       = "";
                    var SubTypeName = "";
                    var AsIndex     = Code.IndexOf(" as ");
                    if (AsIndex >= 0)
                    {
                        SubTypeName = Code.Substring(0, AsIndex);
                        Alias       = Code.Substring(AsIndex + 4, Code.IndexOf(" in ", AsIndex) - AsIndex - 4);
                    }
                    else
                    {
                        SubTypeName = Code.Substring(0, Code.IndexOf(" in "));
                        Alias       = SubTypeName;
                    }
                    Code = Code.Substring(Code.IndexOf(" in ") + 4);

                    // Code = Code.Substring(9);
                    // var SubTypeName = Code.Substring(0, Code.IndexOf(" in "));
                    // Code = Code.Substring(Code.IndexOf("in") + 3);
                    ListSegment.ParentClass = TopSegment.Class;
                    var Type = ListSegment.ParentClass.BaseType.Assembly.ExportedTypes.Where(
                        (FindType) => FindType.Name == SubTypeName
                        ).FirstOrDefault();
                    if (Type == null)
                    {
                        throw new System.Exception("Type not found for " + SubTypeName);
                    }
                    ListSegment.Class = CompileContext.Template.FindOrCreateClass(Type);

                    //ListSegment.ParentClass.MethodSegments.Add(ListSegment);
                    ListSegment.Method     = ListSegment.ParentClass.FindOrCreateMethod(Code, TopSegment.ClassAlias, typeof(System.Collections.IEnumerable), ListSegment.Source);
                    ListSegment.ClassAlias = Alias;
                    TopSegment.Segments.Add(ListSegment);
                    CompileContext.Stack.Push(ListSegment);
                }
                else if (Code.Length >= 3 && Code.Substring(0, 3) == "if ")
                {
                    var IfSegment = new IfSegment();

                    IfSegment.StaticText = StaticText;
                    Code             = Code.Substring(3);
                    IfSegment.Class  = TopSegment.Class;
                    IfSegment.Method = IfSegment.Class.FindOrCreateMethod(Code, TopSegment.ClassAlias, typeof(bool), IfSegment.Source);

                    TopSegment.Segments.Add(IfSegment);
                    CompileContext.Stack.Push(IfSegment);
                }
                else if (Code.Length >= 8 && Code.Substring(0, 8) == "else if ")
                {
                    var TextSegment = new TextSegment(TopSegment);
                    TextSegment.StaticText = StaticText;
                    TopSegment.Segments.Add(TextSegment);

                    var ElseIfSegment = new IfSegment();

                    ElseIfSegment.StaticText = "";
                    Code = Code.Substring(8);
                    ElseIfSegment.Class  = TopSegment.Class;
                    ElseIfSegment.Method = ElseIfSegment.Class.FindOrCreateMethod(Code, TopSegment.ClassAlias, typeof(bool), ElseIfSegment.Source);

                    //TopSegment.Segments.Add(ElseIfSegment);
                    ((IfSegment)TopSegment).ElseSegment = ElseIfSegment;
                    CompileContext.Stack.Push(ElseIfSegment);
                }
                else if (Code == "else")
                {
                    var TextSegment = new TextSegment(TopSegment);
                    TextSegment.StaticText = StaticText;
                    TopSegment.Segments.Add(TextSegment);


                    var ElseSegment = new TextSegment(TopSegment);

                    ElseSegment.StaticText = "";

                    ElseSegment.Class = TopSegment.Class;

                    //TopSegment.Segments.Add(ElseSegment);
                    ((IfSegment)TopSegment).ElseSegment = ElseSegment;
                    CompileContext.Stack.Push(ElseSegment);
                }
                else if (Code.Length >= 9 && Code.Substring(0, 9) == "overwrite")
                {
                    Code = "";
                }
                else if (Code.Length >= 6 && Code.Substring(0, 6) == "ignore")
                {
                    Code = "";
                }
                else if (Code.Length > 7 && Code.Substring(0, 7) == "inject ")
                {
                    var InjectionName = Code.Substring(7);
                    var NamePosition  = InjectionName.IndexOf(" ");
                    var InjectionCode = InjectionName.Substring(NamePosition);
                    InjectionName = InjectionName.Substring(0, NamePosition);
                    var CodeSegment = CompileContext.Template.FindOrCreateCodeSegment(InjectionName);
                    CodeSegment.Code = InjectionCode;
                }
                else
                {
                    if (Code.Length >= 4 && Code.Substring(0, 4) == "next")
                    {
                        CompileContext.Stack.Pop();
                        //TopSegment = CompileContext.Stack.Peek();
                        //ToDo Check that next type matches current for each
                        // if (!ListSegment.GetType().IsAssignableFrom(typeof(ListSegment)))
                        // {
                        //     throw new Exception("for each  doesn't match with code grouping");
                        // }
                        Code = "";
                    }
                    else if (Code.Length >= 6 && Code.Substring(0, 6) == "end if")
                    {
                        var IfSegment = CompileContext.Stack.Pop();

                        var TopPeek = CompileContext.Stack.Peek();

                        while (TopPeek.GetType() == typeof(IfSegment) && ((IfSegment)TopPeek).ElseSegment == IfSegment)
                        {
                            IfSegment = CompileContext.Stack.Pop();
                            TopPeek   = CompileContext.Stack.Peek();
                        }
                        //TopSegment = CompileContext.Stack.Peek();
                        // if (!IfSegment.GetType().IsAssignableFrom(typeof(IfSegment)))
                        // {
                        //     throw new Exception("end if doesn't match with code grouping");
                        // }

                        Code = "";
                    }

                    var TextSegment = new TextSegment(TopSegment);

                    TextSegment.StaticText = StaticText;

                    TopSegment.Segments.Add(TextSegment);
                    TextSegment.Class = TopSegment.Class;
                    if (Code != "")
                    {
                        TextSegment.Method = TextSegment.Class.FindOrCreateMethod(Code, TopSegment.ClassAlias, typeof(string), TextSegment.Source);
                    }
                }
            }
        }
コード例 #3
0
        //Processes Folder name and then sub folders and then sub files
        internal static FolderSegment Compile(CompileContext CompileContext, DirectoryInfo DirectoryInfo)
        {
            var PreviousTopSegment = CompileContext.Stack.Peek();

            Text.Compile(CompileContext, DirectoryInfo.Name);

            var FolderSegment = new FolderSegment();

            FolderSegment.SourceDirectory = DirectoryInfo;

            var TopSegment = CompileContext.Stack.Peek();

            TopSegment.Segments.Add(FolderSegment);
            FolderSegment.Class = TopSegment.Class;


            FolderSegment.OverWrite = false;

            // if (DirectoryInfo.Name.ContainsTags(Template.Tags, "overwrite false"))
            // {
            //     FolderSegment.OverWrite = false;
            // }
            // else
            // {
            //     FolderSegment.OverWrite = true;
            // }

            CompileContext.Stack.Push(FolderSegment);



            //var DirectoryInfo = new DirectoryInfo(Source);
            foreach (var ChildDirectory in DirectoryInfo.GetDirectories())
            {
                bool   ignoreDirectory = false;
                string fullname        = ChildDirectory.FullName.Replace("\\", "/");
                foreach (var ignoreMask in CompileContext.Template.IgnoreMasks)
                {
                    if ((fullname + "/").FitsMask(ignoreMask))
                    {
                        ignoreDirectory = true;
                        break;
                    }
                }
                if (!ignoreDirectory)
                {
                    Compile(CompileContext, ChildDirectory);
                }
            }

            foreach (var ChildFile in DirectoryInfo.GetFiles())
            {
                bool   ignoreFile = false;
                string fullname   = ChildFile.FullName.Replace("\\", "/");
                foreach (var ignoreMask in CompileContext.Template.IgnoreMasks)
                {
                    if (fullname.FitsMask(ignoreMask))
                    {
                        ignoreFile = true;
                        break;
                    }
                }
                if (!ignoreFile)
                {
                    File.Compile(CompileContext, ChildFile);
                }
            }

            while (CompileContext.Stack.Peek() != PreviousTopSegment)
            {
                CompileContext.Stack.Pop();
            }

            return(FolderSegment);
        }
コード例 #4
0
        private void Compile(string Source)
        {
            var CompileContext = new CompileContext();

            CompileContext.Template = this;

            BaseSegment       = new Segment();
            BaseSegment.Class = FindOrCreateClass(Type);

            CompileContext.Stack.Push(BaseSegment);

            //Create a new in memory assembly with classes that inherit from Core Object Model Classes with added functions that contain code from templates
            //if source is a file then compile it straight
            //if, however, it is a folder then compile the folder and file names
            if (Directory.Exists(Source))
            {
                var DirectoryInfo = new DirectoryInfo(Source);
                ReadIgnoreFile(DirectoryInfo);
                ReadCompileFile(DirectoryInfo);
                var FolderSegment = Folder.Compile(CompileContext, DirectoryInfo);
                FolderSegment.IsTopLevel = true;
                FolderSegment.OverWrite  = false;
            }
            else if (System.IO.File.Exists(Source))
            {
                File.Compile(CompileContext, new FileInfo(Source));
            }
            else
            {
                Text.Compile(CompileContext, Source);
            }

            string TemplateCode = "using System;\nusing System.Linq;\nusing System.Collections;\nusing ate.Extensions;\nusing ate.Projects;\nusing ate.Definitions;\n\n namespace N" + Guid.NewGuid().ToString().CodeName() + " { ";

            List <SyntaxTree> SyntaxTrees = new List <SyntaxTree>();

            foreach (var CodeSegment in CodeSegments.Values)
            {
                SyntaxTrees.Add(CSharpSyntaxTree.ParseText(CodeSegment.Code));
            }

            foreach (var Class in Classes.Values)
            {
                TemplateCode += Class.CompiledCode();
            }

            TemplateCode += "\n}";

            var assemblyName = ".atecode";

            System.IO.File.WriteAllText(Path.Combine(Source, assemblyName + ".cs"), TemplateCode);

            SyntaxTrees.Add(CSharpSyntaxTree.ParseText(TemplateCode));

            List <MetadataReference> References = new List <MetadataReference>();

            References.Add(MetadataReference.CreateFromFile(typeof(Object).Assembly.Location));
            References.Add(MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location));
            References.Add(MetadataReference.CreateFromFile(typeof(IEnumerable).Assembly.Location));

            var EntryAssembly = Assembly.GetEntryAssembly();

            foreach (var AssemblyName in EntryAssembly.GetReferencedAssemblies())
            {
                var ReferencedAssembly = Assembly.Load(AssemblyName.FullName);

                References.Add(MetadataReference.CreateFromFile(ReferencedAssembly.Location));
            }

            var ExecutingAssembly = Assembly.GetExecutingAssembly();

            foreach (var AssemblyName in ExecutingAssembly.GetReferencedAssemblies())
            {
                var ReferencedAssembly = Assembly.Load(AssemblyName.FullName);

                References.Add(MetadataReference.CreateFromFile(ReferencedAssembly.Location));
            }

            foreach (var AssemblyName in Type.Assembly.GetReferencedAssemblies())
            {
                var ReferencedAssembly = Assembly.Load(AssemblyName.FullName);

                References.Add(MetadataReference.CreateFromFile(ReferencedAssembly.Location));
            }

            References.Add(MetadataReference.CreateFromFile(Type.Assembly.Location));


            CSharpCompilation compilation = CSharpCompilation.Create(
                assemblyName,
                syntaxTrees: SyntaxTrees,
                references: References,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));


            using (var ms = new MemoryStream())
            {
                EmitResult result = compilation.Emit(ms);

                if (!result.Success)
                {
                    IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
                                                                                 diagnostic.IsWarningAsError ||
                                                                                 diagnostic.Severity == DiagnosticSeverity.Error);

                    foreach (Diagnostic diagnostic in failures)
                    {
                        try
                        {
                            Console.WriteLine("{0}: {1} at {2}\n{3}", diagnostic.Id, diagnostic.GetMessage(), diagnostic.Location.SourceSpan.Start, diagnostic.Location.SourceTree.ToString().Substring(diagnostic.Location.SourceSpan.Start, diagnostic.Location.SourceTree.ToString().IndexOf(Environment.NewLine, diagnostic.Location.SourceSpan.Start) - diagnostic.Location.SourceSpan.Start));
                        }
                        catch (Exception)
                        {
                            Console.WriteLine("{0}: {1} at {2}\n{3}", diagnostic.Id, diagnostic.GetMessage(), diagnostic.Location.SourceSpan.Start, diagnostic.Location.SourceTree.ToString());
                        }
                    }
                    throw new Exception("Compile error");
                }
                else
                {
                    ms.Seek(0, SeekOrigin.Begin);
                    //Assembly = System.Reflection.Assembly.Load(ms.ToArray());
                    Assembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromStream(ms);
                }
            }


            foreach (var Class in Classes.Values)
            {
                Class.CompiledType = Assembly.GetExportedTypes().Where(
                    (FindType) => FindType.Name == Class.BaseType.Name
                    ).FirstOrDefault();
            }

            Console.WriteLine("Successfully compiled");
        }