diff --git a/src/KubeOps.Generator/SyntaxReceiver/EntityControllerSyntaxReceiver.cs b/src/KubeOps.Generator/SyntaxReceiver/EntityControllerSyntaxReceiver.cs index 08351ab8..366056ef 100644 --- a/src/KubeOps.Generator/SyntaxReceiver/EntityControllerSyntaxReceiver.cs +++ b/src/KubeOps.Generator/SyntaxReceiver/EntityControllerSyntaxReceiver.cs @@ -11,6 +11,10 @@ internal sealed class EntityControllerSyntaxReceiver : ISyntaxContextReceiver { private const string IEntityControllerMetadataName = "KubeOps.Abstractions.Reconciliation.Controller.IEntityController`1"; +#pragma warning disable RS1024 + private readonly HashSet _visitedTypeSymbols = new(SymbolEqualityComparer.Default); +#pragma warning restore RS1024 + public List<(ClassDeclarationSyntax Controller, string EntityName)> Controllers { get; } = []; public void OnVisitSyntaxNode(GeneratorSyntaxContext context) @@ -25,6 +29,11 @@ public void OnVisitSyntaxNode(GeneratorSyntaxContext context) return; } + if (!_visitedTypeSymbols.Add(classSymbol)) + { + return; + } + if (classSymbol.IsAbstract) { return; diff --git a/src/KubeOps.Generator/SyntaxReceiver/EntityFinalizerSyntaxReceiver.cs b/src/KubeOps.Generator/SyntaxReceiver/EntityFinalizerSyntaxReceiver.cs index 9f07e3a8..e445500c 100644 --- a/src/KubeOps.Generator/SyntaxReceiver/EntityFinalizerSyntaxReceiver.cs +++ b/src/KubeOps.Generator/SyntaxReceiver/EntityFinalizerSyntaxReceiver.cs @@ -11,6 +11,10 @@ internal sealed class EntityFinalizerSyntaxReceiver : ISyntaxContextReceiver { private const string IEntityFinalizerMetadataName = "KubeOps.Abstractions.Reconciliation.Finalizer.IEntityFinalizer`1"; +#pragma warning disable RS1024 + private readonly HashSet _visitedTypeSymbols = new(SymbolEqualityComparer.Default); +#pragma warning restore RS1024 + public List<(ClassDeclarationSyntax Finalizer, string EntityName)> Finalizer { get; } = []; public void OnVisitSyntaxNode(GeneratorSyntaxContext context) @@ -25,6 +29,11 @@ public void OnVisitSyntaxNode(GeneratorSyntaxContext context) return; } + if (!_visitedTypeSymbols.Add(classSymbol)) + { + return; + } + if (classSymbol.IsAbstract) { return; diff --git a/test/KubeOps.Generator.Test/ControllerRegistrationGenerator.Test.cs b/test/KubeOps.Generator.Test/ControllerRegistrationGenerator.Test.cs index 021bb047..c3bc81e9 100644 --- a/test/KubeOps.Generator.Test/ControllerRegistrationGenerator.Test.cs +++ b/test/KubeOps.Generator.Test/ControllerRegistrationGenerator.Test.cs @@ -88,6 +88,40 @@ public sealed class V1TestEntityController : EntityControllerBase #pragma warning disable CS1591 using KubeOps.Abstractions.Builder; + public static class ControllerRegistrations + { + public static IOperatorBuilder RegisterControllers(this IOperatorBuilder builder) + { + builder.AddController(); + return builder; + } + } + """)] + [InlineData(""" + using k8s; + using k8s.Models; + using KubeOps.Abstractions.Reconciliation.Controller; + + [KubernetesEntity(Group = "testing.dev", ApiVersion = "v1", Kind = "TestEntity")] + public sealed class V1TestEntity : IKubernetesObject + { + } + + public partial class V1TestEntityController : IEntityController + { + } + + public partial class V1TestEntityController + { + } + """, """ + // + // This code was generated by a tool. + // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. + // + #pragma warning disable CS1591 + using KubeOps.Abstractions.Builder; + public static class ControllerRegistrations { public static IOperatorBuilder RegisterControllers(this IOperatorBuilder builder) diff --git a/test/KubeOps.Generator.Test/FinalizerRegistrationGenerator.Test.cs b/test/KubeOps.Generator.Test/FinalizerRegistrationGenerator.Test.cs index fca9af3c..1956ed01 100644 --- a/test/KubeOps.Generator.Test/FinalizerRegistrationGenerator.Test.cs +++ b/test/KubeOps.Generator.Test/FinalizerRegistrationGenerator.Test.cs @@ -147,6 +147,41 @@ public sealed class V1TestEntity : IKubernetesObject { } + public partial class V1TestEntityFinalizer : IEntityFinalizer + { + } + + public partial class V1TestEntityFinalizer : IEntityFinalizer + { + } + """, """ + // + // This code was generated by a tool. + // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. + // + #pragma warning disable CS1591 + using KubeOps.Abstractions.Builder; + + public static class FinalizerRegistrations + { + public const string V1TestEntityFinalizerIdentifier = "testing.dev/v1testentityfinalizer"; + public static IOperatorBuilder RegisterFinalizers(this IOperatorBuilder builder) + { + builder.AddFinalizer(V1TestEntityFinalizerIdentifier); + return builder; + } + } + """)] + [InlineData(""" + using k8s; + using k8s.Models; + using KubeOps.Abstractions.Reconciliation.Finalizer; + + [KubernetesEntity(Group = "testing.dev", ApiVersion = "v1", Kind = "TestEntity")] + public sealed class V1TestEntity : IKubernetesObject + { + } + public sealed class V1TestEntityCleanupDeployment : IEntityFinalizer { }