Skip to content

feat(core): de-duplicate host directives#67996

Merged
atscott merged 6 commits intoangular:mainfrom
crisbeto:duplicate-host-dirs
Apr 3, 2026
Merged

feat(core): de-duplicate host directives#67996
atscott merged 6 commits intoangular:mainfrom
crisbeto:duplicate-host-dirs

Conversation

@crisbeto
Copy link
Copy Markdown
Member

@crisbeto crisbeto commented Apr 2, 2026

With host directives we can end up in a situation where the same directive applies multiple times to the same element, potentially with conflicting configurations. The runtime isn't set up for a directive to apply more than once so historically we were throwing an error when we detect duplicates.

This ended up limiting the usefulness of host directives to library authors, because it meant that host directives couldn't be reused as much as authors wanted. To address the issue, these changes introduce logic in the compiler and runtime that will de-duplicate host directives with the following logic:

  1. If a directive matches once in the template and more than once as a host directive, the host directive matches will be discarded and only the template match will apply. The mental model is that a host directive match represents Partial<YourDirective> while a template match represents the full YourDirective.
  2. If a directive matches multiple times as a host directive, we merge the input/output mappings from all the instances into a single one. If we detect a case where an input/output is exposed under multiple names during the merging process, both the compiler and the runtime will produce an error.

Fixes #57846.

crisbeto added 4 commits April 2, 2026 07:12
Updates the TCB metadata to pre-compute and store the `TcbReferenceKey`, instead of computing it on the fly.
Moves the `matchSource` into the base metadata so the binder can use it.
Moves the `ClassPropertyMapping` into the compiler, rather than having to pass around the limited `InputOutputPropertySet` interface that is only implemented by `ClassPropertyMapping`.
Requires the `DirectiveMeta` to have a `ref` so that we can find duplicates easily.
@crisbeto crisbeto added action: review The PR is still awaiting reviews from at least one requested reviewer target: minor This PR is targeted for the next minor release labels Apr 2, 2026
@angular-robot angular-robot bot added detected: feature PR contains a feature commit area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime labels Apr 2, 2026
@ngbot ngbot bot added this to the Backlog milestone Apr 2, 2026
@crisbeto crisbeto force-pushed the duplicate-host-dirs branch 3 times, most recently from 3373f8a to d301c26 Compare April 2, 2026 09:12
crisbeto added 2 commits April 2, 2026 11:28
…conflicts

Implements the logic at the compiler level that will de-duplicate host directives and merge them together. It will also report if a conflict is detected during merging.
With host directives we can end up in a situation where the same directive applies multiple times to the same element, potentially with conflicting configurations. The runtime isn't set up for a directive to apply more than once so historically we were throwing an error when we detect duplicates.

This ended up limiting the usefulness of host directives to library authors, because it meant that host directives couldn't be reused as much as authors wanted. To address the issue, these changes introduce logic in the compiler and runtime that will de-duplicate host directives with the following logic:

1. If a directive matches once in the template and more than once as a host directive, the host directive matches will be discarded and only the template match will apply. The mental model is that a host directive match represents `Partial<YourDirective>` while a template match represents the full `YourDirective`.
2. If a directive matches multiple times as a host directive, we merge the input/output mappings from all the instances into a single one. If we detect a case where an input/output is exposed under multiple names during the merging process, both the compiler and the runtime will produce an error.

Fixes angular#57846.
@crisbeto crisbeto force-pushed the duplicate-host-dirs branch from d301c26 to a76b3d1 Compare April 2, 2026 09:28
@crisbeto crisbeto requested review from atscott and thePunderWoman and removed request for thePunderWoman April 2, 2026 10:36
@crisbeto crisbeto added the action: global presubmit The PR is in need of a google3 global presubmit label Apr 2, 2026
@crisbeto crisbeto marked this pull request as ready for review April 2, 2026 10:37
@crisbeto crisbeto removed the action: global presubmit The PR is in need of a google3 global presubmit label Apr 2, 2026
@crisbeto
Copy link
Copy Markdown
Member Author

crisbeto commented Apr 2, 2026

Passing TGP

Copy link
Copy Markdown
Contributor

@thePunderWoman thePunderWoman left a comment

Choose a reason for hiding this comment

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

LGTM!

@pullapprove pullapprove bot requested a review from JeanMeche April 2, 2026 16:16
Copy link
Copy Markdown
Contributor

@thePunderWoman thePunderWoman left a comment

Choose a reason for hiding this comment

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

reviewed-for: public-api

@atscott atscott added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Apr 3, 2026
@atscott atscott removed the request for review from JeanMeche April 3, 2026 16:43
@atscott atscott merged commit 9c55fcb into angular:main Apr 3, 2026
24 checks passed
@atscott
Copy link
Copy Markdown
Contributor

atscott commented Apr 3, 2026

This PR was merged into the repository. The changes were merged into the following branches:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: merge The PR is ready for merge by the caretaker area: compiler Issues related to `ngc`, Angular's template compiler area: core Issues related to the framework runtime detected: feature PR contains a feature commit target: minor This PR is targeted for the next minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hostDirectives should auto-resolve double matching

3 participants