From fb9569699e372e994b398c6c73647c968418a12e Mon Sep 17 00:00:00 2001 From: James Hughes Date: Sat, 4 Jan 2025 01:20:00 +0000 Subject: [PATCH] feat: Added support for generic method args --- .../DemoApiDefinition.fluid.yml | 3 +++ .../FluidGeneratorServiceTests.cs | 17 +++++++++-------- .../Definitions/FluidApiMethodDefinition.cs | 2 ++ src/SuperFluid/Internal/Model/FluidApiMethod.cs | 5 ++++- .../Parsers/FluidApiDefinitionParser.cs | 2 +- .../Internal/Services/FluidGeneratorService.cs | 10 +++++++--- 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/SuperFluid.Tests/DemoApiDefinition.fluid.yml b/src/SuperFluid.Tests/DemoApiDefinition.fluid.yml index b79cf40..40fce54 100644 --- a/src/SuperFluid.Tests/DemoApiDefinition.fluid.yml +++ b/src/SuperFluid.Tests/DemoApiDefinition.fluid.yml @@ -26,6 +26,9 @@ Methods: Type: "int" - Name: "direction" Type: "string" + GenericArguments: + # Pointless generic arg for testing + - "T" CanTransitionTo: - "Stop" - "Build" diff --git a/src/SuperFluid.Tests/SourceGenerators/FluidGeneratorServiceTests.cs b/src/SuperFluid.Tests/SourceGenerators/FluidGeneratorServiceTests.cs index bdc0949..c76d4d9 100644 --- a/src/SuperFluid.Tests/SourceGenerators/FluidGeneratorServiceTests.cs +++ b/src/SuperFluid.Tests/SourceGenerators/FluidGeneratorServiceTests.cs @@ -21,15 +21,16 @@ public void CanGenerateDemoApi() result["ICarActor.fluid.g.cs"].ShouldBe(CarActorSource); } + private const string CanLockOrEnterSource = """ - namespace SuperFluid.Tests.Cars; + namespace SuperFluid.Tests.Cars; - public interface ICanLockOrEnter - { - public ICanUnlock Lock(); - public ICanStartOrExit Enter(); - } - """; + public interface ICanLockOrEnter + { + public ICanUnlock Lock(); + public ICanStartOrExit Enter(); + } + """; private const string CanUnlockSource = """ namespace SuperFluid.Tests.Cars; @@ -45,7 +46,7 @@ namespace SuperFluid.Tests.Cars; public interface ICanStartOrExit { - public ICanStopOrBuild Start(int speed, string direction); + public ICanStopOrBuild Start(int speed, string direction); public ICanLockOrEnter Exit(); } """; diff --git a/src/SuperFluid/Internal/Definitions/FluidApiMethodDefinition.cs b/src/SuperFluid/Internal/Definitions/FluidApiMethodDefinition.cs index 459701d..953b579 100644 --- a/src/SuperFluid/Internal/Definitions/FluidApiMethodDefinition.cs +++ b/src/SuperFluid/Internal/Definitions/FluidApiMethodDefinition.cs @@ -10,4 +10,6 @@ internal record FluidApiMethodDefinition public List CanTransitionTo { get; init; } = new(); public List Arguments { get; init; } = new(); + + public List GenericArguments { get; init; } = new(); } diff --git a/src/SuperFluid/Internal/Model/FluidApiMethod.cs b/src/SuperFluid/Internal/Model/FluidApiMethod.cs index aa7e79b..db23543 100644 --- a/src/SuperFluid/Internal/Model/FluidApiMethod.cs +++ b/src/SuperFluid/Internal/Model/FluidApiMethod.cs @@ -5,12 +5,13 @@ namespace SuperFluid.Internal.Model; [DebuggerDisplay("{Name}")] internal record FluidApiMethod { - public FluidApiMethod(string name, string? returnType, IEnumerable transitions, IEnumerable args) + public FluidApiMethod(string name, string? returnType, IEnumerable transitions, IEnumerable args, IEnumerable genericArgs) { Name = name; ReturnType = returnType; Arguments = [..args]; CanTransitionTo = [..transitions]; + GenericArguments = [..genericArgs]; } internal string Name { get; init; } @@ -19,5 +20,7 @@ public FluidApiMethod(string name, string? returnType, IEnumerable CanTransitionTo { get; init; } = new(); internal HashSet Arguments { get; init; } = new(); + + internal HashSet GenericArguments { get; init; } = new(); } diff --git a/src/SuperFluid/Internal/Parsers/FluidApiDefinitionParser.cs b/src/SuperFluid/Internal/Parsers/FluidApiDefinitionParser.cs index 7fe9477..0fa0b14 100644 --- a/src/SuperFluid/Internal/Parsers/FluidApiDefinitionParser.cs +++ b/src/SuperFluid/Internal/Parsers/FluidApiDefinitionParser.cs @@ -87,7 +87,7 @@ private FluidApiMethod FindOrCreateMethod(FluidApiDefinition definition, FluidAp List args = method.Arguments.Select(a => new FluidApiArgument(a.Name, a.Type)).ToList(); - FluidApiMethod newMethod = new(method.Name, method.ReturnType, Array.Empty(), args); + FluidApiMethod newMethod = new(method.Name, method.ReturnType, Array.Empty(), args, method.GenericArguments); stateDict.Add(method, newMethod); List transitionDefinitions = method.CanTransitionTo.Select(m => definition.Methods.Single(d => d.Name == m)).ToList(); diff --git a/src/SuperFluid/Internal/Services/FluidGeneratorService.cs b/src/SuperFluid/Internal/Services/FluidGeneratorService.cs index fd2a8cb..9acdb43 100644 --- a/src/SuperFluid/Internal/Services/FluidGeneratorService.cs +++ b/src/SuperFluid/Internal/Services/FluidGeneratorService.cs @@ -45,9 +45,13 @@ public interface {{model.Name}}: {{string.Join(",", model.States.Select(s => s.N private string GenerateStateSource(FluidApiState fluidApiState, FluidApiModel model) { IEnumerable methodDeclarations = fluidApiState.MethodTransitions.Select(kvp - => $""" - public {kvp.Key.ReturnType ?? kvp.Value.Name} {kvp.Key.Name}({string.Join(", ", kvp.Key.Arguments.Select(a =>$"{a.Type} {a.Name}"))}); - """); + => + { + string genericArgs = kvp.Key.GenericArguments.Count > 0 ? $"<{string.Join(", ", kvp.Key.GenericArguments.Select(a => $"{a}"))}>" : string.Empty; + return $""" + public {kvp.Key.ReturnType ?? kvp.Value.Name} {kvp.Key.Name}{genericArgs}({string.Join(", ", kvp.Key.Arguments.Select(a => $"{a.Type} {a.Name}"))}); + """; + }); string source = $$""" namespace {{model.Namespace}};