From 7556efdfdd286f385d7a12f03bdf18eef01bad41 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Thu, 6 Apr 2023 17:00:39 +0100 Subject: [PATCH] chore: add AutoOverload and OverloadType attribute --- .../MethodOverloadGenerator.cs | 22 ++++++++++ .../SourceGenerator/OverloadSyntaxReceiver.cs | 41 +++++++++++++++++++ .../AutoOverloadAttribute.cs | 6 +++ .../OverloadTypeAttribute.cs | 20 +++++++++ 4 files changed, 89 insertions(+) create mode 100644 tools/SourceGenerator/MethodOverloadGenerator.cs create mode 100644 tools/SourceGenerator/OverloadSyntaxReceiver.cs create mode 100644 tools/X10D.MetaServices/AutoOverloadAttribute.cs create mode 100644 tools/X10D.MetaServices/OverloadTypeAttribute.cs diff --git a/tools/SourceGenerator/MethodOverloadGenerator.cs b/tools/SourceGenerator/MethodOverloadGenerator.cs new file mode 100644 index 0000000..cf05a35 --- /dev/null +++ b/tools/SourceGenerator/MethodOverloadGenerator.cs @@ -0,0 +1,22 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace SourceGenerator; + +[Generator] +internal sealed class MethodOverloadGenerator : ISourceGenerator +{ + /// + public void Initialize(GeneratorInitializationContext context) + { + context.RegisterForSyntaxNotifications(() => new OverloadSyntaxReceiver()); + } + + /// + public void Execute(GeneratorExecutionContext context) + { + var syntaxReceiver = (OverloadSyntaxReceiver)context.SyntaxReceiver!; + IReadOnlyList candidateMethods = syntaxReceiver.CandidateMethods; + // TODO implement + } +} diff --git a/tools/SourceGenerator/OverloadSyntaxReceiver.cs b/tools/SourceGenerator/OverloadSyntaxReceiver.cs new file mode 100644 index 0000000..cfe4668 --- /dev/null +++ b/tools/SourceGenerator/OverloadSyntaxReceiver.cs @@ -0,0 +1,41 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using X10D.MetaServices; + +namespace SourceGenerator; + +public class OverloadSyntaxReceiver : ISyntaxReceiver +{ + private readonly List _candidateMethods = new(); + + public IReadOnlyList CandidateMethods + { + get => _candidateMethods.AsReadOnly(); + } + + public void OnVisitSyntaxNode(SyntaxNode syntaxNode) + { + if (syntaxNode is not MethodDeclarationSyntax methodDeclarationSyntax) + { + return; + } + + if (methodDeclarationSyntax.AttributeLists.Count == 0) + { + return; + } + + string attributeName = nameof(AutoOverloadAttribute).Replace("Attribute", string.Empty); + foreach (AttributeListSyntax attributeListSyntax in methodDeclarationSyntax.AttributeLists) + { + foreach (AttributeSyntax attributeSyntax in attributeListSyntax.Attributes) + { + if (attributeSyntax.Name.ToString() == attributeName) + { + _candidateMethods.Add(methodDeclarationSyntax); + break; + } + } + } + } +} diff --git a/tools/X10D.MetaServices/AutoOverloadAttribute.cs b/tools/X10D.MetaServices/AutoOverloadAttribute.cs new file mode 100644 index 0000000..5630c84 --- /dev/null +++ b/tools/X10D.MetaServices/AutoOverloadAttribute.cs @@ -0,0 +1,6 @@ +namespace X10D.MetaServices; + +[AttributeUsage(AttributeTargets.Method, Inherited = false)] +public sealed class AutoOverloadAttribute : Attribute +{ +} diff --git a/tools/X10D.MetaServices/OverloadTypeAttribute.cs b/tools/X10D.MetaServices/OverloadTypeAttribute.cs new file mode 100644 index 0000000..d938a5b --- /dev/null +++ b/tools/X10D.MetaServices/OverloadTypeAttribute.cs @@ -0,0 +1,20 @@ +namespace X10D.MetaServices; + +[AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] +public sealed class OverloadTypeAttribute : Attribute +{ + /// + /// Initializes a new instance of the class. + /// + /// The types to overload. + public OverloadTypeAttribute(params Type[] types) + { + Types = (Type[])types.Clone(); + } + + /// + /// Gets an array of types to overload. + /// + /// An array of types to overload. + public Type[] Types { get; } +}