Skip to content

Commit 1683aad

Browse files
authored
Merge pull request #17 from dotnet-campus/t/lvyi/all-tags
支持获取所有的语言标签列表
2 parents e8a50bd + f8da374 commit 1683aad

File tree

9 files changed

+64
-21
lines changed

9 files changed

+64
-21
lines changed

samples/LocalizationSample/Program.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ internal class Program
66
{
77
public static void Main(string[] args)
88
{
9+
var tags = Lang.SupportedLanguageTags;
10+
Console.WriteLine(string.Join(", ", tags));
11+
912
var a = Lang.Current.A.A2.ToString(1);
1013
Console.WriteLine(a);
1114
}
1215
}
1316

14-
[LocalizedConfiguration(Default = "zh-hans")]
17+
[LocalizedConfiguration(Default = "zh-CN")]
1518
internal partial class Lang;

src/dotnetCampus.Localizations.Analyzer/Assets/Templates/Localization.g.cs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#nullable enable
2-
32
namespace dotnetCampus.Localizations.Assets.Templates;
43

54
partial class Localization
@@ -17,19 +16,34 @@ partial class Localization
1716
/// </summary>
1817
public static ILocalizedValues Current => _current;
1918

19+
/// <summary>
20+
/// 获取支持的语言标签。
21+
/// </summary>
22+
/// <remarks>
23+
/// 由于项目中可以设置 LocalizationSupportsNonIetfLanguageTag 属性,所以不一定是 IETF 语言标签。
24+
/// </remarks>
25+
public static System.Collections.Immutable.ImmutableArray<string> SupportedLanguageTags { get; } =
26+
[
27+
// <FLAG2>
28+
"en",
29+
// </FLAG2>
30+
];
31+
32+
public static ILocalizedValues Create(string languageTag) => CreateLocalizedValues(languageTag);
33+
2034
/// <summary>
2135
/// 设置当前的本地化字符串集。
2236
/// </summary>
23-
/// <param name="ietfLanguageTag">要设置的 IETF 语言标签。</param>
24-
public static void SetCurrent(string ietfLanguageTag) => _current = CreateLocalizedValues(ietfLanguageTag);
37+
/// <param name="languageTag">要设置的语言标签(推荐 IETF 语言标签。</param>
38+
public static void SetCurrent(string languageTag) => _current = CreateLocalizedValues(languageTag);
2539

2640
/// <summary>
27-
/// 创建指定 IETF 语言标签的本地化字符串集
41+
/// 创建指定语言标签的本地化字符串集
2842
/// </summary>
29-
/// <param name="ietfLanguageTag">IETF 语言标签。</param>
30-
private static LocalizedValues CreateLocalizedValues(string ietfLanguageTag)
43+
/// <param name="languageTag">语言标签(推荐 IETF 语言标签。</param>
44+
private static LocalizedValues CreateLocalizedValues(string languageTag)
3145
{
32-
var lowerTag = ietfLanguageTag.ToLowerInvariant();
46+
var lowerTag = languageTag.ToLowerInvariant();
3347
if (_default is { } @default && lowerTag == "DEFAULT_IETF_LANGUAGE_TAG")
3448
{
3549
return @default;
@@ -39,7 +53,7 @@ private static LocalizedValues CreateLocalizedValues(string ietfLanguageTag)
3953
// <FLAG>
4054
"en" => new LocalizedValues(null!),
4155
// </FLAG>
42-
_ => throw new global::System.ArgumentException($"The language tag {ietfLanguageTag} is not supported.", nameof(ietfLanguageTag)),
56+
_ => throw new global::System.ArgumentException($"The language tag {languageTag} is not supported.", nameof(languageTag)),
4357
};
4458
}
4559
}

