diff --git a/src/AtomUI.Controls/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageResourceConst.g.cs b/src/AtomUI.Controls/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageResourceConst.g.cs new file mode 100644 index 0000000..6d2e2a3 --- /dev/null +++ b/src/AtomUI.Controls/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageResourceConst.g.cs @@ -0,0 +1,9 @@ +using AtomUI.Theme; + +namespace AtomUI.Controls.Lang +{ + public static class LoadingIndicatorLangResourceKey + { + public static readonly LanguageResourceKey LoadingText = new LanguageResourceKey("LoadingIndicator.LoadingText", "AtomUI.Token"); + } +} \ No newline at end of file diff --git a/src/AtomUI.Generator/Language/LangResourceKeyClassSourceWriter.cs b/src/AtomUI.Generator/Language/LangResourceKeyClassSourceWriter.cs new file mode 100644 index 0000000..966d844 --- /dev/null +++ b/src/AtomUI.Generator/Language/LangResourceKeyClassSourceWriter.cs @@ -0,0 +1,141 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace AtomUI.Generator.Language; + +public class LangResourceKeyClassSourceWriter +{ + private SourceProductionContext _context; + private List _languageInfos; + private List _usingInfos; + private Dictionary> _languagesById; + + public LangResourceKeyClassSourceWriter(SourceProductionContext context, List languageInfos) + { + _context = context; + _languageInfos = languageInfos; + _languagesById = new Dictionary>(); + _usingInfos = new List(); + SetupUsingInfos(); + BuildLanguageKeys(); + } + + private void BuildLanguageKeys() + { + foreach (var languageInfo in _languageInfos) { + if (!_languagesById.ContainsKey(languageInfo.LanguageId)) { + _languagesById[languageInfo.LanguageId] = new List(); + } + _languagesById[languageInfo.LanguageId].Add(languageInfo); + } + } + + private void SetupUsingInfos() + { + _usingInfos.Add("AtomUI.Theme"); + } + + public void Write() + { + var compilationUnitSyntax = BuildCompilationUnitSyntax(); + _context.AddSource($"LanguageResourceConst.g.cs", compilationUnitSyntax.NormalizeWhitespace().ToFullString()); + } + + private ClassDeclarationSyntax BuildClassSyntax(string className) + { + var modifiers = new List() + { + SyntaxFactory.Token(SyntaxKind.PublicKeyword), + SyntaxFactory.Token(SyntaxKind.StaticKeyword) + }; + var classSyntax = SyntaxFactory.ClassDeclaration(className) + .AddModifiers(modifiers.ToArray()); + return classSyntax; + } + + private FieldDeclarationSyntax BuildResourceKeyFieldSyntax(string catalog, string name, string value) + { + var modifiers = new List() + { + SyntaxFactory.Token(SyntaxKind.PublicKeyword), + SyntaxFactory.Token(SyntaxKind.StaticKeyword), + SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword) + }; + + var resourceKeyType = SyntaxFactory.ParseTypeName("LanguageResourceKey"); + var argument = SyntaxFactory.Argument( + SyntaxFactory.LiteralExpression( + SyntaxKind.StringLiteralExpression, + SyntaxFactory.Literal($"{value}"))); + + var nsArgument = SyntaxFactory.Argument( + SyntaxFactory.LiteralExpression( + SyntaxKind.StringLiteralExpression, + SyntaxFactory.Literal($"{catalog}"))); + + var resourceKeyInstanceExpr = SyntaxFactory.ObjectCreationExpression(resourceKeyType) + .WithArgumentList(SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new SyntaxNodeOrToken[] + { + argument, + SyntaxFactory.Token(SyntaxKind.CommaToken), + nsArgument + }))); + + var fieldSyntax = SyntaxFactory.FieldDeclaration(SyntaxFactory.VariableDeclaration(resourceKeyType) + .WithVariables(SyntaxFactory.SingletonSeparatedList( + SyntaxFactory.VariableDeclarator(name) + .WithInitializer( + SyntaxFactory.EqualsValueClause(resourceKeyInstanceExpr))))) + .AddModifiers(modifiers.ToArray()); + return fieldSyntax; + } + + private NamespaceDeclarationSyntax BuildLanguageResourceKey(List languages) + { + var targetNamespace = languages.First().Namespace; + var catalog = languages.First().ResourceCatalog; + var languageId = languages.First().LanguageId; + + var keys = new HashSet(); + foreach (var languageInfo in languages) { + keys.UnionWith(languageInfo.Items.Keys); + } + + var namespaceSyntax = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(targetNamespace)); + + var className = $"{languageId}LangResourceKey"; + + var classSyntax = BuildClassSyntax(className); + var resourceKeyFields = new List(); + foreach (var key in keys) { + resourceKeyFields.Add(BuildResourceKeyFieldSyntax(catalog, key, $"{languageId}.{key}")); + } + + classSyntax = classSyntax.AddMembers(resourceKeyFields.ToArray()); + namespaceSyntax = namespaceSyntax.AddMembers(classSyntax); + return namespaceSyntax; + } + + private CompilationUnitSyntax BuildCompilationUnitSyntax() + { + var compilationUnit = SyntaxFactory.CompilationUnit(); + + var usingSyntaxList = new List(); + + foreach (var usingInfo in _usingInfos) { + var usingSyntax = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(usingInfo)); + usingSyntaxList.Add(usingSyntax); + } + + compilationUnit = compilationUnit.AddUsings(usingSyntaxList.ToArray()); + + foreach (var entry in _languagesById) { + if (entry.Value.Count > 0) { + var namespaceDeclSyntax = BuildLanguageResourceKey(entry.Value); + compilationUnit = compilationUnit.AddMembers(namespaceDeclSyntax); + } + } + return compilationUnit; + } +} \ No newline at end of file diff --git a/src/AtomUI.Generator/Language/LanguageProviderWalker.cs b/src/AtomUI.Generator/Language/LanguageProviderWalker.cs index 1c41a4c..63f79ab 100644 --- a/src/AtomUI.Generator/Language/LanguageProviderWalker.cs +++ b/src/AtomUI.Generator/Language/LanguageProviderWalker.cs @@ -47,6 +47,15 @@ public class LanguageProviderWalker : CSharpSyntaxWalker } } + var ns = string.Empty; + if (node.Parent is FileScopedNamespaceDeclarationSyntax fileScopedNamespaceDecl) { + ns = fileScopedNamespaceDecl.Name.ToString(); + } else if (node.Parent is NamespaceDeclarationSyntax namespaceDecl) { + ns = namespaceDecl.Name.ToString(); + } + + LanguageInfo.Namespace = ns; + base.VisitClassDeclaration(node); } } \ No newline at end of file diff --git a/src/AtomUI.Generator/Language/ResourceKeyClassSourceWriter.cs b/src/AtomUI.Generator/Language/ResourceKeyClassSourceWriter.cs deleted file mode 100644 index e91f97b..0000000 --- a/src/AtomUI.Generator/Language/ResourceKeyClassSourceWriter.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AtomUI.Generator.Language; - -public class ResourceKeyClassSourceWriter -{ - -} \ No newline at end of file diff --git a/src/AtomUI.Generator/LanguageGenerator.cs b/src/AtomUI.Generator/LanguageGenerator.cs index 1f83326..9a0a39a 100644 --- a/src/AtomUI.Generator/LanguageGenerator.cs +++ b/src/AtomUI.Generator/LanguageGenerator.cs @@ -20,7 +20,8 @@ public class LanguageGenerator : IIncrementalGenerator }).Collect(); initContext.RegisterImplementationSourceOutput(languageProvider, (context, languageProviders) => { - + var classWriter = new LangResourceKeyClassSourceWriter(context, languageProviders.ToList()); + classWriter.Write(); }); } } \ No newline at end of file diff --git a/src/AtomUI.Generator/TokenInfo/ResourceKeyClassSourceWriter.cs b/src/AtomUI.Generator/TokenInfo/ResourceKeyClassSourceWriter.cs index becfeff..7f31b84 100644 --- a/src/AtomUI.Generator/TokenInfo/ResourceKeyClassSourceWriter.cs +++ b/src/AtomUI.Generator/TokenInfo/ResourceKeyClassSourceWriter.cs @@ -60,7 +60,7 @@ public class ResourceKeyClassSourceWriter var nsArgument = SyntaxFactory.Argument( SyntaxFactory.LiteralExpression( SyntaxKind.StringLiteralExpression, - SyntaxFactory.Literal($"{tokenName.ResourceNamespace}"))); + SyntaxFactory.Literal($"{tokenName.ResourceCatalog}"))); var resourceKeyInstanceExpr = SyntaxFactory.ObjectCreationExpression(resourceKeyType) .WithArgumentList(SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new SyntaxNodeOrToken[] diff --git a/src/AtomUI.Generator/TokenInfo/TokenInfo.cs b/src/AtomUI.Generator/TokenInfo/TokenInfo.cs index 5ea00b8..4f40a77 100644 --- a/src/AtomUI.Generator/TokenInfo/TokenInfo.cs +++ b/src/AtomUI.Generator/TokenInfo/TokenInfo.cs @@ -38,11 +38,11 @@ public class TokenInfo public record TokenName { public string Name { get; } - public string ResourceNamespace { get; } + public string ResourceCatalog { get; } - public TokenName(string name, string resourceNamespace) + public TokenName(string name, string catalog) { Name = name; - ResourceNamespace = resourceNamespace; + ResourceCatalog = catalog; } } \ No newline at end of file diff --git a/src/AtomUI.Theme/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageResourceConst.g.cs b/src/AtomUI.Theme/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageResourceConst.g.cs new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/src/AtomUI.Theme/GeneratedFiles/AtomUI.Generator/AtomUI.Generator.LanguageGenerator/LanguageResourceConst.g.cs @@ -0,0 +1 @@ + \ No newline at end of file