Fix CancellationToken parameter ordering and name collision in v3 OperationCompiler#341
Conversation
…CT name Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/b0c519de-0186-40ca-8174-42ed67a5316a
|
@copilot fix build |
Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/565d6633-576d-4587-b924-a29b0ea53c2c
Fixed in commit Root cause: Fix: |
|
/repo-assist merge target branch into this one and actualize changes |
|
✅ Repo Assist completed successfully! |
|
@copilot merge target repo-assist/feat-cancellationtoken-issue-212-2026-03-23-448c1cde90ec7d95 branch into this one, resolve conflicts and actualize changes |
…dering + uniqueness improvements from this PR Both branches fixed CT name uniqueness independently. This branch additionally fixes the parameter ordering bug (CT must precede optional params). The merge keeps the more complete implementation (buildProvidedParameters helper, two-pass required/optional split, ctArgIndex insertion) and discards the simpler base-branch approach that still appended CT after optional params.
Done in commit |
c56be43
into
repo-assist/feat-cancellationtoken-issue-212-2026-03-23-448c1cde90ec7d95
There was a problem hiding this comment.
Pull request overview
This PR fixes v3 client-method generation in OperationCompiler so CancellationToken is emitted as a required parameter between required and optional OpenAPI parameters (valid .NET ordering), and ensures the generated CT parameter name cannot collide with OpenAPI parameter names. It also adjusts the build script to explicitly restore before building the test solution to avoid multi-TFM assets issues.
Changes:
- Reworked v3 parameter construction into required/optional passes and inserted
CancellationTokenatctArgIndex = requiredParamCount. - Added unique-name generation for the CT parameter (
cancellationToken,cancellationToken1, …) based on already-generated parameter names. - Updated
invokeCodeto extract CT byctArgIndexrather than assuming it is the last argument; updatedBuildTeststorestorethenbuild --no-restore.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/SwaggerProvider.DesignTime/v3/OperationCompiler.fs | Fixes CT parameter ordering and name-collision handling; updates invokeCode arg extraction accordingly. |
| build.fsx | Adds an explicit restore step before building the tests solution to stabilize multi-TFM restore/build behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let ctName = findUniqueName "cancellationToken" 1 | ||
| let ctParam = ProvidedParameter(ctName, typeof<Threading.CancellationToken>) | ||
| // CT is inserted after required params so it never follows optional params | ||
| let ctArgIndex = List.length requiredProvidedParams | ||
| ctArgIndex, requiredProvidedParams @ [ ctParam ] @ optionalProvidedParams | ||
| else |
There was a problem hiding this comment.
The CT ordering/name-collision fixes are not covered by tests. Consider adding a v3 unit test that compiles a minimal schema with both required and optional parameters and asserts (via reflection over the provided method) that the CancellationToken parameter is positioned after required params and before optional params, and another schema containing an OpenAPI parameter named cancellationToken to assert the generated CT parameter name is suffixed (e.g., cancellationToken1).
…vider generated methods (closes #212) (#336) * feat: add CancellationToken support to OpenApiClientProvider generated methods (closes #212) - Add CallAsync overload with CancellationToken to ProvidedApiClientBase - Thread CancellationToken from generated methods through to HttpClient.SendAsync - Each generated method gains an optional cancellationToken parameter (defaults to CancellationToken.None) - Backward-compatible: existing call sites without CT continue to work unchanged - Add unit tests: success with CancellationToken.None, cancellation propagation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: trigger checks * fix: replace optional struct CancellationToken parameter with method overloads (#337) * Initial plan * Fix: revert global.json and address CancellationToken build failures Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/1861c3cb-6a0a-438a-aa31-f65b8c809f88 * fix: use method overloading for CancellationToken support instead of optional struct parameter Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/1861c3cb-6a0a-438a-aa31-f65b8c809f88 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> * Add type provider integration tests for CancellationToken-overloaded methods (#338) * Fix: CT parameter name uniqueness in CancellationToken overload generation (#339) * Initial plan * fix: generate unique CT parameter name to avoid collision with OpenAPI params named 'cancellationToken' Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/7d588ec7-c4df-4a6c-89f8-9c13c2472d29 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> * Fix CancellationToken parameter ordering and name collision in v3 OperationCompiler (#341) * Initial plan * fix: insert CT between required and optional params; generate unique CT name Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/b0c519de-0186-40ca-8174-42ed67a5316a * fix: add explicit restore + --no-restore to BuildTests to fix NETSDK1005 Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Agent-Logs-Url: https://github.com/fsprojects/SwaggerProvider/sessions/565d6633-576d-4587-b924-a29b0ea53c2c --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> * refactor: use UniqueNameGenerator for CT param name uniqueness Replace hand-coded recursive findUniqueName function with the existing UniqueNameGenerator utility (already used in DefinitionCompiler and for method name deduplication in OperationCompiler). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: add optional occupiedNames parameter to UniqueNameGenerator constructor Allows callers to pre-seed the generator with names that are already taken, so MakeUnique will never return any of those names without a numeric suffix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor: single CallAsync overload + single generated method with optional CancellationToken - Remove no-CT CallAsync overload from ProvidedApiClientBase; keep only the version with explicit CancellationToken (quotation code always supplies it) - Remove double-compilation in OperationCompiler: one method per operation with optional cancellationToken (null default = default(CancellationToken).None) - Update RuntimeHelpersTests to pass CancellationToken.None explicitly Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * cleanup: simplify OperationCompiler and add default/async CT tests - Use List.map instead of List.collect since compileOperation returns a single method - Clean up comments in OperationCompiler - Add test for calling generated method without CancellationToken (default token) - Add test for async (PreferAsync=true) generated method without CancellationToken * feat: propagate CancellationToken through ReadAsStringAsync/ReadAsStreamAsync via RuntimeHelpers Add readContentAsString and readContentAsStream wrappers to RuntimeHelpers with #if NET5_0_OR_GREATER guards, enabling CancellationToken propagation in generated quotation code that must compile against netstandard2.0. Also add explicit CancellationToken integration tests and conditional CT support in ProvidedApiClientBase error path. * test: add CT coverage for stream, text/plain, async cancellation, and async POST paths * fix: async tests --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: sergey-tihon <1197905+sergey-tihon@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Sergey Tihon <sergey.tihon@gmail.com>
Two bugs in the CT overload generation: CT was appended after optional parameters (invalid in .NET — required params must precede optional), and the CT parameter name was always
cancellationTokenwith no collision check against generated OpenAPI parameter names.Changes
Parameter ordering: Split parameter building into two passes (required, then optional) with the used-name set threaded between them. CT is now inserted at
ctArgIndex = requiredParamCount, giving the signature:(required...) → CT → (optional...).Name uniqueness: Collect all generated parameter names into a set before creating the CT param; fall back to
cancellationToken1,cancellationToken2, etc. on collision.invokeCodeextraction: CT is now extracted byList.item ctArgIndex allArgs(index captured during parameter building) rather than by peeling off the last argument, which broke under the new ordering.Before / After signature example
📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.