src/dotnetCampus.Localizations.Analyzer/Generators/CodeTransforming/LocalizationCodeTransformer.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,8 @@ public string ToProviderCodeText(string rootNamespace, string ietfLanguageTag)
214214
var code = template.Content
215215
.Replace($"namespace {template.Namespace};", $"namespace {GeneratorInfo.RootNamespace};")
216216
.Replace($"class {nameof(LocalizedStringProvider)}", $"class {nameof(LocalizedStringProvider)}_{typeName}")
217-
.Replace("""IetfLanguageTag => "default";""", $"""IetfLanguageTag => "{ietfLanguageTag}";""");
218-
var dictLines = LocalizationItems.Select(x => ConvertKeyValueToValueCodeLine(x.Key, x.Value));
219-
code = TemplateRegexes.FlagRegex.Replace(code, string.Concat(dictLines));
217+
.Replace("""IetfLanguageTag => "default";""", $"""IetfLanguageTag => "{ietfLanguageTag}";""")
218+
.FlagReplace(string.Concat(LocalizationItems.Select(x => ConvertKeyValueToValueCodeLine(x.Key, x.Value))));
220219
return code;
221220
}
222221

src/dotnetCampus.Localizations.Analyzer/Generators/LocalizationTypeGenerator.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace dotnetCampus.Localizations.Generators;
1717
/// <example>
1818
/// 本生成器会为下方示例中的类型生成分部实现:
1919
/// <code>
20-
/// [LocalizedConfiguration(Default = "zh-hans", Current = "zh-hans")]
20+
/// [LocalizedConfiguration(Default = "zh-CN", Current = "zh-CN")]
2121
/// public static partial class Lang;
2222
/// </code>
2323
/// </example>
@@ -59,14 +59,19 @@ private void Execute(SourceProductionContext context, ((LocalizationGeneratingMo
5959
not null => $"\"{currentLanguage}\"",
6060
null => "global::System.Globalization.CultureInfo.CurrentUICulture.Name",
6161
}});")
62-
.Replace("DEFAULT_IETF_LANGUAGE_TAG", defaultLanguage);
63-
defaultCode = TemplateRegexes.FlagRegex.Replace(defaultCode, GenerateCreateLocalizedValues(defaultLanguage, localizationFiles, supportsNonIetfLanguageTag));
64-
defaultCode = defaultCode
62+
.Replace("DEFAULT_IETF_LANGUAGE_TAG", defaultLanguage.ToLowerInvariant())
63+
.FlagReplace(GenerateCreateLocalizedValues(defaultLanguage, localizationFiles, supportsNonIetfLanguageTag))
64+
.Flag2Replace(GenerateIetfLanguageTagList(localizationFiles.GroupByIetfLanguageTag(supportsNonIetfLanguageTag).Select(x => x.IetfLanguageTag)))
6565
.Replace("ILocalizedValues", $"global::{GeneratorInfo.RootNamespace}.ILocalizedValues")
6666
.Replace(" LocalizedValues", $" global::{GeneratorInfo.RootNamespace}.LocalizedValues");
6767
context.AddSource($"{typeName}.g.cs", SourceText.From(defaultCode, Encoding.UTF8));
6868
}
6969

