Exemple #1
0
        private static void OutputI18nTextJsonFiles(I18nTextCompilerOptions options, I18nTextSource i18textSrc, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (!i18textSrc.Types.Any())
            {
                return;
            }
            if (!Directory.Exists(options.OutDirectory))
            {
                Directory.CreateDirectory(options.OutDirectory);
            }

            var types = i18textSrc.Types
                        .SelectMany(type => type.Value.Langs.Select(lang => (lang, jsonPath: Path.Combine(options.OutDirectory, options.NameSpace + "." + type.Key + "." + lang.Key + ".json"))))
                        .ToArray();

            // Sweep old generated/should be purge text json files.
            var existsTextJsonFiles  = Directory.GetFiles(options.OutDirectory, "*.json");
            var shouldBeSweepedFiles = existsTextJsonFiles.Except(types.Select(t => t.jsonPath));

            foreach (var shouldBeSweepedFile in shouldBeSweepedFiles)
            {
                cancellationToken.ThrowIfCancellationRequested();
                File.Delete(shouldBeSweepedFile);
            }

            Parallel.ForEach(types, new ParallelOptions {
                CancellationToken = cancellationToken
            }, ((KeyValuePair <string, I18nTextTable> lang, string jsonPath)arg) =>
            {
                var textTable = new SortedDictionary <string, string>(arg.lang.Value);
                var jsonText  = JsonConvert.SerializeObject(textTable, Formatting.Indented);
                cancellationToken.ThrowIfCancellationRequested();

                var skipOutput = false;
                if (File.Exists(arg.jsonPath))
                {
                    var prevJsonText = File.ReadAllText(arg.jsonPath);
                    cancellationToken.ThrowIfCancellationRequested();
                    skipOutput = prevJsonText == jsonText;
                }

                if (!skipOutput)
                {
                    File.WriteAllText(arg.jsonPath, jsonText);
                }
            });
Exemple #2
0
        private static I18nTextSource ParseSourceFiles(IEnumerable <I18nTextSourceFile> srcFiles, I18nTextCompilerOptions options)
        {
            var i18textSrc = new I18nTextSource();

            if (!srcFiles.Any())
            {
                return(i18textSrc);
            }

            Parallel.ForEach(srcFiles, srcFile =>
            {
                var fnameParts = Path.GetFileNameWithoutExtension(srcFile.Path).Split('.');
                var typeName   = string.Join(".", fnameParts.Take(fnameParts.Length - 1));
                var langCode   = fnameParts.Last();
                var srcText    = File.ReadAllText(srcFile.Path, srcFile.Encoding);
                var textTable  = DeserializeSrcText(srcText, Path.GetExtension(srcFile.Path).ToLower());

                var type             = i18textSrc.Types.GetOrAdd(typeName, new I18nTextType());
                type.Langs[langCode] = textTable;
            });

            Parallel.ForEach(i18textSrc.Types.Values, type =>
            {
                type.TextKeys = type.Langs
                                .SelectMany(lang => lang.Value)
                                .Select(tt => tt.Key)
                                .OrderBy(key => key)
                                .Distinct()
                                .ToList();

                Parallel.ForEach(type.Langs, lang =>
                {
                    var textTable = lang.Value;
                    foreach (var textKey in type.TextKeys.Where(k => !textTable.ContainsKey(k)))
                    {
                        var text = type.Langs.Keys
                                   .OrderBy(langCode => langCode.StartsWith("en") ? "0" : langCode)
                                   .Select(langCode => type.Langs[langCode].TryGetValue(textKey, out var t) ? t : null)
                                   .FirstOrDefault(t => t != null);
                        textTable[textKey] = text ?? textKey;
                    }
                });
            });
Exemple #3
0
        private static I18nTextSource ParseSourceFiles(IEnumerable <I18nTextSourceFile> srcFiles, I18nTextCompilerOptions options)
        {
            var i18textSrc = new I18nTextSource();

            if (!srcFiles.Any())
            {
                return(i18textSrc);
            }

            var i18nSrcDir = options.I18nTextSourceDirectory;

            if (!i18nSrcDir.EndsWith(Path.DirectorySeparatorChar.ToString()))
            {
                i18nSrcDir += Path.DirectorySeparatorChar;
            }

            ConvertPath convertPath;

            if (options.DisableSubNameSpace)
            {
                convertPath = delegate(string srcPath) { return(Path.GetFileName(srcPath)); };
            }
            else
            {
                convertPath = delegate(string srcPath)
                {
                    return(srcPath.StartsWith(i18nSrcDir) ? srcPath.Substring(i18nSrcDir.Length) : Path.GetFileName(srcPath));
                };
            }

            Parallel.ForEach(srcFiles, srcFile =>
            {
                var srcName    = convertPath(srcFile.Path);
                var fnameParts = srcName.Split('.', Path.DirectorySeparatorChar);
                var typeName   = string.Join(".", fnameParts.Take(fnameParts.Length - 2));
                var langCode   = fnameParts[fnameParts.Length - 2];
                var srcText    = File.ReadAllText(srcFile.Path, srcFile.Encoding);
                var textTable  = DeserializeSrcText(srcText, Path.GetExtension(srcFile.Path).ToLower());

                var type             = i18textSrc.Types.GetOrAdd(typeName, new I18nTextType());
                type.Langs[langCode] = textTable;
            });

            Parallel.ForEach(i18textSrc.Types.Values, type =>
            {
                type.TextKeys = type.Langs
                                .SelectMany(lang => lang.Value)
                                .Select(tt => tt.Key)
                                .OrderBy(key => key)
                                .Distinct()
                                .ToList();

                Parallel.ForEach(type.Langs, lang =>
                {
                    var textTable = lang.Value;
                    foreach (var textKey in type.TextKeys.Where(k => !textTable.ContainsKey(k)))
                    {
                        var text = type.Langs.Keys
                                   .OrderBy(langCode => langCode.StartsWith("en") ? "0" : langCode)
                                   .Select(langCode => type.Langs[langCode].TryGetValue(textKey, out var t) ? t : null)
                                   .FirstOrDefault(t => t != null);
                        textTable[textKey] = text ?? textKey;
                    }
                });
            });
Exemple #4
0
        private static void OutputTypesFiles(
            I18nTextCompilerOptions options,
            I18nTextSource i18textSrc,
            Action <I18nTextCompilerOptions, IEnumerable <I18nTextCompileItem> > beforeCompile,
            Action <I18nTextCompilerOptions, I18nTextCompileItem, IEnumerable <string> > saveCode,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (!i18textSrc.Types.Any())
            {
                return;
            }

            var i18nTextCompilerItems = i18textSrc.Types.Select(type =>
            {
                var typeFullName  = options.NameSpace + "." + type.Key;
                var typeNameParts = typeFullName.Split('.');
                var typeNamespace = string.Join(".", typeNameParts.Take(typeNameParts.Length - 1));
                var typeName      = typeNameParts.Last();

                var typeFilePath = Path.Combine(options.TypesDirectory, typeFullName + ".cs");
                return(new I18nTextCompileItem(type, typeNamespace, typeName, typeFilePath));
            }).ToArray();

            beforeCompile?.Invoke(options, i18nTextCompilerItems);
            cancellationToken.ThrowIfCancellationRequested();

            Parallel.ForEach(i18nTextCompilerItems, new ParallelOptions {
                CancellationToken = cancellationToken
            }, comilerItem =>
            {
                var langs         = comilerItem.Type.Value.Langs;
                var langParts     = options.FallBackLanguage.Split('-');
                var fallbackLangs = langParts.Length > 1 ? new[] { options.FallBackLanguage, langParts[0] } : new[] { options.FallBackLanguage };
                var fallbackLang  = fallbackLangs.FirstOrDefault(lang => langs.ContainsKey(lang));
                if (fallbackLang == null)
                {
                    throw new I18nTextCompileException(DiagnosticCode.FallbackLangNotFound, $"Could not find an I18n source text file of fallback language '{options.FallBackLanguage}', for '{options.NameSpace}.{comilerItem.Type.Key}'.");
                }
                var textTable = langs[fallbackLang];

                var hash = GenerateHash(comilerItem.Type.Value);
                cancellationToken.ThrowIfCancellationRequested();

                var typeCode = new List <string>();
                typeCode.Add(GeneratedMarker);
                typeCode.Add($"namespace {comilerItem.TypeNamespace}");
                typeCode.Add("{");
                typeCode.Add($"    public partial class {comilerItem.TypeName} : global::Toolbelt.Blazor.I18nText.Interfaces.I18nTextFallbackLanguage, global::Toolbelt.Blazor.I18nText.Interfaces.I18nTextLateBinding, global::Toolbelt.Blazor.I18nText.Interfaces.I18nTextTableHash");
                typeCode.Add("    {");
                typeCode.Add($"        string global::Toolbelt.Blazor.I18nText.Interfaces.I18nTextTableHash.Hash => \"{hash}\";");
                typeCode.Add("");
                typeCode.Add($"        string global::Toolbelt.Blazor.I18nText.Interfaces.I18nTextFallbackLanguage.FallBackLanguage => \"{options.FallBackLanguage}\";");
                typeCode.Add("");
                typeCode.Add("        public string this[string key] => global::Toolbelt.Blazor.I18nText.I18nTextExtensions.GetFieldValue(this, key);");
                typeCode.Add("");
                var is1stLine = true;
                foreach (var textKey in comilerItem.Type.Value.TextKeys)
                {
                    if (!is1stLine)
                    {
                        typeCode.Add("");
                    }
                    typeCode.Add($"        /// <summary>\"{EscapeForXMLDocSummary(textTable[textKey])}\"</summary>");
                    typeCode.Add($"        public string {textKey};");
                    is1stLine = false;
                }
                typeCode.Add("    }");
                typeCode.Add("}");

                saveCode?.Invoke(options, comilerItem, typeCode);
            });
        }