From 4bdfa16c114facf663b0b163a0c8728b82735729 Mon Sep 17 00:00:00 2001 From: Bohan Feng Date: Mon, 13 Apr 2026 23:58:55 +0800 Subject: [PATCH 1/2] feat: add Partial keyword fluent API for partial classes Expose the existing Partial keyword through TypeOption and NamespaceOption properties, and add NestedClass extension on KeywordOptionConfigurator. This enables convenient fluent syntax like ns.Partial.Class(...), ns.Public.Static.Partial.Class(...), and parent.Partial.NestedClass(...). Closes #7 Co-Authored-By: Claude Opus 4.6 --- .../Csharp/PartialKeywordTests.cs | 140 ++++++++++++++++++ EasyCodeBuilder/Csharp/NamespaceOption.cs | 5 + .../OptionConfigurations.cs | 42 ++++++ EasyCodeBuilder/Csharp/TypeOption.cs | 5 + 4 files changed, 192 insertions(+) create mode 100644 EasyCodeBuilder.Test/Csharp/PartialKeywordTests.cs diff --git a/EasyCodeBuilder.Test/Csharp/PartialKeywordTests.cs b/EasyCodeBuilder.Test/Csharp/PartialKeywordTests.cs new file mode 100644 index 0000000..08fd2d4 --- /dev/null +++ b/EasyCodeBuilder.Test/Csharp/PartialKeywordTests.cs @@ -0,0 +1,140 @@ +using Fengb3.EasyCodeBuilder.Csharp; +using Fengb3.EasyCodeBuilder.Csharp.OptionConfigurations; +using Xunit.Abstractions; + +namespace EasyCodeBuilder.Test.Csharp; + +public class PartialKeywordTests(ITestOutputHelper testOutputHelper) +{ + private static string Normalize(string text) => text.Replace("\r\n", "\n").Trim(); + + [Fact] + public void TestPartialClassInNamespace() + { + var @namespace = new NamespaceOption() + .WithName("MyNamespace") + .Partial.Class(cls => + { + cls.WithName("MyClass"); + }); + + var code = @namespace.Build(); + + const string expected = + """ + namespace MyNamespace + { + partial class MyClass + { + } + } + """; + + Assert.Equal(Normalize(expected), Normalize(code)); + testOutputHelper.WriteLine(code); + } + + [Fact] + public void TestPublicPartialClass() + { + var @namespace = new NamespaceOption() + .WithName("MyNamespace") + .Public.Partial.Class(cls => + { + cls.WithName("MyClass"); + }); + + var code = @namespace.Build(); + + const string expected = + """ + namespace MyNamespace + { + public partial class MyClass + { + } + } + """; + + Assert.Equal(Normalize(expected), Normalize(code)); + testOutputHelper.WriteLine(code); + } + + [Fact] + public void TestPublicStaticPartialClass() + { + var @namespace = new NamespaceOption() + .WithName("MyNamespace") + .Public.Static.Partial.Class(cls => + { + cls.WithName("MyClass"); + }); + + var code = @namespace.Build(); + + const string expected = + """ + namespace MyNamespace + { + public static partial class MyClass + { + } + } + """; + + Assert.Equal(Normalize(expected), Normalize(code)); + testOutputHelper.WriteLine(code); + } + + [Fact] + public void TestPartialNestedClass() + { + var code = new TypeOption() + .WithTypeKind(TypeOption.Type.Class) + .WithName("OuterClass") + .WithKeywords("public") + .Partial.NestedClass(nc => nc + .WithName("InnerClass") + ) + .Build(); + + const string expected = + """ + public class OuterClass + { + partial class InnerClass + { + } + } + """; + + Assert.Equal(Normalize(expected), Normalize(code)); + testOutputHelper.WriteLine(code); + } + + [Fact] + public void TestPublicPartialNestedClass() + { + var code = new TypeOption() + .WithTypeKind(TypeOption.Type.Class) + .WithName("OuterClass") + .WithKeywords("public") + .Public.Partial.NestedClass(nc => nc + .WithName("InnerClass") + ) + .Build(); + + const string expected = + """ + public class OuterClass + { + public partial class InnerClass + { + } + } + """; + + Assert.Equal(Normalize(expected), Normalize(code)); + testOutputHelper.WriteLine(code); + } +} diff --git a/EasyCodeBuilder/Csharp/NamespaceOption.cs b/EasyCodeBuilder/Csharp/NamespaceOption.cs index f17b1c2..b18203a 100644 --- a/EasyCodeBuilder/Csharp/NamespaceOption.cs +++ b/EasyCodeBuilder/Csharp/NamespaceOption.cs @@ -42,6 +42,11 @@ public override CodeBuilder Build(CodeBuilder cb) /// 私有访问修饰符配置器 /// public KeywordOptionConfigurator Private => Has.Private; + + /// + /// partial 修饰符配置器 + /// + public KeywordOptionConfigurator Partial => Has.Partial; } /// diff --git a/EasyCodeBuilder/Csharp/OptionConfigurations/OptionConfigurations.cs b/EasyCodeBuilder/Csharp/OptionConfigurations/OptionConfigurations.cs index 56763eb..45a34d5 100644 --- a/EasyCodeBuilder/Csharp/OptionConfigurations/OptionConfigurations.cs +++ b/EasyCodeBuilder/Csharp/OptionConfigurations/OptionConfigurations.cs @@ -132,6 +132,48 @@ Action configure #endregion + #region Add nested type to type + + /// + /// 添加嵌套类 + /// + /// 关键字配置器 + /// 嵌套类选项配置委托 + /// 类型选项 + public static TypeOption NestedClass( + this KeywordOptionConfigurator configurator, + Func configure + ) + { + configurator.Parent.AddChild(to => + { + configurator.Configure(keyword => to.WithKeyword(keyword)); + configure(to); + }); + return configurator.Parent; + } + + /// + /// 添加嵌套类 + /// + /// 关键字配置器 + /// 嵌套类选项配置委托 + /// 类型选项 + public static TypeOption NestedClass( + this KeywordOptionConfigurator configurator, + Action configure + ) + { + configurator.Parent.AddChild(to => + { + configurator.Configure(keyword => to.WithKeyword(keyword)); + configure(to); + }); + return configurator.Parent; + } + + #endregion + #region Add member to type /// diff --git a/EasyCodeBuilder/Csharp/TypeOption.cs b/EasyCodeBuilder/Csharp/TypeOption.cs index 7756de8..c50add9 100644 --- a/EasyCodeBuilder/Csharp/TypeOption.cs +++ b/EasyCodeBuilder/Csharp/TypeOption.cs @@ -112,6 +112,11 @@ public override CodeBuilder Build(CodeBuilder cb) /// 静态修饰符配置器 /// public KeywordOptionConfigurator Static => KeywordConfigurator.Static; + + /// + /// partial 修饰符配置器 + /// + public KeywordOptionConfigurator Partial => KeywordConfigurator.Partial; } /// From d79bb689c1e044775d6c3e54f5bd1a553aab8c23 Mon Sep 17 00:00:00 2001 From: Bohan Feng <45181245+fengb3@users.noreply.github.com> Date: Tue, 14 Apr 2026 00:11:06 +0800 Subject: [PATCH 2/2] Update EasyCodeBuilder/Csharp/OptionConfigurations/OptionConfigurations.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../Csharp/OptionConfigurations/OptionConfigurations.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/EasyCodeBuilder/Csharp/OptionConfigurations/OptionConfigurations.cs b/EasyCodeBuilder/Csharp/OptionConfigurations/OptionConfigurations.cs index 45a34d5..3dcde6b 100644 --- a/EasyCodeBuilder/Csharp/OptionConfigurations/OptionConfigurations.cs +++ b/EasyCodeBuilder/Csharp/OptionConfigurations/OptionConfigurations.cs @@ -164,12 +164,11 @@ public static TypeOption NestedClass( Action configure ) { - configurator.Parent.AddChild(to => + return configurator.NestedClass(to => { - configurator.Configure(keyword => to.WithKeyword(keyword)); configure(to); + return to; }); - return configurator.Parent; } #endregion