Commit Graph

1510 Commits

Author SHA1 Message Date
Charles Lyding 0f10d75228 refactor(compiler): use native BigInt when calculating i18n digests (#48321)
To further modernize and improve the performance of the i18n digest generation,
The 64-bit aspects of the process now use the native `BigInt` instead of a
custom JavaScript implementation. This removes the need for the big_integer
helper code and associated tests as the code was not used anywhere else in the
framework. Only the `BigInt` constructor, `BigInt.asUintN` function, and
`.toString` function are currently used. `BigInt` literals can unfortunately
not yet be used due to the bazel test devmode setup which compiles the TypeScript
code at an EcmaScript level that does not yet support the literals.

Browser support information:
- BigInt constructor: https://caniuse.com/mdn-javascript_builtins_bigint_bigint
- BigInt asUintN: https://caniuse.com/mdn-javascript_builtins_bigint_asuintn
- BigInt toString: https://caniuse.com/mdn-javascript_builtins_bigint_tostring

PR Close #48321
2023-09-07 10:07:47 -07:00
Kristiyan Kostadinov 88a0af64fd perf(core): generate arrow functions for pure function calls (#51668)
Reworks the pure functions to use arrow functions with an implicit return instead of function expressions. This allows us to shave off some bytes for each pure function, because we can avoid some of the syntax.

PR Close #51668
2023-09-06 15:32:02 +00:00
Kristiyan Kostadinov 7c068861b7 refactor(compiler): output arrow functions for deferred dependencies functions (#51650)
Reworks the compiler to generate arrow functions for the deferred dependencies which reduces the number of bytes we generate.

PR Close #51650
2023-09-05 18:16:59 +00:00
Kristiyan Kostadinov 05a16b973d refactor(compiler): add support for advanced tracking expressions (#51618)
These changes build on top of #51514 to add support for advanced expressions inside the `track` parameter of `for` loop blocks. There are two different outputs that the compiler can generate:

1. If the tracking function only references the item or `$index`, the compiler generates a pure arrow function as a constant references in the `repeaterCreate` instruction.
2. If the tracking function has references to properties outside of the `for` loop block, the compiler will rewrite those references to go through `this` and generate a function declaration. The runtime will `bind` the declaration to the current component instance so that the rewritten `this` references are resolved correctly.

Advanced tracking expression come with the following limitations to ensure the best possible performance:
1. They can only reference the item, `$index` and properties directly on the component instance. This means that there'll be an error when accessing this like local template variables and references. While we could get this to work, we would have to traverse the context tree at runtime which will degrade the performance of the loop, because it's a linear time operation that is performed on each comparison. Furthermore, allowing local references would require us re-evaluate the list when any one of them has changed.
2. Pipes aren't allowed inside the tracking function.
3. Object literals and pipes used inside the tracking expression will be recreated on each invocation.

PR Close #51618
2023-09-05 14:19:18 +00:00
Kristiyan Kostadinov b51ab59836 refactor(compiler): allow constants pool to track shared functions (#51618)
Expands the constant pool to be able to reuse function declarations that have identical bodies.

PR Close #51618
2023-09-05 14:19:18 +00:00
Kristiyan Kostadinov f36cdd6d1a refactor(core): add instruction to reference component instance (#51618)
Adds an instruction that allows us to access the containing component instance directly instead of having to traverse the context tree. This will be necessary for the tracking function of `for` loop blocks.

PR Close #51618
2023-09-05 14:19:18 +00:00
Kristiyan Kostadinov 6ecafa3305 refactor(compiler): computed for loop variables exposed on the wrong scope (#51618)
Fixes that the computed for loop variables (e.g. $first and $last) were exposed on the parent scope instead of the for loop scope.

PR Close #51618
2023-09-05 14:19:18 +00:00
Kristiyan Kostadinov 98d98f2c94 refactor(compiler): incorrect validation of switch blocks when preserveWhitespaces is enabled (#51570)
When `preserveWhitespaces` is enabled, `switch` blocks can end up with content inside their main block due to the indentation that is usually used for the nested cases. This was tripping up the validation that doesn't allow content inside the main block of `switch`.

These changes update the validation to ignore empty text nodes.

PR Close #51570
2023-09-05 14:18:44 +00:00
Kristiyan Kostadinov 685d01e106 perf(core): chain template instructions (#51546)
With the new control flow and defer blocks it'll be common for several template instructions to be declare one after another. These changes add support for chaining to the `template` instruction which will allow us to save some bytes.

PR Close #51546
2023-08-29 16:38:52 +00:00
Kristiyan Kostadinov d83dfaa8ea refactor(compiler): generate for loop block instructions (#51514)
Adds the initial implementation to generate the instructions for the `for` loop block.

**Note:** the expressions we support in the `track` paramateter are currently limited to tracking by identity or index, or a specific property of the item. Supporting more advanced expression will require additional work that I'll do in a follow-up PR.

PR Close #51514
2023-08-29 16:38:22 +00:00
Dylan Hunn ab0f9eeba5 refactor(compiler): Implement switch blocks in template pipeline (#51518)
`switch` blocks are part of the new control flow syntax. This commit adds support for processing them, and emitting the appropriate templates and conditional instructions.

PR Close #51518
2023-08-29 00:16:00 +00:00
Dylan Hunn c013bff48a refactor(compiler): Support $event in host bindings (#51498)
Run the existing phase that deals with `$event` during host binding compilation.

PR Close #51498
2023-08-28 21:51:04 +00:00
Dylan Hunn 6669bea544 refactor(compiler): Share the same phase list for components and hosts (#51498)
Component compilation and host binding compilation previously used separate compilation emit functions. This was a bit messy, because we had to manage the relative orders of both phase lists. Indeed, there was already some inconsistency between the precise orders!

This commit refactors the emit functions to share the same phase list, and thus guarantees they will always be in the same order.

PR Close #51498
2023-08-28 21:51:04 +00:00
Dylan Hunn bca26b88b1 refactor(compiler): Generalize the ordering phase to also order create mode (#51498)
`syntheticHostListener` and `listener` have ordering dependencies. We reuse the existing ordering phase, and generalize it to also order create mode instructions.

PR Close #51498
2023-08-28 21:51:04 +00:00
Dylan Hunn f13223b140 refactor(compiler): Support host animation events. (#51498)
Animation listeners on host bindings result in a special `syntheticHostListener` instruction. We can now emit this instruction.

Additionally, the naming phase for events has been slightly refactored to smoothly incorporate whether the event is from a host listener, as well as whether it is an animation listener.

PR Close #51498
2023-08-28 21:51:04 +00:00
Dylan Hunn 1ea8617cd2 refactor(compiler): Support host binding listeners (#51498)
We can now ingest host bindings listeners into the template pipeline, and process them using the pre-existing phases.

PR Close #51498
2023-08-28 21:51:04 +00:00
Dylan Hunn 5546cb3197 refactor(compiler): More closely match TDB binding ordering (#51498)
For host bindings, `TemplateDefinitionBuilder` seems to use a different binding ordering, in which style bindings come after all the property bindings. We approximate that by treating `hostProperty` differently from `property` in the ordering phase.

PR Close #51498
2023-08-28 21:51:04 +00:00
Dylan Hunn cae01dae1b refactor(compiler): Support class and style attrs in host bindings (#51498)
The template pipeline is already capable of parsing and processing class and style attributes on templates. We now extend that functionality to host bindings.

The parser, for some reason, splits out class and style attributes into a `specialAttributes` field. We merge them back into the main attributes map, and allow the template pipeline to process them normally.

PR Close #51498
2023-08-28 21:51:04 +00:00
Dylan Hunn d0b83b14be refactor(compiler): Backwards compatibility with TDB for host attributes (#51498)
TemplateDefinitionBuilder only extracts host attributes if they are text attributes. For example, `[attr.foo]="'my-value'"` is not extracted despite being a string literal, because it is not a text attribute.

PR Close #51498
2023-08-28 21:51:04 +00:00
Dylan Hunn 8f90630dc8 refactor(compiler): Support synthetic host property bindings. (#51498)
Host property bindings can be animation bindings, and should be ingested and emitted as such, as well as being processed by the renaming phase.

PR Close #51498
2023-08-28 21:51:04 +00:00
Dylan Hunn 0df7828637 refactor(compiler): Extract host binding static attributes to hostAttrs (#51498)
Host bindings can apply static attributes. These will be extracted to a `hostAttrs` field on the host binding function's metadata.

In order to achieve this, we add an `attributes` field to the host binding job. Then, we peform attribute exraction on host bindings. We finally populate the `attributes` field directly, instead of relying on a `consts` array.

PR Close #51498
2023-08-28 21:51:04 +00:00
Dylan Hunn 8071ed36c5 refactor(compiler): Refactor the compilation job and unit abstractions (#51498)
Convert `CompilationJob` into a abstract class in order to extract common code. Separate host binding jobs and units, in order to allow for more code sharing.

PR Close #51498
2023-08-28 21:51:04 +00:00
Miles Malerba 88fcd27c6d refactor(compiler): add a pointer to the const array in i18nStart (#51353)
Adds a pointer to the const array index containing the i18n message to
the i18nStart instruction.

PR Close #51353
2023-08-28 18:57:08 +00:00
Miles Malerba 5f02b5810b refactor(compiler): resolve element placeholders in i18n messages (#51353)
Adds a new phase to resolve element placeholders in i18n messages.
This requires adding the i18n message to element ops, which means the
creation of i18n start/end ops can now be done in a separate phase
instead of during ingestion.

PR Close #51353
2023-08-28 18:57:08 +00:00
Miles Malerba b064b29776 refactor(compiler): use correct closure variable naming (#51353)
Updates the closure variable naming for i18n variables to match those
generated by TemplateDefinitionBuilder

PR Close #51353
2023-08-28 18:57:08 +00:00
Miles Malerba 99f94747e4 refactor(compiler): extract text nodes in i18n blocks (#51353)
Removes text nodes from i18n blocks, since the text is already captured
in the i18n message.

PR Close #51353
2023-08-28 18:57:08 +00:00
Miles Malerba d13a2ee064 refactor(compiler): support i18n messages in the consts array (#51353)
Creates a new `ExtractedMessageOp` which is consumed by the const
collection pahse to serialize the i18n message into the consts array.
Also adds support to the consts array for initialization statements.

PR Close #51353
2023-08-28 18:57:08 +00:00
Alex Rickabaugh 575a5588f8 refactor(compiler): initial implementation of i18n blocks (#51353)
Adds i18n block start & end ops, as well as a new phase to construct the
i18n message variable to be added to the consts array.

Co-authored-by: Alex Rickabaugh <alx+alxhub@alxandria.net>
Co-authored-by: Dylan Hunn <dylhunn@gmail.com>

PR Close #51353
2023-08-28 18:57:08 +00:00
Andrew Kushnir c4deaac5b0 refactor(core): initial implementation of {#defer} block runtime (#51347)
This commit adds an initial implementation of the `{#defer}` block runtime, which supports the `when` conditions. More conditions and basic prefetching support will be added in followup PRs.

PR Close #51347
2023-08-28 17:09:52 +00:00
Kristiyan Kostadinov fa72384ec5 refactor(compiler): introduce AST for outputting arrow functions (#51436)
Extends the compiler to add support for generating arrow functions in the output AST. This will be required for the `for` control flow block and we can potentially leverage it in other places to reduces the amount of generated code.

PR Close #51436
2023-08-23 14:45:33 -07:00
Kristiyan Kostadinov 36663e6ef6 refactor(compiler): parse let parameters in for loop (#51398)
Adds the logic to parse `let` parameters of a `for` loop block which was missed in #51299.

PR Close #51398
2023-08-22 10:40:17 -07:00
Kristiyan Kostadinov 9f6b565abd refactor(compiler): parse for loop track as an expression (#51398)
Adds some logic to store the `track` parameter of a `for` loop block as an expression AST instead of a string.

PR Close #51398
2023-08-22 10:40:17 -07:00
Kristiyan Kostadinov eb1faa8f87 refactor(compiler): don't allow as expressions in else if blocks (#51398)
Based on some discussions, these changes remove the ability to have an `as` expression on an `else if` block.

PR Close #51398
2023-08-22 10:40:17 -07:00
Kristiyan Kostadinov 9cc0cbed0c refactor(compiler): generate if block instructions (#51380)
Adds the logic to generate the instructions for `if` blocks. There are two primary use cases we need to account for:

A conditional that doesn't use the `as` parameter of the `if` block. To support it we generate a nested ternary expression that evaluates to the index of the template whose condition is truthy. If the block doesn't have an `else` branch, we pass in a special `-1` value which means that no view will be rendered.

Example with an `else`:
```ts
// {#if expr}
//   ...
//   {:else if otherExpr} ...
//   {:else} ...
// {/if}

if (rf & 1) {
  ɵɵtemplate(0, App_Conditional_0_Template, 0, 0);
  ɵɵtemplate(1, App_Conditional_1_Template, 0, 0);
  ɵɵtemplate(2, App_Conditional_2_Template, 0, 0);
}
if (rf & 2) {
  ɵɵconditional(0, ctx.expr ? 0 : ctx.otherExpr ? 1 : 2);
}
```

Example without an `else`:
```ts
// {#if expr}
//   ...
//   {:else if otherExpr} ...
// {/if}

if (rf & 1) {
  ɵɵtemplate(0, App_Conditional_0_Template, 0, 0);
  ɵɵtemplate(1, App_Conditional_1_Template, 0, 0);
}
if (rf & 2) {
  ɵɵconditional(0, ctx.expr ? 0 : ctx.otherExpr ? 1 : -1);
}
```

If a conditional captures it's value in an alias (e.g. `{#if expr; as foo}`) we need to assign the value to a temporary variable before passing it along to `conditional`.

```ts
// {#if expr; as alias}...{/if}
if (rf & 1) {
  ɵɵtemplate(0, App_Conditional_0_Template, 1, 0);
}
if (rf & 2) {
  let App_contFlowTmp;
  ɵɵconditional(0, (App_contFlowTmp = ctx.expr) ? 0 : -1, App_contFlowTmp);
}
```

PR Close #51380
2023-08-18 10:01:02 -07:00
Kristiyan Kostadinov 0c4c773fca refactor(compiler): generate switch block instructions (#51380)
Adds the logic to generate the instructions for `switch` instructions. For the following block:

```html
{#switch value()}
  {:case 0} case 0
  {:case 1} case 1
  {:case 2} case 2
  {:default} default
{/switch}
```

The compiler will produce the following output:

```ts
function App_Template(rf, ctx) {
  if (rf & 1) {
    ɵɵtemplate(0, App_Case_0_Template, 1, 0);
    ɵɵtemplate(1, App_Case_1_Template, 1, 0);
    ɵɵtemplate(2, App_Case_2_Template, 1, 0);
    ɵɵtemplate(3, App_Case_3_Template, 1, 0);
  }
  if (rf & 2) {
    let App_contFlowTmp;
    ɵɵconditional(0, (App_contFlowTmp = ctx.value()) === 0 ? 0 : App_contFlowTmp === 1 ? 1 : App_contFlowTmp === 2 ? 2 : 3);
  }
}
```

PR Close #51380
2023-08-18 10:01:02 -07:00
JoostK 5bd9fbd2c3 fix(compiler-cli): enforce a minimum version to be used when a library uses input transform (#51413)
Angular 16.1 introduced the input transform feature, requiring the partial compilation output to be extended
with a reference to the input transform function. This has resulted in a subtle breaking change, where older
versions of the Angular linker can no longer consume libraries that have started to use this feature.

We do try to support using a 16.1 library from an Angular 16.0 application, but if a library actually
adopts a new feature then this is no longer possible. In such cases, it is desirable to report a message
telling the user that their version of the Angular compiler is too old, as determined by the `"minVersion"`
property that is present in each partial declaration. This version would still indicate that the declaration
required at least Angular 14.0 to be compiled, but this is not accurate once input transforms are being
used. Consequently, this error would not be reported, causing a less informative error once the input transform
was being observed.

Fixes #51411

PR Close #51413
2023-08-18 07:58:53 -07:00
Andrew Kushnir bcc3c43fca refactor(core): update TestBed to handle async component metadata (#51182)
This commit updates TestBed to wait for async component metadata resolution before compiling components.
Async metadata is added by the compiler in case a component uses defer blocks, which contain deferrable
symbols.

PR Close #51182
2023-08-15 11:32:09 -07:00
Andrew Kushnir c41a1950fd refactor(compiler): apply component metadata asynchronously when defer blocks are present (#51182)
This commit updates compiler logic to generate the `setClassMetadataAsync` calls for components that used defer blocks. The `setClassMetadataAsync` function loads deferrable dependencies and invokes the `setClassMetadata` synchronously once everything is loaded. This change is needed to avoid eager references to deferrable symbols in component metadata in generated code.

PR Close #51182
2023-08-15 11:32:09 -07:00
Kristiyan Kostadinov 422d0d5ca3 refactor(compiler): handle deferred when trigger with a pipe (#51368)
Fixes that we weren't processing `when` conditions correctly which led to a compilation error when a pipe is used inside the expression.

PR Close #51368
2023-08-15 10:03:59 -07:00
Kristiyan Kostadinov 5212b47bbf refactor(compiler): introduce defer trigger instructions (#51315)
Adds the logic for generating the instructions for the various deferred triggers.

PR Close #51315
2023-08-11 06:55:13 -07:00
Kristiyan Kostadinov 79f9d49fad refactor(compiler): introduce defer block instructions (#51315)
Adds the logic for generating `{#defer}`, `{:placeholder}`, `{:loading}` and `{:error}` block instructions in the compiler.

PR Close #51315
2023-08-11 06:55:13 -07:00
Kristiyan Kostadinov 151b04f683 refactor(compiler): add method for generating template instructions (#51315)
Moves the logic for creating a `ɵɵtemplate` instruction into a separate method so that it can be reused for `defer` blocks.

PR Close #51315
2023-08-11 06:55:13 -07:00
Kristiyan Kostadinov 36b180ade4 refactor(compiler): implement conditional block AST (#51299)
Adds the AST for `if`, `else if` and `else` blocks.

PR Close #51299
2023-08-10 13:48:55 -07:00
Kristiyan Kostadinov 4424920f0b refactor(compiler): implement for block AST (#51299)
Adds the AST for `for` and `empty` blocks.

PR Close #51299
2023-08-10 13:48:55 -07:00
Kristiyan Kostadinov 31c6c5e944 refactor(compiler): implement switch block AST (#51299)
Adds the AST for `switch`, `case` and `default` blocks.

PR Close #51299
2023-08-10 13:48:55 -07:00
Payam Valadkhan 827e10ae0e refactor(compiler): add a factory for component dependencies in local compilation mode (#51089)
A factory generator function called "i0.ɵɵgetComponentDepsFactory" is added to generate a factory function for component dependencies. This function will use the deps tracker to calculate the component's dependencies.

For standalone components the component imports (if exists) will be passed to this function. Alternatively this function can grab the imports directly from the decorate, but such extraaction needs some runtime logic which overlapps with what the trait compiler is doing. So better to pass the imports directly to this function at compile time.

PR Close #51089
2023-08-08 13:58:48 -07:00
Kristiyan Kostadinov b1f96096d3 refactor(compiler): correctly identify lazy directives and pipes used after a nested defer block (#51262)
Fixes that if a directive/pipe is used after a nested `defer` block, we weren't tracking it as lazy anymore. This was due to the fact that we were resetting the `isInDeferBlock` to false every time instead of the previous value.

PR Close #51262
2023-08-04 11:27:39 -04:00
Kristiyan Kostadinov 1045abd3c8 refactor(compiler): add more deferred validations (#51262)
Adds validations for the following invalid deferred block structures:
* Duplicated triggers.
* Multiple `minimum` parameters on `placeholder` and `loading` blocks.
* Multiple `after` parameters on `loading` blocks.

PR Close #51262
2023-08-04 11:27:39 -04:00
Kristiyan Kostadinov d11548f2ef refactor(compiler): store deferred triggers as a map (#51262)
Stores the `deferred` block triggers as a map instead of an array, because triggers can't be duplicated and because having to search through an array will be inconvenient later on.

I've also added a `DeferredBlock.visitAll` method to deduplicate the logic from the various visitor implementations.

PR Close #51262
2023-08-04 11:27:39 -04:00
Miles Malerba 74974f80e0 refactor(compiler): Parse extracted class attributes (#51258)
Adds logic to parse extracted class attributes into separate
ExtractedAttributeOps per class in the attribute.

PR Close #51258
2023-08-03 14:34:53 -04:00