Repository navigation
Conversation
dylhunn
force-pushed
the
template-ingestion
branch
17 times, most recently
from
December 9, 2023 23:27
383f4c6 to
81c447f
Compare
dylhunn
marked this pull request as ready for review
December 9, 2023 23:28
… template views The Template Pipeline has had a number of tricky bugs involving bindings on structural elements. Consider this template: ``` <div *ngIf="true" [class.bar]="field"></div> ``` We were incorrectly emitting `ɵɵclassProp` on *both* the template's view, and the inner view. The solution is to just emit an extracted attribute on the enclosing template, so it still shows up in the const array, but does not affect the update block. We will refactor binding ingestion soon, but this commit improves our correctness before any big refactor.
Currently Template Pipeline's ingest phase is very complex, especially when it comes to ingesting bindings. In this commit, we make some superficial simplifications, in preparation for a larger refactoring. For example, we pull out common code such as `convertAstWithInterpolation` and the `i18n.Message` checks. This enormously shrinks the main binding ingestion functions. In addition, we reorder the binding kind and flags code above `ingestBindings`, so that `ingestBindings` and `ingestBinding` can be viewed together.
…ates Previously, we had `ingestBindings` and `ingestBinding`, which required tons of cases to support both elements and templates. Now, we have two separate functions, `ingestElementBindings` and `ingestTemplateBindings`. Thanks to the previous refactoring work, `ingestBinding` is now extremely compact. In fact, it's so compact that, in the elements case, it can just be inlined! Therefore, element binding ingestion is now quite easy to read. The template case continues to be pretty gnarly, although I have already removed some code. In subsequent commits, we will simplify it even further.
…f `createTemplateBinding` It turns out that `BindingFlags.BindingTargetsTemplate` is actally a redundant property! It will be true in either of the following cases: 1. The template is a normal non-structural `ng-template`. We already know this from `TemplateKind`. 2. The binding came from `templateAttrs` (instead of `attrs`). We have this information in `BindingFlags.IsStructuralTemplateAttribute`. Therefore, I can just eliminate `BindingFlags.BindingTargetsTemplate`. There's no reason to keep `BindingFlags` around for a single value, so I convert `BindingFlags.IsStructuralTemplateAttribute` to a boolean parameter (with the eventual goal of eliminating it entirely). Additionally, because element binding ingestion now calls `ir.createBindingOp` inline, it was difficult to compare it to template binding ingestion, which uses the `createTemplateBinding` helper. I have changed the parameter order of `createTemplateBinding` to closely mimic `ir.createBindingOp`. This will both make the code easier to read, and allow me to easily replace one with the other in the future. Lastly: the template binding ingestion function is the site of much of the binding ingestion complexity. Add an explanatory function comment.
dylhunn
force-pushed
the
template-ingestion
branch
from
December 9, 2023 23:35
81c447f to
cafbf59
Compare
alxhub
pushed a commit
that referenced
this pull request
Dec 11, 2023
…3457) Consider the case: ``` <button *ngIf="true" [@anim]="field"></button> ``` Only the inner `button` should recieve a `property` instruction for the animation binding. We were previously emitting one for the implicit `ng-template` as well, and collecting it into the consts for the `ng-template`. Both of these issues are now fixed. PR Close #53457
alxhub
pushed a commit
that referenced
this pull request
Dec 11, 2023
alxhub
pushed a commit
that referenced
this pull request
Dec 11, 2023
… template views (#53457) The Template Pipeline has had a number of tricky bugs involving bindings on structural elements. Consider this template: ``` <div *ngIf="true" [class.bar]="field"></div> ``` We were incorrectly emitting `ɵɵclassProp` on *both* the template's view, and the inner view. The solution is to just emit an extracted attribute on the enclosing template, so it still shows up in the const array, but does not affect the update block. We will refactor binding ingestion soon, but this commit improves our correctness before any big refactor. PR Close #53457
alxhub
pushed a commit
that referenced
this pull request
Dec 11, 2023
Currently Template Pipeline's ingest phase is very complex, especially when it comes to ingesting bindings. In this commit, we make some superficial simplifications, in preparation for a larger refactoring. For example, we pull out common code such as `convertAstWithInterpolation` and the `i18n.Message` checks. This enormously shrinks the main binding ingestion functions. In addition, we reorder the binding kind and flags code above `ingestBindings`, so that `ingestBindings` and `ingestBinding` can be viewed together. PR Close #53457
alxhub
pushed a commit
that referenced
this pull request
Dec 11, 2023
…ates (#53457) Previously, we had `ingestBindings` and `ingestBinding`, which required tons of cases to support both elements and templates. Now, we have two separate functions, `ingestElementBindings` and `ingestTemplateBindings`. Thanks to the previous refactoring work, `ingestBinding` is now extremely compact. In fact, it's so compact that, in the elements case, it can just be inlined! Therefore, element binding ingestion is now quite easy to read. The template case continues to be pretty gnarly, although I have already removed some code. In subsequent commits, we will simplify it even further. PR Close #53457
alxhub
pushed a commit
that referenced
this pull request
Dec 11, 2023
…f `createTemplateBinding` (#53457) It turns out that `BindingFlags.BindingTargetsTemplate` is actally a redundant property! It will be true in either of the following cases: 1. The template is a normal non-structural `ng-template`. We already know this from `TemplateKind`. 2. The binding came from `templateAttrs` (instead of `attrs`). We have this information in `BindingFlags.IsStructuralTemplateAttribute`. Therefore, I can just eliminate `BindingFlags.BindingTargetsTemplate`. There's no reason to keep `BindingFlags` around for a single value, so I convert `BindingFlags.IsStructuralTemplateAttribute` to a boolean parameter (with the eventual goal of eliminating it entirely). Additionally, because element binding ingestion now calls `ir.createBindingOp` inline, it was difficult to compare it to template binding ingestion, which uses the `createTemplateBinding` helper. I have changed the parameter order of `createTemplateBinding` to closely mimic `ir.createBindingOp`. This will both make the code easier to read, and allow me to easily replace one with the other in the future. Lastly: the template binding ingestion function is the site of much of the binding ingestion complexity. Add an explanatory function comment. PR Close #53457
alxhub
pushed a commit
that referenced
this pull request
Dec 11, 2023
…emplate` elements (#53457) The behavior of explicit bindings on `ng-template`s was untested, and we differed from `TemplateDefinitionBuilder` significantly. We now have much more similar behavior, although not 100% identical. For example, consider this templarte: ``` <ng-template l="l1" [p]="p1" [attr.a]="a1" [class.c]="c1"></ng-template> ``` It's not clear what a class binding on an `ng-template` would actually do. Nonetheless, it's well-defined behavior in TemplateDefinitionBuilder, which emits `property` instructions for all three bindings, and people actually do this in google3. Note that some of these bindings don't really make much sense, but we have to support them for compatibility purposes. See comments for an in-depth explanation of all the logic. Also, add a test to exercise the problematic case. PR Close #53457
alxhub
pushed a commit
that referenced
this pull request
Dec 11, 2023
…3457) Consider the case: ``` <button *ngIf="true" [@anim]="field"></button> ``` Only the inner `button` should recieve a `property` instruction for the animation binding. We were previously emitting one for the implicit `ng-template` as well, and collecting it into the consts for the `ng-template`. Both of these issues are now fixed. PR Close #53457
alxhub
pushed a commit
that referenced
this pull request
Dec 11, 2023
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
ChellappanRajan
pushed a commit
to ChellappanRajan/angular
that referenced
this pull request
Jan 23, 2024
… template views (angular#53457) The Template Pipeline has had a number of tricky bugs involving bindings on structural elements. Consider this template: ``` <div *ngIf="true" [class.bar]="field"></div> ``` We were incorrectly emitting `ɵɵclassProp` on *both* the template's view, and the inner view. The solution is to just emit an extracted attribute on the enclosing template, so it still shows up in the const array, but does not affect the update block. We will refactor binding ingestion soon, but this commit improves our correctness before any big refactor. PR Close angular#53457
ChellappanRajan
pushed a commit
to ChellappanRajan/angular
that referenced
this pull request
Jan 23, 2024
Currently Template Pipeline's ingest phase is very complex, especially when it comes to ingesting bindings. In this commit, we make some superficial simplifications, in preparation for a larger refactoring. For example, we pull out common code such as `convertAstWithInterpolation` and the `i18n.Message` checks. This enormously shrinks the main binding ingestion functions. In addition, we reorder the binding kind and flags code above `ingestBindings`, so that `ingestBindings` and `ingestBinding` can be viewed together. PR Close angular#53457
ChellappanRajan
pushed a commit
to ChellappanRajan/angular
that referenced
this pull request
Jan 23, 2024
…ates (angular#53457) Previously, we had `ingestBindings` and `ingestBinding`, which required tons of cases to support both elements and templates. Now, we have two separate functions, `ingestElementBindings` and `ingestTemplateBindings`. Thanks to the previous refactoring work, `ingestBinding` is now extremely compact. In fact, it's so compact that, in the elements case, it can just be inlined! Therefore, element binding ingestion is now quite easy to read. The template case continues to be pretty gnarly, although I have already removed some code. In subsequent commits, we will simplify it even further. PR Close angular#53457
ChellappanRajan
pushed a commit
to ChellappanRajan/angular
that referenced
this pull request
Jan 23, 2024
…f `createTemplateBinding` (angular#53457) It turns out that `BindingFlags.BindingTargetsTemplate` is actally a redundant property! It will be true in either of the following cases: 1. The template is a normal non-structural `ng-template`. We already know this from `TemplateKind`. 2. The binding came from `templateAttrs` (instead of `attrs`). We have this information in `BindingFlags.IsStructuralTemplateAttribute`. Therefore, I can just eliminate `BindingFlags.BindingTargetsTemplate`. There's no reason to keep `BindingFlags` around for a single value, so I convert `BindingFlags.IsStructuralTemplateAttribute` to a boolean parameter (with the eventual goal of eliminating it entirely). Additionally, because element binding ingestion now calls `ir.createBindingOp` inline, it was difficult to compare it to template binding ingestion, which uses the `createTemplateBinding` helper. I have changed the parameter order of `createTemplateBinding` to closely mimic `ir.createBindingOp`. This will both make the code easier to read, and allow me to easily replace one with the other in the future. Lastly: the template binding ingestion function is the site of much of the binding ingestion complexity. Add an explanatory function comment. PR Close angular#53457
ChellappanRajan
pushed a commit
to ChellappanRajan/angular
that referenced
this pull request
Jan 23, 2024
…emplate` elements (angular#53457) The behavior of explicit bindings on `ng-template`s was untested, and we differed from `TemplateDefinitionBuilder` significantly. We now have much more similar behavior, although not 100% identical. For example, consider this templarte: ``` <ng-template l="l1" [p]="p1" [attr.a]="a1" [class.c]="c1"></ng-template> ``` It's not clear what a class binding on an `ng-template` would actually do. Nonetheless, it's well-defined behavior in TemplateDefinitionBuilder, which emits `property` instructions for all three bindings, and people actually do this in google3. Note that some of these bindings don't really make much sense, but we have to support them for compatibility purposes. See comments for an in-depth explanation of all the logic. Also, add a test to exercise the problematic case. PR Close angular#53457
ChellappanRajan
pushed a commit
to ChellappanRajan/angular
that referenced
this pull request
Jan 23, 2024
…gular#53457) Consider the case: ``` <button *ngIf="true" [@anim]="field"></button> ``` Only the inner `button` should recieve a `property` instruction for the animation binding. We were previously emitting one for the implicit `ng-template` as well, and collecting it into the consts for the `ng-template`. Both of these issues are now fixed. PR Close angular#53457
ChellappanRajan
pushed a commit
to ChellappanRajan/angular
that referenced
this pull request
Jan 23, 2024
…ngular#53457) Responding to comments on angular#53457 about the previous sequence of template binding PRs. PR Close angular#53457
rlmestre
pushed a commit
to rlmestre/angular
that referenced
this pull request
Jan 26, 2024
… template views (angular#53457) The Template Pipeline has had a number of tricky bugs involving bindings on structural elements. Consider this template: ``` <div *ngIf="true" [class.bar]="field"></div> ``` We were incorrectly emitting `ɵɵclassProp` on *both* the template's view, and the inner view. The solution is to just emit an extracted attribute on the enclosing template, so it still shows up in the const array, but does not affect the update block. We will refactor binding ingestion soon, but this commit improves our correctness before any big refactor. PR Close angular#53457
rlmestre
pushed a commit
to rlmestre/angular
that referenced
this pull request
Jan 26, 2024
Currently Template Pipeline's ingest phase is very complex, especially when it comes to ingesting bindings. In this commit, we make some superficial simplifications, in preparation for a larger refactoring. For example, we pull out common code such as `convertAstWithInterpolation` and the `i18n.Message` checks. This enormously shrinks the main binding ingestion functions. In addition, we reorder the binding kind and flags code above `ingestBindings`, so that `ingestBindings` and `ingestBinding` can be viewed together. PR Close angular#53457
rlmestre
pushed a commit
to rlmestre/angular
that referenced
this pull request
Jan 26, 2024
…ates (angular#53457) Previously, we had `ingestBindings` and `ingestBinding`, which required tons of cases to support both elements and templates. Now, we have two separate functions, `ingestElementBindings` and `ingestTemplateBindings`. Thanks to the previous refactoring work, `ingestBinding` is now extremely compact. In fact, it's so compact that, in the elements case, it can just be inlined! Therefore, element binding ingestion is now quite easy to read. The template case continues to be pretty gnarly, although I have already removed some code. In subsequent commits, we will simplify it even further. PR Close angular#53457
rlmestre
pushed a commit
to rlmestre/angular
that referenced
this pull request
Jan 26, 2024
…f `createTemplateBinding` (angular#53457) It turns out that `BindingFlags.BindingTargetsTemplate` is actally a redundant property! It will be true in either of the following cases: 1. The template is a normal non-structural `ng-template`. We already know this from `TemplateKind`. 2. The binding came from `templateAttrs` (instead of `attrs`). We have this information in `BindingFlags.IsStructuralTemplateAttribute`. Therefore, I can just eliminate `BindingFlags.BindingTargetsTemplate`. There's no reason to keep `BindingFlags` around for a single value, so I convert `BindingFlags.IsStructuralTemplateAttribute` to a boolean parameter (with the eventual goal of eliminating it entirely). Additionally, because element binding ingestion now calls `ir.createBindingOp` inline, it was difficult to compare it to template binding ingestion, which uses the `createTemplateBinding` helper. I have changed the parameter order of `createTemplateBinding` to closely mimic `ir.createBindingOp`. This will both make the code easier to read, and allow me to easily replace one with the other in the future. Lastly: the template binding ingestion function is the site of much of the binding ingestion complexity. Add an explanatory function comment. PR Close angular#53457
rlmestre
pushed a commit
to rlmestre/angular
that referenced
this pull request
Jan 26, 2024
…emplate` elements (angular#53457) The behavior of explicit bindings on `ng-template`s was untested, and we differed from `TemplateDefinitionBuilder` significantly. We now have much more similar behavior, although not 100% identical. For example, consider this templarte: ``` <ng-template l="l1" [p]="p1" [attr.a]="a1" [class.c]="c1"></ng-template> ``` It's not clear what a class binding on an `ng-template` would actually do. Nonetheless, it's well-defined behavior in TemplateDefinitionBuilder, which emits `property` instructions for all three bindings, and people actually do this in google3. Note that some of these bindings don't really make much sense, but we have to support them for compatibility purposes. See comments for an in-depth explanation of all the logic. Also, add a test to exercise the problematic case. PR Close angular#53457
rlmestre
pushed a commit
to rlmestre/angular
that referenced
this pull request
Jan 26, 2024
…gular#53457) Consider the case: ``` <button *ngIf="true" [@anim]="field"></button> ``` Only the inner `button` should recieve a `property` instruction for the animation binding. We were previously emitting one for the implicit `ng-template` as well, and collecting it into the consts for the `ng-template`. Both of these issues are now fixed. PR Close angular#53457
rlmestre
pushed a commit
to rlmestre/angular
that referenced
this pull request
Jan 26, 2024
…ngular#53457) Responding to comments on angular#53457 about the previous sequence of template binding PRs. PR Close angular#53457
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Consider code like the following:
It's quite difficult to follow how the template pipeline ingests these bindings today.
attrsvstemplateAttrs, text vs const bindings, structural vs raw templates, bindings on templates that don't target them, property bindings in theTemplateconst field, etc. It's overwhelming.Fear no longer! This PR is dedicated to fixing ingestion of bindings on templates. The end goal is to make binding ingestion philosophically consistent and understandable when reading. Also, I hope to put a stop to the presubmit failures related to template bindings.
Several commits fix individual, specific issues with bindings on templates. Along the way, I have performed major refactors of the binding ingestion code. This occasionally touches ops and phases, although the bulk of the work is in
ingest.ts.Read individual commit messages in order, for details.