From a6fdcc29543eba1eb1577b70755e94a5c93b0fe2 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sun, 12 Feb 2023 16:18:11 +0100 Subject: [PATCH] Optimized the C# bigfile generator The bigfile generator requires .NET 7 from now on. --- .../Processor/Generators/DotnetBigFile.cs | 115 +++++++++++------- I18N Commander/Processor/Utils.cs | 21 ---- I18N Commander/Processor/Version.cs | 2 +- 3 files changed, 74 insertions(+), 64 deletions(-) diff --git a/I18N Commander/Processor/Generators/DotnetBigFile.cs b/I18N Commander/Processor/Generators/DotnetBigFile.cs index 7b20abd..8ae4a7b 100644 --- a/I18N Commander/Processor/Generators/DotnetBigFile.cs +++ b/I18N Commander/Processor/Generators/DotnetBigFile.cs @@ -43,16 +43,15 @@ public class DotnetBigFile : IGenerator await using var fileStream = new FileStream(pathTemp, FileMode.CreateNew, FileAccess.Write, FileShare.None); await using var writer = new StreamWriter(fileStream, Encoding.UTF8); - await writer.WriteLineAsync($"namespace {await AppSettings.GetGeneratorDotnetNamespace()};"); + await writer.WriteLineAsync("""using System.Globalization;"""); + await writer.WriteLineAsync($"""namespace {await AppSettings.GetGeneratorDotnetNamespace()};"""); await this.CreateStaticClass(writer, "I18N", 0, async (streamWriter, indention) => { var indentionString = this.AddIndention(indention); var buildTime = DateTime.UtcNow; await writer.WriteLineAsync($"{indentionString}public static readonly string BUILD_TIME = \"{buildTime:yyyy.MM.dd HH:mm:ss}\";"); await writer.WriteLineAsync($"{indentionString}public static readonly long BUILD_TIME_TICKS = {buildTime.Ticks};"); - await writer.WriteLineAsync(); - await writer.WriteLineAsync($"{indentionString}private static int PREVIOUS_CULTURE = -1;"); - + // Go through the first layer of sections: var sections = await SectionProcessor.LoadLayer(0); foreach (var section in sections) @@ -114,51 +113,45 @@ public class DotnetBigFile : IGenerator private async Task TransformTextElement(TextWriter writer, int indention, TextElement textElement) { var indentionString = this.AddIndention(indention); - var indentionPropString = this.AddIndention(indention + 1); - var indentionPropInner1String = this.AddIndention(indention + 2); - var indentionPropInner2String = this.AddIndention(indention + 3); - var indentionPropInner3String = this.AddIndention(indention + 4); + var indentionInner1 = this.AddIndention(indention + 1); + var indentionInner2 = this.AddIndention(indention + 2); - await writer.WriteLineAsync($"{indentionString}private static string E_{textElement.Code}_CACHE = \"\";"); - await writer.WriteLineAsync($"{indentionString}public static string E_{textElement.Code}"); - await writer.WriteLineAsync($"{indentionString}{{"); - await writer.WriteLineAsync($"{indentionPropString}get"); - await writer.WriteLineAsync($"{indentionPropString}{{"); - await writer.WriteLineAsync($"{indentionPropInner1String}var currentCulture = CultureInfo.CurrentCulture.Name;"); - await writer.WriteLineAsync($"{indentionPropInner1String}if(PREVIOUS_CULTURE == currentCulture.GetHashCode())"); - await writer.WriteLineAsync($"{indentionPropInner2String}return E_{textElement.Code}_CACHE;"); - await writer.WriteLineAsync($"{indentionPropInner1String}else"); - await writer.WriteLineAsync($"{indentionPropInner1String}{{"); - await writer.WriteLineAsync($"{indentionPropInner2String}PREVIOUS_CULTURE = currentCulture.GetHashCode();"); + await writer.WriteLineAsync($"""{indentionString}public static string E_{textElement.Code}() => E_{textElement.Code}(CultureInfo.CurrentCulture);"""); + await writer.WriteLineAsync($"""{indentionString}public static string E_{textElement.Code}(CultureInfo culture)"""); + await writer.WriteLineAsync($$"""{{indentionString}}{"""); // opening { + + // Write the default culture's text: + var defaultCultureTranslation = textElement.Translations.FirstOrDefault(x => x.Culture == CULTURE_CODES[DEFAULT_CULTURE_INDEX]); + var defaultCultureText = defaultCultureTranslation?.Text ?? string.Empty; + await this.WriteTextContent(writer, indentionInner1, textElement.IsMultiLine, defaultCultureText, variableName: "defaultText"); + + await writer.WriteLineAsync($"""{indentionInner1}var name = culture.Name;"""); + await writer.WriteLineAsync($"""{indentionInner1}if(name.Length < 2)"""); + await writer.WriteLineAsync($$"""{{indentionInner1}}{"""); // opening { + await writer.WriteLineAsync($"""{indentionInner2}return defaultText;"""); + await writer.WriteLineAsync($$"""{{indentionInner1}}}"""); // closing } + for (var cultureIndex = 0; cultureIndex < CULTURE_CODES.Count; cultureIndex++) { - if(cultureIndex == 0) - await writer.WriteLineAsync($"{indentionPropInner2String}if (currentCulture.StartsWith(\"{CULTURE_CODES[cultureIndex]}\", StringComparison.InvariantCultureIgnoreCase))"); - else - await writer.WriteLineAsync($"{indentionPropInner2String}else if (currentCulture.StartsWith(\"{CULTURE_CODES[cultureIndex]}\", StringComparison.InvariantCultureIgnoreCase))"); + await writer.WriteLineAsync($"""{indentionInner1}if ({this.CreateIf(CULTURE_CODES[cultureIndex])})"""); + await writer.WriteLineAsync($$"""{{indentionInner1}}{"""); // opening { - await writer.WriteLineAsync($"{indentionPropInner2String}{{"); - var cultureTranslation = textElement.Translations.FirstOrDefault(x => x.Culture == CULTURE_CODES[cultureIndex]); - var cultureText = cultureTranslation?.Text ?? string.Empty; - await writer.WriteLineAsync($"{indentionPropInner3String}var text = @\"{Utils.MadeVerbatimStringLiteral(cultureText)}\";"); - await writer.WriteLineAsync($"{indentionPropInner3String}E_{textElement.Code}_CACHE = text;"); - await writer.WriteLineAsync($"{indentionPropInner3String}return text;"); - await writer.WriteLineAsync($"{indentionPropInner2String}}}"); + if(cultureIndex == DEFAULT_CULTURE_INDEX) + await writer.WriteLineAsync($"""{indentionInner2}return defaultText;"""); + else + { + var cultureTranslation = textElement.Translations.FirstOrDefault(x => x.Culture == CULTURE_CODES[cultureIndex]); + var cultureText = cultureTranslation?.Text ?? string.Empty; + await this.WriteTextContent(writer, indentionInner2, textElement.IsMultiLine, cultureText); + await writer.WriteLineAsync($"""{indentionInner2}return text;"""); + } + + await writer.WriteLineAsync($$"""{{indentionInner1}}}"""); // closing } } // Add the default case: - await writer.WriteLineAsync($"{indentionPropInner2String}else"); - await writer.WriteLineAsync($"{indentionPropInner2String}{{"); - var defaultCultureTranslation = textElement.Translations.FirstOrDefault(x => x.Culture == CULTURE_CODES[DEFAULT_CULTURE_INDEX]); - var defaultCultureText = defaultCultureTranslation?.Text ?? string.Empty; - await writer.WriteLineAsync($"{indentionPropInner3String}var text = @\"{Utils.MadeVerbatimStringLiteral(defaultCultureText)}\";"); - await writer.WriteLineAsync($"{indentionPropInner3String}E_{textElement.Code}_CACHE = text;"); - await writer.WriteLineAsync($"{indentionPropInner3String}return text;"); - await writer.WriteLineAsync($"{indentionPropInner2String}}}"); - - await writer.WriteLineAsync($"{indentionPropInner1String}}}"); - await writer.WriteLineAsync($"{indentionPropString}}}"); - await writer.WriteLineAsync($"{indentionString}}}"); + await writer.WriteLineAsync($"""{indentionInner1}return defaultText;"""); + await writer.WriteLineAsync($$"""{{indentionString}}}"""); // closing } await writer.WriteLineAsync(); } @@ -172,4 +165,42 @@ public class DotnetBigFile : IGenerator await content(writer, indention + 1); await writer.WriteLineAsync($"{indentionString}}}"); } + + private async Task WriteTextContent(TextWriter writer, string indention, bool isMultiline, string content, string variableName = "text") + { + if(isMultiline) + { + await writer.WriteLineAsync($""""""""" +{indention}const string {variableName} = """""""" +"""""""""); + await writer.WriteLineAsync(content); + await writer.WriteLineAsync($""""""""" +""""""""; +"""""""""); + } + else + await writer.WriteLineAsync($"""""""""{indention}const string {variableName} = """"""""{content}"""""""";"""""""""); + } + + private string CreateIf(string cultureCode) + { + if (string.IsNullOrWhiteSpace(cultureCode)) + return "false"; + + var sb = new StringBuilder(); + var len = cultureCode.Length; + if (len > 2) + sb.Append($"""name.Length >= {len} && """); + + for (var i = 0; i < cultureCode.Length; i++) + { + sb.Append($"""name[{i}] is '{cultureCode[i]}'"""); + + // When this is not the last character, we need to add " && ": + if (i < cultureCode.Length - 1) + sb.Append(" && "); + } + + return sb.ToString(); + } } \ No newline at end of file diff --git a/I18N Commander/Processor/Utils.cs b/I18N Commander/Processor/Utils.cs index 13a625d..f1b89c1 100644 --- a/I18N Commander/Processor/Utils.cs +++ b/I18N Commander/Processor/Utils.cs @@ -47,25 +47,4 @@ internal static class Utils return code; } - - public static string MadeVerbatimStringLiteral(string text) - { - IEnumerable ConvertAll(string source) - { - foreach(var c in source) - if(c == '"') - { - yield return '"'; - yield return '"'; - } - else - yield return c; - } - - var sb = new StringBuilder(); - foreach(var c in ConvertAll(text)) - sb.Append(c); - - return sb.ToString(); - } } \ No newline at end of file diff --git a/I18N Commander/Processor/Version.cs b/I18N Commander/Processor/Version.cs index bb0228c..ce0516e 100644 --- a/I18N Commander/Processor/Version.cs +++ b/I18N Commander/Processor/Version.cs @@ -2,5 +2,5 @@ public static class Version { - public static string Text => $"v0.8.6 (2023-02-12), .NET {Environment.Version}"; + public static string Text => $"v0.9.3 (2023-02-12), .NET {Environment.Version}"; } \ No newline at end of file