Skip to content

[compiler/http] Replace mutative decorators with function calls for visibility and merge-patch#9893

Open
witemple-msft wants to merge 21 commits intomicrosoft:mainfrom
witemple-msft:witemple-msft/transforms-fns
Open

[compiler/http] Replace mutative decorators with function calls for visibility and merge-patch#9893
witemple-msft wants to merge 21 commits intomicrosoft:mainfrom
witemple-msft:witemple-msft/transforms-fns

Conversation

@witemple-msft
Copy link
Member

@witemple-msft witemple-msft commented Mar 3, 2026

This PR replaces the mutative decorators @withVisibilityFilter, @withLifecycleUpdate (compiler), and @applyMergePatch (http) with internal functions. The mutative decorators are then deprecated.

This PR also introduces a new template FilterVisibility to act as a replacement for any public use of @withVisibilityFilter. The function-based implementation is more accurate and preserves decorator metadata that may be present on the input model in a way that the mutative decorators are simply unable to do.

While implementing this functionality, I discovered two bugs that are also addressed by these changes:

  • TemplateParameter types are now assignable to more value positions than they previously were. This fixes issues with assigning template parameters with valueof constraints to other value parameters in default value position, function argument position, and template argument position (also closes [Bug]: Can not provide default value for valueof template parameter #9813)
  • internal items were not correctly excluded from completions when the completion cursor was in another package. In this branch, internal items that will not be accessible from the cursor's position will no longer be offered as completions.

Detection of visibility decorators was a bit fragile, relying on JS function reference equality. This implementation hardens that a bit by also checking that the TypeSpec path to the decorator is the same if the functions are not identical. This can happen due to the library doppelgänger effect that we sometimes see.

A side effect of these changes is that the templates used to instantiate the transforms are now alias delcarations instead of model declarations. Unfortunately, this means their documentation is removed from the website. Tracked in #9892 .

Closes #8976
Closes #8979

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 3, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/compiler@9893
npm i https://pkg.pr.new/@typespec/http@9893
npm i https://pkg.pr.new/@typespec/http-server-csharp@9893
npm i https://pkg.pr.new/@typespec/json-schema@9893

commit: 3709b0a

@github-actions
Copy link
Contributor

github-actions bot commented Mar 3, 2026

All changed packages have been documented.

  • @typespec/compiler
  • @typespec/http
Show changes

@typespec/compiler - internal ✏️

Replaced visibility and merge-patch transforms with invocations of internal functions for greater accuracy.

@typespec/http - internal ✏️

Replaced visibility and merge-patch transforms with invocations of internal functions for greater accuracy.

@typespec/compiler - fix ✏️

Fixed a bug that would prevent template parameters from assigning to values in some cases.

@typespec/compiler - feature ✏️

Added a new template FilterVisibility to support more accurate visibility transforms. This replaces the @withVisibilityFilter decorator, which is now deprecated and slated for removal in a future version of TypeSpec.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR modernizes TypeSpec’s visibility and merge-patch transforms by moving from mutative decorators to internal function-backed transforms (with deprecations), improving correctness and preserving decorator metadata while also fixing related compiler issues.

Changes:

  • Introduces function-based transform implementations and exports them via $functions (compiler + http), deprecating @withVisibilityFilter, @withLifecycleUpdate, and @applyMergePatch.
  • Adds new public FilterVisibility template (alias) as the replacement for @withVisibilityFilter, and updates lifecycle/merge-patch templates to use function calls.
  • Fixes compiler bugs around (1) assignability of value-constrained template parameters in more “value positions” and (2) excluding inaccessible internal symbols from language-server completions across package boundaries.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
website/src/content/docs/docs/standard-library/built-in-decorators.md Adds deprecation callouts for mutative visibility decorators.
website/src/content/docs/docs/standard-library/built-in-data-types.md Updates generated reference output; lifecycle template sections removed due to alias docs limitation.
website/src/content/docs/docs/libraries/http/reference/index.mdx Removes merge-patch template links from reference index (no longer generated as model docs).
website/src/content/docs/docs/libraries/http/reference/data-types.md Removes merge-patch template reference sections (templates converted to aliases).
packages/samples/test/output/visibility/@typespec/openapi3/openapi.yaml Updates golden output (removes empty description artifacts).
packages/samples/test/output/todoApp/@typespec/openapi3/openapi.yaml Updates golden output (removes empty description artifacts).
packages/samples/test/output/init/@typespec/openapi3/openapi.yaml Updates golden output (removes empty description artifacts).
packages/json-schema/test/arrays.test.ts Adjusts schema expectations to reflect new transform behavior (ref vs inline object).
packages/http/src/tsp-index.ts Adds $functions export for http private internal functions.
packages/http/src/merge-patch.ts Adds applyMergePatchTransform function and reimplements decorator via the function.
packages/http/src/index.ts Exposes $functions alongside $decorators (internal surface).
packages/http/lib/private.decorators.tsp Deprecates applyMergePatch decorator and declares internal applyMergePatchTransform fn.
packages/http/lib/main.tsp Converts merge-patch templates to aliases calling applyMergePatchTransform.
packages/http/generated-defs/TypeSpec.Http.Private.ts Updates generated typings to include TypeSpecHttpPrivateFunctions.
packages/http-server-csharp/test/generation.test.ts Updates generator golden assertions due to merge-patch type namespace/using changes.
packages/compiler/test/visibility.test.ts Adds coverage for function-based visibility transforms and FilterVisibility template behavior.
packages/compiler/test/server/completion.test.ts Adds tests ensuring internal fn completion visibility is scoped correctly by package.
packages/compiler/test/checker/model.test.ts Adds regression coverage for value-constrained template parameter passthrough/default scenarios.
packages/compiler/test/checker/functions.test.ts Adds regression coverage for passing value-constrained template params to valueof function params.
packages/compiler/src/server/completion.ts Filters inaccessible internal symbols from completions based on location context.
packages/compiler/src/lib/visibility.ts Introduces applyVisibilityFilter/applyLifecycleUpdate functions and hardens decorator matching.
packages/compiler/src/lib/tsp-index.ts Adds compiler $functions export mapping to generated TypeSpecFunctions.
packages/compiler/src/index.ts Exposes compiler $functions at the package entrypoint (internal surface).
packages/compiler/src/core/checker.ts Fixes template-parameter-as-value behavior by synthesizing a TemplateValue placeholder more broadly.
packages/compiler/lib/std/visibility.tsp Deprecates mutative decorators, adds FilterVisibility alias, and updates lifecycle templates to aliases.
packages/compiler/generated-defs/TypeSpec.ts-test.ts Adds compile-time check ensuring $functions matches generated TypeSpecFunctions signature.
packages/compiler/generated-defs/TypeSpec.ts Updates generated typings to include function implementations (TypeSpecFunctions).
.chronus/changes/witemple-msft-transforms-fns-2026-2-3-18-15-47.md Changelog entry for new FilterVisibility template (feature).
.chronus/changes/witemple-msft-transforms-fns-2026-2-3-17-56-49.md Changelog entry for template-parameter value assignment fix.
.chronus/changes/witemple-msft-transforms-fns-2026-2-3-17-53-51.md Changelog entry for internal function-based transform migration.

@witemple-msft
Copy link
Member Author

TypeSpec Azure integration is failing because the template no longer has to put @doc("") to avoid polluting the description of every instance of merge patch. We'll need to adjust those test expectations to account for this, but those are the only failing tests, so I'm considering azure integration virtually passing here.

@azure-sdk
Copy link
Collaborator

azure-sdk commented Mar 3, 2026

You can try these changes here

🛝 Playground 🌐 Website 🛝 VSCode Extension

@witemple-msft witemple-msft added the int:azure-specs Run integration tests against azure-rest-api-specs label Mar 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compiler:core Issues for @typespec/compiler emitter:json-schema int:azure-specs Run integration tests against azure-rest-api-specs lib:http meta:website TypeSpec.io updates

Projects

None yet

4 participants