Skip to content

feat(http-client-csharp): support experimental types and members - #12028

Open
JoshLove-msft wants to merge 10 commits into
microsoft:mainfrom
JoshLove-msft:joshlove-msft-experimental-diagnostic-dependencies
Open

JoshLove-msft wants to merge 10 commits into
microsoft:mainfrom
JoshLove-msft:joshlove-msft-experimental-diagnostic-dependencies

Conversation

@JoshLove-msft

@JoshLove-msft JoshLove-msft commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #11690.

Summary

The shared @experimental metadata and lifecycle-details API landed in #11684. This PR consumes that metadata throughout C# generation, extending the work originally proposed in the closed companion #11685.

Supported declarations

TypeSpec target C# output
Model Model class or struct
Model property Property
Enum or union emitted as an enum Enum or extensible-enum struct
Enum member or union variant emitted as an enum value Enum field or extensible-enum property, including nested service-version enum members
Operation Synchronous/asynchronous protocol and convenience methods
Namespace or interface emitted as a client Client class
  • Reuse the shared lifecycle-details API and emitter scoping; preserve metadata in the input model and JSON converters.
  • Emit ExperimentalAttribute on the corresponding public declaration. Model factory methods carry the model's diagnostic; partial serialization declarations do not duplicate the model attribute. Custom partial client/method annotations take precedence.
  • Apply explicit dependsOn suppressions to complete method declarations/bodies or generated type files as appropriate. Preserve existing suppressions, deduplicate IDs, and avoid nested restores undoing an enclosing file suppression. Invalid pragma identifiers produce an emitter diagnostic.
  • Handle generated references to source-annotated experimental types/members in models, inheritance, serialization, factories, clients and child accessors, options/settings, nested enums, paging helpers, and streaming signatures.
  • Preserve source lifecycle metadata for explicitly mapped external types, including JSON round trips, without emitting or modifying their declarations. This uses known input metadata, not reflection. External experiments not described by source metadata still require explicit dependsOn entries.
  • Compatibility overloads follow the current API's experimental attribute and suppressions, including changed IDs and explicit graduation.
  • Keep graduation explicit: removing dependencies does not remove a declaration's public experiment, and referencing an experimental type does not automatically promote another public declaration to experimental.
  • Report experimental-target-not-supported for annotations with no representable C# declaration or explicit external mapping, including parameters and scalars/unions/variants erased to built-in types, rather than silently dropping them.
  • Include annotated samples for operations, models, properties, fixed/extensible enums and values, clients, service versions, paging, and streaming, with regenerated source and input JSON.

No C# changelog is added.

Validation

  • Full C# emitter/generator build and API extraction passed.
  • Emitter tests: 349 passed, 2 skipped.
  • Core generator tests: 2,304 passed in the preceding compatibility-fix validation; this follow-up changes no core generator code.
  • ClientModel tests excluding the known path-broken ModelReaderWriterValidation group: 1,591 passed.
  • Input tests: 219 passed; compiled sample tests: 84 passed.
  • Roslyn regressions cover experimental signature/body references, generic and array shapes, expression bodies, suppression scope, undeclared dependencies, public caller diagnostics, customized partials, multipart declarations, compatibility overloads, child accessors, literal enum members, and known external references.
  • Cop checks passed; repository-standard oxlint checked 71 emitter files with no diagnostics; formatting passed.
  • Full sample/Spector regeneration succeeded with no further generated-output changes.

Environment limitations

An earlier unfiltered ClientModel run had 125 System.IO.IOException failures in existing model fixtures caused by mixed separators in extended Windows paths. The affected ModelReaderWriterValidation group was excluded from the final broad ClientModel run; the focused affected suites pass.

The standalone smoke project's default netstandard2.0 target encounters a pre-existing missing/inaccessible ExperimentalAttribute polyfill on generated settings/options; its .NET 8 target passes. The stale package lint script refers to absent ESLint, so validation used the repository's current oxlint configuration instead.

Consume shared lifecycle details, emit public diagnostic attributes and scoped dependency suppressions, and document explicit graduation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 22, 2026 22:59
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Sep 22, 2026
@JoshLove-msft JoshLove-msft added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Sep 22, 2026
@pkg-pr-new

pkg-pr-new Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

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

commit: 0594eac

@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.

Copilot review overview

🟡 Changes recommended

A critical dependency-ID validation issue and a moderate back-compatibility issue remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

This PR integrates experimental lifecycle metadata into C# HTTP client generation, including public diagnostics and dependency suppressions.

Changes:

  • Preserves lifecycle metadata through emitter and generator inputs.
  • Emits experimental attributes and scoped dependency suppressions.
  • Adds focused tests, documentation, and dependency updates.
