Add opt-in ~/ asset-path expansion for Razor components (compiler) - #84796
Draft
chsienki wants to merge 5 commits into
Draft
Add opt-in ~/ asset-path expansion for Razor components (compiler)#84796chsienki wants to merge 5 commits into
chsienki wants to merge 5 commits into
Conversation
Introduce the descriptor and property metadata the Razor compiler uses to recognize opt-in asset-path expansion, ahead of the discovery and lowering that consume them: - AssetPathMetadata carries a single (element, attribute) pair declared via [AcceptsAssetPath], surfaced as a tag-helper descriptor. - PropertyMetadata.AcceptsAssetPath marks a component parameter opted in via [AssetPath]. - New AssetPath / AcceptsAssetPath members on the TagHelperKind, MetadataKind, and TagHelperProducerKind enums, with the component-kind range extended to include the new tag-helper kind. - ComponentsApi gains the well-known metadata names for the [AssetPath] and [AcceptsAssetPath] attributes and the AssetPathAttributes convention type. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ef56ab10-2d3d-4e55-a318-3d03bfbdd713
Read the runtime's asset-path opt-in metadata during tag-helper discovery: - AcceptsAssetPathTagHelperProducer finds the public AssetPathAttributes convention type and emits one carrier tag-helper descriptor per declared (element, attribute) pair, following the BindAttributes / EventHandlers model. The descriptors declare no tag-matching rules; they exist only to carry the allowlist to the lowering pass. - ComponentTagHelperProducer records [AssetPath] on a component parameter as PropertyMetadata.AcceptsAssetPath. - CompilerFeatures registers the new producer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ef56ab10-2d3d-4e55-a318-3d03bfbdd713
Rewrite literal ~/-prefixed attribute values into Assets["..."] expressions, but only where the target has opted in: - HTML element attributes whose (element, attribute) pair appears in the discovered [AcceptsAssetPath] allowlist. - Component parameters whose bound attribute has PropertyMetadata.AcceptsAssetPath. The pass reads the full discovered tag-helper set from ITagHelperFeature so the allowlist is compilation-global rather than scoped to the document's in-scope tag helpers. Mixed literal/expression content on an opted-in attribute is reported as RZ10025. Expansion is gated on Razor language version 11.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ef56ab10-2d3d-4e55-a318-3d03bfbdd713
Cover opted-in expansion for HTML elements and component parameters, plus the backward-compatible cases where ~/ is left untouched: no [AssetPath], an attribute outside the allowlist, bare ~, explicit @() expressions, pre-11.0 language version, and mixed content (RZ10025). Baselines are generated with: dotnet test src/Razor/src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Microsoft.AspNetCore.Razor.Language.UnitTests.csproj /p:GenerateBaselines=true Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ef56ab10-2d3d-4e55-a318-3d03bfbdd713
Add the feature design doc and record the discovery/allowlist pattern and the baseline-regeneration workflow in the agent knowledge base. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ef56ab10-2d3d-4e55-a318-3d03bfbdd713
chsienki
force-pushed
the
features/tilde-path-expansion
branch
from
August 7, 2026 00:53
7eed863 to
ba53e6b
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What this does
Adds opt-in, compile-time expansion of literal
~/-prefixed attribute values in.razorfiles intoAssets["..."]expressions, so<img src="~/images/logo.png">becomes<img src="@Assets["images/logo.png"]">-- only where the target has explicitly opted in:(element, attribute)pair the runtime declares via[AcceptsAssetPath(elementName, attributeName)]on a publicAssetPathAttributesconvention type (built-in allowlist:img[src],link[href],script[src]).[AssetPath].When nothing is opted in,
~/is left untouched -- existing markup is unaffected (no ambient behavior, so no MSBuild opt-out is needed).Design
AcceptsAssetPathTagHelperProducerdiscovers theAssetPathAttributesconvention type during tag-helper discovery and emits carrierTagHelperDescriptors (AssetPathMetadata) with no tag-matching rules -- they exist purely to carry the allowlist to the lowering pass.[AssetPath]on a component parameter is recorded asPropertyMetadata.AcceptsAssetPath.ComponentTildePathPass(anIRazorOptimizationPass, Order 75) reads the full discovered tag-helper set viaITagHelperFeature(compilation-global, not scoped to the document's in-scope tag helpers), builds an element -> attributes allowlist once per engine, and rewrites only opted-in single-literal~/values. Mixed literal/expression content on an opted-in attribute is reported as RZ10025. Gated on Razor language version 11.0.Commits
AssetPathMetadata+PropertyMetadata.AcceptsAssetPath)[AssetPath]/[AcceptsAssetPath]declarations (producer + registration)~/literals viaComponentTildePathPass(+ RZ10025)docs/razor/tilde-path-expansion.md)Each commit builds and is test-green.
Testing
ComponentCodeGenerationTestBaseTildePath_*cases cover opted-in expansion (HTML + component params) and the backward-compatible non-expansion cases (not opted in, attribute outside the allowlist, bare~, explicit@(), pre-11.0, mixed content). 15/15 green.Related
~/asset paths in Razor components #84793Microsoft Reviewers: Open in CodeFlow