Esempio n. 1
0
        private static int Process(Options options)
        {
            try
            {
                Console.WriteLine("Start Process!");

                // Resolve options

                var basePath = Path.GetFullPath(options.Path ?? ".");
                var sources =
                    options.Sources.Where(p => string.IsNullOrWhiteSpace(p) == false &&
                                               p.ToLower().IndexOf(".codegen.cs") == -1)
                           .Select(p => MakeFullPath(p, basePath))
                           .ToArray();
                var references =
                    options.References.Where(p => string.IsNullOrWhiteSpace(p) == false)
                           .Select(p => MakeFullPath(p, basePath))
                           .ToArray();
                var targetDefaultPath = @".\Properties\TrackableData.CodeGen.cs";
                var targetPath = MakeFullPath(options.TargetFile ?? targetDefaultPath, basePath);

                // Parse sources and extract interfaces

                Console.WriteLine("- Parse sources");

                var syntaxTrees = sources.Select(
                    file => CSharpSyntaxTree.ParseText(File.ReadAllText(file), path: file)).ToArray();
                var interfaceDeclarations = syntaxTrees.SelectMany(
                    st => st.GetRoot().DescendantNodes().OfType<InterfaceDeclarationSyntax>()).ToArray();

                // Generate code

                Console.WriteLine("- Generate code");

                var writer = new TextCodeGenWriter();
                var relatedSourceTrees = new HashSet<SyntaxNode>();

                // TrackablePoco

                var pocoCodeGen = new TrackablePocoCodeGenerator() { Options = options };
                foreach (var idecl in interfaceDeclarations)
                {
                    var baseType = idecl.GetGenericBase("TrackableData.ITrackablePoco");
                    if (baseType != null)
                    {
                        var pocoType = baseType.TypeArgumentList.Arguments[0].ToString();
                        if (CodeAnalaysisExtensions.CompareTypeName(idecl.Identifier.ToString(), pocoType) == false)
                        {
                            throw new Exception($"Invalid base type of ITrackablePoco<{pocoType}>");
                        }

                        pocoCodeGen.GenerateCode(idecl, writer);
                        relatedSourceTrees.Add(idecl.GetRootNode());
                    }
                }

                // TrackableContainer

                var containerCodeGen = new TrackableContainerCodeGenerator() { Options = options };
                foreach (var idecl in interfaceDeclarations)
                {
                    var baseType = idecl.GetGenericBase("TrackableData.ITrackableContainer");
                    if (baseType != null)
                    {
                        var containerType = baseType.TypeArgumentList.Arguments[0].ToString();
                        if (CodeAnalaysisExtensions.CompareTypeName(idecl.Identifier.ToString(), containerType) == false)
                        {
                            throw new Exception($"Invalid base type of ITrackableContainer<{containerType}>");
                        }

                        containerCodeGen.GenerateCode(idecl, writer);
                        relatedSourceTrees.Add(idecl.GetRootNode());
                    }
                }

                // Resolve referenced using

                var usingDirectives = new HashSet<string>(relatedSourceTrees.SelectMany(
                    st => st.DescendantNodes().OfType<UsingDirectiveSyntax>()).Select(x => x.Name.ToString()));
                usingDirectives.Add("System");
                usingDirectives.Add("System.Collections.Generic");
                usingDirectives.Add("System.Reflection");
                usingDirectives.Add("System.Runtime.Serialization");
                usingDirectives.Add("System.Linq");
                usingDirectives.Add("System.Text");
                usingDirectives.Add("TrackableData");
                foreach (var usingDirective in usingDirectives)
                    writer.AddUsing(usingDirective);

                // Save generated code

                Console.WriteLine("- Save code");

                if (SaveFileIfChanged(targetPath, writer.ToString()) == false)
                    Console.WriteLine("Nothing changed. Skip writing.");

                return 0;
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception in processing:\n" + e);
                return 1;
            }
        }
