Ejemplo n.º 1
0
        public static void Generate(IEnumerable <Assembly> asms, StringBuilder output)
        {
            if (!_resolverRegistered)
            {
                throw new InvalidOperationException("please call RegisterAssemblyResolver() first so you can get better error messages when a DLL can't be loaded!");
            }

            var(ceras, targets) = CreateSerializerAndTargets(asms);
            SourceFormatterGenerator.GenerateAll(targets, ceras, output);
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                var error = "Not enough arguments. The last argument is always the .cs file output path, all arguments before that are the input assemblies (.dll files) of your unity project. Example: \"C:\\MyUnityProject\\Temp\\bin\\Debug\\Assembly-CSharp.dll C:\\MyUnityProject\\Assets\\Scripts\\GeneratedFormatters.cs\"";

                Console.WriteLine(error);
                throw new ArgumentException(error);
            }

            inputAssemblies  = args.Reverse().Skip(1).Reverse().ToArray();
            outputCsFileName = args.Reverse().First();


            AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;

            var asms = inputAssemblies.Select(Assembly.LoadFrom);

            var(ceras, targets) = CreateSerializerAndTargets(asms);



            StringBuilder fullCode = new StringBuilder(25 * 1000);

            fullCode.AppendLine("using Ceras;");
            fullCode.AppendLine("using Ceras.Formatters;");
            fullCode.AppendLine("namespace Ceras.GeneratedFormatters");
            fullCode.AppendLine("{");

            var setCustomFormatters = targets.Select(t => $"config.ConfigType<{t.FullName}>().CustomFormatter = new {t.Name}Formatter();");

            fullCode.AppendLine($@"
static class GeneratedFormatters
{{
	internal static void UseFormatters(SerializerConfig config)
	{{
		{string.Join("\n", setCustomFormatters)}
	}}
}}
");

            foreach (var t in targets)
            {
                SourceFormatterGenerator.Generate(t, ceras, fullCode);
            }
            fullCode.AppendLine("}");

            Console.WriteLine($"Parsing...");

            var syntaxTree = CSharpSyntaxTree.ParseText(fullCode.ToString());

            Console.WriteLine($"Formatting...");

            var workspace = new AdhocWorkspace();
            var options   = workspace.Options
                            .WithChangedOption(CSharpFormattingOptions.IndentBlock, true)
                            .WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInAccessors, true)
                            .WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInControlBlocks, true)
                            .WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInTypes, true)
                            .WithChangedOption(CSharpFormattingOptions.IndentBraces, false);

            syntaxTree = Formatter.Format(syntaxTree.GetRoot(), workspace, options).SyntaxTree;

            Console.WriteLine($"Saving...");

            using (var fs = File.OpenWrite(outputCsFileName))
                using (var w = new StreamWriter(fs))
                {
                    fs.SetLength(0);
                    w.WriteLine(syntaxTree.ToString());
                }



            // todo: maybe we'll generate an assembly instead of source code at some pointlater...
            //GenerateFormattersAssembly(targets);

            Thread.Sleep(300);
            Console.WriteLine($"> Done!");
        }
Ejemplo n.º 3
0
        static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                var error = "Not enough arguments. The last argument is always the .cs file output path, all arguments before that are the input assemblies (.dll files) of your unity project. Example: \"C:\\MyUnityProject\\Temp\\bin\\Debug\\Assembly-CSharp.dll C:\\MyUnityProject\\Assets\\Scripts\\GeneratedFormatters.cs\"";

                Console.WriteLine(error);
                throw new ArgumentException(error);
            }

            inputAssemblies  = args.Reverse().Skip(1).Reverse().ToArray();
            outputCsFileName = args.Reverse().First();

            var marker = typeof(CerasAutoGenFormatterAttribute);

            AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly;
            var asms = inputAssemblies.Select(Assembly.LoadFrom);

            var targets = asms.SelectMany(a => a.GetTypes())
                          .Where(t => t.GetCustomAttributes(true)
                                 .Any(a => a.GetType().FullName == marker.FullName))
                          .Where(t => !t.IsAbstract)
                          .ToList();

            Console.WriteLine($"Found: {targets.Count} targets");

            // Find config method and create a SerializerConfig
            SerializerConfig config = new SerializerConfig();
            var configMethods       = asms.SelectMany(a => a.GetTypes())
                                      .SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
                                      .Where(m => m.GetCustomAttribute <CerasAutoGenConfigAttribute>() != null)
                                      .ToArray();

            if (configMethods.Length > 1)
            {
                throw new Exception("Found more than one config method!");
            }
            if (configMethods.Length == 1)
            {
                config = (SerializerConfig)configMethods[0].Invoke(null, null);
            }

            targets.AddRange(config.KnownTypes);

            var ceras = new CerasSerializer(config);

            StringBuilder fullCode = new StringBuilder(25 * 1000);

            fullCode.AppendLine("using Ceras;");
            fullCode.AppendLine("using Ceras.Formatters;");
            fullCode.AppendLine("namespace Ceras.GeneratedFormatters");
            fullCode.AppendLine("{");

            var setCustomFormatters = targets.Select(t => $"config.ConfigType<{t.FullName}>().CustomFormatter = new {t.Name}Formatter();");

            fullCode.AppendLine($@"
static class GeneratedFormatters
{{
	internal static void UseFormatters(SerializerConfig config)
	{{
		{string.Join("\n", setCustomFormatters)}
	}}
}}
");

            foreach (var t in targets)
            {
                SourceFormatterGenerator.Generate(t, ceras, fullCode);
            }
            fullCode.AppendLine("}");

            Console.WriteLine($"Parsing...");

            var syntaxTree = CSharpSyntaxTree.ParseText(fullCode.ToString());

            Console.WriteLine($"Formatting...");

            var workspace = new AdhocWorkspace();
            var options   = workspace.Options
                            .WithChangedOption(CSharpFormattingOptions.IndentBlock, true)
                            .WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInAccessors, true)
                            .WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInControlBlocks, true)
                            .WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInTypes, true)
                            .WithChangedOption(CSharpFormattingOptions.IndentBraces, false);

            syntaxTree = Formatter.Format(syntaxTree.GetRoot(), workspace, options).SyntaxTree;

            Console.WriteLine($"Saving...");

            using (var fs = File.OpenWrite(outputCsFileName))
                using (var w = new StreamWriter(fs))
                {
                    fs.SetLength(0);
                    w.WriteLine(syntaxTree.ToString());
                }



            // todo: maybe we'll generate an assembly instead of source code at some pointlater...
            //GenerateFormattersAssembly(targets);

            Thread.Sleep(300);
            Console.WriteLine($"> Done!");
        }
Ejemplo n.º 4
0
 public static void Generate(IEnumerable <Assembly> asms, StringBuilder output)
 {
     var(ceras, targets) = CreateSerializerAndTargets(asms);
     SourceFormatterGenerator.GenerateAll(targets, ceras, output);
 }