feat: implemented SingletonComponent to wrap most of the Is* components
This commit is contained in:
parent
a5694d0cee
commit
e02c56e77e
21 changed files with 276 additions and 138 deletions
12
flake.lock
12
flake.lock
|
@ -2,11 +2,11 @@
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1659877975,
|
"lastModified": 1667395993,
|
||||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -17,11 +17,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1662019588,
|
"lastModified": 1673631141,
|
||||||
"narHash": "sha256-oPEjHKGGVbBXqwwL+UjsveJzghWiWV0n9ogo1X6l4cw=",
|
"narHash": "sha256-AprpYQ5JvLS4wQG/ghm2UriZ9QZXvAwh1HlgA/6ZEVQ=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "2da64a81275b68fdad38af669afeda43d401e94b",
|
"rev": "befc83905c965adfd33e5cae49acb0351f6e0404",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
using MfGames.Nitride.Generators;
|
||||||
|
|
||||||
namespace MfGames.Nitride.Calendar;
|
namespace MfGames.Nitride.Calendar;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A marker component for identifying an entity that represents a calendar.
|
/// A marker component for identifying an entity that represents a calendar.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record IsCalendar
|
[SingletonComponent]
|
||||||
|
public partial class IsCalendar
|
||||||
{
|
{
|
||||||
public static IsCalendar Instance { get; } = new();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
|
using MfGames.Nitride.Generators;
|
||||||
|
|
||||||
namespace MfGames.Nitride.Feeds;
|
namespace MfGames.Nitride.Feeds;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A marker component that indicates this page is a feed.
|
/// A marker component that indicates this page is a feed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsFeed
|
[SingletonComponent]
|
||||||
|
public partial class IsFeed
|
||||||
{
|
{
|
||||||
public IsFeed()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IsFeed Instance { get; } = new();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
using MfGames.Nitride.Generators;
|
||||||
|
|
||||||
namespace MfGames.Nitride.Gemtext;
|
namespace MfGames.Nitride.Gemtext;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A marker component for indicating that an entity is Gemtext, the format
|
/// A marker component for indicating that an entity is Gemtext, the format
|
||||||
/// for text files using the Gemini protocol.
|
/// for text files using the Gemini protocol.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record IsGemtext
|
[SingletonComponent]
|
||||||
|
public partial class IsGemtext
|
||||||
{
|
{
|
||||||
public static IsGemtext Instance { get; } = new();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ namespace MfGames.Nitride.Generators;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Internal class that consolidates all of the information needed to generate a
|
/// Internal class that consolidates all of the information needed to generate a
|
||||||
/// file.
|
/// class for adding With* properties.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class WithPropertyClass
|
public class ClassAttributeReference
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the syntax for the class declaration.
|
/// Gets the syntax for the class declaration.
|
|
@ -0,0 +1,66 @@
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.Text;
|
||||||
|
|
||||||
|
namespace MfGames.Nitride.Generators;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for classes marked with an attribute.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ClassAttributeSourceGeneratorBase<TSyntaxReceiver>
|
||||||
|
: ISourceGenerator
|
||||||
|
where TSyntaxReceiver : ClassAttributeSyntaxReceiverBase
|
||||||
|
{
|
||||||
|
public void Execute(GeneratorExecutionContext context)
|
||||||
|
{
|
||||||
|
// Get the generator infrastructure will create a receiver and
|
||||||
|
// populate it we can retrieve the populated instance via the
|
||||||
|
// context.
|
||||||
|
if (context.SyntaxReceiver is not TSyntaxReceiver syntaxReceiver)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report any messages.
|
||||||
|
foreach (string? message in syntaxReceiver.Messages)
|
||||||
|
{
|
||||||
|
context.Warning(
|
||||||
|
MessageCode.Debug,
|
||||||
|
Location.Create(
|
||||||
|
"Temporary.g.cs",
|
||||||
|
TextSpan.FromBounds(0, 0),
|
||||||
|
new LinePositionSpan(
|
||||||
|
new LinePosition(0, 0),
|
||||||
|
new LinePosition(0, 0))),
|
||||||
|
"{0}: Syntax Message: {1}",
|
||||||
|
this.GetType().Name,
|
||||||
|
message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we didn't find anything, then there is nothing to do.
|
||||||
|
if (syntaxReceiver.ReferenceList.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go through each one.
|
||||||
|
foreach (ClassAttributeReference reference in syntaxReceiver
|
||||||
|
.ReferenceList)
|
||||||
|
{
|
||||||
|
this.GenerateClassFile(context, reference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(GeneratorInitializationContext context)
|
||||||
|
{
|
||||||
|
// Register a factory that can create our custom syntax receiver
|
||||||
|
context.RegisterForSyntaxNotifications(
|
||||||
|
() => this.CreateSyntaxReceiver(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract TSyntaxReceiver CreateSyntaxReceiver(
|
||||||
|
GeneratorInitializationContext context);
|
||||||
|
|
||||||
|
protected abstract void GenerateClassFile(
|
||||||
|
GeneratorExecutionContext context,
|
||||||
|
ClassAttributeReference reference);
|
||||||
|
}
|
|
@ -6,18 +6,26 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
|
||||||
namespace MfGames.Nitride.Generators;
|
namespace MfGames.Nitride.Generators;
|
||||||
|
|
||||||
internal class WithPropertySyntaxReceiver : ISyntaxReceiver
|
public abstract class ClassAttributeSyntaxReceiverBase : ISyntaxReceiver
|
||||||
{
|
{
|
||||||
|
private readonly string attributeName;
|
||||||
|
|
||||||
private readonly GeneratorInitializationContext context;
|
private readonly GeneratorInitializationContext context;
|
||||||
|
|
||||||
public WithPropertySyntaxReceiver(GeneratorInitializationContext context)
|
public ClassAttributeSyntaxReceiverBase(
|
||||||
|
GeneratorInitializationContext context,
|
||||||
|
string attributeName)
|
||||||
{
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.ClassList = new List<WithPropertyClass>();
|
this.attributeName = attributeName;
|
||||||
|
this.ReferenceList = new List<ClassAttributeReference>();
|
||||||
this.Messages = new List<string>();
|
this.Messages = new List<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<WithPropertyClass> ClassList { get; }
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether we should debug parsing attributes.
|
||||||
|
/// </summary>
|
||||||
|
public bool DebugAttributes { get; set; }
|
||||||
|
|
||||||
public List<string> Messages { get; }
|
public List<string> Messages { get; }
|
||||||
|
|
||||||
|
@ -26,6 +34,8 @@ internal class WithPropertySyntaxReceiver : ISyntaxReceiver
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Namespace { get; private set; }
|
public string? Namespace { get; private set; }
|
||||||
|
|
||||||
|
public List<ClassAttributeReference> ReferenceList { get; }
|
||||||
|
|
||||||
public List<UsingDirectiveSyntax> UsingDirectiveList { get; set; } = new();
|
public List<UsingDirectiveSyntax> UsingDirectiveList { get; set; } = new();
|
||||||
|
|
||||||
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
|
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
|
||||||
|
@ -64,21 +74,30 @@ internal class WithPropertySyntaxReceiver : ISyntaxReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if the class has our set properties attribute.
|
// See if the class has our set properties attribute.
|
||||||
bool found = cds.AttributeLists.AsEnumerable()
|
var attributes = cds.AttributeLists
|
||||||
|
.AsEnumerable()
|
||||||
.SelectMany(x => x.Attributes)
|
.SelectMany(x => x.Attributes)
|
||||||
.Select(x => x.Name.ToString())
|
.Select(x => x.Name.ToString())
|
||||||
|
.ToList();
|
||||||
|
bool found = attributes
|
||||||
.Any(
|
.Any(
|
||||||
x => x switch
|
x => x == this.attributeName
|
||||||
{
|
|| x == $"{this.attributeName}Attribute");
|
||||||
"WithProperties" => true,
|
|
||||||
"WithPropertiesAttribute" => true,
|
if (this.DebugAttributes)
|
||||||
_ => false,
|
{
|
||||||
});
|
this.Messages.Add(
|
||||||
|
string.Format(
|
||||||
|
"Parsing {0} found? {1} from attributes [{2}]",
|
||||||
|
cds.Identifier,
|
||||||
|
found,
|
||||||
|
string.Join(", ", attributes)));
|
||||||
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
this.ClassList.Add(
|
this.ReferenceList.Add(
|
||||||
new WithPropertyClass
|
new ClassAttributeReference
|
||||||
{
|
{
|
||||||
Namespace = this.Namespace!,
|
Namespace = this.Namespace!,
|
||||||
UsingDirectiveList = this.UsingDirectiveList,
|
UsingDirectiveList = this.UsingDirectiveList,
|
|
@ -18,7 +18,7 @@ public static class CodeAnalysisExtensions
|
||||||
this GeneratorExecutionContext context,
|
this GeneratorExecutionContext context,
|
||||||
MessageCode messageCode,
|
MessageCode messageCode,
|
||||||
string format,
|
string format,
|
||||||
params object[] parameters)
|
params object?[] parameters)
|
||||||
{
|
{
|
||||||
Error(context, messageCode, null, format, parameters);
|
Error(context, messageCode, null, format, parameters);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public static class CodeAnalysisExtensions
|
||||||
MessageCode messageCode,
|
MessageCode messageCode,
|
||||||
Location? location,
|
Location? location,
|
||||||
string format,
|
string format,
|
||||||
params object[] parameters)
|
params object?[] parameters)
|
||||||
{
|
{
|
||||||
context.Message(
|
context.Message(
|
||||||
messageCode,
|
messageCode,
|
||||||
|
@ -57,7 +57,7 @@ public static class CodeAnalysisExtensions
|
||||||
this GeneratorExecutionContext context,
|
this GeneratorExecutionContext context,
|
||||||
MessageCode messageCode,
|
MessageCode messageCode,
|
||||||
string format,
|
string format,
|
||||||
params object[] parameters)
|
params object?[] parameters)
|
||||||
{
|
{
|
||||||
Information(context, messageCode, null, format, parameters);
|
Information(context, messageCode, null, format, parameters);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ public static class CodeAnalysisExtensions
|
||||||
MessageCode messageCode,
|
MessageCode messageCode,
|
||||||
Location? location,
|
Location? location,
|
||||||
string format,
|
string format,
|
||||||
params object[] parameters)
|
params object?[] parameters)
|
||||||
{
|
{
|
||||||
context.Message(
|
context.Message(
|
||||||
messageCode,
|
messageCode,
|
||||||
|
@ -96,7 +96,7 @@ public static class CodeAnalysisExtensions
|
||||||
this GeneratorExecutionContext context,
|
this GeneratorExecutionContext context,
|
||||||
MessageCode messageCode,
|
MessageCode messageCode,
|
||||||
string format,
|
string format,
|
||||||
params object[] parameters)
|
params object?[] parameters)
|
||||||
{
|
{
|
||||||
Warning(context, messageCode, null, format, parameters);
|
Warning(context, messageCode, null, format, parameters);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ public static class CodeAnalysisExtensions
|
||||||
MessageCode messageCode,
|
MessageCode messageCode,
|
||||||
Location? location,
|
Location? location,
|
||||||
string format,
|
string format,
|
||||||
params object[] parameters)
|
params object?[] parameters)
|
||||||
{
|
{
|
||||||
context.Message(
|
context.Message(
|
||||||
messageCode,
|
messageCode,
|
||||||
|
@ -139,7 +139,7 @@ public static class CodeAnalysisExtensions
|
||||||
Location? location,
|
Location? location,
|
||||||
DiagnosticSeverity severity,
|
DiagnosticSeverity severity,
|
||||||
string format,
|
string format,
|
||||||
params object[] parameters)
|
params object?[] parameters)
|
||||||
{
|
{
|
||||||
context.ReportDiagnostic(
|
context.ReportDiagnostic(
|
||||||
Diagnostic.Create(
|
Diagnostic.Create(
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MfGames.Gallium" Version="0.3.0"/>
|
<PackageReference Include="MfGames.Gallium" Version="0.3.0" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.3.1"/>
|
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.3.1" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.1"/>
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.1" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.3.1"/>
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace MfGames.Nitride.Generators;
|
||||||
|
|
||||||
|
public class SingletonComponentSyntaxReceiver : ClassAttributeSyntaxReceiverBase
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public SingletonComponentSyntaxReceiver(
|
||||||
|
GeneratorInitializationContext context)
|
||||||
|
: base(context, "SingletonComponent")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,62 +15,22 @@ namespace MfGames.Nitride.Generators;
|
||||||
/// together calls.
|
/// together calls.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Generator]
|
[Generator]
|
||||||
public class WithPropertySourceGenerator : ISourceGenerator
|
public class WithPropertiesSourceGenerator
|
||||||
|
: ClassAttributeSourceGeneratorBase<WithPropertiesSyntaxReceiver>
|
||||||
{
|
{
|
||||||
public void Execute(GeneratorExecutionContext context)
|
/// <inheritdoc />
|
||||||
|
protected override WithPropertiesSyntaxReceiver CreateSyntaxReceiver(
|
||||||
|
GeneratorInitializationContext context)
|
||||||
{
|
{
|
||||||
// Get the generator infrastructure will create a receiver and
|
return new WithPropertiesSyntaxReceiver(context);
|
||||||
// populate it we can retrieve the populated instance via the
|
|
||||||
// context.
|
|
||||||
var syntaxReceiver =
|
|
||||||
(WithPropertySyntaxReceiver?)context.SyntaxReceiver;
|
|
||||||
|
|
||||||
if (syntaxReceiver == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Report any messages.
|
|
||||||
foreach (string? message in syntaxReceiver.Messages)
|
|
||||||
{
|
|
||||||
context.Information(
|
|
||||||
MessageCode.Debug,
|
|
||||||
Location.Create(
|
|
||||||
"Temporary.g.cs",
|
|
||||||
TextSpan.FromBounds(0, 0),
|
|
||||||
new LinePositionSpan(
|
|
||||||
new LinePosition(0, 0),
|
|
||||||
new LinePosition(0, 0))),
|
|
||||||
"Generating additional identifier code: {0}",
|
|
||||||
message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we didn't find anything, then there is nothing to do.
|
|
||||||
if (syntaxReceiver.ClassList.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through each one.
|
|
||||||
foreach (WithPropertyClass classInfo in syntaxReceiver.ClassList)
|
|
||||||
{
|
|
||||||
this.GenerateClassFile(context, classInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(GeneratorInitializationContext context)
|
protected override void GenerateClassFile(
|
||||||
{
|
|
||||||
// Register a factory that can create our custom syntax receiver
|
|
||||||
context.RegisterForSyntaxNotifications(
|
|
||||||
() => new WithPropertySyntaxReceiver(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GenerateClassFile(
|
|
||||||
GeneratorExecutionContext context,
|
GeneratorExecutionContext context,
|
||||||
WithPropertyClass unit)
|
ClassAttributeReference unit)
|
||||||
{
|
{
|
||||||
// Pull out some fields.
|
// Pull out some fields.
|
||||||
ClassDeclarationSyntax? cds = unit.ClassDeclaration;
|
ClassDeclarationSyntax cds = unit.ClassDeclaration;
|
||||||
|
|
||||||
// Create the partial class.
|
// Create the partial class.
|
||||||
StringBuilder buffer = new();
|
StringBuilder buffer = new();
|
||||||
|
@ -100,9 +60,8 @@ public class WithPropertySourceGenerator : ISourceGenerator
|
||||||
foreach (PropertyDeclarationSyntax pds in properties)
|
foreach (PropertyDeclarationSyntax pds in properties)
|
||||||
{
|
{
|
||||||
// See if we have a setter.
|
// See if we have a setter.
|
||||||
bool found =
|
bool found = pds.AccessorList?.Accessors
|
||||||
pds.AccessorList?.Accessors.Any(
|
.Any(x => x.Keyword.ToString() == "set")
|
||||||
x => x.Keyword.ToString() == "set")
|
|
||||||
?? false;
|
?? false;
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
|
@ -0,0 +1,12 @@
|
||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace MfGames.Nitride.Generators;
|
||||||
|
|
||||||
|
public class WithPropertiesSyntaxReceiver : ClassAttributeSyntaxReceiverBase
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public WithPropertiesSyntaxReceiver(GeneratorInitializationContext context)
|
||||||
|
: base(context, "WithProperties")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,11 @@
|
||||||
|
using MfGames.Nitride.Generators;
|
||||||
|
|
||||||
namespace MfGames.Nitride.Html;
|
namespace MfGames.Nitride.Html;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A marker component that indicates that the entity is an HTML file.
|
/// A marker component that indicates that the entity is an HTML file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record IsHtml
|
[SingletonComponent]
|
||||||
|
public partial class IsHtml
|
||||||
{
|
{
|
||||||
public static IsHtml Instance { get; } = new();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,8 @@ public partial class AddPathPrefix : OperationBase
|
||||||
{
|
{
|
||||||
this.validator.ValidateAndThrow(this);
|
this.validator.ValidateAndThrow(this);
|
||||||
|
|
||||||
return this.replacePath.WithReplacement(this.RunReplacement)
|
return this.replacePath
|
||||||
|
.WithReplacement(this.RunReplacement)
|
||||||
.Run(input);
|
.Run(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
using MfGames.Nitride.Generators;
|
||||||
|
|
||||||
namespace MfGames.Nitride.Json;
|
namespace MfGames.Nitride.Json;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A marker class that indicates that the entity is JSON.
|
/// A marker class that indicates that the entity is JSON.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record IsJson
|
[SingletonComponent]
|
||||||
|
public partial class IsJson
|
||||||
{
|
{
|
||||||
public static IsJson Instance { get; } = new();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
using MfGames.Gallium;
|
|
||||||
|
|
||||||
namespace MfGames.Nitride.Json;
|
|
||||||
|
|
||||||
public static class IsJsonExtensions
|
|
||||||
{
|
|
||||||
public static Entity RemoveIsJson(this Entity entity)
|
|
||||||
{
|
|
||||||
return entity.Remove<IsJson>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Entity SetIsJson(this Entity entity)
|
|
||||||
{
|
|
||||||
return entity.Set(IsJson.Instance);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
using MfGames.Nitride.Generators;
|
||||||
|
|
||||||
namespace MfGames.Nitride.Markdown;
|
namespace MfGames.Nitride.Markdown;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A marker class that indicates that the file is a Markdown file.
|
/// A marker class that indicates that the file is a Markdown file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record IsMarkdown
|
[SingletonComponent]
|
||||||
|
public partial class IsMarkdown
|
||||||
{
|
{
|
||||||
public static IsMarkdown Instance { get; } = new();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
using MfGames.Nitride.Generators;
|
||||||
|
|
||||||
namespace MfGames.Nitride.Yaml;
|
namespace MfGames.Nitride.Yaml;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A marker class that indicates that the entity is YAML.
|
/// A marker class that indicates that the entity is YAML.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public record IsYaml
|
[SingletonComponent]
|
||||||
|
public partial class IsYaml
|
||||||
{
|
{
|
||||||
public static IsYaml Instance { get; } = new();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
using MfGames.Gallium;
|
|
||||||
|
|
||||||
namespace MfGames.Nitride.Yaml;
|
|
||||||
|
|
||||||
public static class IsYamlExtensions
|
|
||||||
{
|
|
||||||
public static Entity RemoveIsYaml(this Entity entity)
|
|
||||||
{
|
|
||||||
return entity.Remove<IsYaml>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Entity SetIsYaml(this Entity entity)
|
|
||||||
{
|
|
||||||
return entity.Set(IsYaml.Instance);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,12 +10,12 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\MfGames.Nitride\MfGames.Nitride.csproj"/>
|
<ProjectReference Include="..\MfGames.Nitride\MfGames.Nitride.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MfGames.Gallium" Version="0.3.0"/>
|
<PackageReference Include="MfGames.Gallium" Version="0.3.0" />
|
||||||
<PackageReference Include="YamlDotNet" Version="12.0.0"/>
|
<PackageReference Include="YamlDotNet" Version="12.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- Include the source generator -->
|
<!-- Include the source generator -->
|
||||||
|
|
Reference in a new issue