public async Task GenerateFileAsync( string input, string output, string conditionalSymbol, string resolverName, string @namespace, bool useMapMode, string multipleIfDirectiveOutputSymbols) { var namespaceDot = string.IsNullOrWhiteSpace(@namespace) ? string.Empty : @namespace + "."; var conditionalSymbols = conditionalSymbol?.Split(',') ?? Array.Empty <string>(); var multipleOutputSymbols = multipleIfDirectiveOutputSymbols?.Split(',') ?? Array.Empty <string>(); var sw = Stopwatch.StartNew(); foreach (var multioutSymbol in multipleOutputSymbols.Length == 0 ? new[] { string.Empty } : multipleOutputSymbols) { logger("Project Compilation Start:" + input); var compilation = (Path.GetExtension(input) == ".csproj") ? await MessagePackCompilation.CreateFromProjectAsync(input.Split(','), conditionalSymbols.Concat(new[] { multioutSymbol }).ToArray(), cancellationToken) .ConfigureAwait(false) : await MessagePackCompilation.CreateFromDirectoryAsync(input, conditionalSymbols.Concat(new[] { multioutSymbol }).ToArray(), cancellationToken).ConfigureAwait(false); var collector = new TypeCollector(compilation, true, useMapMode, x => Console.WriteLine(x)); logger("Project Compilation Complete:" + sw.Elapsed.ToString()); sw.Restart(); logger("Method Collect Start"); var(objectInfo, enumInfo, genericInfo, unionInfo) = collector.Collect(); logger("Method Collect Complete:" + sw.Elapsed.ToString()); logger("Output Generation Start"); sw.Restart(); if (Path.GetExtension(output) == ".cs") { // SingleFile Output var objectFormatterTemplates = objectInfo .GroupBy(x => x.Namespace) .Select(x => new FormatterTemplate() { Namespace = namespaceDot + "Formatters" + ((x.Key == null) ? string.Empty : "." + x.Key), ObjectSerializationInfos = x.ToArray(), }) .ToArray(); var enumFormatterTemplates = enumInfo .GroupBy(x => x.Namespace) .Select(x => new EnumTemplate() { Namespace = namespaceDot + "Formatters" + ((x.Key == null) ? string.Empty : "." + x.Key), EnumSerializationInfos = x.ToArray(), }) .ToArray(); var unionFormatterTemplates = unionInfo .GroupBy(x => x.Namespace) .Select(x => new UnionTemplate() { Namespace = namespaceDot + "Formatters" + ((x.Key == null) ? string.Empty : "." + x.Key), UnionSerializationInfos = x.ToArray(), }) .ToArray(); var resolverTemplate = new ResolverTemplate() { Namespace = namespaceDot + "Resolvers", FormatterNamespace = namespaceDot + "Formatters", ResolverName = resolverName, RegisterInfos = genericInfo.Cast <IResolverRegisterInfo>().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo).ToArray(), }; var sb = new StringBuilder(); sb.AppendLine(resolverTemplate.TransformText()); sb.AppendLine(); foreach (var item in enumFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } sb.AppendLine(); foreach (var item in unionFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } sb.AppendLine(); foreach (var item in objectFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } if (multioutSymbol == string.Empty) { await OutputAsync(output, sb.ToString(), cancellationToken).ConfigureAwait(false); } else { var fname = Path.GetFileNameWithoutExtension(output) + "." + MultiSymbolToSafeFilePath(multioutSymbol) + ".cs"; var text = $"#if {multioutSymbol}" + Environment.NewLine + sb.ToString() + Environment.NewLine + "#endif"; await OutputAsync(Path.Combine(Path.GetDirectoryName(output), fname), text, cancellationToken).ConfigureAwait(false); } } else { // Multiple File output foreach (var x in objectInfo) { var template = new FormatterTemplate() { Namespace = namespaceDot + "Formatters" + ((x.Namespace == null) ? string.Empty : "." + x.Namespace), ObjectSerializationInfos = new[] { x }, }; var text = template.TransformText(); await OutputToDirAsync(output, template.Namespace, x.Name + "Formatter", multioutSymbol, text, cancellationToken).ConfigureAwait(false); } foreach (var x in enumInfo) { var template = new EnumTemplate() { Namespace = namespaceDot + "Formatters" + ((x.Namespace == null) ? string.Empty : "." + x.Namespace), EnumSerializationInfos = new[] { x }, }; var text = template.TransformText(); await OutputToDirAsync(output, template.Namespace, x.Name + "Formatter", multioutSymbol, text, cancellationToken).ConfigureAwait(false); } foreach (var x in unionInfo) { var template = new UnionTemplate() { Namespace = namespaceDot + "Formatters" + ((x.Namespace == null) ? string.Empty : "." + x.Namespace), UnionSerializationInfos = new[] { x }, }; var text = template.TransformText(); await OutputToDirAsync(output, template.Namespace, x.Name + "Formatter", multioutSymbol, text, cancellationToken).ConfigureAwait(false); } var resolverTemplate = new ResolverTemplate() { Namespace = namespaceDot + "Resolvers", FormatterNamespace = namespaceDot + "Formatters", ResolverName = resolverName, RegisterInfos = genericInfo.Cast <IResolverRegisterInfo>().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo).ToArray(), }; await OutputToDirAsync(output, resolverTemplate.Namespace, resolverTemplate.ResolverName, multioutSymbol, resolverTemplate.TransformText(), cancellationToken).ConfigureAwait(false); } } logger("Output Generation Complete:" + sw.Elapsed.ToString()); }
public async Task GenerateFileAsync( string input, string output, bool unuseUnityAttr, string @namespace, string conditionalSymbol) { // Prepare args var namespaceDot = string.IsNullOrWhiteSpace(@namespace) ? string.Empty : @namespace + "."; var conditionalSymbols = conditionalSymbol?.Split(',') ?? Array.Empty <string>(); // Generator Start... var sw = Stopwatch.StartNew(); logger("Project Compilation Start:" + input); var collector = new MethodCollector(input, conditionalSymbols, logger); logger("Project Compilation Complete:" + sw.Elapsed.ToString()); sw.Restart(); logger("Method Collect Start"); var definitions = collector.CollectServiceInterface(); var hubDefinitions = collector.CollectHubInterface(); GenericSerializationInfo[] genericInfos; EnumSerializationInfo[] enumInfos; ExtractResolverInfo(definitions, out genericInfos, out enumInfos); ExtractResolverInfo(hubDefinitions.Select(x => x.hubDefinition).ToArray(), out var genericInfos2, out var enumInfos2); ExtractResolverInfo(hubDefinitions.Select(x => x.receiverDefintion).ToArray(), out var genericInfos3, out var enumInfos3); enumInfos = enumInfos.Concat(enumInfos2).Concat(enumInfos3).Distinct().OrderBy(x => x.FullName).ToArray(); genericInfos = genericInfos.Concat(genericInfos2).Concat(genericInfos3).Distinct().OrderBy(x => x.FullName).ToArray(); logger("Method Collect Complete:" + sw.Elapsed.ToString()); logger("Output Generation Start"); sw.Restart(); var resolverTemplate = new ResolverTemplate() { Namespace = namespaceDot + "Resolvers", FormatterNamespace = namespaceDot + "Formatters", ResolverName = "MagicOnionResolver", registerInfos = genericInfos.OrderBy(x => x.FullName).Cast <IResolverRegisterInfo>().Concat(enumInfos.OrderBy(x => x.FullName)).ToArray() }; var registerTemplate = new RegisterTemplate { Namespace = @namespace, Interfaces = definitions.Where(x => x.IsServiceDefinition).ToArray(), HubInterfaces = hubDefinitions, UnuseUnityAttribute = unuseUnityAttr }; if (Path.GetExtension(output) == ".cs") { var enumTemplates = enumInfos.GroupBy(x => x.Namespace) .OrderBy(x => x.Key) .Select(x => new EnumTemplate() { Namespace = namespaceDot + "Formatters", enumSerializationInfos = x.ToArray() }) .ToArray(); var texts = definitions .GroupBy(x => x.Namespace) .OrderBy(x => x.Key) .Select(x => new CodeTemplate() { Namespace = x.Key, Interfaces = x.ToArray() }) .ToArray(); var hubTexts = hubDefinitions .GroupBy(x => x.hubDefinition.Namespace) .OrderBy(x => x.Key) .Select(x => new HubTemplate() { Namespace = x.Key, Interfaces = x.ToArray() }) .ToArray(); var sb = new StringBuilder(); sb.AppendLine("// <auto-generated />"); sb.AppendLine(registerTemplate.TransformText()); sb.AppendLine(resolverTemplate.TransformText()); foreach (var item in enumTemplates) { sb.AppendLine(item.TransformText()); } foreach (var item in texts) { sb.AppendLine(item.TransformText()); } foreach (var item in hubTexts) { sb.AppendLine(item.TransformText()); } Output(output, sb.ToString()); } else { Output(NormalizePath(output, registerTemplate.Namespace, "MagicOnionInitializer"), WithAutoGenerated(registerTemplate.TransformText())); Output(NormalizePath(output, resolverTemplate.Namespace, resolverTemplate.ResolverName), WithAutoGenerated(resolverTemplate.TransformText())); foreach (var enumTemplate in enumInfos) { var x = new EnumTemplate() { Namespace = namespaceDot + "Formatters", enumSerializationInfos = new[] { enumTemplate } }; Output(NormalizePath(output, x.Namespace, enumTemplate.Name + "Formatter"), WithAutoGenerated(x.TransformText())); } foreach (var serviceClient in definitions) { var x = new CodeTemplate() { Namespace = serviceClient.Namespace, Interfaces = new[] { serviceClient } }; Output(NormalizePath(output, serviceClient.Namespace, serviceClient.ClientName), WithAutoGenerated(x.TransformText())); } foreach (var hub in hubDefinitions) { var x = new HubTemplate() { Namespace = hub.hubDefinition.Namespace, Interfaces = new[] { hub } }; Output(NormalizePath(output, hub.hubDefinition.Namespace, hub.hubDefinition.ClientName), WithAutoGenerated(x.TransformText())); } } if (definitions.Length == 0 && hubDefinitions.Length == 0) { logger("Generated result is empty, unexpected result?"); } logger("Output Generation Complete:" + sw.Elapsed.ToString()); }
private static async Task <int> Main(string[] args) { try { var cmdArgs = new CommandlineArguments(args); if (!cmdArgs.IsParsed) { return(0); } // Generator Start... var sw = Stopwatch.StartNew(); Console.WriteLine("Project Compilation Start:" + cmdArgs.InputPath); var collector = await TypeCollector.CreateAsync(cmdArgs.InputPath, cmdArgs.ConditionalSymbols, true, cmdArgs.IsUseMap); Console.WriteLine("Project Compilation Complete:" + sw.Elapsed.ToString()); Console.WriteLine(); sw.Restart(); Console.WriteLine("Method Collect Start"); (ObjectSerializationInfo[] objectInfo, EnumSerializationInfo[] enumInfo, GenericSerializationInfo[] genericInfo, UnionSerializationInfo[] unionInfo) = collector.Collect(); Console.WriteLine("Method Collect Complete:" + sw.Elapsed.ToString()); Console.WriteLine("Output Generation Start"); sw.Restart(); FormatterTemplate[] objectFormatterTemplates = objectInfo .GroupBy(x => x.Namespace) .Select(x => new FormatterTemplate() { Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? string.Empty : "." + x.Key), ObjectSerializationInfos = x.ToArray(), }) .ToArray(); EnumTemplate[] enumFormatterTemplates = enumInfo .GroupBy(x => x.Namespace) .Select(x => new EnumTemplate() { Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? string.Empty : "." + x.Key), EnumSerializationInfos = x.ToArray(), }) .ToArray(); UnionTemplate[] unionFormatterTemplates = unionInfo .GroupBy(x => x.Namespace) .Select(x => new UnionTemplate() { Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? string.Empty : "." + x.Key), UnionSerializationInfos = x.ToArray(), }) .ToArray(); var resolverTemplate = new ResolverTemplate() { Namespace = cmdArgs.GetNamespaceDot() + "Resolvers", FormatterNamespace = cmdArgs.GetNamespaceDot() + "Formatters", ResolverName = cmdArgs.ResolverName, RegisterInfos = genericInfo.Cast <IResolverRegisterInfo>().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo).ToArray(), }; var sb = new StringBuilder(); sb.AppendLine("// <auto-generated />"); sb.AppendLine(); sb.AppendLine(resolverTemplate.TransformText()); foreach (EnumTemplate item in enumFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } foreach (UnionTemplate item in unionFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } foreach (FormatterTemplate item in objectFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } Output(cmdArgs.OutputPath, sb.ToString()); Console.WriteLine("String Generation Complete:" + sw.Elapsed.ToString()); return(0); } catch (Exception ex) { Console.WriteLine("Unhandled Error:" + ex); return(1); } }
/// <summary> /// Generates the specialized resolver and formatters for the types that require serialization in a given compilation. /// </summary> /// <param name="resolverName">The resolver name.</param> /// <param name="namespaceDot">The namespace for the generated type to be created in.</param> /// <param name="objectInfo">The ObjectSerializationInfo array which TypeCollector.Collect returns.</param> /// <param name="enumInfo">The EnumSerializationInfo array which TypeCollector.Collect returns.</param> /// <param name="unionInfo">The UnionSerializationInfo array which TypeCollector.Collect returns.</param> /// <param name="genericInfo">The GenericSerializationInfo array which TypeCollector.Collect returns.</param> public static string GenerateSingleFileSync(string resolverName, string namespaceDot, ObjectSerializationInfo[] objectInfo, EnumSerializationInfo[] enumInfo, UnionSerializationInfo[] unionInfo, GenericSerializationInfo[] genericInfo) { var objectFormatterTemplates = objectInfo .GroupBy(x => (x.Namespace, x.IsStringKey)) .Select(x => { var(nameSpace, isStringKey) = x.Key; var objectSerializationInfos = x.ToArray(); var ns = namespaceDot + "Formatters" + (nameSpace is null ? string.Empty : "." + nameSpace); var template = isStringKey ? new StringKeyFormatterTemplate(ns, objectSerializationInfos) : (IFormatterTemplate) new FormatterTemplate(ns, objectSerializationInfos); return(template); }) .ToArray(); string GetNamespace <T>(IGrouping <string?, T> x) { if (x.Key == null) { return(namespaceDot + "Formatters"); } return(namespaceDot + "Formatters." + x.Key); } var enumFormatterTemplates = enumInfo .GroupBy(x => x.Namespace) .Select(x => new EnumTemplate(GetNamespace(x), x.ToArray())) .ToArray(); var unionFormatterTemplates = unionInfo .GroupBy(x => x.Namespace) .Select(x => new UnionTemplate(GetNamespace(x), x.ToArray())) .ToArray(); var resolverTemplate = new ResolverTemplate(namespaceDot + "Resolvers", namespaceDot + "Formatters", resolverName, genericInfo.Where(x => !x.IsOpenGenericType).Cast <IResolverRegisterInfo>().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo.Where(x => !x.IsOpenGenericType)).ToArray()); var sb = new StringBuilder(); sb.AppendLine(resolverTemplate.TransformText()); sb.AppendLine(); foreach (var item in enumFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } sb.AppendLine(); foreach (var item in unionFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } sb.AppendLine(); foreach (var item in objectFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } return(sb.ToString()); }
private Task GenerateMultipleFileAsync(string output, string resolverName, ObjectSerializationInfo[] objectInfo, EnumSerializationInfo[] enumInfo, UnionSerializationInfo[] unionInfo, string namespaceDot, string multioutSymbol, GenericSerializationInfo[] genericInfo) { string GetNamespace(INamespaceInfo x) { if (x.Namespace == null) { return(namespaceDot + "Formatters"); } return(namespaceDot + "Formatters." + x.Namespace); } var waitingTasks = new Task[objectInfo.Length + enumInfo.Length + unionInfo.Length + 1]; var waitingIndex = 0; foreach (var x in objectInfo) { var ns = namespaceDot + "Formatters" + (x.Namespace is null ? string.Empty : "." + x.Namespace); var template = x.IsStringKey ? new StringKeyFormatterTemplate(ns, new[] { x }) : (IFormatterTemplate) new FormatterTemplate(ns, new[] { x }); var text = template.TransformText(); waitingTasks[waitingIndex++] = OutputToDirAsync(output, template.Namespace, x.Name + "Formatter", multioutSymbol, text); } foreach (var x in enumInfo) { var template = new EnumTemplate(GetNamespace(x), new[] { x }); var text = template.TransformText(); waitingTasks[waitingIndex++] = OutputToDirAsync(output, template.Namespace, x.Name + "Formatter", multioutSymbol, text); } foreach (var x in unionInfo) { var template = new UnionTemplate(GetNamespace(x), new[] { x }); var text = template.TransformText(); waitingTasks[waitingIndex++] = OutputToDirAsync(output, template.Namespace, x.Name + "Formatter", multioutSymbol, text); } var resolverTemplate = new ResolverTemplate(namespaceDot + "Resolvers", namespaceDot + "Formatters", resolverName, genericInfo.Where(x => !x.IsOpenGenericType).Cast <IResolverRegisterInfo>().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo.Where(x => !x.IsOpenGenericType)).ToArray()); waitingTasks[waitingIndex] = OutputToDirAsync(output, resolverTemplate.Namespace, resolverTemplate.ResolverName, multioutSymbol, resolverTemplate.TransformText()); return(Task.WhenAll(waitingTasks)); }
static void Main(string[] args) { var cmdArgs = new CommandlineArguments(args); if (!cmdArgs.IsParsed) { return; } // Generator Start... var sw = Stopwatch.StartNew(); Console.WriteLine("Project Compilation Start:" + cmdArgs.InputPath); var collector = new MethodCollector(cmdArgs.InputPath, cmdArgs.ConditionalSymbols); Console.WriteLine("Project Compilation Complete:" + sw.Elapsed.ToString()); Console.WriteLine(); sw.Restart(); Console.WriteLine("Method Collect Start"); var definitions = collector.CollectServiceInterface(); var hubDefinitions = collector.CollectHubInterface(); GenericSerializationInfo[] genericInfos; EnumSerializationInfo[] enumInfos; ExtractResolverInfo(definitions, out genericInfos, out enumInfos); ExtractResolverInfo(hubDefinitions.Select(x => x.hubDefinition).ToArray(), out var genericInfos2, out var enumInfos2); ExtractResolverInfo(hubDefinitions.Select(x => x.receiverDefintion).ToArray(), out var genericInfos3, out var enumInfos3); enumInfos = enumInfos.Concat(enumInfos2).Concat(enumInfos3).Distinct().ToArray(); genericInfos = genericInfos.Concat(genericInfos2).Concat(genericInfos3).Distinct().ToArray(); Console.WriteLine("Method Collect Complete:" + sw.Elapsed.ToString()); Console.WriteLine("Output Generation Start"); sw.Restart(); var enumTemplates = enumInfos.GroupBy(x => x.Namespace) .OrderBy(x => x.Key) .Select(x => new EnumTemplate() { Namespace = x.Key, enumSerializationInfos = x.ToArray() }) .ToArray(); var resolverTemplate = new ResolverTemplate() { Namespace = cmdArgs.NamespaceRoot + ".Resolvers", FormatterNamespace = cmdArgs.NamespaceRoot + ".Formatters", ResolverName = "MagicOnionResolver", registerInfos = genericInfos.OrderBy(x => x.FullName).Cast <IResolverRegisterInfo>().Concat(enumInfos.OrderBy(x => x.FullName)).ToArray() }; var texts = definitions .GroupBy(x => x.Namespace) .OrderBy(x => x.Key) .Select(x => new CodeTemplate() { Namespace = x.Key, Interfaces = x.ToArray() }) .ToArray(); var hubTexts = hubDefinitions .GroupBy(x => x.hubDefinition.Namespace) .OrderBy(x => x.Key) .Select(x => new HubTemplate() { Namespace = x.Key, Interfaces = x.ToArray() }) .ToArray(); var registerTemplate = new RegisterTemplate { Namespace = cmdArgs.NamespaceRoot, Interfaces = definitions.Where(x => x.IsServiceDifinition).ToArray(), HubInterfaces = hubDefinitions, UnuseUnityAttribute = cmdArgs.UnuseUnityAttr }; var sb = new StringBuilder(); sb.AppendLine(registerTemplate.TransformText()); sb.AppendLine(resolverTemplate.TransformText()); foreach (var item in enumTemplates) { sb.AppendLine(item.TransformText()); } foreach (var item in texts) { sb.AppendLine(item.TransformText()); } foreach (var item in hubTexts) { sb.AppendLine(item.TransformText()); } Output(cmdArgs.OutputPath, sb.ToString()); Console.WriteLine("String Generation Complete:" + sw.Elapsed.ToString()); Console.WriteLine(); }
static void Main(string[] args) { //var inputFiles = new string[0]; //var inputDirectories = new[] { @"C:\Users\y.kawai\Documents\Grani\IvoryLfs\Ivory\Ivory.Shared" }; //var c = new TypeCollector(inputFiles, inputDirectories, new string[0], true); var cmdArgs = new CommandlineArguments(args); if (!cmdArgs.IsParsed) { return; } // Generator Start... var sw = Stopwatch.StartNew(); Console.WriteLine("Project Compilation Start:" + string.Join(",", cmdArgs.InputFiles) + " " + string.Join(",", cmdArgs.InputDirectories)); var collector = new TypeCollector(cmdArgs.InputFiles, cmdArgs.InputDirectories, cmdArgs.ConditionalSymbols, cmdArgs.AdditionalCompilationDirectories, !cmdArgs.AllowInternal); Console.WriteLine("Project Compilation Complete:" + sw.Elapsed.ToString()); Console.WriteLine(); sw.Restart(); Console.WriteLine("Method Collect Start"); var(objectInfo, genericInfo) = collector.Collect(); Console.WriteLine("Method Collect Complete:" + sw.Elapsed.ToString()); Console.WriteLine("Output Generation Start"); sw.Restart(); var objectFormatterTemplates = objectInfo .GroupBy(x => x.Namespace) .Select(x => new FormatterTemplate() { Namespace = cmdArgs.GetNamespaceDot() + "Formatters" + ((x.Key == null) ? "" : "." + x.Key), objectSerializationInfos = x.ToArray(), }) .ToArray(); var resolverTemplate = new ResolverTemplate() { Namespace = cmdArgs.GetNamespaceDot() + "Resolvers", FormatterNamespace = cmdArgs.GetNamespaceDot() + "Formatters", ResolverName = cmdArgs.ResolverName, registerInfos = genericInfo.Cast <IResolverRegisterInfo>().Concat(objectInfo).ToArray() }; var sb = new StringBuilder(); sb.AppendLine(resolverTemplate.TransformText()); sb.AppendLine(); foreach (var item in objectFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } Output(cmdArgs.OutputPath, sb.ToString()); Console.WriteLine("String Generation Complete:" + sw.Elapsed.ToString()); }
static void Main(string[] args) { var cmdArgs = new CommandlineArguments(args); if (!cmdArgs.IsParsed) { return; } // Generator Start... var sw = Stopwatch.StartNew(); Console.WriteLine("Project Compilation Start:" + cmdArgs.InputPath); var collector = new TypeCollector(cmdArgs.InputPath, cmdArgs.ConditionalSymbols, true, cmdArgs.IsUseMap); Console.WriteLine("Project Compilation Complete:" + sw.Elapsed.ToString()); Console.WriteLine(); sw.Restart(); Console.WriteLine("Method Collect Start"); var(objectInfo, enumInfo, genericInfo, unionInfo) = collector.Collect(); Console.WriteLine("Method Collect Complete:" + sw.Elapsed.ToString()); Console.WriteLine("Output Generation Start"); sw.Restart(); var objectFormatterTemplates = objectInfo .GroupBy(x => x.Namespace) .Select(x => new FormatterTemplate() { Namespace = cmdArgs.GetNamespaceDot() + "Formatters." + x.Key, objectSerializationInfos = x.ToArray(), }) .ToArray(); var enumFormatterTemplates = enumInfo .GroupBy(x => x.Namespace) .Select(x => new EnumTemplate() { Namespace = cmdArgs.GetNamespaceDot() + "Formatters." + x.Key, enumSerializationInfos = x.ToArray() }) .ToArray(); var unionFormatterTemplates = unionInfo .GroupBy(x => x.Namespace) .Select(x => new UnionTemplate() { Namespace = cmdArgs.GetNamespaceDot() + "Formatters." + x.Key, unionSerializationInfos = x.ToArray() }) .ToArray(); var resolverTemplate = new ResolverTemplate() { Namespace = cmdArgs.GetNamespaceDot() + "Resolvers", FormatterNamespace = cmdArgs.GetNamespaceDot() + "Formatters", ResolverName = cmdArgs.ResolverName, registerInfos = genericInfo.Cast <IResolverRegisterInfo>().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo).ToArray() }; var sb = new StringBuilder(); sb.AppendLine(resolverTemplate.TransformText()); sb.AppendLine(); foreach (var item in enumFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } sb.AppendLine(); foreach (var item in unionFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } sb.AppendLine(); foreach (var item in objectFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } Output(cmdArgs.OutputPath, sb.ToString()); Console.WriteLine("String Generation Complete:" + sw.Elapsed.ToString()); }
public void Run( [Option("i", "Input path of analyze csproj.")] string input, [Option("o", "Output path(file) or directory base(in separated mode).")] string output, [Option("u", "Unuse UnityEngine's RuntimeInitializeOnLoadMethodAttribute on MagicOnionInitializer.")] bool unuseUnityAttr = false, [Option("n", "Conditional compiler symbol.")] string @namespace = "MagicOnion", [Option("c", "Set namespace root name.")] string[] conditionalSymbol = null) { // Prepare args conditionalSymbol = conditionalSymbol ?? new string[0]; // Generator Start... var sw = Stopwatch.StartNew(); Console.WriteLine("Project Compilation Start:" + input); var collector = new MethodCollector(input, conditionalSymbol); Console.WriteLine("Project Compilation Complete:" + sw.Elapsed.ToString()); Console.WriteLine(); sw.Restart(); Console.WriteLine("Method Collect Start"); var definitions = collector.CollectServiceInterface(); var hubDefinitions = collector.CollectHubInterface(); GenericSerializationInfo[] genericInfos; EnumSerializationInfo[] enumInfos; ExtractResolverInfo(definitions, out genericInfos, out enumInfos); ExtractResolverInfo(hubDefinitions.Select(x => x.hubDefinition).ToArray(), out var genericInfos2, out var enumInfos2); ExtractResolverInfo(hubDefinitions.Select(x => x.receiverDefintion).ToArray(), out var genericInfos3, out var enumInfos3); enumInfos = enumInfos.Concat(enumInfos2).Concat(enumInfos3).Distinct().ToArray(); genericInfos = genericInfos.Concat(genericInfos2).Concat(genericInfos3).Distinct().ToArray(); Console.WriteLine("Method Collect Complete:" + sw.Elapsed.ToString()); Console.WriteLine("Output Generation Start"); sw.Restart(); var enumTemplates = enumInfos.GroupBy(x => x.Namespace) .OrderBy(x => x.Key) .Select(x => new EnumTemplate() { Namespace = @namespace + ".Formatters", enumSerializationInfos = x.ToArray() }) .ToArray(); var resolverTemplate = new ResolverTemplate() { Namespace = @namespace + ".Resolvers", FormatterNamespace = @namespace + ".Formatters", ResolverName = "MagicOnionResolver", registerInfos = genericInfos.OrderBy(x => x.FullName).Cast <IResolverRegisterInfo>().Concat(enumInfos.OrderBy(x => x.FullName)).ToArray() }; var texts = definitions .GroupBy(x => x.Namespace) .OrderBy(x => x.Key) .Select(x => new CodeTemplate() { Namespace = x.Key, Interfaces = x.ToArray() }) .ToArray(); var hubTexts = hubDefinitions .GroupBy(x => x.hubDefinition.Namespace) .OrderBy(x => x.Key) .Select(x => new HubTemplate() { Namespace = x.Key, Interfaces = x.ToArray() }) .ToArray(); var registerTemplate = new RegisterTemplate { Namespace = @namespace, Interfaces = definitions.Where(x => x.IsServiceDefinition).ToArray(), HubInterfaces = hubDefinitions, UnuseUnityAttribute = unuseUnityAttr }; var sb = new StringBuilder(); sb.AppendLine("// <auto-generated />"); sb.AppendLine(registerTemplate.TransformText()); sb.AppendLine(resolverTemplate.TransformText()); foreach (var item in enumTemplates) { sb.AppendLine(item.TransformText()); } foreach (var item in texts) { sb.AppendLine(item.TransformText()); } foreach (var item in hubTexts) { sb.AppendLine(item.TransformText()); } Output(output, sb.ToString()); Console.WriteLine("String Generation Complete:" + sw.Elapsed.ToString()); Console.WriteLine(); }
/// <summary> /// Generates the specialized resolver and formatters for the types that require serialization in a given compilation. /// </summary> /// <param name="compilation">The compilation to read types from as an input to code generation.</param> /// <param name="output">The name of the generated source file.</param> /// <param name="resolverName">The resolver name.</param> /// <param name="namespace">The namespace for the generated type to be created in. May be null.</param> /// <param name="useMapMode">A boolean value that indicates whether all formatters should use property maps instead of more compact arrays.</param> /// <param name="multipleIfDirectiveOutputSymbols">A comma-delimited list of symbols that should surround redundant generated files. May be null.</param> /// <param name="externalIgnoreTypeNames"> May be null.</param> /// <returns>A task that indicates when generation has completed.</returns> public async Task GenerateFileAsync( Compilation compilation, string output, string resolverName, string @namespace, bool useMapMode, string multipleIfDirectiveOutputSymbols, string[] externalIgnoreTypeNames) { var namespaceDot = string.IsNullOrWhiteSpace(@namespace) ? string.Empty : @namespace + "."; var multipleOutputSymbols = multipleIfDirectiveOutputSymbols?.Split(',') ?? Array.Empty <string>(); var sw = Stopwatch.StartNew(); foreach (var multioutSymbol in multipleOutputSymbols.Length == 0 ? new[] { string.Empty } : multipleOutputSymbols) { logger("Project Compilation Start:" + compilation.AssemblyName); var collector = new TypeCollector(compilation, true, useMapMode, externalIgnoreTypeNames, x => Console.WriteLine(x)); logger("Project Compilation Complete:" + sw.Elapsed.ToString()); sw.Restart(); logger("Method Collect Start"); var(objectInfo, enumInfo, genericInfo, unionInfo) = collector.Collect(); logger("Method Collect Complete:" + sw.Elapsed.ToString()); logger("Output Generation Start"); sw.Restart(); if (Path.GetExtension(output) == ".cs") { // SingleFile Output var objectFormatterTemplates = objectInfo .GroupBy(x => (x.Namespace, x.IsStringKey)) .Select(x => { var(nameSpace, isStringKey) = x.Key; var objectSerializationInfos = x.ToArray(); var template = isStringKey ? new StringKeyFormatterTemplate() : (IFormatterTemplate) new FormatterTemplate(); template.Namespace = namespaceDot + "Formatters" + (nameSpace is null ? string.Empty : "." + nameSpace); template.ObjectSerializationInfos = objectSerializationInfos; return(template); }) .ToArray(); var enumFormatterTemplates = enumInfo .GroupBy(x => x.Namespace) .Select(x => new EnumTemplate() { Namespace = namespaceDot + "Formatters" + ((x.Key == null) ? string.Empty : "." + x.Key), EnumSerializationInfos = x.ToArray(), }) .ToArray(); var unionFormatterTemplates = unionInfo .GroupBy(x => x.Namespace) .Select(x => new UnionTemplate() { Namespace = namespaceDot + "Formatters" + ((x.Key == null) ? string.Empty : "." + x.Key), UnionSerializationInfos = x.ToArray(), }) .ToArray(); var resolverTemplate = new ResolverTemplate() { Namespace = namespaceDot + "Resolvers", FormatterNamespace = namespaceDot + "Formatters", ResolverName = resolverName, RegisterInfos = genericInfo.Where(x => !x.IsOpenGenericType).Cast <IResolverRegisterInfo>().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo.Where(x => !x.IsOpenGenericType)).ToArray(), }; var sb = new StringBuilder(); sb.AppendLine(resolverTemplate.TransformText()); sb.AppendLine(); foreach (var item in enumFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } sb.AppendLine(); foreach (var item in unionFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } sb.AppendLine(); foreach (var item in objectFormatterTemplates) { var text = item.TransformText(); sb.AppendLine(text); } if (multioutSymbol == string.Empty) { await OutputAsync(output, sb.ToString(), cancellationToken); } else { var fname = Path.GetFileNameWithoutExtension(output) + "." + MultiSymbolToSafeFilePath(multioutSymbol) + ".cs"; var text = $"#if {multioutSymbol}" + Environment.NewLine + sb.ToString() + Environment.NewLine + "#endif"; await OutputAsync(Path.Combine(Path.GetDirectoryName(output), fname), text, cancellationToken); } } else { // Multiple File output foreach (var x in objectInfo) { var template = x.IsStringKey ? new StringKeyFormatterTemplate() : (IFormatterTemplate) new FormatterTemplate(); template.Namespace = namespaceDot + "Formatters" + (x.Namespace is null ? string.Empty : "." + x.Namespace); template.ObjectSerializationInfos = new[] { x }; var text = template.TransformText(); await OutputToDirAsync(output, template.Namespace, x.Name + "Formatter", multioutSymbol, text, cancellationToken); } foreach (var x in enumInfo) { var template = new EnumTemplate() { Namespace = namespaceDot + "Formatters" + ((x.Namespace == null) ? string.Empty : "." + x.Namespace), EnumSerializationInfos = new[] { x }, }; var text = template.TransformText(); await OutputToDirAsync(output, template.Namespace, x.Name + "Formatter", multioutSymbol, text, cancellationToken); } foreach (var x in unionInfo) { var template = new UnionTemplate() { Namespace = namespaceDot + "Formatters" + ((x.Namespace == null) ? string.Empty : "." + x.Namespace), UnionSerializationInfos = new[] { x }, }; var text = template.TransformText(); await OutputToDirAsync(output, template.Namespace, x.Name + "Formatter", multioutSymbol, text, cancellationToken); } var resolverTemplate = new ResolverTemplate() { Namespace = namespaceDot + "Resolvers", FormatterNamespace = namespaceDot + "Formatters", ResolverName = resolverName, RegisterInfos = genericInfo.Where(x => !x.IsOpenGenericType).Cast <IResolverRegisterInfo>().Concat(enumInfo).Concat(unionInfo).Concat(objectInfo.Where(x => !x.IsOpenGenericType)).ToArray(), }; await OutputToDirAsync(output, resolverTemplate.Namespace, resolverTemplate.ResolverName, multioutSymbol, resolverTemplate.TransformText(), cancellationToken); } if (objectInfo.Length == 0 && enumInfo.Length == 0 && genericInfo.Length == 0 && unionInfo.Length == 0) { logger("Generated result is empty, unexpected result?"); } } logger("Output Generation Complete:" + sw.Elapsed.ToString()); }