Commit graph

1814 commits

Author SHA1 Message Date
Kristiyan Kostadinov
b7fc7fdba9 refactor(compiler): integrate let declarations into the template binder (#56199)
Integrates the let declarations into the template binder which will be used to power the scoping behavior of the new syntax.

PR Close #56199
2024-06-04 17:28:03 +00:00
Kristiyan Kostadinov
6cef0ed3ed refactor(compiler-cli): add compiler flag for testing let declarations (#56199)
Adds a private `_enableLetSyntax` flag that allows for let declarations to be enabled in tests.

PR Close #56199
2024-06-04 17:28:02 +00:00
Kristiyan Kostadinov
9eef041211 refactor(compiler): implement let declarations in render3 ast (#55848)
Introduces a new `LetDeclaration` into the Render3 AST, simiarly to the HTML AST, and adds an initial integration into the various visitors.

PR Close #55848
2024-05-30 14:55:36 +00:00
Kristiyan Kostadinov
1ae06e4fc6 refactor(compiler): implement let declarations in html ast (#55848)
Adds a new `LetDeclaration` node to the AST that captures the `LetStart`, `LetValue` and `LetEnd` tokens into a single node.

PR Close #55848
2024-05-30 14:55:36 +00:00
Kristiyan Kostadinov
62c5b66b41 refactor(compiler): add support for tokenizing let declarations (#55848)
Updates the lexer to produce tokens for `let` declarations. Currently it' behind a flag while the feature is being worked on.

PR Close #55848
2024-05-30 14:55:36 +00:00
Kristiyan Kostadinov
6aeea69d5b fix(compiler): optimize track function that only passes $index (#55872)
Currently we optimize methods that pass both `$index` and the item into a method. We can take this a step further by also optimizing calls that only pass `$index` into the first parameter.

PR Close #55872
2024-05-23 14:02:30 +02:00
Kristiyan Kostadinov
08523ec650 fix(compiler): allow comments between connected blocks (#55966)
Fixes that the logic which looks for connected blocks didn't allow for comments between them.

Fixes #55954.

PR Close #55966
2024-05-21 10:37:58 -07:00
Bouguima, Walid
2bb12ac02f fix(compiler): prevent usage of reserved control flow symbol in custom interpolation context. (#55809)
* Fixes the issue where using a reserved control flow @ symbol in a custom interpolation context yields improper parser feedback.

PR Close #55809
2024-05-16 09:28:13 -07:00
Kristiyan Kostadinov
aa8df1d029 refactor(core): clean up clang comments and workarounds (#55750)
Since we aren't using clang anymore, we can remove the comments and the workarounds that were in place to prevent it from doing the wrong thing.

PR Close #55750
2024-05-13 11:10:36 -07:00
Kristiyan Kostadinov
533ec52aca refactor(compiler): move variable optimization earlier in pipeline (#55771)
Currently the variable optimization phase happens somewhat late in the process which is okay since the variables are generally static (e.g. `reference()` instruction calls). In some upcoming work we'll have variables that consume slots and require `advance` instructions. To allow for them to be optimized correctly, we need to move the variable optimization phase earlier, at least before we allocate the slots.

PR Close #55771
2024-05-13 11:09:26 -07:00
Alan Agius
3e1d6e9d6e fix(compiler): maintain multiline CSS selectors during CSS scoping (#55509)
Previously, multiline selectors were being converted into single lines, resulting in sourcemap disruptions due to shifts in line numbers.

Closes #55508

PR Close #55509
2024-05-06 12:39:50 -07:00
Kristiyan Kostadinov
2e891ad72a fix(compiler): add math elements to schema (#55631)
Fixes that we didn't have the MathML elements in the schema. Note that we can't discover which tag names are available by looking at globally-available classes, because all MathML elements are `MathMLElement` rather than something like `SVGCircleElement`. As such, I ended up having to hardcode the currently-available tags.

Fixes #55608.

PR Close #55631
2024-05-02 11:12:14 -07:00
Doug Parker
292c987791 refactor(compiler): add handler attribute to XMB output (#54865)
This allows tracking of which tools generated which XMB files and helps attribute Angular usage.

PR Close #54865
2024-04-29 11:56:31 -07:00
Kristiyan Kostadinov
97eea8d50e fix(core): resolve error for multiple component instances that use fallback content (#55478)
Currently fallback content for `ng-content` gets declared and rendered out in one go. This breaks down if multiple instances of the same component are used where one doesn't render the fallback content while the other one does, because the `TNode` for the content has to be created during the first creation pass.

These changes resolve the issue by always _declaring_ the template, but only rendering it if the slot is empty.

Fixes #55466.

PR Close #55478
2024-04-25 09:04:01 -07:00
Joey Perrott
8f69c83b84 refactor: migrate compiler to prettier formatting (#55398)
Migrate formatting to prettier for compiler from clang-format

PR Close #55398
2024-04-18 14:18:08 -07:00
Kristiyan Kostadinov
4eb0165750 fix(compiler): remove support for unassignable expressions in two-way bindings (#55342)
Two-way bindings are meant to represent a property binding to an input and an event binding to an output, e.g. `[(ngModel)]="foo"` represents `[ngModel]="foo" (ngModelChange)="foo = $event"`. Previously due to a quirk in the template parser, we accidentally supported unassignable expressions in two-way bindings.

In #54154 the quirk was fixed, but we kept support or some common expression because of internal usages. Now the internal usages have been cleaned up so the backwards-compatibility code can be deleted.

Externally a migration was added in #54630 that will automatically fix any places that depended on the old behavior.

BREAKING CHANGE:
Angular only supports writable expressions inside of two-way bindings.

PR Close #55342
2024-04-16 17:26:09 +02:00
Kristiyan Kostadinov
7d5bc1c628 fix(compiler): remove container index from conditional instruction (#55190)
Stops passing in the `containerIndex` argument to the `conditional` instruction since it isn't being used anymore.

PR Close #55190
2024-04-16 10:23:30 +02:00
cexbrayat
32eb23defb refactor(compiler): duplicate instructions in template pipeline (#54776)
Both `textInterpolate` and `collateInterpolationArgs` were doing the same work.

PR Close #54776
2024-04-16 10:21:52 +02:00
Kristiyan Kostadinov
39624c6b12 fix(compiler): output input flags as a literal (#55215)
Previously the input flags were being generated as a reference to an enum member for better readability and under the assumption that minifiers would inline the values. That doesn't appear to be the case so these changes switch to using the literal values instead.

PR Close #55215
2024-04-04 11:13:52 -07:00
Andrew Scott
38bb95a8f5 Revert "refactor(compiler): add support for the new search element (#54945)" (#55127)
This reverts commit 367b3ee6e9.
The search element is not a void element but existing components may use
the same selector and be used as a void element.

PR Close #55127
2024-03-29 12:56:31 -07:00
Matthieu Riegler
367b3ee6e9 refactor(compiler): add support for the new search element (#54945)
See #whatwg/html#5811
Spec: https://html.spec.whatwg.org/multipage/grouping-content.html#the-search-element

fixes #54944

PR Close #54945
2024-03-29 10:01:54 -07:00
Andrea Canciani
f3b624553a refactor: fix a number of typos throughout the codebase (#55018)
Fix some typos detected using spellchecking tools, both in
documentation and in code (comments, identifiers).

PR Close #55018
2024-03-27 10:54:31 -07:00
Kristiyan Kostadinov
cf8fb33a23 refactor(compiler-cli): integrate fallback content for ng-content into template type checker (#54854)
Adds logic to ingest the content of an `ng-content` element in the template type checker. We treat `ng-content` as a `ScopedNode`, because its content is inserted conditionally.

PR Close #54854
2024-03-26 09:17:58 -07:00
Kristiyan Kostadinov
8997837f3c refactor(compiler): pass default content to projection instruction (#54854)
Updates the code that generates the `projection` instruction to pass the template function containing the default content into it.

PR Close #54854
2024-03-26 09:17:58 -07:00
Kristiyan Kostadinov
c7348084f0 refactor(compiler-cli): capture ng-content children in AST (#54854)
Updates the template AST to capture the content of `ng-content` elements instead of throwing an error.

PR Close #54854
2024-03-26 09:17:58 -07:00
Kristiyan Kostadinov
e1650e3b13 fix(compiler): throw error if item name and context variables conflict (#55045)
Based on some internal feedback, these changes add validations to prevent cases where the `@for` loop variable name is the same as one of the built-in context variables, or when one of the context variables is aliased to the same name as the item.

PR Close #55045
2024-03-26 09:10:06 -07:00
Kristiyan Kostadinov
5bd188a394 feat(compiler-cli): add partial compilation support for deferred blocks (#54908)
Builds on top of the previous changes to add support for deferred blocks during partial compilation. To do this, the following changes had to be made:
* The metadata passed into `ɵɵngDeclareComponent` has an additional field called `deferBlockDependencies` which has an array of the dependency loading functions for each defer block in the template. During linking, the dependency functions are loaded by matching their template index to the index in the `deferBlockDependencies` array.
* There's a new `ɵɵngDeclareClassMetadataAsync` function that is created for components that have deferred dependencies. It gets transpiled to `setClassMetadataAsync` and works in the same way by capturing a dependency loading function and setting the metadata after the dependencies are resolved. It also has some extra fields for capturing the version which are standard in linker-generated code.
* Deferred import statements are now stripped in partial compilation mode, similar to full compilation.

PR Close #54908
2024-03-21 22:15:32 -07:00
Kristiyan Kostadinov
84410f58ae refactor(core): introduce API for declaring asynchronous partial metadata (#54908)
Adds the `ɵɵngDeclareClassMetadataAsync` function that will be produced during partial compilation for component classes that have deferred dependencies. At runtime the dependencies will be resolved before setting the metadata.

PR Close #54908
2024-03-21 22:15:31 -07:00
Kristiyan Kostadinov
102688bf83 refactor(compiler): widen type of resolver function (#54908)
Updates the type of the resolver function to be any `Expression` since JIT may receive a function reference rather than a `ArrowFunctionExpr`.

PR Close #54908
2024-03-21 22:15:30 -07:00
Kristiyan Kostadinov
36de5c3434 refactor(compiler): ensure defer blocks maintain the template order in the binder (#54908)
Switches to tracking the deferred blocks in a flat array in the binder to ensure that their template order is maintained. This will be relevant in the next commits where we'll match deferred blocks by their index.

Note that the current map we have technically guarantees the insertion order in the spec, but the array is a bit more explicit.

PR Close #54908
2024-03-21 22:15:30 -07:00
Kristiyan Kostadinov
a369f43fbd fix(compiler): capture switch block cases for content projection (#54921)
Captures the individual cases in `switch` blocks for content projection purposes.

PR Close #54921
2024-03-21 22:14:17 -07:00
Kristiyan Kostadinov
7fc7f3f05f fix(compiler): capture all control flow branches for content projection in if blocks (#54921)
Previously only the first branch of an `if` block was captured for content projection. This was done because of some planned refactors in the future. Since we've decided not to apply those refactors to conditionals, these changes update the compiler to capture each branch individually for content projection purposes.

PR Close #54921
2024-03-21 22:14:16 -07:00
Kristiyan Kostadinov
eb625d3783 fix(compiler): declare for loop aliases in addition to new name (#54942)
Currently when aliasing a `for` loop variable with `let`, we replace the variable's old name with the new one. Since users have found this to be confusing, these changes switch to a model where the variable is available both under the original name and the new one.

Fixes #52528.

PR Close #54942
2024-03-21 22:13:14 -07:00
Kristiyan Kostadinov
bfd0bd574e fix(compiler): invoke method-based tracking function with context (#54960)
Previously we assumed that if a `for` loop tracking function is in the form of `someMethod($index, $item)`, it will be pure so we didn't pass the parameter to bind the context to it. This appears to be risky, because we don't know if the method is trying to access `this`.

These changes play it safe by always binding method-based tracking functions.

Fixes #53628.

PR Close #54960
2024-03-21 22:08:40 -07:00
Kristiyan Kostadinov
879bd80b57 fix(compiler): capture data bindings for content projection purposes in blocks (#54876)
Fixes a regression in the template pipeline where data bindings weren't being captured for content projection purposes.

Fixes #54872.

PR Close #54876
2024-03-15 15:11:19 -07:00
Kristiyan Kostadinov
6ea208ee90 refactor(compiler-cli): move defer resolver compilation into compiler package (#54759)
Moves the logic that creates the defer resolver function into `@angular/compiler` for consistency with the rest of the compilation APIs. Also renames some of the symbols to make it clearer what they're used for.

PR Close #54759
2024-03-11 15:52:42 -07:00
Kristiyan Kostadinov
83932aa85e refactor(compiler): rework defer block analysis (#54759)
Currently we have the `deferrableDeclToImportDecl`, `deferBlocks`, `deferrableTypes` and `deferBlockDepsEmitMode` fields on the `R3ComponentMetadata` which is incorrect, because the interface is used both for JIT and AOT mode even though the information for those fields is AOT-specific. It will be problematic for partial compilation since the runtime will have a reference to the dependency loading function, but will not be able to provide any of the other information.

These changes make the following refactors:
1. It changes the defer-related information in `R3ComponentMetadata` to include only references to dependency functions which can be provided both in JIT and AOT.
2. Moves the AOT-specific defer analysis into the `ComponentResolutionData`.
3. Moves the construction the defer dependency function into the compilation phase of the `ComponentDecoratorHandler`.
4. Drops support for defer blocks from the `TemplateDefinitionBuilder`. This allows us to clean up some TDB-specific code and shouldn't have an effect on users since the TDB isn't used anymore.

PR Close #54759
2024-03-11 15:52:41 -07:00
Kristiyan Kostadinov
5ae2bf4806 fix(compiler): handle two-way bindings to signal-based template variables in instruction generation (#54714)
Updates the instruction generation for two-way bindings to only emit the `twoWayBindingSet` call when writing to template variables. Since template variables are constants, it's only allowed to write to them when they're signals. Non-signal values are flagged during template type checking.

Fixes #54670.

PR Close #54714
2024-03-11 11:01:43 -07:00
Kristiyan Kostadinov
81ccf5d102 fix(compiler): not catching for loop empty tracking expressions (#54772)
Fixes that the template parser wasn't catching empty expressions in the `track` parameter of for loops.

Fixes #54763.

PR Close #54772
2024-03-11 09:17:39 -07:00
Dylan Hunn
ef32b5322e refactor(compiler): Delete TemplateDefinitionBuilder and helpers (#54757)
`TemplateDefinitionBuilder` is the legacy template compiler, and was replaced by Template Pipeline as the default in v17.3.

This PR attempts to delete `TemplateDefinitionBuilder`, `ExpressionConverter`, and various helpers (i18n context, style builder, property visitors, etc).

Consider this a first pass: a lot of code has not yet been deleted (e.g. old TDB-specific test cases), and I'm sure I have missed additional helper code.

PR Close #54757
2024-03-08 16:51:01 -08:00
Andrew Scott
fb189c6997
Revert "refactor(compiler): rework defer block analysis (#54700)" (#54758)
This reverts commit eee620aa00.
2024-03-07 16:20:09 -08:00
Kristiyan Kostadinov
eee620aa00 refactor(compiler): rework defer block analysis (#54700)
Currently we have the `deferrableDeclToImportDecl`, `deferBlocks`, `deferrableTypes` and `deferBlockDepsEmitMode` fields on the `R3ComponentMetadata` which is incorrect, because the interface is used both for JIT and AOT mode even though the information for those fields is AOT-specific. It will be problematic for partial compilation since the runtime will have a reference to the dependency loading function, but will not be able to provide any of the other information.

These changes make the following refactors:
1. It changes the defer-related information in `R3ComponentMetadata` to include only references to dependency functions which can be provided both in JIT and AOT.
2. Moves the AOT-specific defer analysis into the `ComponentResolutionData`.
3. Moves the construction the defer dependency function into the compilation phase of the `ComponentDecoratorHandler`.
4. Drops support for defer blocks from the `TemplateDefinitionBuilder`. This allows us to clean up some TDB-specific code and shouldn't have an effect on users since the TDB isn't used anymore.

PR Close #54700
2024-03-07 12:40:44 -08:00
Dylan Hunn
126879e9d0 refactor(language-service): Make a variety of fixes to the language service to build in g3. (#54726)
The following changes help the language service code build in g3:
* `Omit<T>` produces an index signature, so we must access the resulting properties with square bracket (because `noPropertyAccessFromIndexSignature` is on in g3).
* Explicitly export `absoluteFrom` from `packages/compiler-cli/index.ts`, since the `*` re-export is patched out in g3.
* Remove const from a few const enums, since accessing const enums across modules is not compatible with `isolatedModules` (which is on in g3).

PR Close #54726
2024-03-07 10:49:01 -08:00
Dylan Hunn
b40f1e5b86 refactor(compiler): Remove deep imports in the language service (#54695)
Previously, the language service relied on deep imports such as `@angular/compiler/render3/...`. This is bad form, because that creates a dependency on the package's internal structure. Additionally, this is not compatible with google3.

In this PR, I replace all the deep imports with shallow imports, in some cases adding the missing symbol to the `compiler.ts` exports.

PR Close #54695
2024-03-05 10:28:45 +01:00
cexbrayat
5e32a775d9 refactor(compiler): cleanup unused code in template builder pipeline (#54654)
This removes some unused code and fixes a few typos across the pipeline code.

PR Close #54654
2024-03-04 18:15:54 +01:00
Dylan Hunn
1a6beae8a2 feat(compiler): Enable template pipeline by default. (#54571)
Template pipeline is now the default template compiler.

A pair of source map tests is failing, related to DI in JIT mode; I will fix and re-enable these during the preview period.

PR Close #54571
2024-02-23 11:15:36 -08:00
Kristiyan Kostadinov
badda0c389 fix(compiler-cli): correctly detect deferred dependencies across scoped nodes (#54499)
This is based on an internal issue report.

An earlier change introduced a diagnostic to report cases where a symbol is in the `deferredImports` array, but is used eagerly. The check worked by looking through the deferred blocks in a scope, resolving the scope for each and checking if the element is within the scope. The problem is that resolving the scope won't work across scoped node boundaries. For example, if there's a control flow statement around the block or within the block but around the deferred dependency, it won't be able to resolve the scope since it isn't a direct child, e.g.

```
@if (true) {
  @defer {
   <deferred-dep/>
  }
}
```

To fix this the case where the deferred block is inside a scoped node, I've changed the `R3BoundTarget.deferBlocks` to be a `Map` holding both the deferred block and its corresponding scope. Then to resolve the case where the dependency is within a scoped node inside the deferred block, I've added a depth-first traversal through the scopes within the deferred block.

PR Close #54499
2024-02-21 15:22:36 -08:00
Dmitry Ivanitskiy
dba3e0b5aa fix(compiler): adding the inert property to the "SCHEMA" array (#53148)
This change allows template binding "inert" attribute with the following syntax: [inert]="isInert"

Fixes #51879

fixup! fix(compiler): adding the inert property to the "SCHEMA" array

revert: "fixup! fix(compiler): adding the inert property to the "SCHEMA" array"

This reverts commit b637b7ce646e8bab2f585339028a84018e8ea982.

This commit is being reverted because the inert property is safe as a boolean attribute

PR Close #53148
2024-02-21 15:13:48 -08:00
Dylan Hunn
6c2d4b650b refactor(compiler): Enable Template Pipeline globally in 1P. (#54435)
The switch/index.ts file only affects g3; externally, it is replaced with a Blaze genrule.

PR Close #54435
2024-02-15 09:24:18 -08:00
Kristiyan Kostadinov
e921e108e1 refactor(core): correctly distinguish getter functions from writable signals (#54252)
Fixes that `ɵunwrapWritableSignal` inferring getter functions as not matching the interface of `WritableSignal` instead of preserving them.

PR Close #54252
2024-02-07 16:36:15 +00:00
Kristiyan Kostadinov
243b94c6e1 refactor(compiler-cli): fix regression in two-way bindings to inputs with different getter/setter types (#54252)
In a previous commit the TCB was changed to cast the assignment to an input in order to widen its type to allow `WritableSignal`. This ended up breaking existing inputs whose setter has a wider type than its getter. These changes switch to unwrapping the value on the binding side.

PR Close #54252
2024-02-07 16:36:13 +00:00
Kristiyan Kostadinov
a17f6cb2d0 refactor(compiler-cli): rework TCB for two-way bindings (#54252)
Reworks the TCB for two-way bindings to make them simpler and to avoid regressions for two-way bindings to generic inputs. The new TCB looks as follows:

```
var _t1: Dir;
var _t2 = _t1.input;
(_t1 as typeof _t2 | WritableSignal<typeof _t2>) = expression;
```

PR Close #54252
2024-02-07 16:36:11 +00:00
Kristiyan Kostadinov
67b977ea97 refactor(compiler-cli): allow writable signals in two-way bindings (#54252)
Updates the TCB generation logic to allow for `WritableSignal` to be assigned in two-way bindings.

PR Close #54252
2024-02-07 16:36:07 +00:00
Paul Gschwendtner
bfbb30618b fix(compiler-cli): do not error due to multiple components named equally (#54273)
Currently, when two components are named `TestComponent`, and both would
use e.g. control flow. Templates would be generated by the compiler and
those would conflict at runtime because the names for the template
functions are not ensured to be unique.

This seems like a more general problem that could be tackled in the
future in the template pipeline by always using the `ConstantPool`, but
for now, we should be good already, given us ensuring the `baseName`'s are
always unique.

PR Close #54273
2024-02-06 17:33:23 +00:00
Dylan Hunn
f600f0fb27 refactor(compiler): Show an error when a property binding duplicates an i18n attribute (#54063)
Consider the following very quirky Angular template, which has both an i18n attribute binding and a property binding to `in`:
```
<cmp [in]="foo" in="bar" i18n-in />
```

What would you expect the above template to do? `TemplateDefinitionBuilder` will emit the following Ivy instructions:
```
// Element constant attributes
consts: () => {
    __i18nMsg__('bar', [], {}, {})
    return [["in", i18n_0, __AttributeMarker.I18n__, "in"]];
}
// ...
function MyComponent_Template(rf, ctx) {
    if (rf & 1) {
        // Create mode
        i0.ɵɵelement(0, "cmp", 0);
    }
}
```

This makes some sense -- we create a single element, and attach an i18n message to the `in` attribute. But is this actually correct? Notice that the property binding is completely missing!

Indeed, Template Pipeline actually produces this code:
```
// Element constant attributes
consts: () => {
    __i18nMsg__('bar', [], {}, {})
    return [["in", i18n_0, __AttributeMarker.I18n__, "in"]];
}
// ...
function MyComponent_Template(rf, ctx) {
    if (rf & 1) {
        // Create mode
        i0.ɵɵelement(0, "cmp", 0);
    } else if (rf & 2) {
        // Update mode
        i0.ɵɵproperty("in", ctx.foo);
    }
}
```

Aha! There's the property binding! Arguably, this is a bug in `TemplateDefinitionBuilder`, but after some discussion on Slack, we have decided to ban this practice in a future Angular version.

For now, we allow Template Pipeline to have slightly different output, but print an error to warn the user of the issue.

PR Close #54063
2024-02-02 20:52:39 +00:00
Kristiyan Kostadinov
95dcf5fafa fix(compiler-cli): handle default imports in defer blocks (#53695)
Fixes that `@defer` blocks weren't recognizing default imports and generating the proper code for them. Default symbols need to be accessed through the `default` property in the `import` statement, rather than by their name.

PR Close #53695
2024-02-01 15:58:21 +00:00
Kristiyan Kostadinov
3b892e98b0 refactor(compiler): update ordering in template pipeline (#54154)
Updates the instruction ordering logic in the template pipeline.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov
ec8e8ab5d5 refactor(compiler): maintain order between two-way and one-way properties (#54154)
One of the earlier commits separated one-way and two-way bindings which ended up breaking some internal targets, because it changed the assignment order. These changes bring back the old order.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov
cbe6e1ffcf refactor(compiler): allow some invalid expressions in two-way bindings that previously worked by accident (#54154)
In one of the earlier commits, the logic that appends `=$event` before parsing two-way bindings was removed and some validation was added to prevent unassignable expressions from being used. This ended up being problematic, because previously the parser was incorrectly allowing some invalid expressions which users came to depend on. For example, it transformed `[(value)]="a && a.b"` to `a && (a.b = $event)`.

These changes add some special cases for the common breakages that came up during the TGP.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov
cbdfc88b24 refactor(compiler): implement new two-way listener shape in pipeline (#54154)
Implements the new shape of two-way listener instructions in the template pipeline.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov
4babc47b31 refactor(compiler): update two-way listener emit in definition builder (#54154)
Updates the template definition builder to emit the new format for the listener side of two-way bindings.

```js
// Before
listener("ngModelChange", function($event) {
  return ctx.name = $event;
});

// After
ɵɵtwoWayListener("ngModelChange", function($event) {
  ɵɵtwoWayBindingSet(ctx.name, $event) || (ctx.name = $event);
  return $event;
});
```

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov
a436e2d5ea refactor(compiler): preserve expression in two-way listeners (#54154)
Currently the listener side two-way listeners are parsed by appending `=$event` to the raw expression. This is problematic, because:
1. It can interfere with other expressions (see #37809).
2. It can lead to confusing error messages because users will see code that they didn't write.
3. It doesn't allow us to further manipulate the expression.

These changes remove the logic that appends `=$event` to resolve the issue. There's also some new logic that checks the expression after it has been parsed to ensure that the result is an assignable expression.

Subsequent commits will update the code that emits the expression to add back the `$event` assignment where it's needed.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov
e7a75d3ec2 refactor(core): introduce two-way listener instructions (#54154)
Adds the following new instructions:
* `twoWayBindingSet` - used to assign values inside of the listener side of a two-way binding. Currently a noop, but will come into play later.
* `twoWayListener` - used to bind a two-way listener. Currently calls directly into `listener`, but it may be useful in the future.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov
a22d765cca refactor(compiler): update access of members in expression parser (#54154)
Currently all the members of `_ParseAST` are public, even though they're all used only within the class. This change marks them as private so that it's explicit which ones are intended to be used outside the class.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov
ea7d1b363f refactor(compiler): implement two-way property instruction (#54154)
Reworks the compiler so that it generates a `twoWayProperty` instruction, instead of `property`, for the property side of a two-way binding. Currently the new instruction passes through to `property`, but it'll have some two-way-binding-specific logic in subsequent PRs.

PR Close #54154
2024-02-01 14:39:32 +00:00
Kristiyan Kostadinov
93188cb439 refactor(compiler): distinguish two-way bindings in the AST (#54065)
During the template parsing stage two-way bindings are split up into a property and event binding. All the downstream code treats these binding the same as their one-way equivalents. For some future work we'll have to distinguish between the two so these changes update the `BoundElementProperty.type` and `ParsedEvent.type` to include a `TwoWay` type. All existing call-sites have been updated to treat `TwoWay` the same as `Property`/`Regular`, but more specialized logic will be added in the future.

PR Close #54065
2024-01-25 16:31:57 +00:00
Dylan Hunn
c3bb00a2eb refactor(compiler): Fix defer deps fn duplicate names in Template Pipeline (#54060)
Previously, defer deps fns names were only prefixed with the component name, meaning that distinct deps fns in the same component would produce a name collision. Now, we take into account the entire template function name when naming inner deps fns.

PR Close #54060
2024-01-25 16:31:01 +00:00
Andrew Scott
eddf5dae5e fix(compiler): Update type check block to fix control flow source mappings (#53980)
The source mappings and types for various pieces of the control flow
were not quite right and prevented the language service from providing
accurate information.

fixes https://github.com/angular/vscode-ng-language-service/issues/1988

PR Close #53980
2024-01-24 18:37:58 -05:00
Dylan Hunn
47e6e84101 feat(compiler): Add a TSConfig option useTemplatePipeline (#54057)
The Template Pipeline is a brand new backend for the Angular compiler, replacing `TemplateDefinitionBuilder`. It generates the Ivy instructions corresponding to an input template (or host binding). The Template Pipeline has an all-new design based on an intermediate representation compiled over many phases, which will allow us to experiment with compiler changes more easily in the future.

With this commit, the template pipeline can now be enabled in any project via the `useTemplatePipeline` TSConfig option. However, it is still disabled by default.

PR Close #54057
2024-01-24 18:36:23 -05:00
Dylan Hunn
0f5f45c0fa refactor(compiler): Support externally provided defer deps fns (#54043)
In #53591, Andrew added local compliation support for defer blocks. However, this requires the ability to emit pre-generated static defer deps functions. We now also support that feature in Template Pipeline.

PR Close #54043
2024-01-24 18:35:24 -05:00
Paul Gschwendtner
77516450c8 refactor(compiler): support JIT for signal-based queries (#54019)
Similar to signal-based inputs, we support signal-based queries in JIT
by expecting a decorator to be added. This is a consequence of the
design, given that JIT requires query declaration information before
the class is initialized- but ironically there is no way to collect this
information without instantiating the class.

A JIT transform in the Angular CLI will automatically generate these
decorators for testing.

PR Close #54019
2024-01-24 16:13:31 +01:00
Paul Gschwendtner
3b6f636edf refactor(compiler-cli): collapse multiple query advance statements (#54019)
Collapses multiple sibling query advance statements into single
query advance invocations. This will help reducing generated code
for directives/components with many queries.

PR Close #54019
2024-01-24 16:13:31 +01:00
Paul Gschwendtner
998af3276f refactor(compiler-cli): move more query generation logic to dedicated file (#54019)
Without any modifications, this commit moves more of the the query
generation logic into its dedicated file.

PR Close #54019
2024-01-24 16:13:31 +01:00
Dylan Hunn
d99bc8aeb6 refactor(compiler): ICUs should roll up to the root i18n block for application (#54026)
Previously, if an ICU was inside a nested i18n root, it would use the nested root to calculate whether it should be applied. Now, we use the root i18n block.

PR Close #54026
2024-01-23 15:09:36 +01:00
Paul Gschwendtner
d4c84a97e8 refactor(compiler-cli): generate partial compilation output for signal-based queries (#53978)
This commit ensures that libraries can use signal-based queries, and the
partial compilation output will capture their metadata.

The linker is updated to support parsing this.

Two notes:

1. Older linker versions are not capable of parsing this, so the minimum
   version for signal-based queries is adjusted when such are used.
2. We only emit `isSignal` metadata for queries when signal queries are
   used. This enables libraries to continue supporting older linker
   versions, if signal-based queries are not used.

PR Close #53978
2024-01-23 10:24:36 +01:00
Paul Gschwendtner
8f936a4111 refactor(compiler-cli): recognize signal-based queries in class initializers (#53978)
This commit uses the initializer API recognition that we built for
signal-based inputs, and teaches the compiler to recognize class members
that refer to `viewChild`, `viewChildren`, `contentChild` or
`contentChildren`. Those will declare signal-based view or content queries.

PR Close #53978
2024-01-23 10:24:36 +01:00
Paul Gschwendtner
35ee10e357 refactor(compiler-cli): support generation of signal-based queries (#53978)
This commit introduces the compiler output generation for signal-based
queries. Signal-based queries will have new creation-mode instructions
and update instructions to advance the current query indices in the
global shared context.

An output like the following is the expected output for signal-based
queries:

```
i0.ɵɵdefineComponent({
  viewQuery: function App_Query(rf, ctx) {
      if (rf & 1) {
          i0.ɵɵviewQuery(ctx.d, _c0, 5);
          i0.ɵɵviewQuerySignal(ctx.ds1, _c0, 5);
          i0.ɵɵviewQuerySignal(ctx.ds2, _c0, 5);
      }
      if (rf & 2) {
          let _t;
          // only change-detected queries need explicit refresh
          i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.d = _t.first);
          // we bump up current query index by 2 positions since there are 2 signal-based queries
          i0.ɵɵqueryAdvance(2);
      }
      …
  },
  …
});

```

Note: For now, the collapsing of multiple advance instructions is not
implemented. This will be a follow-up.

Note 2: A couple of query helpers are now in their own file. This makes
it easier to focus on query-specific compiler code. The new function is
called `createQueryCreateCall`, which is a modified variant of the
existing function that previously only generated query parameters.

PR Close #53978
2024-01-23 10:24:36 +01:00
Matthieu Riegler
7dd56736e8 refactor(compiler): remove mentions of unused compiler options. (#53746)
Those options where removed in #49672.

PR Close #53746
2024-01-17 16:41:35 -08:00
Andrew Kushnir
b0e0f0014e refactor(compiler): extra diagnostics for @defer in local compilation mode (#53899)
This commit adds extra logic to produce a diagnostic in case `@Component.deferredImports` contain types from imports that also bring eager symbols. This would result in retaining a regular import and generating a dynamic import, which would not allow to defer-load dependencies.

PR Close #53899
2024-01-17 10:46:15 -08:00
Daniel Puckowski
66e940aebf feat(compiler): scope selectors in @starting-style (#53943)
make sure selectors inside @starting-style queries are correctly scoped

PR Close #53943
2024-01-17 09:14:11 -08:00
Andrew Kushnir
8ca0b0515d refactor(compiler): update TemplateDefinitionBuilder to support local compilation (#53591)
This commit updates the logic of the `TemplateDefinitionBuilder` to support local compilation and generate a single dependency function for all explicitly deferred deps within a component.

PR Close #53591
2024-01-10 15:28:58 -08:00
Andrew Kushnir
a2aa23d8b5 refactor(compiler): add support for internal deferredImports field (#53591)
This commit updates the logic to add support for internal `deferredImports` field in compiler.

PR Close #53591
2024-01-10 15:28:58 -08:00
Andrew Kushnir
6eb5e37d6f refactor(compiler): add an internal API to check is an element is inside a defer block (#53591)
This commit updates the logic to expose an internal API on the `R3BoundTarget` to check if an element belongs to any defer block.

PR Close #53591
2024-01-10 15:28:58 -08:00
Paul Gschwendtner
d7147507e4 refactor(core): properly emit input flags using bitwise or (#53808)
As part of testing we did accidentally use `bitwiseAnd` for the input
flags, given we started without an extra flag for `HasTransform`.

This commit teaches the compiler to support emitting bitwise OR
and uses it when combining input flags, fully re-enabling transforms
for signal components after the new flag mechanism was introduced in
previous commits.

PR Close #53808
2024-01-10 12:21:04 +00:00
Paul Gschwendtner
cfab5a59d6 refactor(core): detect signal input transforms independently of flag (#53808)
This commit changes the `HasTransform` flag to be only concerned with
decorator inputs. This allows us to automatically detect signal input
transforms without reliance on the flag, resulting in less complexity in
the compiler (as outlined in the design doc) and various  other places,
while it also allows us to simplify JIT support for signal inputs
because there would be no need to capture the "hasTransform" state in
the decorator so that JIT can generate the according input flags.

`isSignal` will still persist as an input flag to allow for monomorphic
and highly efficient distinguishing at runtime, whether an input is
signal based or not. JIT transform will also need to propagate this
information to the runtime somehow.

PR Close #53808
2024-01-10 12:21:04 +00:00
Paul Gschwendtner
eee0af0599 refactor(core): add internal signal input support for @Input decorator (#53808)
We are adding internal support for declaring signal inputs via the
`@Input` decorator. This is needed for JIT unit testing, or JIT
applications.

In JIT, Angular is not able to recognize signal inputs due to the
lack of static reflection metadata. Decorators attach their information
on the class- without it needing to be instantiated. This allows Angular
to know inputs when preparing/generating the directive definition. With
signal inputs this is not possible- so we need a way to tell Angular
about inputs for JIT applications. We've decided that this is not
something users should have to deal with, so a transform will be added
in a follow-up that will automatically derive/and add the decorators
for signal inputs when requested in JIT environments.

PR Close #53808
2024-01-10 12:21:04 +00:00
Kristiyan Kostadinov
2dedc4a969 fix(compiler): generate less code for advance instructions (#53845)
We generate `advance` instructions before most update instructions and the majority of `advance` calls are advancing by one. We can save some bytes for the most common case by omitting the parameter for `advance(1)` altogether.

PR Close #53845
2024-01-09 12:27:58 -08:00
Paul Gschwendtner
36318dbd41 refactor(compiler-cli): reference InputFlags enum directly for full compiler output (#53571)
Instead of computing the bit input flags at compile-time and inling
the final bit flag number, we will use the `InputFlags` enum directly.
This is a little more code in the compiler side, but will allow us to
have better debuggable development code, and also prevents problems
where runtime flag bitmasks differ from the compiler flag bitmasks.

This is in practice a noop for optimized applications as the enum values
would be inlined anyway. This matches existing compiler emit for e.g.
change detection strategy, or view encapsulation enums.

PR Close #53571
2024-01-04 12:07:13 -08:00
Paul Gschwendtner
1d95a832e3 refactor(core): detect signal inputs at runtime using input flags (#53571)
This commit introduces a new enum for capturing additional metadata
about inputs. Called `InputFlags`. These will be built up at compile
time and then propagated into the runtime logic, in a way that does
not require additional lookup dictionaries data structures, or
additional memory allocations for "common inputs" that do not have any flags.

The flags will incorporate information on whether an input is signal
based. This can then be used to avoid megamorphic accesses when such
input is set- as we'd not need to check the input field value. This also
avoids cases where an input signal may be used as initial value for an
input (as we'd not incorrectly detect the input as a signal input then).

The new metadata emit will be useful for incorporating additional
metadata for inputs, such as whether they are required etc (although
required inputs are a build-time only construct right now- but this is a
good illustration of why input flags can be useful). An alternative
could have been to have an additional boolean entry for signal inputs,
but allocating a number with more flexible input flags seems more future
proof and more reasonable andreadable.

More information on the megamorphic access when updating an input
signal
https://docs.google.com/document/d/1FpnFruviKb6BFTQfMAP2AMEqEB0FI7z-3mT_qm7lzX8/edit.

PR Close #53571
2024-01-04 12:07:13 -08:00
Dylan Hunn
ec661a3f0b refactor(compiler): Fix ambiguous repeater context variables in template pipeline (#53662)
In #52931, Kristiyan fixed a TemplateDefinitionBuilder bug in which derived alias variables in for loops (`$even`, `$first`, etc) were referring to the wrong level of nested `@for` block. (These variables are unique because they become inlined expressions, and are not "real" context variables.) He fixed this by appending level information to the generated alias name.

Template Pipeline actually suffered from the same bug. We fix it in a very similar way -- in particular, whenever these derived context variables are used, we make them depend on versions of `$index` and `$count` that have been suffixed with the xref of the enclosing repeater.

I have added a few more pipeline goldens, because we are not quite as clever as TDB about only generating the duplicate suffixed index and count variables when inside nested loops. This is fine, since in the long run, we want to refactor it more fundamentally.

I have also added a TODO to fix this more rigorously. In particular, it would be nice if we had proper support for shadowed variables, as well as unlimited levels of variables depending on one another.

PR Close #53662
2024-01-03 11:24:20 -08:00
Miles Malerba
3584a230e4 test(compiler): Fix mangling of camel case CSS vars in host bindings (#53665)
Template pipeline previously mangled CSS property names like
`--camelCase` when used in host style bindings. Note: It still *does*
mangle these names in static style attrs, both in host bindings and on
elements. This is clearly wrong, but is consistent with what TDB does
today.

PR Close #53665
2024-01-03 11:23:37 -08:00
Miles Malerba
330242595e refactor(compiler): Fix handling of namespaced attributes (#53646)
It's possible for attributes to have a namespace, we need to handle this
possiblity for both attribute instructions and attributes extracted to
the consts array.

PR Close #53646
2024-01-03 10:19:02 -08:00
Kristiyan Kostadinov
e5f02052cb fix(compiler): ignore empty switch blocks (#53776)
Adds some code to the compiler so that it ignores empty `@switch` blocks instead of trying to generate code for them.

Fixes #53773.

PR Close #53776
2024-01-03 10:15:17 -08:00
Miles Malerba
cc74ebfdf6 refactor(compiler): Rework how ICU placeholders are handled (#53643)
The way we were handling ICU placeholders was not compatible with using
interpolations on attributes of elements inside the ICU. This change
refactors the handling of ICU placeholders and unifies the way
expression and tag placeholders work inside ICUs.

The new approach modifies the ingest logic to add the placeholder on to
the TextOp rather than the TextInterpolationOp. This is because, in
ICUs, we may need multiple i18n expressions created from the
interpolation expressions to roll up into the same placeholder. ICUs
essentially do the interpolation at compile time, combining the static
strings with special placeholder strings that represent the expression
values.

PR Close #53643
2023-12-20 07:23:54 -08:00
Dylan Hunn
cafc3b0081 refactor(compiler): Drop the explicit this. in most explicit receivers (#53594)
Consider a case when an explicit `this` read is inside a template with a context that also provides the variable name being read:

```
<ng-template let-a>{{this.a}}</ng-template>
```

Clearly, `this.a` should refer to the class property `a`. However, in today's Angular, `this.a` will refer to `let-a` on the template context.

Amazingly, both TemplateDefinitionBuilder and the Typecheck block have the same bug, and are consistent with each other! This is because `ImplicitReceiver` extends `ThisReceiver` in the parser AST, which is an insane gotcha.

In this commit, I patch the template pipeline to emulate this behavior as well.

To actually fix this nastiness, we have to:
- Update `ingest.ts` in the Template Pipeline (see the corresponding comment)
- Check `type_check_block.ts` in the Typecheck block code (see the corresponding comment)
- Turn off legacy TemplateDefinitionBuilder
- Fix g3, and release in a major version

PR Close #53594
2023-12-19 13:46:11 -08:00
Dylan Hunn
89dd890046 refactor(compiler): Put projection instructions through the regular element const collection (#53594)
`ng-content` elements, and thus their corresponding projection instructions, can have many attributes on them. Some of these attributes may result in special behavior. For example, `ngProjectAs` and `i18n-foo` both result in special const collection, into the approprate BindingKind slot in the const array. Additionally, `i18n-foo` needs to recieve all the additional i18n attribute processing.

We solve this by subjecting `ng-content` attributes to all the same pipeline logic that applies to attributes on elements, and then allow the element const collection phase to collect them.

PR Close #53594
2023-12-19 13:46:11 -08:00
Dylan Hunn
9ecf0b31ca refactor(compiler): Host bindings do not const collect listener names (#53594)
For regular templates, any listener will have its name const collected into the bindings section of the element consts.

In contrast, host bindings omit listener names from their hostAttrs. This is a strange and inconsistent behavior, so we hide it behind a compatiblity mode flag.

PR Close #53594
2023-12-19 13:46:11 -08:00
Dylan Hunn
0b1144563b refactor(compiler): Host bindings have a different order for update instructions (#53594)
Annoyingly, TDB uses a separate code path for host bindings, and they have a different order.

PR Close #53594
2023-12-19 13:46:11 -08:00
Dylan Hunn
be54cc852c refactor(compiler): Don't allow pipe bindings in track functions (#53594)
For block track functions may not contain pipe bindings.

PR Close #53594
2023-12-19 13:46:11 -08:00
Dylan Hunn
3e7195764a refactor(compiler): Fix a naming collision in template pipeline (#53594)
We has some special behavior for naming identifiers in Template Pipline, for the sake of compatibility with TDB's source maps tests. However, this has the potential to cause a variable name collision in a particular special case (when the identifier is `ctx`). We add a special check for this, and also tuck all the backwards-compatible naming code inside a compatibility block.

PR Close #53594
2023-12-19 13:46:10 -08:00
Dylan Hunn
f89030b83e refactor(compiler): Add source maps support for i18n instructions (#53594)
i18n start/end instructions now take the source spans of the elements they refer to.

PR Close #53594
2023-12-19 13:46:10 -08:00
Kristiyan Kostadinov
478d622265 fix(compiler): project empty block root node in template pipeline (#53620)
Updates the template pipeline to allow for the root node of an `@empty` block to be content projected.

PR Close #53620
2023-12-19 08:37:33 -08:00
Kristiyan Kostadinov
df8a825910 fix(compiler): project empty block root node (#53620)
Expands the workaround from #52414 to allow for the root nodes of `@empty` blocks to be content projected.

Fixes #53570.

PR Close #53620
2023-12-19 08:37:33 -08:00
Miles Malerba
8460a4380c test(compiler): Fix handling of deceptively named attributes (#53626)
It's possible for the user to create a host attrbiute binding with a
name that makes it _look_ like a class binding `{['class.foo']: ''}`, we
were previously treating these as actual class property bindings. This
change fixes the logic so that only true property bindings cam be
converted to class property bindings.

Note: A user who added an attribute like the above almost certainly
intended to create an actual class property binding. It would be nice if
we could add a diagnostic to warn them about this.

PR Close #53626
2023-12-18 22:10:30 +00:00
Miles Malerba
73faf94273 refactor(compiler): Allow duplicate style and class consts (#53596)
Further refine the template pipeline's behavior w.r.t. duplicate values
in the consts array to better align its behavior with TDB. In particular
this means allowing duplicate values for classes and styles.

PR Close #53596
2023-12-18 22:09:26 +00:00
Miles Malerba
2ef1bb960e test(compiler): Add a test for handling of duplicate bindings (#53596)
Adds a test for handling of duplicate bindings. Fow now we replicate the
TDB behavior in template pipeline, which is: For style and class text
attributes, only keep the last one. For all other text attributes, add
all of the values to the consts array.

PR Close #53596
2023-12-18 22:09:26 +00:00
Miles Malerba
4c8e8e3714 refactor(compiler): support multiple statements in host listener (#53596)
Support multiple statements in a host listener, like we do for listeners
in the template. Also adds a test to verify the behavior.

PR Close #53596
2023-12-18 22:09:26 +00:00
Kristiyan Kostadinov
3a689c2050 fix(compiler): correctly intercept index in loop tracking function (#53604)
The for loop tracking function doesn't allow references to local template variables, aside from `$index` and the item which are passed in as parameters. We enforce this by rewriting all variable references to the components scope.

The problem is that the logic that rewrites the references first walks the view tree and then checks if the variable is `$index` or the item. This is problematic in nested for loops, because it'll find the `$index` of the parent.

These changes resolve the issue by checking for `$index` and the item first.

Fixes #53600.

PR Close #53604
2023-12-18 16:27:06 +00:00
Miles Malerba
dda656e054 refactor(compiler): Make attribute const collection less aggressive (#53580)
Changes template pipeline to be less aggressive in const collecting
attrs, to match the behavior of template definition builder. There is
nothing wrong with the more aggressive const collection, and in fact it
would be good to re-enable it later, but for now this makes it easier to
transition from TDB to template pipeline.

Also adds a test to verify that sensitive iframe attributes are properly
validated.

PR Close #53580
2023-12-18 16:26:03 +00:00
Dylan Hunn
c9879457f6 refactor(compiler): Not all attribute values beginning with a colon are namespaced (#53574)
TemplateDefinitionBuilder is apparently more careful about when it attempts to split namespaces in attribute values. However, we are doing this on style attributes, which might start with a single `:`. Rather than refactor our logic to only try to split namespaces in some cases, we can just add an option to make namespace splitting fail gracefully. We only use this option for attributes, not elements.

Note also: the compiled code for this, while "correct" is absolutely insane. Maybe we should consider fixing this, as a matter of principle.

PR Close #53574
2023-12-15 19:48:28 +00:00
Dylan Hunn
7ef5d9deef refactor(compiler): Support class and non-class attributes with the same name (#53574)
Some elements may have multiple bindings with the same name. We should accept and emit them all, as long as they have different kinds.

Co-authored-by: Miles Malerba <mmalerba@users.noreply.github.com>

PR Close #53574
2023-12-15 19:48:28 +00:00
Dylan Hunn
39767e764f refactor(compiler): Repeaters may consume a variable for their empty block (#53574)
Repeaters consume a variable slot only when they have an empty block.

PR Close #53574
2023-12-15 19:48:28 +00:00
Dylan Hunn
d1e7ce1b2d refactor(compiler): Host attribute bindings should always be extracted into hostAttrs (#53574)
Host attribute literal bindings should not result in an `attribute` update instruction.

PR Close #53574
2023-12-15 19:48:28 +00:00
Dylan Hunn
06286ce413 refactor(compiler): Defer when consumes a variable (binding) slot (#53574)
The template pipeline was previously not reserving a variable slot for the result of the `deferWhen` instruction, which caused the `defer when` feature to crash at runtime.

PR Close #53574
2023-12-15 19:48:28 +00:00
Dylan Hunn
ea71ff8ef7 refactor(compiler): Fix self-closing element source spans in template pipeline (#53574)
When an element is self-closing, it will cause an `element` instruction to be emitted (instead of `elementStart`/`elementEnd`). In that case, we should use map whole source span for the instruction, not just the starting span.

PR Close #53574
2023-12-15 19:48:28 +00:00
Dylan Hunn
a5565d176a refactor(compiler): Update a user visible error to match TDB (#53574)
This error about global event targets is user-facing; update it to match TDB's error verbatim.

PR Close #53574
2023-12-15 19:48:27 +00:00
Dylan Hunn
98277dacab refactor(compiler): Add an escape hatch to use non-unique const pool names (#53574)
The template pipeline was producing slightly different names than TemplateDefinitionBuilder for defer deps functions. I have added a workaround in the name of backwards compatibility, to avoid suffixing the const pool function names.

PR Close #53574
2023-12-15 19:48:27 +00:00
Miles Malerba
e8f00423fa refactor(compiler): Ensure correct context kind on ICU contexts (#53557)
Previously when we found an ICU that was the only translatable content
in its i18n block, we assigned the block's i18n context to the ICU.
However, we neglected to set the contextKind to inidcate that the
context was associated with an ICU. As of this change we now set the
correct contextKind.

This change also refactors the context creation to explicitly separate
creation of contexts for attributes, root i18n blocks, child i18n
blocks, and ICUs. This allows us to more easily ensure that contexts are
shared appropriately between i18n blocks and ICUs.

Finally, this change also refactors the i18n message extraction pahse to
simplify how contexts are converted to i18n messages. This
simplification should make it easier to merge i18n contexts and i18n
messages into a single op in a future refactor.

PR Close #53557
2023-12-14 09:33:52 -08:00
Paul Gschwendtner
abdc7e4578 feat(compiler-cli): support type-checking for generic signal inputs (#53521)
This commit adds the last remaining piece for signal input
type-checking. Bound values to signal inputs are already checked
properly at this point, but inference of generic directive/component
types through their inputs is not implemented.

This commit fixes this. To achieve this, there are a couple of potential
solutions. The generics of a directive are inferred based on input
value expressions using a so-called type constructor. The constructor
looks something like this:

```
const _ctor = <T>(v: Pick<Dir<T>, 'input1', 'input2'>) => Dir<T>;

_ctor({input1: expr1, input2: expr2});
```

This works very well for non-signal inputs where the class member is
directly holding the input values. For signal inputs, this does NOT
work because the class member will actually hold the `InputSignal`
instance. There are a couple of solutions to this:

1. Calling `_ctor` with an `InputSignal<typeof value>`
2. Converting the `_ctor` input signal fields to their write types
   (unwrapping the input signals).

We've decided to go with the second option as TypeScript is very
sensitive with assignments and its checks. i.e. co-variance,
contravariance or bivariance. Semantically it makes more sense to unwrap
the input signal "write type" directly and "assign to it". This is safer
and conceptually also easier to follow. A type constructor continues to
only receive the "expresison values". This simplifies code as well.

It's worth noting that the unwrapping as per option 2 also comes at a
cost. We need to be able to generate imports in type constructors. This
was not possible until the previous commit because inline type constructors
did not have an associated type-check block `Environment` and we were
missing access to expression translation and correct import generation.

Overall, solution 2 is now implemented as works as expected. This commit
adds additional unit tests to ensure this.

PR Close #53521
2023-12-13 15:44:00 -08:00
Paul Gschwendtner
5f7db018eb refactor(compiler-cli): finalize transform support for signal input transforms (#53521)
Signal inputs do not need coercion members for their transforms. That is
because the `InputSignal` type- which is accessible in the class member-
already holds the type of potential "write values". This eliminates the
need for coercion members which were simply used to somehow capture this
write type (especially when libraries are consumed and only `.d.ts` is
available).

We can simplify this, and also significantlky loosen restrictions
of transform functions- given that we can fully rely on TypeScript for
inferring the type. There is no requirement in being able to
"transplant" the type into different places- hence also allowing
supporting transform functions with generics, or overloads.

In a follow-up commit, once more parts are place, there will be some
compliance tests to ensure these new "loosend restrictions".

PR Close #53521
2023-12-13 15:44:00 -08:00
Paul Gschwendtner
8908fcd809 refactor(compiler-cli): initial type-checking for signal inputs (#53521)
This commit introduces the initial type-checking for signal inputs.
To enable type-checking od signal inputs, there are a couple of tricks
needed. It's not trivial as it would look like at first glance.

Initial attempts could have been to generate additional statements in
type-checking blocks for signal inputs to simply call a method like
`InputSignal#applyNewValue`. This would seem natural, as it would match
what will happen at runtime, but this would break the language-service
auto completion in a highly subtle way. Consider the case where multiple
directives match the same input. Consider the directives have some
overlap in accepted input values, but they also have distinct diverging
values, like:

```ts
class DirA {
  value = input<'apple'|'shared'>();
}

class DirB {
  value = input<'orange'|'shared'>();
}
```

In such cases, auto completion for the binding expression should suggest
the following values: `apple`, `shared`, `orange` and `undefined`.

The language service achieves this by getting completions in the
type-check block where the user expression would live. This BREAKS if
we'd have multiple places where the expression from the user is used.

Two different places, or more, surface additional problems with
diagnostic collection. Previously diagnostics would surface the union
type of allowed values, but with multiple places, we'd have to work with
potentially 1+ diagnostics. This is non-ideal.

Another important consideration is test coverage. It might sound
problematic to consider the existing test infrastructure as relevant,
but in practice, we have thousands of diagnostic type check block tests
that would greatly benefit if the general emit structure would still
match conceptually. This is another bonus argument on why changing the
way inputs are applied is probably an option we should consider as a
last resort.

Ultimately, there is a good solution where we unwrap directive signal
inputs, based on metadata, and access a brand type field on the
`InputSignal`. This ensures auto-completion continues to work as is, and
also the structure of type check blocks doesn't change conceptually. In
future commits we also need to handle type-inference for generic signal
inputs.

Note: Another alternative considered, in terms of using metadata or not.
We could have type helpers to unwrap signal inputs using type helpers
like: `T extends InputSignal<any, WriteT> ? WriteT : T`. This would
allow us to drop the input signal metadata dependency, but in reality,
this has a few issues:

- users might have `@Input`'s passing around `InputSignal`'s. This is
  unlikely, but shows that the solution would not be fully correct.
- we need the metadata regardless, as we plan on accessing it at runtime
  as well, to distinguish between signal inputs and normal inputs when
  applying new values. This was not clear when this option was
  considered initially.

PR Close #53521
2023-12-13 15:44:00 -08:00
Paul Gschwendtner
3e0e0b42fa refactor(compiler): emit signal input info in d.ts and generate partial compilation output (#53521)
This commit captures the metadata on whether an input is signal based or
not, in the `.d.ts` of directives and components. This exposes this
information to consumers of the directives. This is needed because
libraries may use signal inputs, and we need to know whether bound
inputs to this library are signal-based or not- so that we can generate
proper type-checking code (account for `InputSignal` or not).

Additionally, this commit introduces a new structure for the partial
compilation output of directive inputs. With the current emit, inputs
are captured in a data structure that is equivalent to the internal data
structure passed to `defineDirective` (the full compilation output).
This worked fine as we only captured a few strings, but in ends up
being a bad practice because partial compilation output should NOT
capture internal data structures that might be specific to a certian
Angular core version. Instead, we introduce a new "future proof"
structure that:

- can hold additional metadata in backwards-compatible ways, like
  `isSignal` or `isRequired`.
- can be parsed trivially using the `AstHost` for the linker, instead of
  having to unwrap/parse an array structure.

The new structure is only emitted when we discover that some inputs are
signal based (or ultimately end up configuring input flags). This is
done for backwards compatibility, so that libraries without signal
inputs remain compatible with older linker versions. In the future,
this might be the only emit.

Compliance tests for this follow in future commits, when the linker
portion is also in place. This commit specialices on the code
generation. With the linker, and compliance test infrastructure fixed
(that is broken right now), we can test the full integration.

PR Close #53521
2023-12-13 15:44:00 -08:00
Paul Gschwendtner
d0ff9b2ceb refactor(core): clean-up duplicate interface for input metadata in facade (#53521)
When working on integrating a new metadata field for inputs, I realized
there are quite a lot of duplications of interfaces. Turns out, the
facade input map type can be replaced in favor of just
`R3DirectiveInput`- even improving type safety-ness of e.g. the wrapped
node expressions of transform functions.

PR Close #53521
2023-12-13 15:44:00 -08:00
Dylan Hunn
84f143a80f refactor(compiler): Support o.WrappedNodeExpr inside expression conversion (#53478)
`o.WrappedNodeExpr` can show up in some cases, when a host binding's value is inside a TS expression.

It's an open question whether we will need to support all of the TS expression types as a result.

PR Close #53478
2023-12-13 09:21:53 -08:00
Dylan Hunn
6d1d55d2a2 refactor(compiler): Fix a bug involving listeners with targets (#53478)
For some reason, the parser reuses the same field to store the animation phase and the event target. We were incorrectly interpreting the presence of any value on that field as an animation phase, leading us to incorrectly emit synthetic listener instructions for listeners on events with targets. This bug is now fixes.

PR Close #53478
2023-12-13 09:21:53 -08:00
Dylan Hunn
8f2c824a70 refactor(compiler): Support $any in host bindings (#53478)
`$any` should be interpreted as a cast, not as a context read of a variable called `$any`. This already worked in template compilations, but the relevant phase was not enabled for host bindings.

PR Close #53478
2023-12-13 09:21:53 -08:00
Miles Malerba
00a1b3bd81 refactor(compiler): Add sanitization support for host bindings (#53513)
Adds support for sanitizing host bindings. Since the tag name of the
element the host binding is being set on isn't always known, we have to
consider multiple possible security contexts.

This commit also adds additional tests to help verify correct behavior
of the sanitization logic for different edge cases.

PR Close #53513
2023-12-12 14:30:11 -08:00
Miles Malerba
4f7d8f3bac refactor(compiler): Simplify how sanitizers are generated (#53473)
Previously we generated an intermediate expression which was later
converted into a symbol import expression for the sanitizer function.
This commit simplifies the behavior by just generating the symbol import
from the beginning

PR Close #53473
2023-12-12 09:00:36 -08:00
Miles Malerba
44bf6d6dec refactor(compiler): Generate trusted const values for extracted attrs (#53473)
Use the DomElementSchemaRegistry to determine the correct security
context for static attributes, and pass it along during ingestion. Then
during the resolve sanitizers phase, use the security context to
determine if a trusted value function is needed

PR Close #53473
2023-12-12 09:00:36 -08:00
Dylan Hunn
921964220d refactor(compiler): Make some fixups to template binidng ingestion (#53457)
Responding to comments on #53457 about the previous sequence of template binding PRs.

PR Close #53457
2023-12-11 14:03:43 -08:00
Dylan Hunn
41955b89b8 refactor(compiler): Fix animation bindings on structural elements (#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 #53457
2023-12-11 14:03:43 -08:00
Dylan Hunn
c4db46824d refactor(compiler): Fix some behavior with bindings on explicit ng-template 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
2023-12-11 14:03:43 -08:00
Dylan Hunn
0874ef5ecb refactor(compiler): Eliminate BindingFlags and reorder parameters of 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
2023-12-11 14:03:42 -08:00
Dylan Hunn
95fecddfe3 refactor(compiler): Split up binding ingestion for elements and templates (#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
2023-12-11 14:03:42 -08:00
Dylan Hunn
a2e4505bd2 refactor(compiler): Simplify some code in ingest (#53457)
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
2023-12-11 14:03:42 -08:00
Dylan Hunn
b44b115785 refactor(compiler): Don't emit class and style bindings on structural 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
2023-12-11 14:03:42 -08:00
Miles Malerba
3544f86775 refactor(compiler): Add i18n support for @defer blocks (#53440)
Pass through the i18n placeholders for the various parts of the defer
block during ingestion so its i18n message can be constructed

PR Close #53440
2023-12-08 14:32:31 -08:00
Miles Malerba
d35b457820 refactor(compiler): Ensure consistent handling of @empty template (#53440)
Phases that walk through the views by following template and repeater
ops need to remember to check the empty view as well for repeaters. This
commit adds fixes for phases that were missing it, or comments
explaining why its not handled.

PR Close #53440
2023-12-08 14:32:31 -08:00
Miles Malerba
36942d9b72 refactor(compiler): Add i18n support for @for blocks (#53440)
@for does not use actual TemplateOps, but instead has a similar
RepeaterCreateOp. This commit adds support for this op to the relevant
i18n phases.

PR Close #53440
2023-12-08 14:32:31 -08:00
Charles Lyding
f0377d33a1 refactor(compiler): provide a private API to perform direct style encapsulation (#53363)
To support the development of component specific HMR capabilities, the build/serve
tooling may need to directly process styles to match the view encapsulation
expectations of individual components. To allow for this scenario and to avoid tooling
to need to re-implement the emulated encapsulation logic, an private API is now
available in the `@angular/compiler` package named `encapsulateStyle` that converts
a stylesheet content string to an encapsulated form. This function is not considered
part of the public API nor does it have any of its respective support or versioning guarantees.

PR Close #53363
2023-12-08 14:29:18 -08:00
Dylan Hunn
44c2c26235 refactor(compiler): Fix out-of-order i18n issue (#53405)
Fix a bug in the i18n retargeting and reordering phase.

PR Close #53405
2023-12-08 09:37:56 -08:00
Dylan Hunn
8ab7e8474a refactor(compiler): Fix extra attribute on ng-template (#53405)
We no longer emit extra attribute instructions on certain `ng-template` elements with attributes.

PR Close #53405
2023-12-08 09:37:56 -08:00
Dylan Hunn
3ac6e3ef5b refactor(compiler): Keep a TemplateKind on various binding ops (#53405)
Previously, binding ops only knew whether they applied to a structural template (and even this was actually very misleading!).

Now, binding ops have full information about what kind of template they apply to, if any (e.g. plain template, structural template, etc). Additionally, each binding knows whether it `IsStructuralTemplateAttribute`, which is a property of the binding rather than the template target.

In the future, we should refactor this to unify the various flags that can describe binding types, as well as the flags that describe template targets, into a single and comprehensive field on binding ops.

PR Close #53405
2023-12-08 09:37:56 -08:00
Dylan Hunn
df25f462c5 refactor(compiler): Move the creation of i18n attribute contexts into a phase (#53405)
Previously, we created i18n contexts for i18n attributes in ingest. This turned out to be the wrong approach, because we don't always want to produce i18n messages for all i18n attributes! In fact, several kinds of i18n attributes on elements with structural directives should not produce their own messages.

This commit also contains related refactors to fix one such structural directives test.

PR Close #53405
2023-12-08 09:37:55 -08:00
Dylan Hunn
3bc5bd6be4 refactor(compiler): Don't create i18n context ops for attribute bindings on structural templates (#53405)
When a binding is present on an element with a structural directive, that binding is parsed onto *both* the synthetic `ng-template`, as well as the inner element. However, we do not want to create different i18n messages for both bindings; we only want to generate a new i18n message for the inner, "real" element.

PR Close #53405
2023-12-08 09:37:55 -08:00
Dylan Hunn
fe8cd6adf7 refactor(compiler): Listeners should be ingested before i18nStart (#53405)
Listener instructions should not be inside the i18n block. In order to avoid this, we ingest bindings on an element before starting the i18n block.

We previously missed this case because almost all bindings result in *update* instructions, which don't need to be ordered relative to i18nStart/i18nEnd create instructions. However, listeners are the only kind of binding that gets ingested into the create block.

PR Close #53405
2023-12-08 09:37:55 -08:00
Dylan Hunn
4950c8d19b refactor(compiler): Fix i18nExp moving phase in Template Pipeline (#53405)
Previously, our i18n slot moving process was buggy. Specifically, it was not resilient to cases in which a create op consumed a slot, but no update ops depended on that slot.

The new algorithm fixes this issue, and is also easier to understand.

PR Close #53405
2023-12-08 09:37:55 -08:00
Dylan Hunn
dc51f6ee3b refactor(compiler): Support unary ops in template pipeline (#53376)
Template Pipeline can now ingest and emit unary ops, such as `+` and `-`.

PR Close #53376
2023-12-06 09:43:35 -08:00
Dylan Hunn
29469ffb9b refactor(compiler): template pipeline support for i18n blocks (#53376)
Blocks can contain i18n expressions. We already have most of the logic to make them work; we were just missing some ingestion code.

PR Close #53376
2023-12-06 09:43:35 -08:00
Dylan Hunn
91eafa89cc refactor(compiler): Separate ownership and target for i18n expressions, and various refactors (#53376)
I18n expressions logically have both a target and an owner:
- For i18n text expressions, the owner is the i18nStart instruction. The target is initially the same, but later moves to be the last slot consumer in the i18n block.
- For i18n attribute expressions, the owner is the I18nAttributes config instruction, whereas the target is the ElementCreate that hosts the attribute.

This refactor makes the code clearer in quite a few plases.

Additionally, we now perform a lot of the i18n processing earlier. For example, re-targeting and re-ordering of i18n expressions happens *before* apply instructions are generated. As a result, the re-ordering logic is a lot simpler.

These changes also have consequences on i18n const collection, along with a couple other minor changes.

PR Close #53376
2023-12-06 09:43:35 -08:00
Dylan Hunn
05f9c7bd31 refactor(compiler): Initial support for i18n attributes (#53341)
Add support for i18n attributes:
- Generate i18n contexts from i18n attributes, and extract the eventual messages into the constant pool.
- Emit I18nAttributes config instructions when needed.
- Use the generated i18n variable in the appropriate places, including extracted attribute instructions, as well as I18nAttributes config arrays.

PR Close #53341
2023-12-05 17:13:58 -08:00
Miles Malerba
12dfa9ba13 test(compiler): Update golden partial file (#53327)
Update the golden partial file to include the newly added tests in this
PR.

PR Close #53327
2023-12-04 14:24:21 -08:00
Miles Malerba
4099bd0de6 refactor(compiler): Fix structural directive i18n placeholders (#53327)
Previously we recorded separate param values for a strucural directive
and the element tag it goes on. We then later attempted to combine those
into a single value. However in some cases this merging logic matched
the directive with the wrong tag.

This change implements an alternate approach where we match the
directive to its element tag from the start, while we're traversing the
ops. This should be a more robust solution.

PR Close #53327
2023-12-04 14:24:21 -08:00
Miles Malerba
9a0bf516c3 refactor(compiler): Add missing projection arguments (#53327)
We previously failed to populate the attributes property on projection
ops, this commit populates it and later strips out the "select"
attribute.

PR Close #53327
2023-12-04 14:24:21 -08:00
Miles Malerba
c555120d48 refactor(compiler): Add support for ng-content in i18n blocks (#53327)
Adds support for handling i18n paceholders on ng-content and adds a new
test to verify behavior.

PR Close #53327
2023-12-04 14:24:20 -08:00
Miles Malerba
0a1611d4cc refactor(compiler): Fix sub-template index for sibling i18n blocks (#53327)
Previously we failed to reset the sub-template index counter when we
exited a root block. This caused following sibling blocks to start
counting at the wrong index.

PR Close #53327
2023-12-04 14:24:20 -08:00
Miles Malerba
1baf26f589 refactor(compiler): Fix not expressions (#53327)
Adds `PrefixNot` to the handled expressions in the template pipeline

PR Close #53327
2023-12-04 14:24:20 -08:00
Miles Malerba
acd6100960 docs(compiler): Improve code comments (#53300)
Adds better comments describing the case where we have multiple ICU
sub-messages that share the same plaeholder.

PR Close #53300
2023-12-01 14:51:29 -08:00
Miles Malerba
8c34ad5d86 refactor(compiler): Fix ingestion of nested ICUs (#53300)
It is possible for ICUs to be nested inside other ICUs. This change
adjusts our ingestion logic to create extra interpolation ops for the
nested ICUs during ingestion.

PR Close #53300
2023-12-01 14:51:29 -08:00
Miles Malerba
2b3f06a8db refactor(compiler): Remove invalid assertion about i18n params (#53300)
We previously had an assertion that every placeholder in the i18n AST
had a corresponding param in the output. However, there are some cases
such as interpolations nested inside ICUs where this assertion is not
true. This change simply removes the asserion.

PR Close #53300
2023-12-01 14:51:29 -08:00
Miles Malerba
e23752c184 refactor(compiler): Add support for ICUs that share a placeholder (#53300)
ICUs may share a placeholder, and in that case they need special
post-processing. This change adds logic to cover this possibility. In
particular, we set the param to a special placeholder value and then
pass an array containing the sub-message variables as a post-processing
param.

PR Close #53300
2023-12-01 14:51:28 -08:00
Miles Malerba
4afa5ac2f9 refactor(compiler): Handle i18n placeholders with spaces (#53300)
I18n placeholders may contain spaces, this change updates the formatting
logic to replace them with underscores in the output.

PR Close #53300
2023-12-01 14:51:28 -08:00
Miles Malerba
a9fb5fa458 refactor(compiler): Put i18n expression ops in the correct order (#53300)
When we re-assign the slot dependencies for the i18nExprs, we should
move them down below the other ops that target their same slot. This
keeps the behavior consistent with TDB

PR Close #53300
2023-12-01 14:51:28 -08:00
Andrew Kushnir
77ac4cd324 fix(compiler): generate proper code for nullish coalescing in styling host bindings (#53305)
This commit fixes an issue where having an expression with nullish coalescing in styling host bindings leads to JS errors due to the fact that a declaration for a temporary variable was not included into the generated code.

Resolves #53295.

PR Close #53305
2023-12-01 09:12:20 -08:00
Miles Malerba
4c5f3b52dc refactor(compiler): Fix order of compound template/element param values (#53209)
As part of this fix, I realized that child i18n blocks don't need their
own context. Instead, we can just add their params directly to the
context for their root block, and forgo the step of merging the contexts.

PR Close #53209
2023-11-29 10:31:50 +01:00
Miles Malerba
2eadc955a3 refactor(compiler): Fix sub-template index logic (#53209)
Fixes a bug in the sub-template index logic that caused it to reuse
indices that had already been assigned to more deeply nested templates

PR Close #53209
2023-11-29 10:31:50 +01:00
Miles Malerba
898033f868 refactor(compiler): Fix i18n parms for structural directives (#53209)
Structural directives inside an i18n block previously resulted in a
"list" param value (represented as "[...|...]"). This commit adds a
special case to the template pipeline to collapse the list into a single
compound value like TemplateDefinitionBuilder does.

PR Close #53209
2023-11-29 10:31:50 +01:00
Miles Malerba
1881fb881a refactor(compiler): Record sub-messages as belonging to root i18n block (#53209)
ICU sub-messages should be recorded as belonging to the message for the
root i18n block they are part of. This ensures that they still get
emitted even if they are nested in a child template.

PR Close #53209
2023-11-29 10:31:50 +01:00
Miles Malerba
e1640f92ac refactor(compiler): Add contextType to I18nContextOp (#53209)
Adding a context type makes code that depends on the kind of context
more explicit and easier to follow

PR Close #53209
2023-11-29 10:31:50 +01:00
Kristiyan Kostadinov
897391ccbd refactor(compiler-cli): expose ng-content selectors and preserveWhitespaces during template type checking (#53190)
These changes expose the `ngContentSelectors` and `preserveWhitespaces` metadata to the TCB so they can be used in the next commit to implement a new diagnostic.

PR Close #53190
2023-11-28 11:18:43 +01:00
Kristiyan Kostadinov
11207deb5a refactor(compiler): expose utility for creating CSS selectors from AST nodes (#53190)
When doing directive matching in the compiler, we need to be able to create a selector from an AST node. We already have the utility, but these changes simplify the public API and expose it so it can be used in `compiler-cli`.

PR Close #53190
2023-11-28 11:18:43 +01:00
Kristiyan Kostadinov
c7c7ea9813 fix(core): inherit host directives (#52992)
Adds support for inheriting host directives from the parent class. This is consistent with how we inherit other features like host bindings.

Fixes #51203.

PR Close #52992
2023-11-20 13:16:15 -08:00
Kristiyan Kostadinov
406049b95e fix(compiler): generate i18n instructions for blocks (#52958)
Adds support for generating i18n instructions inside of blocks.

Fixes #52540.
Fixes #52767.

PR Close #52958
2023-11-20 08:59:25 -08:00
Kristiyan Kostadinov
5fb707f81a fix(compiler): produce placeholder for blocks in i18n bundles (#52958)
When blocks were initially implemented, they were represented as containers in the i18n AST. This is problematic, because block affect the structure of the message.

These changes introduce a new `BlockPlaceholder` AST node and integrate it into the i18n pipeline. With the new node blocks are represented with the `START_BLOCK_<name>` and `CLOSE_BLOCK_<name>` placeholders.

PR Close #52958
2023-11-20 08:59:24 -08:00
Kristiyan Kostadinov
715218a7dc Revert "refactor(compiler-cli): expose ng-content selectors and preserveWhitespaces during template type checking (#52726)" (#53012)
This reverts commit 4550a81bdc.

PR Close #53012
2023-11-17 11:52:01 -08:00
Kristiyan Kostadinov
356ca7e5d8 Revert "refactor(compiler): expose utility for creating CSS selectors from AST nodes (#52726)" (#53012)
This reverts commit adbea7befb.

PR Close #53012
2023-11-17 11:52:01 -08:00
Kristiyan Kostadinov
4550a81bdc refactor(compiler-cli): expose ng-content selectors and preserveWhitespaces during template type checking (#52726)
These changes expose the `ngContentSelectors` and `preserveWhitespaces` metadata to the TCB so they can be used in the next commit to implement a new diagnostic.

PR Close #52726
2023-11-17 08:08:40 -08:00
Kristiyan Kostadinov
adbea7befb refactor(compiler): expose utility for creating CSS selectors from AST nodes (#52726)
When doing directive matching in the compiler, we need to be able to create a selector from an AST node. We already have the utility, but these changes simplify the public API and expose it so it can be used in `compiler-cli`.

PR Close #52726
2023-11-17 08:08:40 -08:00
Kristiyan Kostadinov
d9d566d315 fix(compiler): nested for loops incorrectly calculating computed variables (#52931)
The `$first`, `$last`, `$even` and `$odd` variables in `@for` loops aren't defined on the template context of the loop, but are computed based on `$index` and `$count` (e.g. `$first` is defined as `$index === 0`). We do this calculation by looking up `$index` and `$count` when one of the variables is used.

The problem is that all `@for` loop variables are available implicitly which means that when a nested loop tries to rewrite a reference to an outer loop computed variable, it finds its own `$index` and `$count` first and it doesn't look up the ones on the parent at all. This means that the calculated values will be incorrect at runtime.

These changes work around the issue by defining nested-level-specific variable names that can be used for lookups (e.g. `$index` at level `2` will also be available as `ɵ$index_2`). This isn't the most elegant solution, however the `TemplatDefitinionBuilder` wasn't set up to handle shadowed variables like this and it doesn't make sense to refactor it given the upcoming template pipeline.

Fixes #52917.

PR Close #52931
2023-11-16 09:29:46 -08:00
Kristiyan Kostadinov
ec2d6e7b9c fix(compiler): changed after checked error in for loops (#52935)
Reworks the `repeater` instruction to go through `advance`, instead of passing in the index directly. This ensures that lifecycle hooks run at the right time and that we don't throw "changed after checked" errors when we shouldn't be.

Fixes #52885.

PR Close #52935
2023-11-15 21:13:36 +00:00
Miles Malerba
70fe5e60b3 refactor(compiler): Handle trailing spaces in ICU placeholders (#52698)
In some cases ICU expression placeholders may have trailing spaces that
need to be trimmed when matching the placeholder to its corresponding
text binding.

PR Close #52698
2023-11-10 17:01:07 +00:00
Miles Malerba
2c3b6c6e27 refactor(compiler): Fix some issues with i18n expressions in ICUs (#52698)
We were previously counting the i18n expression index and deciding when
to apply i18n expressions based on the i18n context. These should be
done based on the i18n block instead.

PR Close #52698
2023-11-10 17:01:07 +00:00
Miles Malerba
0864dbe571 refactor(compiler): Change how ICUs are ingested (#52698)
The previous commit added support for interpolated text in ICUs, but it
made the assumption that the interpolation would be a single variable
read expression.

To properly support all kinds of interpolation expressions, this commit
refactors how ICUs are ingested to allow us to re-use the same logic we
use for bound text outside of ICUs.

To accomplish this, the `IcuOp` creation op has been removed in favor of
a pair of ops: `IcuStartOp` and `IcuEndOp`, that mark the beginning and
end of the ICU. Now, instead of inserting an `IcuUpdateOp` in the update
IR, we call `ingestBoundText` and use the presence of the surrounding
`IcuStartOp` and `IcuEndOp` to match the interpolation with the ICU.

PR Close #52698
2023-11-10 17:01:07 +00:00
Miles Malerba
3a0ac32dcb refactor(compiler): Support expressions inside ICUs (#52698)
Previously ICUs were assumed to only generate a single i18n expression
per ICU. However, it is possible for ICUs to contain text interpolations
which requires additional expressions. This commit adds support for
multiple expressions per ICU.

PR Close #52698
2023-11-10 17:01:06 +00:00
Miles Malerba
ef6999f2f6 refactor(compiler): Support element tags inside ICUs (#52698)
ICUs that contain element tags need extra parameters for the i18n
message. These are in addition to the element slot params that are
already added to the parent i18n block's params. In this commit we add a
new phase to fill in these placeholders.

PR Close #52698
2023-11-10 17:01:06 +00:00
Miles Malerba
50a06fa451 refactor(compiler): More consistent sorting of i18n params (#52698)
Previously the template pipeline sorted i18n message params before
adding the sub-message placeholders. Now its sorts after all
placeholders are added.

Both the template pipeline and TemplateDefinitionBuilder previously
failed to sort the post-processing params. They both now sort these as
well. This is safe to change in TemplateDefinitionBuilder, as it does
not change anything about the functionality, it simply ensures that
params map in the output has the keys ordered in a way that can be
easily reproduced in the template pipeline.

PR Close #52698
2023-11-10 17:01:06 +00:00
Dylan Hunn
699ae60df2 refactor(compiler): Fix two-way binding source maps (#52479)
Now that two-way bindings work correctly with implicit receivers, we can fix the corresponing source map tests. The main issue was that we were not properly mapping `elementEnd` for elements with no closing tag (self-closing elements).

PR Close #52479
2023-11-06 11:42:59 -08:00
Dylan Hunn
97b1377402 refactor(compiler): Fix two-way bindings in template pipeline (#52479)
Some two-way bindings tests were not working properly, because we could not ingest the implicit receiver required to write to the `ngModelChanges` property. Now, we properly resolve that implicit receiver to the root component context.

Also, add some tests, both for the simple case, and the case where the listener is inside a nested view.

PR Close #52479
2023-11-06 11:42:59 -08:00
Dylan Hunn
ee5d60b29b refactor(compiler): Support extracting deps functions for defer in template pipeline (#52479)
Some `defer` blocks have external dependencies on other components or directives. These dependencies need to be extracted into deps functions, which either return local deps, or use a dynamic import for non-local deps. Template Pipeline can now generate these functions.

PR Close #52479
2023-11-06 11:42:59 -08:00
Dylan Hunn
8b1b6d5678 refactor(compiler): Emit a template ref extractor on ng-templates with local refs (#52479)
When an `ng-template` has local refs, such as `<ng-template #foo>`, we must emit a `ɵɵtemplateRefExtractor` argument to the template creation functino. The template pipeline now supports this.

PR Close #52479
2023-11-06 11:42:59 -08:00
Dylan Hunn
02c6a1192a refactor(compiler): Support defer triggers with no arguments in template pipeline (#52479)
Some defer triggers, such as `hover`, expect a local reference as an argument. For example, `@defer (on hover(target))` waits until the user hovers over the target.

However, these defer conditions also have a nullary form, in which the trigger is implicitly the first element in the placeholder block. We now support that case in template pipeline.

PR Close #52479
2023-11-06 11:42:58 -08:00
Dylan Hunn
2715eecc9c refactor(compiler): Support deferWhen instructions in template pipeline (#52479)
We already supported `defer on` conditions, which become instructions in the create mode block.

Now, we also support `defer when` conditions, where are very similar, with the notable difference that they go in the update block (because a user-supplied condition must be re-evaluated on each update.)

PR Close #52479
2023-11-06 11:42:58 -08:00
Miles Malerba
89cfadd196 refactor(compiler): Add more comments for i18n template pipeline phases (#52503)
Adds some additional comments about the i18n termplate pipeline phases
to more clearly document how they work.

PR Close #52503
2023-11-06 09:49:47 -08:00
Miles Malerba
0c6a911919 refactor(compiler): Add support for ICUs as part of another i18n message (#52503)
Previously we supported ICUs where the ICU itself represetned the entire
translated message. This change allows ICUs to act as a sub-message
inside other translated messages.

PR Close #52503
2023-11-06 09:49:47 -08:00
Miles Malerba
09039beb1e refactor(compiler): Introduce i18n context objects (#52503)
Previously we assumed that all i18n messages that are eventually
extracted into the consts array would be generated based on an i18n
block. However, it is also possible to have messages generated directly
from ICUs. This change introduces an i18n context op, so that we can
consistently extract i18n messages from the context op in all cases.

PR Close #52503
2023-11-06 09:49:47 -08:00
Kristiyan Kostadinov
9cfd35a594 fix(compiler): ng-template directive invoke twice at the root of control flow (#52515)
Discovered this while validating #52414 against Angular Material. We were projecting `<ng-template>` nodes at the root of `@if` and `@for` with the `ng-template` tag name which enables directive matching and applies the directive to the control flow node.

These changes fix the issue by never passing along the `ng-template` tag name.

PR Close #52515
2023-11-06 09:03:45 -08:00
Aanchal Agarwal
25600375a3 docs: omit repetitions (#52413)
PR Close #52413
2023-11-03 07:46:54 -07:00
Dylan Hunn
184d8246cb refactor(compiler): Delete some unused imports in template pipeline (#52464)
Remove a variety of unused imports.

PR Close #52464
2023-11-02 10:58:48 -07:00
Dylan Hunn
95644569e9 refactor(compiler): Rename slot -> handle in slot consumers (#52464)
This name is a bit more precise, and avoids the `foo.slot.slot` "stuttering access" on consumers.

PR Close #52464
2023-11-02 10:58:47 -07:00
Dylan Hunn
6347e0ebf4 refactor(compiler): Move an enum to enums.ts for Template Pipeline (#52464)
This enum belongs in the main enums file.

PR Close #52464
2023-11-02 10:58:47 -07:00
Dylan Hunn
3cd86f4cfc refactor(compiler): Delete an unused OpKind in template pipeline. (#52464)
`DeferSecondaryBlock` is no longer used.

PR Close #52464
2023-11-02 10:58:47 -07:00
Dylan Hunn
df40843dc0 refactor(compiler): Replace cpl with job in template pipeline (#52464)
Eliminate all the remaining `cpl` names, and use `job` instead, which is the predominant convention.

Also, replace `.views.values()` with `.unit` in a few places, and perform the corresponding rename.

PR Close #52464
2023-11-02 10:58:47 -07:00
Dylan Hunn
84ceb74f6c refactor(compiler): Rename and comment template pipeline phases (#52464)
In this cleanup commit:
1. Add explanatory comments to all phases that were previously missing them.
2. Rename all phases, to eliminate the "phase" prefix, and directly describe their functions.

PR Close #52464
2023-11-02 10:58:47 -07:00
Kristiyan Kostadinov
c7b730eb72 refactor(compiler): implement control flow content projection fix in template pipeline (#52414)
Recreates the fix for content projection in control flow in the new template pipeline. I also had to make the following adjustments to the pipeline:
1. The `TemplateOp.tag` property was being used to generate the name of the template function, rather than the actual tag name being passed into `ɵɵtemplate`. Since the content projection fix requires the tag name to be passed in, I've introduced a new `functionNameSuffix` property instead.
2. `TemplateOp.block` was being used to determine whether to pass `TemplateOp.tag` into the `ɵɵtemplate` instruction. Now that we're always passing in the tag name after the refactor in point 1, we no longer need this flag.

In addition to the refactors above, I also made some minor cleanups where I saw the opportunity to do so.

PR Close #52414
2023-10-31 14:52:30 -07:00
Kristiyan Kostadinov
eb15358479 fix(compiler): project control flow root elements into correct slot (#52414)
With the directive-based control flow users were able to conditionally project content using the `*` syntax. E.g. `<div *ngIf="expr" projectMe></div>` will be projected into `<ng-content select="[projectMe]"/>`, because the attributes and tag name from the `div` are copied to the template via the template creation instruction. With `@if` and `@for` that is not the case, because the conditional is placed *around* elements, rather than *on* them. The result is that content projection won't work in the same way if a user converts from `*ngIf` to `@if`.

These changes aim to cover the most common case by doing the same copying when a control flow node has *one and only one* root element or template node.

This approach comes with some caveats:
1. As soon as any other node is added to the root, the copying behavior won't work anymore. A diagnostic will be added to flag cases like this and to explain how to work around it.
2. If `preserveWhitespaces` is enabled, it's very likely that indentation will break this workaround, because it'll include an additional text node as the first child. We can work around it here, but in a discussion it was decided not to, because the user explicitly opted into preserving the whitespace and we would have to drop it from the generated code. The diagnostic mentioned point #1 will flag such cases to users.

Fixes #52277.

PR Close #52414
2023-10-31 14:52:30 -07:00
Kristiyan Kostadinov
d7c4f569f4 fix(compiler): allow decimals in defer block time values (#52433)
Fixes that our regex for parsing time values in defer blocks didn't allow for decimals. This isn't relevant for times in milliseconds, but it can be convenient to write something like `on timer(1.5s)`.

PR Close #52433
2023-10-31 13:39:27 -07:00
Kristiyan Kostadinov
245a6b3f23 refactor(compiler): account for comments when resolving implicit deferred triggers (#52449)
Adds some logic to skip over comments when resolving implicit `@defer` block triggers. This currently isn't a problem since we don't capture comments by default, but it may come up if we start capturing comments.

PR Close #52449
2023-10-31 13:34:59 -07:00
Kristiyan Kostadinov
5f528bfb41 fix(compiler): allow comments between switch cases (#52449)
Fixes that the template parser was throwing an error if a comment is used directly inside an `@switch` block.

Fixes #52421.

PR Close #52449
2023-10-31 13:34:59 -07:00
Kristiyan Kostadinov
b5ef68ff0f fix(compiler): compilation error when for loop block expression contains new line (#52447)
Fixes that the regex which captures the expression of a `@for` loop block wasn't accounting for line breaks.

Fixes #52446.

PR Close #52447
2023-10-31 13:30:42 -07:00
Andrew Scott
bf5bda448f refactor(language-service): Add quick info for built in control flow/blocks (#52386)
Adds hover info for:

* Defer blocks
* Triggers and trigger behavior keywords
* For loop empty block
* Track keyword in for loop block

resolves https://github.com/angular/vscode-ng-language-service/issues/1946

PR Close #52386
2023-10-31 12:56:45 -07:00
Dylan Hunn
73c5d1c04a refactor(compiler): Implement the remaining defer on triggers (#52387)
The previous commits provided the scaffolding for `defer on`. In this commit, we build on that work, adding triggers for `immediate`, `timer`, `hover`, and `viewport`.

PR Close #52387
2023-10-31 12:45:18 -07:00
Dylan Hunn
79684499e4 refactor(compiler): Introduce ConstCollectedExpr, and use it in defer on expressions (#52387)
Previously, we supported a `HasConst` trait, allowing an op to be const collected automatically. However, that approach had the shortcoming that each op could only collect a single constant.

Instead, we now provide a `ConstCollectedExpr`, which collects constants at the expression level, allowing ops to have multiple collectible consts.

Then, we use this new abstraction to support the `defer on` conditions.

PR Close #52387
2023-10-31 12:45:18 -07:00
Dylan Hunn
6c507e75a6 refactor(compiler): Implement defer conditions, and change the way slots are linked (#52387)
Previously, we had an "empty shell" implementation of defer conditions, and we used separate ops to represent secondary defer blocks.

Now, we have a real scaffolding for supporting the various defer conditions, and the secondary defer block information has been refactored onto the main defer op.

Additionally, to enable this, we refactor the way that using slot indices works. Instead of having a trait that causes users of slot indices to be linked to the allocated slot, we share a single `SlotHandle` object by reference. This allows an op to use slot information for more than one Xref at a time, and eliminates a layer of indirection.

Co-authored-by: Alex Rickabaugh <alxhub@users.noreply.github.com>

PR Close #52387
2023-10-31 12:45:18 -07:00
Miles Malerba
99805323bb refactor(compiler): Split the i18n placeholder mega-phase (#52390)
The i18n placeholder resolution phase has accumulated too much logic,
making it difficult to understand. This commit refactors it into several
smaller phases to make it easier to manage.

I suspect this will undergo further refactoring in the near future as I
work through the ICU logic. In particular `ExtractedMessageOp` feels
like a bit of a grab bag of properties, and the i18n const collection
phase is also starting to get quite heavy. This refactor at least feels
like a good start.

PR Close #52390
2023-10-27 16:16:04 -07:00
Dylan Hunn
d82d58621e refactor(compiler): Don't double-create pipes in switch cases (#52289)
Previously, we would emit *two* pipe creation instructions for each pipe in a switch case. This is because we were visiting both the transformed and raw versions of the pipe bindings.

Now, we clear the raw case expressions array after generating the transformed test expression.

Also, we introduce some new goldens, because our pipe creation order is harmlessly different.

PR Close #52289
2023-10-24 11:07:50 -07:00
Dylan Hunn
17be1a8aca refactor(compiler): Support content projection source maps (#52289)
The `projection` op should map onto the entire corresponding `ng-content`.

PR Close #52289
2023-10-24 11:07:50 -07:00
Dylan Hunn
3343ceb82d refactor(compiler): Update pipe test golden for alternative create order (#52289)
We roughly attempt to match TemplateDefinitionBuilder's pipe creation order, by placing pipe creation instructions after their target elements. However, we cannot fully emulate the "inside-out" ordering TemplateDefinitionBuilder uses when multiple pipes apply to one element, because TemplateDefinitionBuilder creates the pipes as expressions are visited, from the leaves up. Our order is perfectly adequate though.

We also add a non-compatibility-mode ordering, which just appends them to the end of the create block. This is better because it allows for more chaining opportunities.

PR Close #52289
2023-10-24 11:07:49 -07:00
Dylan Hunn
0491fba523 refactor(compiler): Fix a special case involving var counting for singleton propertyInterpolate (#52289)
Singleton property interpolation instructions consume only one variable, but are still emitted as an interpolation instruction (they cannot be collapsed because `propertyInterpolate` implicitly stringifies its argument.)

PR Close #52289
2023-10-24 11:07:49 -07:00
Dylan Hunn
f6cc09b0f4 refactor(compiler): The projection instruction takes an array literal (#52289)
We were incorrectly emiting a extracted constant pool index for the final argument of the projection instruction. It actually takes an array literal.

(N.B.: This means we re-create the array every time! We should probably modify the runtime to use a const index for this.)

Additionally, we alter the projection op to not extend the element op base type.

PR Close #52289
2023-10-24 11:07:49 -07:00
Dylan Hunn
9f839272bd refactor(compiler): Improve the ordering of update ops (#52289)
The correct order of attributes and properties is:

1. Interpolated properties
2. Interpolated attributes
3. Non-interpolated properties
4. Non-interpolated attributes

This includes an additional nuance: singleton attribute interpolations, such as `[attr.foo]="{{bar}}"`, will be "collaped" into a simple `attribute` instruction. However, this is *not* the case for singleton property interpolations! The ordering phase must take this nuance into account to match the TemplateDefinitionBuilder order.

After the project lands, it might be nice to also collapse singleton property interpolations.

PR Close #52289
2023-10-24 11:07:49 -07:00
Dylan Hunn
d55ff744e3 refactor(compiler): Order elements before other phases (#52289)
Previously, we ran the ordering phase near the end of the compilation. However, this meant that phases like slot assignment and variable offset assignment would happen first, and then the nice, monotonically-increasing orders would be scrambled by the reordering.

It's much more intelligible to order first, and then perform these assignments. However, to make this happen, some modifications to the ordering phase are required. In particular, we can no longer rely on `advance` instructions to break up orderable groups.

PR Close #52289
2023-10-24 11:07:49 -07:00
Dylan Hunn
b814b97d8e refactor(compiler): Imitate TemplateDefinitionBuilder's variable offset assignment order (#52289)
Many instructions consume variable slots, which are used to persist data between update runs. For top-level instructions, the offset into the variable data array is implicitly advanced, because those instructions always run.

However, instructions in non-top-level expressions cannot be assumed to run every time, because they might be conditionally executed. Therefore, they cannot implicitly advance the offset into the variable data, and must be given an explicitly assigned variable offset.

TemplateDefinitionBuilder assigned offsets top-to-bottom for all instructions *except* pure functions. Pure functions would be assigned offsets lazily, on a second pass.

Template Pipeline can now imitate this behavior, when in compatibility mode: pure functions are assigned offsets on a second pass.

This also makes the "variadic var offsets" phase unnecessary -- the new approach is more general and correct.

PR Close #52289
2023-10-24 11:07:49 -07:00
Dylan Hunn
044df0c1a8 refactor(compiler): Use already available context in closures, instead of saving it (#52289)
Previously, inside an event listener, template pipeline would always save the context from restoring a view, e.g.

```
const restored_ctx = r0.ɵɵrestoreView(s);
```

This is usually correct! However, consider the case of a listener in the template's root view. The appropriate context will already be available via closure capture, and we can just use it (as `ctx`).

Now, the context resolution phase understands that we don't need to use the restored view's saved context if we would have access to it by closure.

Note: we also create a new golden, because the const array is in a harmlessly different order.

PR Close #52289
2023-10-24 11:07:48 -07:00
Dylan Hunn
f5dffe1c5b refactor(compiler): Empty context variable reads are $implicit (#52289)
Previously, the template pipeline did not handle "empty" reads gracefully: it would emit syntactically invalid reads of empty properties. Now we read `$implicit`.

This allows us to enable a test that relies on `$implicit`. However, we also have to create another golden, because our variable inlining is more aggressive.

PR Close #52289
2023-10-24 11:07:48 -07:00
Dylan Hunn
30e81d4469 refactor(compiler): Support track functions and context variables in @for loops for template pipeline (#52001)
The template pipeline can now generate track functions, and extract them into the constant pool (or optimize them if needed). Additionally, context variables such as `$index` can be used inside track functions and for loop bodies.

PR Close #52001
2023-10-23 13:44:29 -07:00
Dylan Hunn
c8a5a4f852 refactor(compiler): Support @for blocks in template pipeline (#52001)
Add support for `repeaterCreate` and `repeater` instructions. Correctly count decls and vars, and support primary and empty blocks.

`track` functions are not yet extracted.

PR Close #52001
2023-10-23 13:44:29 -07:00
Dylan Hunn
605a50654e refactor(compiler): Create an alias concept on views (#52001)
View compilations previously had context variables, which were variables available in the view that would result in a property read on the context object.

We now also support the notion of aliases. An alias is a variable available in the view compilation, which might be derived from a context variable, which it may reference by name. It is always inlined at all usage sites, and therefore is not allowed to depend on the current context.

Under the hood, aliases rely on the new `AlwaysInline` mode.

Co-authored-by: Alex Rickabaugh <alxhub@users.noreply.github.com>

PR Close #52001
2023-10-23 13:44:29 -07:00
Dylan Hunn
c92d34e1fd refactor(compiler): Create an AlwaysInline variable mode (#52001)
The template pipeline now supports lexical variables that are always inlined into their call sites, even if multiple call sites exist.

An `AlwaysInline` variable may not rely on the current context, because it will potentially be inlined at several different locations.

Co-authored-by: Alex Rickabaugh <alxhub@users.noreply.github.com>

PR Close #52001
2023-10-23 13:44:29 -07:00
Dylan Hunn
e6affeff61 fix(language-service): Autocomplete block keywords in more cases (#52198)
Previously, autocompletions were not available in two main cases. We correct them.

1. Autocompletions immediately after `@` were usually not working, for example `foo @|`. We fix this by causing the lexer to not consider the `@` part of the text node.
2. Autocompletions such as `@\nfoo`, where a newline follows a bare `@`, were not working because the language service visitor considered us inside the subsequent text node. We fix this by adding a block name span for the block keyword, and special-case whether we are completing inside the name span. If we are, we don't continue to the following text node.

PR Close #52198
2023-10-23 12:01:52 -07:00
Miles Malerba
3ef5d6ebb7 docs(compiler): Clarify the purpose of i18n param resolution time (#52250)
Adds some additional doc comments clarifying when the `Creation`
resolution time is used vs the `Postprocessing` resolution time.

PR Close #52250
2023-10-18 14:00:04 +02:00
Miles Malerba
1cb039fa53 refactor(compiler): Wrap bare ICUs in an i18n block (#52250)
ICUs can be used outside of an i18n block. In this case the ICU should
be automatically wrapped in a new i18n block. This commit adds a new
phase to handle wrapping these bare ICUs.

PR Close #52250
2023-10-18 14:00:04 +02:00
Miles Malerba
1cd51d6d68 refactor(compiler): Resolve ICU params during i18n post-processing (#52250)
ICU params in i18n messages are now resolved in the post-processing call
rather than in the initial message creation. This matches the output
generated by TemplateDefinitionBuilder.

PR Close #52250
2023-10-18 14:00:03 +02:00
Miles Malerba
8eed992052 refactor(compiler): Add support for ingesting ICUs (#52250)
ICUs are now ingested by adding ops to both the creation and update IR.
Both of these ops are ultimately removed before reification, but they
are needed to coordinate and link data between the creation and update
ops. This is done in a new ICU extraction phase that removes both ICU
ops and adds an i18nExpr op to the update IR.

PR Close #52250
2023-10-18 14:00:03 +02:00
Miles Malerba
7929097820 refactor(compiler): Fix handling of structural directive on i18n element (#52202)
Placing a structural directive on an element with an `i18n` attribute
was generating too many i18n blocks. This was due to both the element
and the template generating their own i18n block. To fix the issue, we
no longer generate top-level i18n blocks for structural directive
templates.

PR Close #52202
2023-10-17 10:13:23 +02:00
Miles Malerba
197819ee5e refactor(compiler): Fix handling of sturctural directive on ng-template (#52202)
Structural directives on an ng-template (e.g. <ng-template *ngIf>) were
being assigned the wrong tag name ('ng-template' instead of null).

PR Close #52202
2023-10-17 10:13:23 +02:00
Miles Malerba
9f4927e778 refactor(compiler): Fix i18n placeholders for slef-closing elements (#52195)
Fixes handling of placeholders for self-closing tags. Self-closing tags
set a combined value for the start tag placeholder, rather than separate
values for the start and close placeholders.

This commit also enables a number of now passing tests. For some of
these tests I had create a separate golden file due to the different
ordering of the const array. In the template pipeline, i18n and
attribute const collection happen in different pahses and we therefore
get a different order than TemplateDefinitionBuilder, which collected
everything in one pass. The order should not affect the overall behavior.

PR Close #52195
2023-10-16 19:25:05 +02:00
Miles Malerba
fb487ea603 refactor(compiler): Add support for i18n post-processing (#52195)
Runs post-processing on any i18n messages that have multiple values
assigned to a single placeholder.

PR Close #52195
2023-10-16 19:25:05 +02:00
Miles Malerba
3f2620c1f3 refactor(compiler): Fix propagation of child i18n params (#52195)
The way we were propagating params up to parent i18n ops didn't account
for the fact that a parent and child could both have a value for the
same placeholder. In order to properly merge the value for these cases,
we need to propagate the params up *before* serialization. Therefore I
removed the standalone param propagation phase and folded the logic into
the placeholder resolution phase.

PR Close #52195
2023-10-16 19:25:05 +02:00
Miles Malerba
5371e4672b refactor(compiler): Remove unnecessary checks for empty container types (#52195)
I added these in an earlier PR when we were considering moving the empty
elements phase earlier. Since we decided not to do that, this commit
cleans up unnecessary references to the empty versions of the element to
simplify the code and types.

PR Close #52195
2023-10-16 19:25:05 +02:00
Kristiyan Kostadinov
302ab340e0 fix(compiler): avoid error in template parser for tag names that can occur in object prototype (#52225)
Fixes that the compiler was throwing an error if an element tag name is the same as a built-in prototype property (e.g. `constructor` or `toString`). The problem was that we were storing the tag names in an object literal with the `Object` prototype. These changes resolve the issue by creating an object without a prototype.

Fixes #52224.

PR Close #52225
2023-10-16 18:22:15 +02:00
Matthieu Riegler
0198d21231 fix(compiler): apply style on :host attributes in prod builds. (#49118)
In prod builds, selectors are optimized and spaces a removed. #48558 introduced a regression on selectors without spaces. This commit fixes tihs.

Fixes #49100

PR Close #49118
2023-10-11 11:32:19 -07:00
Kristiyan Kostadinov
9d19c8e317 fix(compiler): don't allocate variable to for loop expression (#52158)
Currently the compiler allocates a variable slot to the `@for` loop expression which ends up unused since we don't store the result on the `LView`.

PR Close #52158
2023-10-11 09:12:57 -07:00
Payam Valadkhan
1eefa0c9c4 refactor(compiler-cli): include forbidOrphanComponents option in component's debug info (#52061)
A new flag added to the component's debug info to determine whether to throw runtime error (in dev mode) if component is being rendered without its NgModule. This flag is only set for non-standalone components.

PR Close #52061
2023-10-10 15:30:26 -07:00
Kristiyan Kostadinov
21b085d221 refactor(compiler): capture unknown blocks inside switch (#52136)
Updates the Ivy AST to allow for `@switch` blocks to capture nested blocks that are not `@case` and `@default`. These blocks will be used for autocompletion in the language service.

These changes also update the logic for `@switch` and `@if` blocks so that they produce an AST node even if there are errors. The errors will still be surfaced to users, but producing AST nodes allows us to recover parts of the expression later if necessary.

PR Close #52136
2023-10-10 11:34:10 -07:00
Kristiyan Kostadinov
7dbd47fb30 fix(compiler): allow newlines in track and let expressions (#52137)
Fixes that the template parser didn't allow for newlines in the `track` and `let` expressions of `@for` blocks.

Fixes #52132.

PR Close #52137
2023-10-10 11:19:41 -07:00
Kristiyan Kostadinov
861ce3a7c5 fix(compiler): pipes using DI not working in blocks (#52112)
Fixes that the new block syntax was generating instructions in the wrong order which meant that pipes were being declared too early. This meant that if the block is first in the template, any pipes used in it won't be able to inject things like `ChangeDetectorRef`.

These changes update the compiler and add a bunch of tests to ensure that pipes work as expected.

Fixes #52102.

PR Close #52112
2023-10-10 09:48:37 -07:00
Matthieu Riegler
40113f653c feat(core): Remove deprecated CompilerOptions.useJit andCompilerOptions.missingTranslation. (#49672)
Both properties have been deprecated in v13 and are unused in v16.

PR Close #49672
2023-10-10 09:35:55 -07:00
Andrew Kushnir
2eebd47733 refactor(core): make timer-related @defer logic tree-shakable (#52042)
This commit updates `@defer` logic related to handling `after` and `minimum` parameters tree-shakable.

If `after` or `minimum` was used on a `@loading` or `@placeholder` blocks, compiler generates an extra argument for the `ɵɵdefer` instruction. This extra argument is a reference to a function that brings timer-related code.

PR Close #52042
2023-10-09 15:57:59 -07:00
Payam Valadkhan
421d790a1c refactor(compiler): compile debug info for angular classes (#51919)
A new utility function `compileClassDebugInfo` is introduced which creates compile result necessary to generate statement for attaching some useful debug info into angular classes. An example of teh new statement would be:

```
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(Main, { className: "Main", filePath: "$PROJECT_ROOT/src/main.ts", lineNumber: 8 }); })();
```

Currently, the debug info contains:
 - the class name
 - the file path in which it is defined
 - the line number in which it is defined

 The debug info will be used in runtime to generate more helpful error messages.

PR Close #51919
2023-10-09 15:57:03 -07:00
Kristiyan Kostadinov
29b876b16f refactor(compiler): clean up block syntax switch (#52091)
Now that the block syntax is fully rolled out, we don't need the switch constants anymore.

PR Close #52091
2023-10-09 13:41:02 -07:00