Esempio n. 2
0
        private static int Process(Options options)
        {
            try
            {
                Console.WriteLine("Start Process!");

                // Resolve options

                var basePath = Path.GetFullPath(options.Path ?? ".");
                var sources =
                    options.Sources.Where(p => string.IsNullOrWhiteSpace(p) == false &&
                                               p.ToLower().IndexOf(".codegen.cs") == -1)
                           .Select(p => MakeFullPath(p, basePath))
                           .ToArray();
                var references =
                    options.References.Where(p => string.IsNullOrWhiteSpace(p) == false)
                           .Select(p => MakeFullPath(p, basePath))
                           .ToArray();
                var targetDefaultPath = @".\Properties\TrackableData.CodeGen.cs";
                var targetPath = MakeFullPath(options.TargetFile ?? targetDefaultPath, basePath);

                // Parse sources and extract interfaces

                Console.WriteLine("- Parse sources");

                var syntaxTrees = sources.Select(
                    file => CSharpSyntaxTree.ParseText(File.ReadAllText(file), path: file)).ToArray();
                var interfaceDeclarations = syntaxTrees.SelectMany(
                    st => st.GetRoot().DescendantNodes().OfType<InterfaceDeclarationSyntax>()).ToArray();

                // Generate code

                Console.WriteLine("- Generate code");

                var settings = new CodeWriterSettings(CodeWriterSettings.CSharpDefault);
                settings.TranslationMapping["`"] = "\"";

                var w = new CodeWriter.CodeWriter(settings);
                var relatedSourceTrees = new HashSet<SyntaxNode>();

                w.HeadLines = new List<string>
                {
                    "// ------------------------------------------------------------------------------",
                    "// <auto-generated>",
                    "//     This code was generated by TrackableData.CodeGenerator.",
                    "//",
                    "//     Changes to this file may cause incorrect behavior and will be lost if",
                    "//     the code is regenerated.",
                    "// </auto-generated>",
                    "// ------------------------------------------------------------------------------",
                    "",
                    "using System;",
                    "using System.Collections.Generic;",
                    "using System.Reflection;",
                    "using System.Runtime.Serialization;",
                    "using System.Linq;",
                    "using System.Text;",
                    "using TrackableData;",
                    ""
                };

                // TrackablePoco

                var pocoCodeGen = new TrackablePocoCodeGenerator() { Options = options };
                foreach (var idecl in interfaceDeclarations)
                {
                    var baseType = idecl.GetGenericBase("TrackableData.ITrackablePoco");
                    if (baseType != null)
                    {
                        var pocoType = baseType.TypeArgumentList.Arguments[0].ToString();
                        if (CodeAnalaysisExtensions.CompareTypeName(idecl.Identifier.ToString(), pocoType) == false)
                        {
                            throw new Exception($"Invalid base type of ITrackablePoco<{pocoType}>");
                        }

                        pocoCodeGen.GenerateCode(idecl, w);
                        relatedSourceTrees.Add(idecl.GetRootNode());
                    }
                }

                // TrackableContainer

                var containerCodeGen = new TrackableContainerCodeGenerator() { Options = options };
                foreach (var idecl in interfaceDeclarations)
                {
                    var baseType = idecl.GetGenericBase("TrackableData.ITrackableContainer");
                    if (baseType != null)
                    {
                        var containerType = baseType.TypeArgumentList.Arguments[0].ToString();
                        if (CodeAnalaysisExtensions.CompareTypeName(idecl.Identifier.ToString(), containerType) == false)
                        {
                            throw new Exception($"Invalid base type of ITrackableContainer<{containerType}>");
                        }

                        containerCodeGen.GenerateCode(idecl, w);
                        relatedSourceTrees.Add(idecl.GetRootNode());
                    }
                }

                // Resolve referenced using

                var usingDirectives = new HashSet<string>(relatedSourceTrees.SelectMany(
                    st => st.DescendantNodes().OfType<UsingDirectiveSyntax>()).Select(x => x.Name.ToString()));
                foreach (var usingDirective in usingDirectives)
                    EnsureUsing(w, usingDirective);

                // Save generated code

                Console.WriteLine("- Save code");

                if (w.WriteAllText(targetPath, true) == false)
                    Console.WriteLine("Nothing changed. Skip writing.");

                return 0;
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception in processing:\n" + e);
                return 1;
            }
        }