You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
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.
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>
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.
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>
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>
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
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.
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>
!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>
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.
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.
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #11690.
Summary
The shared
@experimentalmetadata 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
ExperimentalAttributeon 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.dependsOnsuppressions 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.dependsOnentries.experimental-target-not-supportedfor 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.No C# changelog is added.
Validation
ModelReaderWriterValidationgroup: 1,591 passed.Environment limitations
An earlier unfiltered ClientModel run had 125
System.IO.IOExceptionfailures in existing model fixtures caused by mixed separators in extended Windows paths. The affectedModelReaderWriterValidationgroup was excluded from the final broad ClientModel run; the focused affected suites pass.The standalone smoke project's default
netstandard2.0target encounters a pre-existing missing/inaccessibleExperimentalAttributepolyfill 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.