Describe the bug
ModelProvider.BuildDescription appends the sentence "...The derived classes available for instantiation are: " for any discriminated base type, and then loops over the public derived models to fill in the list:
https://github.com/microsoft/typespec/blob/main/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs
var publicDerivedModels = _derivedModels.Where(m => m.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Public)).ToList();
var derivedClassesDescription = DeclarationModifiers.HasFlag(TypeSignatureModifiers.Abstract)
? "Please note this is the abstract base class. The derived classes available for instantiation are: "
: "Please note this is the base class. The derived classes available for instantiation are: ";
for (int i = 0; i < publicDerivedModels.Count; i++) { ... }
description = $"{description}\n{derivedClassesDescription}";
When every derived model is internal, publicDerivedModels is empty, the loop body never executes, and the sentence is emitted with nothing after it. Two problems result:
- Semantic — the doc promises a list of instantiable derived classes and then provides none. There are no public derived classes, so the sentence should not be emitted at all.
- Trailing whitespace — the description ends with the dangling
"are: ", so the generated /// line has a trailing space. This trips git diff --check and any whitespace linting on generated output.
Reproduction
A discriminated base type whose only derived type is the generated Unknown* fallback (which is internal). Generated output:
/// <summary>
/// LimitJson abstract class.
/// Please note this is the abstract base class. The derived classes available for instantiation are:
/// </summary>
Note the trailing space after are:. Compare with a type that does have a public derived model, which renders correctly:
/// Please note this is the abstract base class. The derived classes available for instantiation are: <see cref="Models.TypeAPolyDevice"/>.
Real-world impact
This is present in committed output today. In Azure/azure-sdk-for-net, on main:
eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/Models/LimitJsonObject.cs:16
eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/Models/LimitJsonObject.Serialization.cs:17
and in shipped SDKs, e.g. sdk/machinelearningservices/Azure.Provisioning.MachineLearning/src/Generated/Models/MachineLearningDatastoreSecrets.cs:14 and sdk/servicefabric/Azure.Provisioning.ServiceFabric/src/Generated/Models/ServicePlacementPolicyDescription.cs:14.
Suggested fix
Skip the appended sentence entirely when publicDerivedModels.Count == 0, which resolves both the dangling prose and the trailing whitespace.
Checklist
Describe the bug
ModelProvider.BuildDescriptionappends the sentence"...The derived classes available for instantiation are: "for any discriminated base type, and then loops over the public derived models to fill in the list:https://github.com/microsoft/typespec/blob/main/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs
When every derived model is internal,
publicDerivedModelsis empty, the loop body never executes, and the sentence is emitted with nothing after it. Two problems result:"are: ", so the generated///line has a trailing space. This tripsgit diff --checkand any whitespace linting on generated output.Reproduction
A discriminated base type whose only derived type is the generated
Unknown*fallback (which is internal). Generated output:Note the trailing space after
are:. Compare with a type that does have a public derived model, which renders correctly:/// Please note this is the abstract base class. The derived classes available for instantiation are: <see cref="Models.TypeAPolyDevice"/>.Real-world impact
This is present in committed output today. In
Azure/azure-sdk-for-net, onmain:eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/Models/LimitJsonObject.cs:16eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/Models/LimitJsonObject.Serialization.cs:17and in shipped SDKs, e.g.
sdk/machinelearningservices/Azure.Provisioning.MachineLearning/src/Generated/Models/MachineLearningDatastoreSecrets.cs:14andsdk/servicefabric/Azure.Provisioning.ServiceFabric/src/Generated/Models/ServicePlacementPolicyDescription.cs:14.Suggested fix
Skip the appended sentence entirely when
publicDerivedModels.Count == 0, which resolves both the dangling prose and the trailing whitespace.Checklist