70+
private string GenerateIetfLanguageTagList(IEnumerable<string> languageTags) => $"""
71+
72+
{string.Join("\n", languageTags.Select(x => $" \"{x}\","))}
73+
""";
74+
7075
private string GenerateCreateLocalizedValues(string defaultIetfTag, ImmutableArray<LocalizationFileModel> models, bool supportsNonIetfLanguageTag) => $"""
7176
7277
{string.Join("\n", models.GroupByIetfLanguageTag(supportsNonIetfLanguageTag).Select(x => ConvertModelToPatternMatch(defaultIetfTag, x.IetfLanguageTag)))}
@@ -79,7 +84,7 @@ private string ConvertModelToPatternMatch(string defaultIetfTag, string ietfTag)
7984
? "null"
8085
: "_default.LocalizedStringProvider";
8186
return $"""
82-
"{ietfTag}" => new global::{GeneratorInfo.RootNamespace}.LocalizedValues(new global::{GeneratorInfo.RootNamespace}.{nameof(LocalizedStringProvider)}_{tagIdentifier}({defaultProvider})),
87+
"{ietfTag.ToLowerInvariant()}" => new global::{GeneratorInfo.RootNamespace}.LocalizedValues(new global::{GeneratorInfo.RootNamespace}.{nameof(LocalizedStringProvider)}_{tagIdentifier}({defaultProvider})),
8388
""";
8489
}
8590

src/dotnetCampus.Localizations.Analyzer/Generators/ModelProviding/IetfLanguageTagExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public static string IetfLanguageTagToIdentifier(string ietfLanguageTag)
8282
public static string GuessIetfLanguageTagFromFileName(string fileNameWithoutExtension)
8383
{
8484
var parts = fileNameWithoutExtension.Split([' ', '.', '_', ',', ';'], StringSplitOptions.RemoveEmptyEntries).Reverse();
85-
return parts.FirstOrDefault(IsIetfLanguageTag)?.ToLowerInvariant() ?? fileNameWithoutExtension.ToLowerInvariant();
85+
return parts.FirstOrDefault(IsIetfLanguageTag) ?? fileNameWithoutExtension;
8686
}
8787

8888
/// <summary>

src/dotnetCampus.Localizations.Analyzer/Generators/ModelProviding/LocalizationGeneratingModelExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ public static IncrementalValuesProvider<LocalizationGeneratingModel> SelectGener
6767
.FirstOrDefault(a => a.AttributeClass!.IsAttributeOf<LocalizedConfigurationAttribute>());
6868
var x = attribute!.ConstructorArguments.ToImmutableArray();
6969
var namedArguments = attribute!.NamedArguments.ToImmutableDictionary();
70-
var defaultLanguage = namedArguments.GetValueOrDefault(nameof(Localization.Default)).Value?.ToString()!.ToLowerInvariant()!;
71-
var currentLanguage = namedArguments.GetValueOrDefault(nameof(Localization.Current)).Value?.ToString().ToLowerInvariant();
70+
var defaultLanguage = namedArguments.GetValueOrDefault(nameof(Localization.Default)).Value?.ToString()!;
71+
var currentLanguage = namedArguments.GetValueOrDefault(nameof(Localization.Current)).Value?.ToString();
7272

7373
// 创建模型时,分析器确保了这些值不为空。
7474
return new LocalizationGeneratingModel(rootNamespace, typeName, defaultLanguage, currentLanguage);

src/dotnetCampus.Localizations.Analyzer/Utils/CodeAnalysis/TemplateRegexes.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,28 @@ public static class TemplateRegexes
3333
public static Regex Flag2Regex => _flag2Regex ??= GetFlag2Regex();
3434

3535
private static Regex GetFlagRegex() => _flagRegex ??= new Regex(@"\s+// <FLAG>.+?</FLAG>", RegexOptions.Compiled | RegexOptions.Singleline);
36-
private static Regex GetFlag2Regex() => _flagRegex ??= new Regex(@"\s+// <FLAG2>.+?</FLAG2>", RegexOptions.Compiled | RegexOptions.Singleline);
36+
private static Regex GetFlag2Regex() => _flag2Regex ??= new Regex(@"\s+// <FLAG2>.+?</FLAG2>", RegexOptions.Compiled | RegexOptions.Singleline);
3737
private static Regex GetTypeRegex() => _typeRegex ??= new Regex(@"\b(?:class|record|struct|enum|interface)\s([\w_]+)\b", RegexOptions.Compiled);
38+
39+
/// <summary>
40+
/// 替换代码中的 // <FLAG>...</FLAG> 注释,将其替换为指定的内容。
41+
/// </summary>
42+
/// <param name="content">包含要替换的代码的字符串。</param>
43+
/// <param name="flagContent">要替换的内容。</param>
44+
/// <returns>替换后的字符串。</returns>
45+
public static string FlagReplace(this string content, string flagContent)
46+
{
47+
return FlagRegex.Replace(content, flagContent);
48+
}
49+
50+
/// <summary>
51+
/// 替换代码中的 // <FLAG2>...</FLAG2> 注释,将其替换为指定的内容。
52+
/// </summary>
53+
/// <param name="content">包含要替换的代码的字符串。</param>
54+
/// <param name="flagContent">要替换的内容。</param>
55+
/// <returns>替换后的字符串。</returns>
56+
public static string Flag2Replace(this string content, string flagContent)
57+
{
58+
return Flag2Regex.Replace(content, flagContent);
59+
}
3860
}

0 commit comments

Comments
 (0)