Skip to content

Fix C# date-time naming feedback - #11751

Merged
JoshLove-msft merged 9 commits into
microsoft:mainfrom
JoshLove-msft:josh/date-time-naming-feedback
Aug 25, 2026
Merged

JoshLove-msft merged 9 commits into
microsoft:mainfrom
JoshLove-msft:josh/date-time-naming-feedback

Conversation

@JoshLove-msft

Copy link
Copy Markdown
Contributor

Summary

  • normalize date-time Start* and End* names to StartsOn and EndsOn
  • preserve exact First* and Last* date-time names while retaining compound-name normalization
  • keep normalized operation parameters mapped to their original input names so header, query, and path serialization is not dropped

Addresses feedback from Azure/azure-sdk-for-net#62390.

Validation

  • npm run build
  • eng/scripts/Generate.ps1
  • npm test
  • npm run cop

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 813a9e1d-ed7a-4e38-ac7a-2096d4933fa5
Copilot AI lite review requested due to automatic review settings August 25, 2026 02:35
@microsoft-github-policy-service microsoft-github-policy-service Bot added emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp labels Aug 25, 2026
@pkg-pr-new

pkg-pr-new Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@11751

commit: f0597f0

@github-actions

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates C# date-time naming normalization and preserves serialization for renamed operation parameters.

Changes:

  • Normalize Start*/End* date-time names to StartsOn/EndsOn.
  • Preserve exact First*/Last* names.
  • Map normalized parameters to original input names during serialization.
  • Update naming, provider, constructor, and request serialization tests.

A critical collision remains unresolved: distinct inputs such as startTime and startsOn can produce the same generated name.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Summary
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Utilities/CSharpNameExtensionsTests.cs Tests naming normalization.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/PropertyProviderTests.cs Tests normalized property names.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ParameterProviderTests.cs Tests normalized parameter names.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelProviderTests/ConstructorParameterNormalizesDateTimeSuffix.cs Updates generated constructor output.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelProviderTests/BackCompat_ConstructorParameterPreservesDateTimeSuffix.cs Updates compatibility output.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelProviderTests.cs Updates constructor naming expectations.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/CSharpNameExtensions.cs Updates date-time naming rules; collision handling remains required.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/RestClientProviders/RestClientProviderTests.cs Tests header, query, and path serialization.
packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/RestClientProvider.cs Maps original parameter names for serialization.
Suppressed comments (1)

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/CSharpNameExtensions.cs:106

  • This new mapping changes an existing public StartTime/EndTime date-time member from the previously emitted StartOn/EndOn to StartsOn/EndsOn. The model-property back-compat check only recognizes the raw StartTime name (PropertyProvider.cs:106-115), so a normal regeneration whose last contract contains StartOn will not preserve the shipped property name (and there is no later property-name restoration). Please preserve the last-contract member name or otherwise add an explicit compatibility path before applying this rename.
                ["End"] = "Ends",
                ["Expiration"] = "Expires",
                ["Modification"] = "Modified",
                ["Start"] = "Starts"

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (1)

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/CSharpNameExtensions.cs:106

  • These rewrites can make a valid operation un-generatable. For example, date-time parameter startTime and a separate parameter startsOn now both produce the requested C# name startsOn (similarly endTime/endsOn). RestClientProvider.BuildMessage then calls signature.Parameters.ToDictionary(p => p.Name, ...), which throws on the duplicate before CodeWriter can disambiguate declarations. Please resolve normalized-name collisions when constructing parameters and map serialization by the originating InputParameter rather than by the colliding string name.
                ["End"] = "Ends",
                ["Expiration"] = "Expires",
                ["Modification"] = "Modified",
                ["Start"] = "Starts"

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 813a9e1d-ed7a-4e38-ac7a-2096d4933fa5
Copilot AI review requested due to automatic review settings August 25, 2026 16:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 813a9e1d-ed7a-4e38-ac7a-2096d4933fa5
Copilot AI review requested due to automatic review settings August 25, 2026 16:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 813a9e1d-ed7a-4e38-ac7a-2096d4933fa5
Copilot AI review requested due to automatic review settings August 25, 2026 17:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (1)

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/RestClientProvider.cs:1672

  • For next-link requests that reinject only one of two raw names differing by case (for example, startTime but not StartTime), the reduced map contains only the first exact key, yet this fallback also resolves StartTime to that value. Since query/header emission still iterates every operation parameter, both wire parameters are then serialized from the single reinjected argument. Exact case-collision handling therefore remains incorrect for reinjected subsets; preserve knowledge of case-colliding operation names and do not use the insensitive fallback for an absent exact alias (and add a paging regression where only one casing is reinjected).
            public bool TryGetValue(string name, [NotNullWhen(true)] out ParameterProvider? parameter)
                => _exact.TryGetValue(name, out parameter) ||
                    _caseInsensitive.TryGetValue(name, out parameter);

@JoshLove-msft
JoshLove-msft added this pull request to the merge queue Aug 25, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Aug 25, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 813a9e1d-ed7a-4e38-ac7a-2096d4933fa5
Copilot AI review requested due to automatic review settings August 25, 2026 18:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/RestClientProvider.cs:269

  • Generated names are inserted before exact input-name aliases, so parameter order still determines correctness. For an operation ordered as startsOn (string), then startTime (date-time), both providers initially use the generated key startsOn; the second assignment overwrites the first, and the first parameter's later TryAdd("startsOn", ...) cannot restore its exact alias. Consequently both wire parameters serialize the date-time argument. The current regression uses only the favorable reverse order. Give exact InputParameter.Name aliases precedence over generated-name keys (or store them separately) so lookup is order-independent.
            foreach (var parameter in parameters)
            {
                paramMap[parameter.Name] = parameter;
            }

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 813a9e1d-ed7a-4e38-ac7a-2096d4933fa5
Copilot AI review requested due to automatic review settings August 25, 2026 19:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.

Input model names (wire name, original name and alias) are now registered before the normalized C# names, which are kept only as fallback aliases. Previously the generated names were written first with overwrite semantics, so a raw input name that matched another parameter's normalized name could not be recovered, causing both wire parameters to serialize the same value.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 813a9e1d-ed7a-4e38-ac7a-2096d4933fa5
Copilot AI review requested due to automatic review settings August 25, 2026 19:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

The reinjected parameter subset must not fall back to case-insensitive lookup: a parameter left out of the subset would otherwise resolve to another parameter whose name differs only by casing, emitting a spurious wire parameter on the next page request. ParameterProviderMap now takes an allowCaseInsensitiveFallback flag that the reinjected map disables, and the next request signature filter matches reinjected names with an ordinal comparer. Page size names remain case-insensitive because the operation and method parameters intentionally differ in casing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 813a9e1d-ed7a-4e38-ac7a-2096d4933fa5
Copilot AI review requested due to automatic review settings August 25, 2026 20:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated no new comments.

@JoshLove-msft
JoshLove-msft added this pull request to the merge queue Aug 25, 2026
Merged via the queue into microsoft:main with commit 210f84c Aug 25, 2026
29 checks passed
@JoshLove-msft
JoshLove-msft deleted the josh/date-time-naming-feedback branch August 25, 2026 22:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants