Skip to content

Commit cad3fdb

Browse files
committed
Merge branch 'main' of https://github.com/microsoft/typespec into sramsey/csharp-server-union-failure
2 parents 3b42243 + dffc2b0 commit cad3fdb

26 files changed

Lines changed: 368 additions & 134 deletions

.chronus/changes/add-python-duration-seconds-milliseconds-encode-2026-6-10-9-3-37.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

.chronus/changes/add-python-multiple-services-tests-2026-6-10-8-56-11.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

.chronus/changes/fix-paging-unset-body-placement-2026-06-10.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

.chronus/changes/fix-sphinx-required-after-code-block-2026-6-9-15-20-0.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

.chronus/changes/fix-test-case-for-response-error-2026-6-16-0-0-0.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

.chronus/changes/python-add-arm-managementgroup-armresourceidentifier-tests-2026-6-10-8-52-0.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

.chronus/changes/python-add-dollar-sign-query-test-2026-6-15-6-6-0.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

.chronus/changes/refactor-node-python-emitter-2026-5-3-15-23-59.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/ScmTypeFactoryTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
using System.Linq;
88
using Microsoft.TypeSpec.Generator.ClientModel.Providers;
99
using Microsoft.TypeSpec.Generator.Input;
10+
using Microsoft.TypeSpec.Generator.Primitives;
11+
using Microsoft.TypeSpec.Generator.Providers;
1012
using Microsoft.TypeSpec.Generator.Tests.Common;
1113
using NUnit.Framework;
1214

@@ -144,6 +146,53 @@ public void TestCreateSerializations_ReturnsBothMrwAndMultipart_WhenJsonAndMpfdU
144146
"Expected a multipart serialization provider for a model with MultipartFormData usage.");
145147
}
146148

149+
// ScmTypeFactory overrides CreateModelCore to return ScmModelProvider. External-type
150+
// handling lives in the (non-overridable) base TypeFactory.CreateModel, so it must still
151+
// apply here. This guards against regressing the fix by re-introducing external handling
152+
// into CreateModelCore only, which would silently drop the discriminator for the Scm path.
153+
[Test]
154+
public void ExternalBaseModel_MapsToSystemObjectModelProvider_AndForwardsDiscriminator_ThroughScmTypeFactory()
155+
{
156+
var baseModel = InputFactory.Model(
157+
"Animal",
158+
properties:
159+
[
160+
InputFactory.Property("kind", InputPrimitiveType.String, isRequired: true, isDiscriminator: true),
161+
InputFactory.Property("name", InputPrimitiveType.String, isRequired: true),
162+
],
163+
external: new InputExternalTypeMetadata("System.Exception", null, null));
164+
var derivedModel = InputFactory.Model(
165+
"Pet",
166+
baseModel: baseModel,
167+
discriminatedKind: "pet",
168+
properties:
169+
[
170+
InputFactory.Property("kind", InputPrimitiveType.String, isRequired: true, isDiscriminator: true),
171+
InputFactory.Property("trained", InputPrimitiveType.Boolean, isRequired: true),
172+
]);
173+
174+
MockHelpers.LoadMockGenerator(inputModels: () => [baseModel, derivedModel]);
175+
176+
// The external base maps to a SystemObjectModelProvider even though ScmTypeFactory
177+
// overrides CreateModelCore.
178+
var baseProvider = ScmCodeModelGenerator.Instance.TypeFactory.CreateModel(baseModel);
179+
Assert.IsInstanceOf<SystemObjectModelProvider>(baseProvider);
180+
181+
// The derived model is a regular ScmModelProvider whose base is the SystemObjectModelProvider.
182+
var derivedProvider = ScmCodeModelGenerator.Instance.TypeFactory.CreateModel(derivedModel) as ModelProvider;
183+
Assert.IsNotNull(derivedProvider);
184+
Assert.IsInstanceOf<ScmModelProvider>(derivedProvider);
185+
Assert.IsInstanceOf<SystemObjectModelProvider>(derivedProvider!.BaseModelProvider);
186+
187+
// Some constructor forwards the discriminator literal to the external base.
188+
var forwardsDiscriminator = derivedProvider.Constructors.Any(
189+
c => c.Signature.Initializer is { IsBase: true } init &&
190+
init.Arguments.Any(a => a.ToDisplayString() == "\"pet\""));
191+
Assert.IsTrue(
192+
forwardsDiscriminator,
193+
"Expected a base constructor call forwarding the discriminator value \"pet\" to the external base.");
194+
}
195+
147196
private static InputModelProperty FilePartProperty(string name)
148197
=> InputFactory.Property(
149198
name,

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/CodeModelGenerator.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ internal set
100100
public IReadOnlyList<string> SharedSourceDirectories => _sharedSourceDirectories;
101101

102102
/// <summary>
103-
/// The list of <see cref="TypeProvider"/> instances that define custom-code attributes. These attribute
103+
/// The list of <see cref="CustomCodeAttributeDefinition"/> instances that define custom-code attributes. These attribute
104104
/// definitions are generated into the SDK project and are made available to the compiler while it compiles
105105
/// custom code. Derived generators can contribute additional providers via
106-
/// <see cref="AddCustomCodeAttributeProvider(TypeProvider)"/>.
106+
/// <see cref="AddCustomCodeAttributeProvider(CustomCodeAttributeDefinition)"/>.
107107
/// </summary>
108-
internal List<TypeProvider> CustomCodeAttributeProviders { get; } =
108+
internal List<CustomCodeAttributeDefinition> CustomCodeAttributeProviders { get; } =
109109
[
110110
new CodeGenTypeAttributeDefinition(),
111111
new CodeGenMemberAttributeDefinition(),
@@ -171,8 +171,8 @@ public virtual void AddSharedSourceDirectory(string sharedSourceDirectory)
171171
/// generator-specific attribute definitions. The provider's attribute definition is generated into
172172
/// the SDK project and made available to the compiler while it compiles custom code.
173173
/// </summary>
174-
/// <param name="provider">The <see cref="TypeProvider"/> that defines the custom-code attribute.</param>
175-
protected void AddCustomCodeAttributeProvider(TypeProvider provider)
174+
/// <param name="provider">The <see cref="CustomCodeAttributeDefinition"/> that defines the custom-code attribute.</param>
175+
protected void AddCustomCodeAttributeProvider(CustomCodeAttributeDefinition provider)
176176
{
177177
CustomCodeAttributeProviders.Add(provider);
178178
}

0 commit comments

Comments
 (0)