From bb9e91783bb0f15c0f07f81677bed83ebcd63c5d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 11 Sep 2026 23:32:08 +0000 Subject: [PATCH 1/3] Initial plan From 03aed9dcecfb0455d5f723e6a49c06787e727eef Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 11 Sep 2026 23:37:30 +0000 Subject: [PATCH 2/3] fix(http-client-csharp): sort derived models deterministically Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> --- .../src/Providers/ModelProvider.cs | 2 +- .../ModelProviders/DiscriminatorTests.cs | 6 ++--- .../ModelProviders/ModelProviderTests.cs | 26 +++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs index d846653a60a..25b395718e4 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs @@ -131,7 +131,7 @@ private IReadOnlyList BuildDerivedModels() } } - return [.. derivedModels]; + return [.. derivedModels.OrderBy(m => m.Name, StringComparer.Ordinal)]; } internal override TypeProvider? BaseTypeProvider => _baseTypeProvider ??= BuildBaseTypeProvider(); private TypeProvider? _baseTypeProvider; diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/DiscriminatorTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/DiscriminatorTests.cs index 7e42ef5030c..c00b6cf5459 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/DiscriminatorTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/DiscriminatorTests.cs @@ -87,7 +87,7 @@ private static IEnumerable GetBaseModels() yield return new TestCaseData(_baseModel, """ /// /// pet description - /// Please note this is the abstract base class. The derived classes available for instantiation are: , , and . + /// Please note this is the abstract base class. The derived classes available for instantiation are: , , and . /// """); @@ -120,8 +120,8 @@ public void BaseShouldBeAbstract(InputModelType inputModel, string expectedSumma Assert.AreEqual(expectedSummary, baseModel.XmlDocs.Summary!.ToDisplayString()); } - [TestCase(true, "Please note this is the abstract base class. The derived classes available for instantiation are: , , and .")] - [TestCase(false, "Please note this is the base class. The derived classes available for instantiation are: , , and .")] + [TestCase(true, "Please note this is the abstract base class. The derived classes available for instantiation are: , , and .")] + [TestCase(false, "Please note this is the base class. The derived classes available for instantiation are: , , and .")] public void DiscriminatedBaseDescriptionReflectsAbstractness(bool isAbstract, string expectedDescription) { MockHelpers.LoadMockGenerator(); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs index 71a5504fb94..ed9345d2f60 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs @@ -50,6 +50,32 @@ public void TestBuildDescription_SkipsDerivedClassesTextWhenNoPublicDerivedModel Assert.AreEqual("BaseModel description", provider!.Description.ToString()); } + [TestCase(false)] + [TestCase(true)] + [SetCulture("en-US")] + public void DerivedModelsAreSortedAndDeduplicated(bool reverseInputOrder) + { + var cat = InputFactory.Model("Cat"); + var zebra = InputFactory.Model("Zebra"); + var antelope = InputFactory.Model("antelope", isExactName: true); + InputModelType[] subtypes = [zebra, cat]; + InputModelType[] derivedModels = [antelope, cat]; + if (reverseInputOrder) + { + Array.Reverse(subtypes); + Array.Reverse(derivedModels); + } + + var inputModel = InputFactory.Model( + "Animal", + discriminatedModels: subtypes.ToDictionary(m => m.Name), + derivedModels: derivedModels); + var model = CodeModelGenerator.Instance.TypeFactory.CreateModel(inputModel); + + Assert.IsNotNull(model); + Assert.AreEqual(new[] { "Cat", "Zebra", "antelope" }, model!.DerivedModels.Select(m => m.Name)); + } + [Test] public void TestBuildProperties_ValidateInheritHierarchyWithOverride() { From 510e4916c73e1e7fd9972b6d3387597d3dd3703d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 12 Sep 2026 04:29:00 +0000 Subject: [PATCH 3/3] chore(http-client-csharp): regenerate derived-model references Co-authored-by: JoshLove-msft <54595583+JoshLove-msft@users.noreply.github.com> --- .../src/Generated/Models/Animal.Serialization.cs | 6 +++--- .../Local/Sample-TypeSpec/src/Generated/Models/Animal.cs | 2 +- .../src/Generated/SampleTypeSpecModelFactory.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs index fa3a9214a91..cccad18165e 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs @@ -14,7 +14,7 @@ namespace SampleTypeSpec { /// /// Base animal with discriminator - /// Please note this is the abstract base class. The derived classes available for instantiation are: and . + /// Please note this is the abstract base class. The derived classes available for instantiation are: and . /// [PersistableModelProxy(typeof(UnknownAnimal))] public abstract partial class Animal : IJsonModel @@ -150,10 +150,10 @@ internal static Animal DeserializeAnimal(JsonElement element, ModelReaderWriterO { switch (discriminator.GetString()) { - case "pet": - return Pet.DeserializePet(element, options); case "dog": return Dog.DeserializeDog(element, options); + case "pet": + return Pet.DeserializePet(element, options); } } return UnknownAnimal.DeserializeUnknownAnimal(element, options); diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.cs index 9843416b0e4..9ee6e838dcd 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.cs @@ -12,7 +12,7 @@ namespace SampleTypeSpec { /// /// Base animal with discriminator - /// Please note this is the abstract base class. The derived classes available for instantiation are: and . + /// Please note this is the abstract base class. The derived classes available for instantiation are: and . /// public abstract partial class Animal { diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecModelFactory.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecModelFactory.cs index 9a2c754494b..b51746632cb 100644 --- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecModelFactory.cs +++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/SampleTypeSpecModelFactory.cs @@ -440,7 +440,7 @@ public static StreamingItem StreamingItem(string message = default) /// /// Base animal with discriminator - /// Please note this is the abstract base class. The derived classes available for instantiation are: and . + /// Please note this is the abstract base class. The derived classes available for instantiation are: and . /// /// The kind of animal. /// Name of the animal.