File Reviewed changes
packages/​http-client-csharp/​readme.md Documents experimental operations.
packages/​http-client-csharp/​package.json Updates HTTP client dependency metadata.
packages/​http-client-csharp/​package-lock.json Updates locked dependencies.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator.Input/​test/​TypeSpecInputConverterTests.cs Tests experimental metadata deserialization.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator.Input/​src/​InputTypes/​Serialization/​InputOperationConverter.cs Reads experimental metadata.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator.Input/​src/​InputTypes/​InputOperation.cs Stores operation metadata.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator.Input/​src/​InputTypes/​InputExperimentalDetails.cs Defines the experimental metadata input type.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator.ClientModel/​test/​Providers/​TestData/​ScmMethodProviderCollectionTests/​ExperimentalOperationSupportsPartialMethods/​TestClient.cs Provides partial-method test data.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator.ClientModel/​test/​Providers/​ScmMethodProviderCollectionTests.cs Tests generated attributes and suppressions.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator.ClientModel/​src/​Utilities/​ExperimentalApiHelpers.cs Builds experimental attributes and dependency pragmas.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator.ClientModel/​src/​Providers/​ScmMethodProviderCollection.cs Applies metadata to generated methods.
packages/​http-client-csharp/​generator/​Microsoft.TypeSpec.Generator.ClientModel/​src/​Providers/​RestClientProvider.cs Applies suppressions to request helpers.
packages/​http-client-csharp/​emitter/​test/​Unit/​utils/​test-util.ts Supports HTTP client test imports.
packages/​http-client-csharp/​emitter/​test/​Unit/​decorator-list.test.ts Tests lifecycle metadata and scope handling.
packages/​http-client-csharp/​emitter/​src/​type/​input-operation.ts Extends emitter input types.
packages/​http-client-csharp/​emitter/​src/​lib/​operation-converter.ts Extracts lifecycle details.
packages/​http-client-csharp/​.tspd/​docs/​usage.md Documents usage and graduation semantics.
Files not reviewed (1)
  • packages/http-client-csharp/package-lock.json: Generated file

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Annotate direct and composed sample experiments, regenerate C# output, and verify public diagnostic attributes across generated overloads.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 22, 2026 23:10

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.

Copilot review overview

🔵 Needs a closer look

Dependency IDs need validation before being emitted into C# pragma suppressions; documentation wording also needs qualification.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
Files not reviewed (1)
  • packages/http-client-csharp/package-lock.json: Generated file
Previously missed (2)

In code that hasn't changed since last review

Low severity Qualify claim about absent diagnosticId and multipart operations

packages/​http-client-csharp/​.tspd/​docs/​usage.md:33

This sentence is too broad for the behavior preserved above: when an operation is multipart and diagnosticId is absent, BuildConvenienceMethodAttributes still emits the existing SCME0004 attribute. Qualify this as “no metadata-derived public attribute” or document the multipart exception.

Low severity Qualify claim about absent diagnosticId and multipart operations

packages/​http-client-csharp/​readme.md:45

This sentence is too broad for the behavior preserved above: when an operation is multipart and diagnosticId is absent, BuildConvenienceMethodAttributes still emits the existing SCME0004 attribute. Qualify this as “no metadata-derived public attribute” or document the multipart exception.

…ures

Use member-scoped suppressions for generated signatures and bodies, preserve existing suppressions, and add compilation coverage for experimental type references.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 22, 2026 23: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.

Copilot review overview

🔵 Needs a closer look

Moderate issues remain with internal diagnostic suppression and metadata propagation to compatibility overloads.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
Files not reviewed (1)
  • packages/http-client-csharp/package-lock.json: Generated file

Generalize lifecycle metadata and attribute emission to models, properties, enums and values, and namespace/interface clients. Preserve compilation of generated references and helpers, diagnose unrepresentable targets, and add annotated samples and regression coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 23, 2026 00:49
@JoshLove-msft JoshLove-msft changed the title feat(http-client-csharp): emit experimental diagnostics and dependency suppressions feat(http-client-csharp): support experimental types and members Sep 23, 2026

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.

Copilot review overview

🟡 Changes recommended

Unresolved critical issues remain in duplicate-attribute handling, suppression coverage, and warning-identifier validation.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 6 High severity · 1 Low severity

Open (7)
Resolved since last review (2)
Files not reviewed (1)
  • packages/http-client-csharp/package-lock.json: Generated file

