From aa47d7bf485d77ab597790ee5b6e0ace2d167f8b Mon Sep 17 00:00:00 2001 From: LazyLinh2 Date: Tue, 24 Mar 2026 20:11:47 +0900 Subject: [PATCH 1/5] Remove internal CodeGenMember propeties from model factory method --- .../src/Providers/ModelFactoryProvider.cs | 7 +++++ .../ModelFactoryProviderTests.cs | 30 +++++++++++++++++++ .../MockInputModel.cs | 12 ++++++++ 3 files changed, 49 insertions(+) create mode 100644 packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/TestData/ModelFactoryProviderTests/SkipsCodeGenMemberInternalProperty/MockInputModel.cs diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs index a61da49e42b..47caab2127b 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs @@ -459,6 +459,13 @@ private static IReadOnlyList GetParameters( continue; } + // Skip parameters for properties that were customized via CodeGenMember to be non-public + if (param.Property?.OriginalName != null + && !param.Property!.Modifiers.HasFlag(MethodSignatureModifiers.Public)) + { + continue; + } + parameters.Add(GetModelFactoryParam(param)); } return [.. parameters]; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs index 52e0ffb88a8..e254a18a583 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/ModelFactoryProviderTests.cs @@ -466,6 +466,36 @@ public void RequiredConstantPropertiesAreNotExposedAsParameters() Assert.AreEqual("return new global::Sample.Models.MockInputModel(\"constant\", prop2, additionalBinaryDataProperties: null);\n", factoryMethod.BodyStatements!.ToDisplayString()); } + [Test] + public async Task SkipsCodeGenMemberInternalProperty() + { + var inputModel = InputFactory.Model( + "mockInputModel", + properties: + [ + InputFactory.Property("prop1", InputPrimitiveType.String), + InputFactory.Property("prop2", InputPrimitiveType.String) + ]); + + var mockGenerator = await MockHelpers.LoadMockGeneratorAsync( + inputModelTypes: [inputModel], + compilation: async () => await Helpers.GetCompilationFromDirectoryAsync()); + + var modelFactoryProvider = mockGenerator.Object.OutputLibrary.TypeProviders.OfType().SingleOrDefault(); + Assert.IsNotNull(modelFactoryProvider); + + var factoryMethod = modelFactoryProvider!.Methods.FirstOrDefault(m => m.Signature.Name == "MockInputModel"); + Assert.IsNotNull(factoryMethod); + + // prop1 is customized via CodeGenMember to be internal, so it should not appear in the factory method + Assert.AreEqual(1, factoryMethod!.Signature.Parameters.Count); + Assert.AreEqual("prop2", factoryMethod.Signature.Parameters[0].Name); + + // The body should pass default for the internal property + var body = factoryMethod.BodyStatements!.ToDisplayString(); + StringAssert.Contains("default", body); + } + private static InputModelType[] GetTestModels() { InputType additionalPropertiesUnknown = InputPrimitiveType.Any; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/TestData/ModelFactoryProviderTests/SkipsCodeGenMemberInternalProperty/MockInputModel.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/TestData/ModelFactoryProviderTests/SkipsCodeGenMemberInternalProperty/MockInputModel.cs new file mode 100644 index 00000000000..caa2352d91a --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelFactories/TestData/ModelFactoryProviderTests/SkipsCodeGenMemberInternalProperty/MockInputModel.cs @@ -0,0 +1,12 @@ +#nullable disable + +using Microsoft.TypeSpec.Generator.Customizations; + +namespace Sample.Models +{ + public partial class MockInputModel + { + [CodeGenMember("Prop1")] + internal string Prop1Internal { get; set; } + } +} From a17e3e263354a1245b74720d8da3050b5c6aed21 Mon Sep 17 00:00:00 2001 From: LazyLinh2 Date: Thu, 26 Mar 2026 16:54:58 +0900 Subject: [PATCH 2/5] change to only public params --- .../src/Providers/ModelFactoryProvider.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs index 47caab2127b..03452447d2b 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs @@ -460,8 +460,7 @@ private static IReadOnlyList GetParameters( } // Skip parameters for properties that were customized via CodeGenMember to be non-public - if (param.Property?.OriginalName != null - && !param.Property!.Modifiers.HasFlag(MethodSignatureModifiers.Public)) + if (!param.Property!.Modifiers.HasFlag(MethodSignatureModifiers.Public)) { continue; } From cdbc5ca71b8974f58f8f86143b2f2afa72ed9e31 Mon Sep 17 00:00:00 2001 From: LazyLinh2 Date: Thu, 26 Mar 2026 16:56:51 +0900 Subject: [PATCH 3/5] comment --- .../src/Providers/ModelFactoryProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs index 03452447d2b..34f52bb8d72 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs @@ -459,7 +459,7 @@ private static IReadOnlyList GetParameters( continue; } - // Skip parameters for properties that were customized via CodeGenMember to be non-public + // Skip parameters for non-public properties - ex. properties that were customized via CodeGenMember if (!param.Property!.Modifiers.HasFlag(MethodSignatureModifiers.Public)) { continue; From 00dce96d90df83c10635e8d5f5456b4e78da090e Mon Sep 17 00:00:00 2001 From: LazyLinh2 Date: Thu, 26 Mar 2026 20:45:57 +0900 Subject: [PATCH 4/5] Test regen in pipeline with protected flag as well --- .../src/Providers/ModelFactoryProvider.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs index 34f52bb8d72..a779479c11b 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs @@ -459,8 +459,8 @@ private static IReadOnlyList GetParameters( continue; } - // Skip parameters for non-public properties - ex. properties that were customized via CodeGenMember - if (!param.Property!.Modifiers.HasFlag(MethodSignatureModifiers.Public)) + // Skip parameters for non-public/protected properties - ex. properties that were customized via CodeGenMember + if (!param.Property!.Modifiers.HasFlag(MethodSignatureModifiers.Public) && !param.Property!.Modifiers.HasFlag(MethodSignatureModifiers.Protected)) { continue; } From a328c3a16a0b598566d147266f7c29651203e00c Mon Sep 17 00:00:00 2001 From: LazyLinh2 Date: Thu, 26 Mar 2026 21:25:35 +0900 Subject: [PATCH 5/5] revert back to check specifically for renamed properties as non-public/protected is too broad --- .../src/Providers/ModelFactoryProvider.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs index a779479c11b..47caab2127b 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelFactoryProvider.cs @@ -459,8 +459,9 @@ private static IReadOnlyList GetParameters( continue; } - // Skip parameters for non-public/protected properties - ex. properties that were customized via CodeGenMember - if (!param.Property!.Modifiers.HasFlag(MethodSignatureModifiers.Public) && !param.Property!.Modifiers.HasFlag(MethodSignatureModifiers.Protected)) + // Skip parameters for properties that were customized via CodeGenMember to be non-public + if (param.Property?.OriginalName != null + && !param.Property!.Modifiers.HasFlag(MethodSignatureModifiers.Public)) { continue; }