This repository has been archived on 2023-02-02. You can view files and clone it, but cannot push or open issues or pull requests.
mfgames-nitride-cil/src/MfGames.Nitride.Generators/SingletonComponentSourceGen...

92 lines
3.1 KiB
C#

using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace MfGames.Nitride.Generators;
/// <summary>
/// Implements a source generator that creates the additional properties
/// and methods for a singleton component including the constructor and
/// instance methods, along with extension methods for adding them to entities.
/// </summary>
[Generator]
public class SingletonComponentSourceGenerator
: ClassAttributeSourceGeneratorBase<SingletonComponentSyntaxReceiver>
{
protected override SingletonComponentSyntaxReceiver CreateSyntaxReceiver(
GeneratorInitializationContext context)
{
return new SingletonComponentSyntaxReceiver(context);
}
protected override void GenerateClassFile(
GeneratorExecutionContext context,
ClassAttributeReference unit)
{
// Pull out some fields.
ClassDeclarationSyntax cds = unit.ClassDeclaration;
// Create the partial class.
StringBuilder buffer = new();
buffer.AppendLine("#nullable enable");
// Copy the using statements from the file.
foreach (UsingDirectiveSyntax? uds in unit.UsingDirectiveList)
{
buffer.AppendLine(uds.ToString());
}
buffer.AppendLine();
// Create the namespace.
SyntaxToken cls = cds.Identifier;
buffer.AppendLine(
string.Join(
"\n",
$"using MfGames.Gallium;",
$"",
$"namespace {unit.Namespace}",
$"{{",
$" public partial class {cls}",
$" {{",
$" static {cls}()",
$" {{",
$" Instance = new {cls}();",
$" }}",
$"",
$" private {cls}()",
$" {{",
$" }}",
$"",
$" public static {cls} Instance {{ get; }}",
$" }}",
$"",
$" public static class {cls}Extensions",
$" {{",
$" public static bool Has{cls}(this Entity entity)",
$" {{",
$" return entity.Has<{cls}>();",
$" }}",
$"",
$" public static Entity Remove{cls}(this Entity entity)",
$" {{",
$" return entity.Remove<{cls}>();",
$" }}",
$"",
$" public static Entity Set{cls}(this Entity entity)",
$" {{",
$" return entity.Set({cls}.Instance);",
$" }}",
$" }}",
$"}}",
""));
// Create the source text and write out the file.
var sourceText = SourceText.From(buffer.ToString(), Encoding.UTF8);
context.AddSource(cls + ".Generated.cs", sourceText);
}
}