Skip to content

[http-client-csharp] Prototype compiler-backed structural C# reduction - #12432

Draft
Wei Hu (live1206) wants to merge 4 commits into
microsoft:mainfrom
live1206:prototype/provider-name-reducer
Draft

Wei Hu (live1206) wants to merge 4 commits into
microsoft:mainfrom
live1206:prototype/provider-name-reducer

Conversation

@live1206

@live1206 Wei Hu (live1206) commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Part of #12442

Opt-in compiler-backed C# structural reduction through C9, SDK-shaped cast/interface qualification, both Optional.IsDefined refinements, bounded whole-cref import activation/exception provenance, and branch-local static invocations. Enable with TYPESPEC_PROVIDER_REDUCER=structural; Roslyn remains the default.

Original writer provenance and shared original-compilation facts feed one rewrite traversal and final serialization. Unsupported cases retain their spelling, without a Roslyn fallback, per-edit production compilation or occurrence-acceptance cache.

Applied rules

  • Supported type/declaration qualifications, namespace prefixes/aliases and constructed/nested/array/nullable forms; certified static type receivers, field/property this., attribute names/suffixes, optional defaults and grammar-safe parentheses/statement cleanup.
  • Retained ((IPersistableModel<T>)this) receivers: recorded interface heads and enclosing SELF-model arguments only, with import witnesses and exact composed-type/parser/source proofs. No cast removal or foreign-model expansion.
  • Optional.IsDefined: exact/actual ancestor namespace with no intervening namespace-local import activation and invariant affected statement/binding scope.
  • Whole-type crefs: real exception provenance without changing qualified writer text; bare top-level nongeneric type import activation only when exact binding is preserved. The intentional diagnostic delta is limited to disappearance of unsuppressed default-Hidden CS8019 for the normal import genuinely made used. Other diagnostics/reporting/source checks remain.
  • Branch-local static invocations: invariant complete method/occurrence in active parses; whole call disabled in inactive parses, with no overlapping active expression/argument/local-function source span. Original closure, outer-argument, source-observation, visibility, token and directive safeguards remain.

The paused serialization-context experiment and deferred imported-cref code-witness prototype are not included. Historical C3, C6 nameof, C7 method-call this and C10 SDK-shaped generic inference remain excluded.

Pre-merge saved AppService evaluation

Same saved input/reference, 2,301 emitted files. Counts are canonical syntax events, not diff lines or promises for other SDKs.

Checkpoint Residual events
Initial structural slice 165,725
Historical C9 29,336
C9 + SDK-shaped casts 25,726
Both Optional refinements 23,747
Cref policy/provenance 20,718
Bounded branch-static rule 19,463

Latest delta: 1,255 static-receiver prefix removals /596 files—627 JsonDocument,627 JsonSerializer and1 BinaryData.FromString. All other categories unchanged; every changed output independently reconstructed through UTF16 deletions with exact UTF8/BOM parity. Remaining largest categories: type names3,940; method-call this.3,834; static receivers2,811; nameof2,399; crefs1,945.

Change-specific validation

Merged main at 6ba281975981910906590563363d16e74b5fbf47; resolved the binary-expression writer conflict while retaining both main's AddParentheses option and grammar-safe unparenthesized statement emission.

  • Pre-merge latest epoch: 308 focused Roslyn5.9 tests, including21 new branch cases/direct checks and both unsafe CAE capture regressions. Six-configuration operation trees/calls/conversions/constants and complete compiler/emit diagnostic multisets/all endpoints; not explicit CFG comparison.
  • The regressions retain qualification when another configuration selects a source-capturing overload or introduces a capturing closure only in the inactive parse. Forced edits still change real synthesized strings. The old directive-bearing receiver veto was traced and preserved, not relaxed to force a positive.
  • Authentic original reconstruction:2,699 documents/20 references. Actual SDK ProcessDocument with all116 writer records/138 type nodes removes exactly2JSON prefixes, preserving exact constructed calls/receiver types and complete ordinary/unfiltered document diagnostic bags4→4. Original missing source-generator .Default errors are preserved, not repaired or ignored.
  • One candidate-only saved-input replay:115.5s, zero baseline generations/builds, no fresh TypeSpec compilation or comparative speed claim. Actual runtime hashes, all2,301 output hashes and exact2,677-file SDK/unrelated-WIP restoration independently verified. The method smoke was20.08s total/7.78s first ProcessDocument including initial shared facts.
  • Post-main-merge full suites: Core 3,966/3,966; client 2,671/2,671; input 307/307. Emitter 396 passed / 2 skipped. The merge's AddParentheses/statement-emission combination is covered by four new true/false option tests, all passing.
  • Post-merge official unfiltered opt-in structural local regeneration/integration passed: Local 818/818; Spector 962 passed / 10 skipped. Temporary generated outputs and merged launcher settings were restored exactly.
  • Post-merge wide Roslyn5.9 structural/provider/statement focus: 2,584/2,584 passed. An isolated-output fixture-path failure was corrected by supplying the existing shared TestProjects resource directory; the same built assembly and identical test-name multiset were rerun. Temporary package props were restored.

Limits

The saved SDK measurements above belong to the pre-merge source epoch. They are not post-merge whole-SDK semantic/compiler/emit/native/API clearance. Historical CAST validation included full implementation/local integration checks and net10 GA AppService1.5.0 API/byte-identical XML; that evidence is not automatically inherited by later permissions or the main merge. Broader SDK semantic/native/API/whole-XML validation and fresh netstandard2.0/net8.0/comparative profiling remain pending. The oversized context graph pipeline remains stopped.

This remains a draft prototype, not default enablement or a complete Roslyn-simplifier replacement. Large local captures/benchmarks and separately paused work are intentionally not committed. Status: packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/perf/ProviderReducerStatus.md.

- by copilot

@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 Oct 29, 2026
@pkg-pr-new

pkg-pr-new Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

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

commit: 1378067

@github-actions

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

Consolidate the provider-aware prototype, accepted structural rules through C9, supporting benchmarks and regression coverage. Keep Roslyn as the default.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@live1206
Wei Hu (live1206) force-pushed the prototype/provider-name-reducer branch from 1f5245a to a6134d0 Compare October 29, 2026 09:37
Wei Hu (live1206) and others added 3 commits October 29, 2026 13:59
Add the accepted stable-method SELF interface-cast qualification slice and its diagnostic/import/source regression coverage. Update the published prototype status and residual inventory.

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

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.

1 participant