Commit graph

1634 commits

Author SHA1 Message Date
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
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
Payam Valadkhan
8798abb744 refactor(core): implement runtime logic to compute component dependencies in local compilation mode (#51377)
The runtime `ɵɵsetNgModuleScope` is modified to accept raw scope info as passed to it in local compilation mode. The runtime further registers the ng-module in the deps tracker. Then the runtime `ɵɵgetComponentDepsFactory` is implemented to use the deps tracker to get the component dependencies which leads to a valid and working Angular code.

PR Close #51377
2023-08-17 14:01:51 -07:00
Payam Valadkhan
e69e41ecf8 refactor(core): more accurate types for standalone component imports in deps tracker (#51377)
The standalone components import as passed to the deps tracker will be the raw import, i.e., it is either a Type or a module with providers or a factory of these. So we use the existing type `RawScopeInfoFromDecorator` for these imports instead of the current one to be more realistic.

PR Close #51377
2023-08-17 14:01:51 -07:00
Payam Valadkhan
56e0b8526a refactor(core): allow empty raw import info for standalone components in the runtime deps tracker (#51377)
The current logic requires that standalone component always provide an array of raw imports. But such array could be dropped from the downstream tools if the component has no imports. So it is more natural to allow undefined raw imports for standalone components and treat it as empty array.

PR Close #51377
2023-08-17 14:01:51 -07:00
Payam Valadkhan
8b431a0164 refactor(core): kill circular deps by moving scope runtime functions to a new scope.ts file (#51377)
This refactoring is needed for next commit not to produce circular deps as we start using the `depsTracker` inside `ɵɵsetNgModuleScope`. The runtime `ɵɵsetComponentScope` is not needed to move but it moved to the new file just for consistency sake.

PR Close #51377
2023-08-17 14:01:51 -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
Pawel Kozlowski
93675dc797 feat(core): conditional built-in control flow (#51346)
Initial PoC of the built-in control flow support. The goal is to
unblock compiler work.

PR Close #51346
2023-08-14 17:16:39 -07:00
Pawel Kozlowski
ebd217d393 Revert "refactor(core): remove class type check when clearing cache in deps tracker (#51293)" (#51358)
This reverts commit a9f609e75c.

PR Close #51358
2023-08-14 13:48:47 -07:00
Pawel Kozlowski
b1f0fc9129 Revert "refactor(core): enabled using deps tracker in JIT compilation (#51293)" (#51358)
This reverts commit bc55d82eb9.

PR Close #51358
2023-08-14 13:48:47 -07:00
Pawel Kozlowski
b0ea81d562 Revert "refactor(core): kill circular deps by moving scope runtime functions to a new scope.ts file (#51309)" (#51358)
This reverts commit 45105555da.

PR Close #51358
2023-08-14 13:48:47 -07:00
Pawel Kozlowski
b297ea7966 Revert "refactor(core): allow empty raw import info for standalone components in the runtime deps tracker (#51309)" (#51358)
This reverts commit 8156128863.

PR Close #51358
2023-08-14 13:48:47 -07:00
Pawel Kozlowski
32d30f26a7 Revert "refactor(core): more accurate types for standalone component imports in deps tracker (#51309)" (#51358)
This reverts commit e7ea016e00.

PR Close #51358
2023-08-14 13:48:47 -07:00
Pawel Kozlowski
ee73d180fd Revert "refactor(core): implement runtime logic to compute component dependencies in local compilation mode (#51309)" (#51358)
This reverts commit f7cfc3b8fa.

PR Close #51358
2023-08-14 13:48:47 -07:00
Payam Valadkhan
f7cfc3b8fa refactor(core): implement runtime logic to compute component dependencies in local compilation mode (#51309)
The runtime `ɵɵsetNgModuleScope` is modified to accept raw scope info as passed to it in local compilation mode. The runtime further registers the ng-module in the deps tracker. Then the runtime `ɵɵgetComponentDepsFactory` is implemented to use the deps tracker to get the component dependencies which leads to a valid and working Angular code.

PR Close #51309
2023-08-14 08:58:47 -07:00
Payam Valadkhan
e7ea016e00 refactor(core): more accurate types for standalone component imports in deps tracker (#51309)
The standalone components import as passed to the deps tracker will be the raw import, i.e., it is either a Type or a module with providers or a factory of these. So we use the existing type `RawScopeInfoFromDecorator` for these imports instead of the current one to be more realistic.

PR Close #51309
2023-08-14 08:58:47 -07:00
Payam Valadkhan
8156128863 refactor(core): allow empty raw import info for standalone components in the runtime deps tracker (#51309)
The current logic requires that standalone component always provide an array of raw imports. But such array could be dropped from the downstream tools if the component has no imports. So it is more natural to allow undefined raw imports for standalone components and treat it as empty array.

PR Close #51309
2023-08-14 08:58:47 -07:00
Payam Valadkhan
45105555da refactor(core): kill circular deps by moving scope runtime functions to a new scope.ts file (#51309)
This refactoring is needed for next commit not to produce circular deps as we start using the `depsTracker` inside `ɵɵsetNgModuleScope`. The runtime `ɵɵsetComponentScope` is not needed to move but it moved to the new file just for consistency sake.

PR Close #51309
2023-08-14 08:58:46 -07:00
Payam Valadkhan
bc55d82eb9 refactor(core): enabled using deps tracker in JIT compilation (#51293)
This change simply flip the flag which enables using the deps tracker in JIT compilation (the logic is already implemented in a previous PR). Some tests which depend on the old JIT implementation (e.g., patching the scope info into the type) are modified accordingly.

PR Close #51293
2023-08-14 08:57:32 -07:00
Payam Valadkhan
a9f609e75c refactor(core): remove class type check when clearing cache in deps tracker (#51293)
Using verification helpers such as `isComponent` may trigger JIT compilation. Now in some tests such compilation is made purposely to fail, and so in such cases any reference to the `depsTracker.clearScopeCacheFor` method will cause the exception to be thrown earlier than expected which results in teh test failure. Such scenario is the case in the next commit when we enable using the deps tracker in the jit compilation. Note that such failure is only for the framework tests and is a very edge case. The tests in downstream apps will not lead to such scenario of failure at all.

PR Close #51293
2023-08-14 08:57:32 -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
Payam Valadkhan
f8c2a0d07f refactor(core): add an empty implementation for getComponentDepsFactory runtime (#51089)
An empty runtime is added just to make the local compiled angular files valid to run. A separate PR will implement the runtime in the right way using the deps tracker.

PR Close #51089
2023-08-08 13:58:48 -07:00
Payam Valadkhan
6a7c1ab9e9 refactor(core): migrate JIT to use deps tracker behind a flag (#51122)
The current change is done behind a flag which is set to false. So no change in code path took place here. In a followup PR the flag is changed to true which will make the actual change.

PR Close #51122
2023-08-07 09:25:27 -07:00
Andrew Kushnir
55965cbf8c fix(core): handle hydration of view containers for root components (#51247)
For cases when a root component also acts as an anchor node for a ViewContainerRef (for example, when ViewContainerRef is injected in a root component), there is a need to serialize information about the component itself, as well as an LContainer that represents this ViewContainerRef. Effectively, we need to serialize 2 pieces of info: (1) hydration info for the root component itself and (2) hydration info for the ViewContainerRef instance (an LContainer). Each piece of information is included into the hydration data (in the TransferState object) separately, thus we end up with 2 ids. Since we only have 1 root element, we encode both bits of info into a single string: ids are separated by the `|` char (e.g. `10|25`, where `10` is the ngh for a component view and 25 is the `ngh` for a root view which holds LContainer).

Previously, we were only including component-related information, thus all the views in the view container remained dehydrated and duplicated (client-rendered from scratch) on the client.

Resolves #51157.

PR Close #51247
2023-08-07 09:24:26 -07:00
Pawel Kozlowski
f12f906bd7 refactor(core): introduce LView and LContainer utility functions (#51191)
This refactoring adds utility functions to add / remove LView from LContainer.
Those utils are preparation for the control flow and defer work.
Existing code was refactored to use the new utility functions and avoid
any code duplication.

PR Close #51191
2023-08-04 16:00:44 -04:00
Gerald Monaco
e53d4ecf4c feat(core): add afterRender and afterNextRender (#50607)
Add and expose the after*Render functions as developer preview

PR Close #50607
2023-08-01 13:02:27 -07:00
Matthieu Riegler
4602545fe6 refactor(core): remove useless hack (#51224)
This hack is remnant of the Ivy migration.

PR Close #51224
2023-08-01 12:12:52 -07:00
Matthieu Riegler
a871e23857 docs: remove duplicate words. (#51215)
Using the `\b(\w+)\s+\1\b` we can find duplicate word. Let's remove them.

PR Close #51215
2023-08-01 12:08:33 -07:00
Andrew Kushnir
efb486e8bc refactor(compiler): handle defer blocks in TemplateDefinitionBuilder (#51162)
Updates the TemplateDefinitionBuilder class to generate the `defer` instruction for `{#defer}` blocks. Also generates dependency function that would be invoked at runtime (with dynamic imports inside).

PR Close #51162
2023-08-01 11:50:05 -07:00
AleksanderBodurri
98d262fd27 feat(core): create injector debugging APIs (#48639)
This commit introduces 3 new APIs.

getDependenciesFromInstantiation:
- Given an injector and a token that was instantiated by that injector, discover all of the things were injected in the instance of that token
- This API is meant to enable recursive inspection of dependencies. Dependencies returned by this API include which injector they were providedIn, which enables the continous use of getDependenciesFromInstantiation to determine the dependencies of dependencies

getInjectorProviders:
- Given an injector, discover all of the providers that were configured in that injector.
- This API returns information on the configured providers of an injector, including the import path that leads to the container that the provider originated from (NgModule or standalone directive). This enables fine grained inspection to determine where a specific provider comes from.

getInjectorParent:
- Given an injector, discover the parent of that injector.
- This function is meant to be used recursively to discover the entire resolution path from a starting injector to the NullInjector.

These APIs were designed to be used together. For example, getInjectorParent can be used to discover the structure of an injector hierarchy. Once that's done, getInjectorProviders can be used to determine the providers of each injector in that hierarchy.

Another example: getDependenciesFromInstantiation can be used to discover the dependencies of a specific injector constructed instance. From there, we can use getInjectorParent to discover the injector resolution path and map each dependency to a path from the starting injector to the injector that it was provided in.

PR Close #48639
2023-08-01 11:44:40 -07:00
AleksanderBodurri
ff4d1b4a0e feat(devtools): create profiler for DI and injector events (#48639)
Currently, understanding dependency injection in Angular requires a lot of context and has been sited in our surveys as one of the largest points of confusion that our users have with the framework. This commit is the beginning of our approach to make debugging dependency injection in Angular easier.

This commit introduces injector profiler callbacks in parts of the framework to emit injector events. It also introduces a default handler for these events. This default handler parses the stream of events to construct some data structures that will support new injector debug APIs.

We have implemented a similar pattern in the past to minimize overhead. There is also the possiblity of making the internal `setInjectorProfiler` function a public debug API in the future, so that users can implement their own handlers to debug DI events. Lastly DI in Angular maps nicely to a stream of events.

For production applications there is no runtime overhead. For applications in dev mode there is some additional overhead from the default profiler handling injector events and holding debug data in memory.

For production applications, dead code elimination should strip all of the code used by this PR.

PR Close #48639
2023-08-01 11:44:40 -07:00
Payam Valadkhan
07b04b2511 refactor(core): implement logic for getting component dependencies in the runtime deps tracker (#50980)
This includes implementation of methods getComponentDependencies and registerNgModule.

In order to correlate ng-modules with their declarations it is required to use the method registerNgModule to regiater the ng-module. However, the actual correlation will happen lazily once getComponentDependencies method is called. This lazy behaviour also allows for forward refs to be resolved.

The method getComponentDependencies will be used in local compilation mode to compute the rendering component deps in runtime.

PR Close #50980
2023-07-18 14:04:39 +00:00
Payam Valadkhan
548cf56782 refactor(core): implement clearScopeCacheFor for runtime deps tracker (#50980)
This method mainly has application test beds where we want to apply overrides and re-compute the scope.

PR Close #50980
2023-07-18 14:04:39 +00:00
Payam Valadkhan
afae358009 refactor(core): implement getStandaloneComponentScope method of the runtime deps tracker (#50980)
The logic mainly followed the `render3/jit/directive.ts#getStandaloneDefFunctions` helper.

PR Close #50980
2023-07-18 14:04:39 +00:00
Payam Valadkhan
48a3197d8f refactor(core): implement getNgModuleScope method of runtime dependency tracker (#50980)
The implementation is more or less follows the pattern in render3/jit/module.ts#transitiveScopesFor helper. A few additional helper functions also added to jit utils.

PR Close #50980
2023-07-18 14:04:39 +00:00
Matthieu Riegler
3dafc14e84 refactor(core): Log a warning when multiple pipes match a name (#50389)
Since this might be too breaking, let's log for now and wait for a major to throw an actual error.

Fixes #13569

PR Close #50389
2023-07-11 08:29:07 -07:00
Matthieu Riegler
61be62d621 refactor(core): fix Tnode/TView assertion. (#50914)
The debug data structure was removed in #48281. Before this fix the assertion relied on it.

PR Close #50914
2023-07-11 08:23:18 -07:00
Matthieu Riegler
394ca3b49a docs: Improve documentation about Injection context / inject (#49782)
Injection context has gain public visibility with the exposure of `inject`. Lets provide some insights.

Closes  #49774

PR Close #49782
2023-07-10 07:09:31 -07:00
Andrew Kushnir
031b599a55 fix(core): ensure that standalone components get correct injector instances (#50954)
Prior to this change, we've used `componentDef.id` as a key in a Map that acts as a cache to avoid re-creating injector instances for standalone components. In v16, the logic that generates the id has changed from an auto-incremental to a generation based on metadata. If multiple components have similar metadata, their ids might overlap.

This commit updates the logic to stop using `componentDef.id` as a key and instead, use the `componentDef` itself. This would ensure that we always have a correct instance of an injector associated with a standalone component instance.

Resolves #50724.

PR Close #50954
2023-07-10 07:07:44 -07:00
Kristiyan Kostadinov
29340a0678 fix(core): expose input transform function on ComponentFactory and ComponentMirror (#50713)
Exposes the function used to transform an input on `ComponentFactory.inputs` and `ComponentMirror.inputs`. We'll need this to support input transforms in `elements`.

PR Close #50713
2023-06-22 09:47:15 -07:00
Payam Valadkhan
7d7fc48e58 refactor(core): tweak runtime deps tracker to accommodate JIT requirements. (#50606)
The previous API design for the runtime deps tracker was done with only local compilation in mind. Now if we want to use it for JIT as well then some new requirements come along which are addressed by this commit as follows:
  - JIT scopes need distinct sets for directive and pipes. Thus the ScopeData interface is modified to include these info.
  - JIT needs access to scopes for various operations. So methods `getNgModuleScope` and `getStandaloneComponentScope` are added to the tracker's public api.
  - Test bed needs to clear the scope cache for its override mechanism. So method `clearScopeCacheFor` is added to the tracker's public api for this reason.

PR Close #50606
2023-06-21 11:48:56 -07:00
Payam Valadkhan
bff1010a6f refactor(core): add runtime deps tracker public interface with an empty implementation (#50606)
The types and interfaces re;ated to the runtime deps tracker are added. Also an empty implementation is added to be completed in follow up PRs (after the interfaces are confirmed in this PR).

The added files are not used anywhere, so the change should not affect anything in anyway.

PR Close #50606
2023-06-21 11:48:56 -07:00
Matthieu Riegler
028bd90bb1 docs(core): Make links out of @see tags (#50110)
This commit is part of the work for #50097 to improve the linking on the online documentation.

PR Close #50110
2023-06-14 10:54:38 +02:00
Andrew Kushnir
307f8eee2c fix(core): avoid duplicated content during hydration while processing a component with i18n (#50644)
This commit updates an internal hydration logic to make sure that the content of components with i18n blocks is cleaned up before we start rendering it.

Resolves #50627.

PR Close #50644
2023-06-13 13:12:07 +02:00
Kristiyan Kostadinov
79a706c847 fix(core): incorrectly throwing error for self-referencing component (#50559)
Components are implied to be self-referencing, but if they explicitly set themselves in the `imports` array, they would throw an error because we weren't filtering them out.

Fixes #50525.

PR Close #50559
2023-06-06 14:23:40 -07:00
Kristiyan Kostadinov
68017d4e75 feat(core): add ability to transform input values (#50420)
According to the HTML specification most attributes are defined as strings, however some can be interpreted as different types like booleans or numbers. [In the HTML standard](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes), boolean attributes are considered `true` if they are present on a DOM node and `false` if they are omitted. Common examples of boolean attributes are `disabled` on interactive elements like `<button>` or `checked` on `<input type="checkbox">`. Another example of an attribute that is defined as a string, but interpreted as a different type is the `value` attribute of `<input type="number">` which logs a warning and ignores the value if it can't be parsed as a number.

Historically, authoring Angular inputs that match the native behavior in a type-safe way has been difficult for developers, because Angular interprets all static attributes as strings. While some recent TypeScript versions made this easier by allowing setters and getters to have different types, supporting this pattern still requires a lot of boilerplate and additional properties to be declared. For example, currently developers have to write something like this to have a `disabled` input that behaves like the native one:

```typescript
import {Directive, Input} from '@angular/core';

@Directive({selector: 'mat-checkbox'})
export class MatCheckbox {
  @Input()
  get disabled() {
    return this._disabled;
  }
  set disabled(value: any) {
    this._disabled = typeof value === 'boolean' ? value : (value != null && value !== 'false');
  }
  private _disabled = false;
}
```

This feature aims to address the issue by introducing a `transform` property on inputs. If an input has a `transform` function, any values set through the template will be passed through the function before being assigned to the directive instance. The example from above can be rewritten to the following:

```typescript
import {Directive, Input, booleanAttribute} from '@angular/core';

@Directive({selector: 'mat-checkbox'})
export class MatCheckbox {
  @Input({transform: booleanAttribute}) disabled: boolean = false;
}
```

These changes also add the `booleanAttribute` and `numberAttribute` utilities to `@angular/core` since they're common enough to be useful for most projects.

Fixes #8968.
Fixes #14761.

PR Close #50420
2023-05-30 13:01:13 -07:00
gdarnell
75fdbcb8f2 fix(core): fix Self flag inside embedded views with custom injectors (#50270)
When an embedded view injector is present anywhere above a node in the tree, the `Self` flag was effectively ignored. With this change, embedded view injectors are not checked at all when the `Self` flag is present, because resolution should stop at the current node before reaching any embedded view injector(s).

Fixes #49959

PR Close #50270
2023-05-24 13:59:20 +00:00
Matthieu Riegler
9054f95c6a refactor(core): Improve NG100 (#50391)
Improve the NG100 error message by formating the value using `JSON.stringify`

See #34454

PR Close #50391
2023-05-23 15:31:17 +00:00