diff --git a/PKHeX.Core/Util/Localization/LocalizationUtil.cs b/PKHeX.Core/Util/Localization/LocalizationUtil.cs index 9563e64df..af3c9397f 100644 --- a/PKHeX.Core/Util/Localization/LocalizationUtil.cs +++ b/PKHeX.Core/Util/Localization/LocalizationUtil.cs @@ -1,46 +1,59 @@ -using System; +using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; +using System.Reflection; namespace PKHeX.Core; +/// +/// Localization utility for changing all properties of a static type. +/// public static class LocalizationUtil { private const string TranslationSplitter = " = "; + private const char TranslationFirst = ' '; // perf; no properties contain spaces. /// /// Gets the names of the properties defined in the given input /// /// Enumerable of translation definitions in the form "Property = Value". - private static string[] GetProperties(IEnumerable input) + private static string[] GetProperties(ReadOnlySpan input) { - static string AfterSplit(string l) + var result = new string[input.Length]; + for (int i = 0; i < input.Length; i++) { - var split = l.IndexOf(TranslationSplitter, StringComparison.Ordinal); - return l[..split]; + var l = input[i]; + var split = l.IndexOf(TranslationFirst); + result[i] = l[..split]; } - return input.Select(AfterSplit).ToArray(); + return result; } - private static IEnumerable DumpStrings(Type t) + private static string[] DumpStrings(Type t) { - var props = ReflectUtil.GetPropertiesStartWithPrefix(t, string.Empty); - return props.Select(p => $"{p}{TranslationSplitter}{ReflectUtil.GetValue(t, p)}"); + var ti = t.GetTypeInfo(); + var props = (PropertyInfo[])ti.DeclaredProperties; + var result = new string[props.Length]; + for (int i = 0; i < props.Length; i++) + { + var p = props[i]; + var value = p.GetValue(null); + result[i] = $"{p}{TranslationSplitter}{value}"; + } + return result; } /// /// Gets the current localization in a static class containing language-specific strings /// /// - public static string[] GetLocalization(Type t) => DumpStrings(t).ToArray(); + public static string[] GetLocalization(Type t) => DumpStrings(t); /// /// Gets the current localization in a static class containing language-specific strings /// /// /// Existing localization lines (if provided) - public static string[] GetLocalization(Type t, string[] existingLines) + public static string[] GetLocalization(Type t, ReadOnlySpan existingLines) { var currentLines = GetLocalization(t); var existing = GetProperties(existingLines); @@ -60,28 +73,27 @@ public static string[] GetLocalization(Type t, string[] existingLines) /// /// Type of the static class containing the desired strings. /// Lines containing the localized strings - private static void SetLocalization(Type t, IReadOnlyCollection lines) + private static void SetLocalization(Type t, ReadOnlySpan lines) { - if (lines.Count == 0) + if (lines.Length == 0) return; + + var translatable = new Dictionary(lines.Length); foreach (var line in lines) { - var index = line.IndexOf(TranslationSplitter, StringComparison.Ordinal); + var index = line.IndexOf(TranslationFirst); if (index < 0) continue; var prop = line[..index]; - var value = line[(index + TranslationSplitter.Length)..]; + translatable[prop] = line[(index + TranslationSplitter.Length)..]; + } - try - { - ReflectUtil.SetValue(t, prop, value); - } - // Malformed translation files, log - catch (Exception e) - { - Debug.WriteLine($"Property not present: {prop} || Value written: {value}"); - Debug.WriteLine(e.Message); - } + var ti = t.GetTypeInfo(); + var props = (PropertyInfo[])ti.DeclaredProperties; + foreach (var p in props) + { + if (translatable.TryGetValue(p.Name, out var value)) + p.SetValue(null, value); } }