Preserve custom experimental attributes, validate pragma-safe diagnostic IDs, cover client options/settings references, and add compiler-backed production and multipart regressions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 23, 2026 02:02

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.

Copilot review overview

🟡 Changes recommended

Unresolved critical and moderate findings remain in metadata propagation, compatibility overloads, cache invalidation, and child-client suppression handling.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 3 High severity

Open (3)
Resolved since last review (7)
Files not reviewed (1)
  • packages/http-client-csharp/package-lock.json: Generated file

Comment thread packages/http-client-csharp/emitter/src/lib/operation-converter.ts Outdated
Comment thread packages/http-client-csharp/.tspd/docs/usage.md
Comment thread packages/http-client-csharp/emitter/src/lib/operation-converter.ts Outdated
Comment thread packages/http-client-csharp/package.json
Keep current experimental attributes and suppressions on compatibility overloads, include child accessor parameter dependencies, and clarify validation-only handling for unsupported direct parameter annotations.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 23, 2026 16:36

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.

Copilot review overview

🟡 Changes recommended

Unresolved findings affect unsupported-target handling and experimental diagnostic propagation.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
Resolved since last review (3)
Files not reviewed (1)
  • packages/http-client-csharp/package-lock.json: Generated file
Previously missed (1)

In code that hasn't changed since last review

Medium severity Preserve external experimental metadata for diagnostic suppression

packages/​http-client-csharp/​emitter/​src/​lib/​type-converter.ts:201

!retVar.external makes every external model/enum take hasGeneratedDeclaration: false, so any lifecycle metadata on a source-annotated external type is reported as experimental-target-not-supported and then discarded. That conflicts with the documented external behavior (the new usage docs state that external experiments require explicit dependsOn entries): a generated API referencing an external experimental type should be able to preserve/suppress the known diagnostic without trying to emit an attribute on the external declaration. Please allow the external model/enum metadata to flow into the input/suppression collector while keeping attribute emission limited to locally generated declarations.

Preserve source lifecycle details on explicitly mapped external types through input serialization without emitting their declarations, and add compiler regressions for external references and literal enum members.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 23, 2026 18:55
@JoshLove-msft

Copy link
Copy Markdown
Contributor Author

Addressed the review summary's “Preserve external experimental metadata for diagnostic suppression” finding in f363450.

Explicitly mapped external types now retain their source @experimental metadata through emitter conversion and JSON deserialization. Generated references can use the known diagnostic without emitting or modifying the external declaration. Emitter scoping and invalid-ID validation remain in place; unsupported non-external erased declarations are still diagnosed.

Added scoped external-type coverage, input round trips for all supported external type shapes, and a compiler-backed test using the real external JsonPatch type. The latter verifies reference suppression, no external type/factory generation, and no experimental attribute being added to the containing generated model. Updated the documentation to distinguish source-known metadata from external experiments that still need explicit dependsOn entries; there is no reflection-based discovery.

--generated by Copilot

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.

Copilot review overview

🔵 Needs a closer look

Compatibility factory overloads can retain stale or missing experimental attributes when model diagnostics change; their metadata must be synchronized before approval.

Review effort: Lite
Findings: None

Resolved since last review (1)
Files not reviewed (1)
  • packages/http-client-csharp/package-lock.json: Generated file

Preserve experimental lifecycle regression coverage alongside upstream opaque JSON reference tests, pagination fixes, and dependency updates.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 23, 2026 22:14

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.

Copilot review overview

🔵 Needs a closer look

The broad cross-cutting generator changes require final human review.

Review effort: Lite
Findings: None

Files not reviewed (1)
  • packages/http-client-csharp/package-lock.json: Generated file

Regenerate Sample-TypeSpec to retain experimental model registrations alongside deterministic Result names. Add context-registration regression coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 25, 2026 03: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.

Copilot review overview

🟡 Changes recommended

A critical emitter issue rejects valid experimental model variants in unions; documentation also needs the decorator name corrected.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
Files not reviewed (1)
  • packages/http-client-csharp/package-lock.json: Generated file

Comment thread packages/http-client-csharp/emitter/src/lib/type-converter.ts
Cover experimental models referenced by unions and retain rejection of annotations on erased variants. Clarify the declaration target and decorator syntax in the usage docs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 26, 2026 04:08

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.

Copilot review overview

🔵 Needs a closer look

Preserve experimental metadata in InputStreamingTypeConverter and add round-trip coverage.

Review effort: Lite
Findings: None

Resolved since last review (1)
Files not reviewed (1)
  • packages/http-client-csharp/package-lock.json: Generated file

This branch has not been deployed

No deployments
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.

Enhance @experimental with diagnostic IDs and dependencies

3 participants