Commit graph

1484 commits

Author SHA1 Message Date
Dylan Hunn
8d230e1259 refactor(compiler): Fix a source maps i18n test for Template Pipeline (#54063)
TemplateDefinitionBuilder and Template Pipeline choose different const array orders, which is fine. Update the tests to reflect that.

PR Close #54063
2024-02-02 20:52:39 +00:00
Paul Gschwendtner
d74ee6e343 refactor(compiler-cli): group initializer-API based transforms into single transform (#54200)
Instead of maintaining individual transforms for `input`, `output`,
`model` etc. we are grouping them directly and the first one matching,
will execute.

This reduces needed traversal through AST and also makes it a little
more clean to write new initializer API metadata transforms.

Note: The Angular JIT transform is now also moving from `tooling.ts`
directly into `/transformers` for more local placement of transformer
logic.

PR Close #54200
2024-02-01 15:58:50 +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
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
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
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
Payam Valadkhan
64fa5715c6 fix(compiler-cli): generating extra imports in local compilation mode when cycle is introduced (#53543)
At the moment the extra import generation in local compilation mode fails if these extra imports produce a cycle. To handle this, the cycle handling strategy is updated for local compilation, and following the behaviour in the full compilation mode, the compiler does not generate extra import if it leads to cycle and instead leave things to the runtime.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan
7e861c640e feat(compiler-cli): generate extra imports for component local dependencies in local mode (#53543)
With option `generateExtraImportsInLocalMode` set, in local mode the compiler generates extra imports for each component local dependencies. Here local dependencies means all component's dependencies within the same compilation unit.

To achieve this, the compiler performs a "local version" of its regular static analysis to find each component's deps, and these deps are used to generate extra side effect imports.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan
3263df23f2 feat(compiler-cli): generate global imports in local compilation mode (#53543)
With option `generateExtraImportsInLocalMode` set in local compilation mode, the compiler generates extra side effect imports using this rule: any external module from which an identifier is imported into an NgModule will be added as side effect import to every file in the compilation unit. To illustrate this better assume the compilation unit has source files `a.ts` and `b.ts`, and:

```
// a.ts
import {SomeExternalStuff} from 'path/to/some_where';
import {SomeExternalStuff2} from 'path/to/some_where2';

...

@NgModule({imports: [SomeExternalStuff]})

```

then the extra import `import "path/to/some_where"` will be added to both `a.js` and `b.js`. Note that this is not the case for `import "path/to/some_where2"` though, since the symbol `SomeExternalStuff2` is not imported into any NgModule.

The math behind this mechanism is, in local compilation mode we cannot resolve component external dependencies fully. For example if a component in `a.ts` uses an external component defined in an external file `some_external_comp.ts` then we can generate the import to this file in `a.js`. Instead, we want to generate an import to a file that "gurantees" that `a.js` is placed after `some_external_comp.js` in the bundle. Now since the component in  `some_external_comp.ts` is used in `a.ts`, then there must be a chain of imports starting from the NgModule that declares the component in `a.ts` to the component in `some_external_comp.ts`. This chain means some file in the same compilation unit as `a.ts` should import some external NgModule which includes `some_external_comp.ts` in its transitive closure and import it to some NgModule. So by adding this import to `a.js` we ensure that the bundling will have the right order.

PR Close #53543
2024-01-30 15:05:43 +00:00
Payam Valadkhan
0970129e20 fix(compiler-cli): show proper error for custom decorators in local compilation mode (#53983)
At the moment local compilation mode does not support custom decorators, and it leads to unhandled errors. In this change a compile time diagnostic is produced in local mode for custom decorators. This is a temporary solution since there are few custom decorators are in use in g3. Custom decorators will be eventually supported in local mode.

PR Close #53983
2024-01-26 19:11:34 +00:00
Paul Gschwendtner
b78042f3a5 refactor(core): separate InputSignal and InputSignalWithTransform (#54053)
This commit separates `InputSignal` for input signals with transforms.
The reason being that most of the time, signal inputs are not using
transforms and the generics are rather confusing.

Especially for users with inferred types displayed in their IDEs, the
input signal types are seemingly complex, even if no transform is used.

For this reason, we are introducing a new type called
`InputSignalWithTransform`. This type will be used for inputs with
transforms, while non-transform inputs just use `InputSignal`.

A notable fact is that `InputSignal` extends `InputSignalWithTransform`,
with the "identity transform". i.e. there is no transform. This allows
us to share the code for input signals. In practice, we don't expect
users to pass around `InputSignal`'s anyway.

PR Close #54053
2024-01-26 19:10:56 +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
Paul Gschwendtner
17a47c4c54 refactor(compiler-cli): additional diagnostics for signal-based queries (#54019)
This commit introduces three additional diagnostics for queries:

- If a query (either using decorator or signal-based) is declared on a
  static class member, a diagnostic is raised.
- If a signal-based query is mixed with a query decorator, a diagnostic
  is raised. Similar to signal inputs.
- If a singal-based query is also declared in the directive/component
  class decorator metadata, a diagnostic is raised.

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
Andrew Kushnir
aeaec8629c refactor(compiler-cli): rephrase an error message related to @defer and local compilation (#54030)
This commit updates the error message to cover cases when imported symbols have eager references inside of a file.

PR Close #54030
2024-01-24 10:08:50 +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
f81a4365fe test: add compliance tests for signal-based queries (#53978)
This commit adds compliance tests to ensure that the generated output of
signal-based queries matches our expectation.

Note: collapsing query advance instructions is not implemented yet.

PR Close #53978
2024-01-23 10:24:37 +01:00
Paul Gschwendtner
df828e9947 test: add compiler integration test for signal-based queries (#53978)
Adds a compiler integration test for recognizing signal-based queries,
and emitting the expected output. Concrete output will be verified via
the compliance tests.

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
Payam Valadkhan
3e1384048e feat(compiler-cli): support host directives for local compilation mode (#53877)
At the moment local compilation breaks for host directives because the current logic relies on global static analysis. This change creates a local version by cutting the diagnostics and copying the directive identifier as it is to the generated code without attempting to statically resolve it.

PR Close #53877
2024-01-22 14:44:24 +01:00
Payam Valadkhan
b774e22d8e feat(compiler-cli): make it configurable to generate alias reexports (#53937)
At the moment when unified host is selected (through option `_useHostForImportGeneration`) the compiler always generates alias reexports. Such reexports are mainly generated to satisfy strict dependency condition for generated files. Such condition is no longer the case for G3. At the same time, these alias reexports make it impossible to mix locally compiled targets with globally compiled targets. More precisely, a globally compiled target may not be able to consume a locally compiled target as its dependency since the former may import from the alias reexports which do not exist in the latter due to local compilation mode. So, to make global-local compilation interop possible, it is required to be able to turn off alias reexport generation.

PR Close #53937
2024-01-22 14:20:26 +01: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
Paul Gschwendtner
760b1f3d0b fix(compiler-cli): do not throw fatal error if extended type check fails (#53896)
Currently when the extended type check fails due to an import reference
that cannot be generated, the fatal diagnostic is not caught and
not properly exposed as a `ts.Diagnostic` that can be gracefully
handled. This is inconsistent to non-extended type checking diagnostics.

This is problematic because Angular CLI applications currently fail in
obscure ways because:

- the CLI does not expect `getDiagnosticsForFile` to actually throw
  runtime errors.
- the CLI does not seem to properly print these errors given the
  parallel workers and build excection, and those errors are
  especially hard to debug because there is no `stack` for
  `FatalDiagnosticError`'s.

Example: `MyDir` is not exported and the type check block cannot reference it.

PR Close #53896
2024-01-16 09:36:36 -08:00
Andrew Kushnir
79fbc4eaba refactor(compiler-cli): add tests for defer blocks and local compilation (#53591)
This commit adds tests to cover local compilation support for `@defer` blocks.

PR Close #53591
2024-01-10 15:28:59 -08:00
Paul Gschwendtner
b2066d4922 refactor(compiler-cli): detect input functions without partial evaluation (#53872)
This allows us to ensure signal inputs and a potential JIT transform
remain single file compilation compatible. The consequences are that
options need to be statically analyzable more strictly, compared to
loosened restrictions with static interpretation where e.g. `alias`
can be defined through a shared variable.

PR Close #53872
2024-01-10 12:33:31 -08:00
Paul Gschwendtner
e934f3a581 refactor(compiler-cli): add diagnostic for inputs declared on static members (#53808)
Currently when someone declares a signal or non-signal input on a static
class member, the compiler will not yield any diagnostic. We can detect
these mistakes and report a diagnostic to help our users.

PR Close #53808
2024-01-10 12:21:06 +00:00
Paul Gschwendtner
40b0467d3e refactor(compiler-cli): diagnostics ensuring signal inputs are declared properly (#53808)
This commit addds two diagnostics for two scenarios where signal inputs
are declared incorrectly:

- a signal input is also annotated with `@Input` in the TypeScript
  sources.
- a signal input is also declared in the `inputs` option of
  `@Directive/`@Component`.

PR Close #53808
2024-01-10 12:21:05 +00:00
Paul Gschwendtner
eba017f8c7 refactor(compiler-cli): add transform to support signal input in JIT (#53808)
This commit adds a transform for supporting input signals in JIT
environments. The transform will be wired up for Angular CLI
applications automatically. An integration test verifies that this fixes
unit testing with signal inputs.

The transform basically will take the signal input metadata and
transform it into `@Input` decorators that can provide static
information to the Angular JIT runtime when the directive/component
definition is compiled.

PR Close #53808
2024-01-10 12:21:05 +00:00
Paul Gschwendtner
4a016886fa test: add signal input compliance tests for linking, partial output and full compilations (#53808)
Adds signal input compliance tests, ensuring linking works as expected,
partial output is generated properly, types are inferred properly, and
that the full, or linked output matches our expected runtime structure.

PR Close #53808
2024-01-10 12:21:05 +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
6fcfe2b0ce build: fix partial output generation errors swallowed (#53808)
In some cases, the input files for a partial output generation
compliance tests may be invalid and lead to compilation errors.

The golden partial would be silently generated with the remaining
test cases. Instead of hiding errors, we will now print these and
cause the script to fail properly.

Note that the error logging is pretty minimalistic, but it's sufficient.

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
56ff04607c build: re-enable linker compliance tests (#53571)
The linker compliance tests were disabled with a Babel update and
nobody realized for quite a while, via
https://github.com/angular/angular/pull/49914.

As we've came across this lost coverage, which also is quite
impactful as all libraries depend on linked output- I've took initiative
to debug the root cause as there was no follow-up.
https://github.com/angular/angular/issues/51647.

It turned out to be a highly complex issue that is non-trivial to fix,
but at least we should try to resurrect the significant portion of test
coverage by still running the linker tests- avoiding regressions, or
unexpected issues (like with defer being developed). We can work on
re-enabling and fixing source-maps separately.

Tracked via https://github.com/angular/angular/issues/51647.

PR Close #53571
2024-01-04 12:07:13 -08:00
Paul Gschwendtner
56ce8dabc5 test: fix linker compliance tests after not running for a while (#53571)
The linker compliance tests did not run for a while. There were a couple
of new tests that were not passing as this wasn't flagged on CI. This commit fixes this.
Fortunately there was no problematic code that did indicate issues with linking.

In the follow-up commit, we fix the compliance test infrastructure to
re-enable linker testing..

One clear issue is still that the defer blocks are not handled properly
in linked output- hence making defer not actually "lazy" for compiled
libraries. This needs to be handled separately by the framework team.

PR Close #53571
2024-01-04 12:07:13 -08:00
Paul Gschwendtner
659b921ab1 test(compiler-cli): add ngtsc test for new signal input API (#53571)
This commit adds a final test for input signals, integrating all major
parts:

* type-checking
* compiler detection
* compiler emit
* API signature tests

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
Payam Valadkhan
1a6eaa0fea fix(compiler-cli): input transform in local compilation mode (#53645)
Currently compiling input transform in local mode breaks, since compiler does static analysis for the transform function, and this cannot be done in local mode if the function is imported from another compilation unit. In this fix the static analysis is ditched in local mode.

PR Close #53645
2024-01-03 10:29:34 -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
Dylan Hunn
1731988e72 refactor(compiler): Add a test for attribute namespaces (#53646)
We currently do not support the `namespace` argument for the attribute instruction. (Who knew it even existed!)

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
3212935f4d refactor(compiler): Tricky implicit context issue in template pipeline (#53594)
Add a failing tests about an implicit context issue; I will debug this shortly.

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
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
d485cfef28 test(compiler): Update partial golden files (#53596)
Update partial golden files to reflect newly added tests

PR Close #53596
2023-12-18 22:09:26 +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
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
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
Dylan Hunn
cba1b902da refactor(compiler): Add test for ICU root message with element tags (#53557)
Add test for ICU root message with element tags

PR Close #53557
2023-12-14 09:33:52 -08:00
Paul Gschwendtner
4866fce320 refactor(compiler-cli): capture signal inputs in semantic graph for directives (#53521)
Whenever an input of a directive changes, the semantic symbol should
reflect this change for the type check API. This is important because
signal inputs require special output in the type checking blocks- hence
we need to ensure that such type checking blocks are re-generated
properly.

Test verify that incremental type-checking builds work as expected now.

PR Close #53521
2023-12-13 15:44:00 -08:00
Paul Gschwendtner
e6db288ffd refactor(compiler-cli): ensure proper TS incremental program re-use w/ signal inputs (#53521)
Whenever a signal input is captured in a type check block, we will
insert an import. This will change the import graph so that the full
TypeScript program cannot be structurally re-used.

We can fix this trivially by ensuring the import graph remains stable,
by always generating an import to e.g. `@angular/core`. This fixes the
issue nicely for type-check block files. A test verifies this.

For inline code, such as TCB inline or the type constructors inline,
this fix is not applicable because we would change user-input source files,
adding new edges that would not exist for subsequent builds- causing the
program to be not re-used completely. One idea was to rely on the
existing edge that can be assumed to exist for directive code files.
This is true technically, but in practice TS does not deduplicate
imports- so our new namespace import when referencing our symbols will
invalidate the re-use. We will address this in a follow-up. There are a
couple of options, such as working with the TS team, updating the
existing edge, or inlining our helpers as well.

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
Kristiyan Kostadinov
b98d8f79ed fix(compiler): handle ambient types in input transform function (#51474)
Fixes that the compiler was throwing an error if an ambient type is used inside of an input `transform` function. The problem was that the reference emitter was trying to write a reference to the ambient type's source file which isn't necessary.

Fixes #51424.

PR Close #51474
2023-12-13 09:15:17 -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
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
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
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
Charles Lyding
119a94ef4b build: remove unneeded babel types postinstall patching (#53441)
These patches are no longer necessary with the current state of the
type packages and the code within the repository. The types are now
included in the already required babel.d.ts file for the relevant
babel packages (currently: `@babel/core` and `@babel/generator`).

PR Close #53441
2023-12-08 14:33:59 -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
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
Miles Malerba
2798aad9ae test(compiler): fix legacy message id test (#53459)
This test actually passes, template pipeline just orders the translated
messages and consts array differently. Since the order isn't important,
we just fork off an alternate golden file for template pipeline.

PR Close #53459
2023-12-08 14:28:27 -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
90e090864f refactor(compiler): Add an additional failing test about i18n ordering (#53405)
I discovered this failure while looking at presubmit results. We appear to still have ordering issues, when more update ops are present.

PR Close #53405
2023-12-08 09:37:56 -08:00
Dylan Hunn
db3b05a68d refactor(compiler): Add failing tests about structural attr bindings (#53405)
While running a g3 presubmit, I discovered two related novel failure modes:

1. Simple case: this new test uses an `ngFor` structural directive, which binds a context variable. That variable is immediately used in an attribute binding. It looks like we generate an extra attribute instruction, which might result in an invalid property read at runtime.
2. Complex case: this is another attribute binding, this time on a structural element, inside of an `ng-template`. Not sure what's going on here.

PR Close #53405
2023-12-08 09:37:56 -08:00
Dylan Hunn
671e4f0109 refactor(compiler): Enable meaning_description i18n test in template pipeline (#53405)
The meaning decription test has different i18n message orders, as well as a different const order, but it is in fact passing.

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
Kristiyan Kostadinov
e620b3a724 fix(compiler-cli): add compiler option to disable control flow content projection diagnostic (#53311)
These changes add an option to the `extendedDiagnostics` field that allows the check from #53190 to be disabled. This is a follow-up based on a recent discussion.

PR Close #53311
2023-12-05 17:21:16 -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
Kristiyan Kostadinov
d7a83f9521 fix(compiler-cli): avoid conflicts with built-in global variables in for loop blocks (#53319)
Currently we generate the following TCB for a `@for` loop:

```ts
// @for (item of items; track item) {...}

for (const item of this.items) {
  var _t1 = item;
  // Do things with `_t1`
}
```

This is problematic if the item name is the same as a global variable (e.g. `document`), because when the TCB has references to that variable (e.g. `document.createElement`), it'll find the loop initializer instead of the global variable.

These changes fix the issue by generating the following instead:

```ts
for (const _t1 of this.items) {
  // Do things with `_t1`
}
```

Fixes #53293.

PR Close #53319
2023-12-04 21:45:17 -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