Files
ResourceString.Net.Contract/ResourceString.Net/Generator.cs

56 lines
2.2 KiB
C#

using Microsoft.CodeAnalysis;
using ResourceString.Net.Logic.Factories;
using ResourceString.Net.Logic.Parsers.Resx;
namespace ResourceString.Net;
[Generator]
public class Generator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext initContext)
{
// find all additional files that end with .txt
var resxFiles = initContext.AdditionalTextsProvider.Where(static file => file.Path.EndsWith(".resx"));
var assemblies = initContext.CompilationProvider.Select(static (c, _) => c.Assembly);
// read their contents and save their name
var config = resxFiles.Combine(assemblies).Select(
(t, cancellationToken) => (
name: System.IO.Path.GetFileNameWithoutExtension(t.Left.Path),
content: t.Left.GetText(cancellationToken)!.ToString(),
assembly: t.Right,
path: t.Left.Path
)
);
// generate a class that contains their values as const strings
initContext.RegisterSourceOutput(config, (spc, t) =>
{
Parser.TryParse(t.content).IfSome(v =>
{
var relativeNamespace = System.IO.Path.GetDirectoryName(t.path).Substring(
System.IO.Path.GetDirectoryName(t.assembly.Locations[0].GetLineSpan().Path).Length
).Trim(System.IO.Path.DirectorySeparatorChar).Replace(System.IO.Path.DirectorySeparatorChar, '.');
var ns = string.IsNullOrWhiteSpace(relativeNamespace)
? t.assembly.Name
: $"{t.assembly.Name}.{relativeNamespace}";
var resourceFileName = t.name;
var className = CodeSnippetFactory.TransformToClassName(t.name);
var snippet = CodeSnippetFactory.CreateResourceClassCodeSnippet(
CodeSnippetFactory.TransformToNamespace(ns),
className,
CodeSnippetFactory.CreateResourceMangerMemberCodeSnippet(
$"{ns}.{resourceFileName}",
className
),
v.Resources
);
spc.AddSource($"{ns}.{className}", snippet.Value);
});
});
}
}