# Overview

Ivy is a new backwards-compatible Angular renderer focused on further speed improvements, size reduction, and increased flexibility.

Ivy is currently not feature complete, but can be tested via [`enableIvy: true`](https://next.angular.io/guide/aot-compiler#enableivy) [`angularCompilerOptions` flag](https://next.angular.io/guide/aot-compiler#angular-compiler-options).

We currently expect Ivy to remain behind the flag until it's feature complete and battle tested at Google. In the meantime you can check out this [Hello World demo](https://ng-ivy-demo.firebaseapp.com/).

# Implementation Status

The work can be divided into three categories:
- `@angular/compiler-cli`: TypeScript transformer pipeline which includes two command line tools:
  - `ngtsc`: (Angular TypeScript Compiler) Angular compiler which strips out `@Component` (and friends) and replaces it with `defineComponent` (and friends).
  - `ngcc`: (Angular Compatibility Compiler) NPM upgrade compiler which reads the `.STORING_METADATA_IN_D.TS.json` files and `.js` files and adds `defineComponent` (and friends) into the `node_module`. This in effect converts a pre-ivy module into ivy module.
- `@angular/compiler`: Ivy Compiler which converts decorator into ivy
- `@angular/core`: Decorators which can be patched with `@angular/compiler`.


## `@angular/compiler-cli` changes
### `ngtsc` TSC compiler transformer

TSC transformer which removes and converts `@Pipe`, `@Component`, `@Directive` and `@NgModule`
to the corresponding `definePipe`, `defineComponent`, `defineDirective` and `defineInjector`.

- ❌ Basic setup of the transformer into `tsc`
- ❌ Can read STORING_METADATA_IN_D.TS from `.d.ts` (see: [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md))
- ❌ Detect decorators and convert them to the `defineXXX` method using the `__Compiler` in `@angular/compiler`.
  - ❌ `@Pipe` => `definePipe`
  - ❌ `@Component` => `defineComponent`
  - ❌ `@Directive` => `defineDirective`
  - ❌ `@NgModule` => `defineInjector`
- ❌ Encode selectors into `.d.ts` file.
  - ❌ `@Pipe` => see [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md)
  - ❌ `@Component` => see [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md)
  - ❌ `@Directive` => see [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md)
  - ❌ `@NgModule` => see [STORING_METADATA_IN_D.TS.md](./STORING_METADATA_IN_D.TS.md)
- ❌ support `extends` for `@Pipe`, `@Component`, `@Directive` and `@NgModule`.
- ❌ Documentation

### `ngcc` Angular `node_module` compatibility compiler 

A tool which "upgrades" `node_module` compiled with non-ivy `ngc` into ivy compliant format.

- ❌ Basic setup of stand alone executable
- ❌ Integration with WebPack (cli)
- ❌ Rewrite existing code by interpreting the associated STORING_METADATA_IN_D.TS
  - ❌ `PipeCompiler`: `@Pipe` => `definePipe`
  - ❌ `DirectiveCompiler`: `@Directive` => `defineDirective`
  - ❌ `NgModuleCompiler`: `@NgModule` => `defineInjector`
  - ❌ `ComponentCompiler`: `@Component` => `defineComponent`
    - ❌ `TemplateCompiler`
    - ❌ `StyleCompiler`
- ❌ Documentation

## `@angular/compiler` changes

- ❌ Component compilation: Translates `@Component` => `defineComponent`
  - ❌ `TemplateCompiler` (current known as `ViewCompiler`)
  - ❌ `StyleCompiler`
- ❌ `PipeCompiler`: Translates `@Pipe` => `definePipe`
- ❌ `DirectiveCompiler`: Translates `@Directive` => `defineDirective`
- ❌ `InjectableCompiler`: Translates `@Injectable` => `defineInjectable`
- ❌ `NgModuleCompiler`: Translates `@NgModule` => `defineInjector` (and `defineNgModule` only in jit)
- ❌ Documentation


## `@angular/core` changes

The goal is for the `@Component` (and friends) to be the compiler of template. Since decorators are functions which execute during parsing of the `.js` file, the decorator can compile the template into Ivy. The AoT compiler's job is to remove the `@Component` and replace it with call to `defineComponent`.

- ❌ Remove `createDecorator` (and friends) since we no longer support other modes.
- ❌ `@angular/compiler` can patch itself onto:
  - ❌ `@Injectable`
  - ❌ `@NgModule`
  - ❌ `@Pipe`
  - ❌ `@Directive`
  - ❌ `@Component`
- ❌ `ResourceLoader.resolved: Promise<>` Returns true if all `templateUrl`s and `styleUrl` have been resolved and application is ready to be bootstrapped. 

# Testing / Debugging
- ❌ in debug mode publish components into DOM nodes for easier debugging.

# Crosscutting

## Decorators
| Annotation          | `defineXXX()`                  | Run time | Spec     | Compiler | Back Patch |
| -------------------- | ------------------------------ | ------- | -------- | -------- | -------- |
| `@Component`         | ✅ `defineComponent()`         |    ✅    |  ✅      |  ✅      |  ❌      |
| `@Directive`         | ✅ `defineDirective()`         |    ✅    |  ✅      |  ✅      |  ❌      |
| `@Directive`         | ❌ `defineAbstractDirective()` |    ❌    |  ❌      |  ❌      |  ❌      |
| `@Pipe`              | ✅ `definePipe()`              |    ✅    |  ✅      |  ✅      |  ❌      |
| `@Injectable`        | ✅ `defineInjectable()`        |    ✅    |  ❌      |  ❌      |  ❌      |
| `@NgModule`          | ✅ `defineInjector()`          |    ✅    |  ❌      |  ❌      |  ❌      |
| `@ConfigureInjector` | ❌ `defineInjector()`          |    ❌    |  ❌      |  ❌      |  ❌      |



## Component Composition
| Feature                                  | Runtime | Spec     | Compiler |
| ---------------------------------------- | ------- | -------- | -------- |
| creation reordering based on injection   |   ❌    |    ❌    |    ✅    |
| `class CompA extends CompB {}`           |   ❌    |    ❌    |    ❌    |
| `class CompA extends CompB { @Input }`   |   ❌    |    ❌    |    ❌    |
| `class CompA extends CompB { @Output }`  |   ❌    |    ❌    |    ❌    |



## Change Detection
| Feature                             | Runtime | 
| ----------------------------------- | ------- | 
| `markDirty()`                       |  ✅     | 
| `detectChanges()`                   |  ✅     | 
| `tick()`                            |  ✅     | 
| `attach()`                          |  ✅     | 
| `detach()`                          |  ✅     | 
| `ON_PUSH`                           |  ✅     | 
| `ALWAYS`                            |  ✅     | 
| `DIRTY`                             |  ✅     | 
| `ATTACHED`                          |  ✅     | 



## Bootstrap API
| Feature                             | Runtime | 
| ----------------------------------- | ------- | 
| `renderComponent()`                 |  ✅     | 
| `getHostElement()`                  |  ✅     | 
| `createInjector()`                  |  ✅     | 

## Template Compiler

### Template Syntax
| Feature                                 | Runtime | Spec     | Compiler |
| --------------------------------------- | ------- | -------- | -------- |
| `<div>`                                 |  ✅     |  ✅      |  ✅      |
| `<div>{{exp}}</div>`                    |  ✅     |  ✅      |  ✅      |
| `<div attr=value>`                      |  ✅     |  ✅      |  ✅      |
| `<div (click)="stmt">`                  |  ✅     |  ✅      |  ✅      |
| `<div #foo>`                            |  ✅     |  ✅      |  ✅      |
| `<div #foo="bar">`                      |  ✅     |  ✅      |  ✅      |
| `<div [value]="exp">`                   |  ✅     |  ✅      |  ✅      |
| `<div title="Hello {{name}}!">`         |  ✅     |  ✅      |  ✅      |
| `<div [attr.value]="exp">`              |  ✅     |  ✅      |  ❌      |
| `<div class="literal">`                 |  ✅     |  ✅      |  ✅      |
| `<div [class]="exp">`                   |  ❌     |  ❌      |  ❌      |
| `<div [class.foo]="exp">`               |  ✅     |  ✅      |  ❌      |
| `<div style="literal">`                 |  ✅     |  ✅      |  ✅      |
| `<div [style]="exp">`                   |  ❌     |  ❌      |  ❌      |
| `<div [style.foo]="exp">`               |  ✅     |  ✅      |  ❌      |
| `{{ ['literal', exp ] }}`               |  ✅     |  ✅      |  ✅      |
| `{{ { a: 'literal', b: exp } }}`        |  ✅     |  ✅      |  ✅      |
| `{{ exp \| pipe: arg }}`                |  ✅     |  ✅      |  ✅      |
| `<svg:g svg:p>`                         |  ❌     |  ❌      |  ❌      |
| `<img src=[userData]>` sanitization     |  ❌     |  ❌      |  ❌      |
| `<div (nocd.click)>`                    |  ❌     |  ❌      |  ❌      |
| `<div (bubble.click)>`                  |  ❌     |  ❌      |  ❌      |
| `<div (keyup.enter)>`                   |  ❌     |  ❌      |  ❌      |
| `<div (hammer.js)>`                     |  ❌     |  ❌      |  ❌      |

### Life Cycle Hooks
| Feature                   | Runtime | Spec     | Compiler |
| ------------------------- | ------- | -------- | -------- |
| `onChanges()`             |    ✅   |  ✅      |  ✅      |
| `onDestroy()`             |    ✅   |  ✅      |  ✅      |
| `onInit()`                |    ✅   |  ✅      |  ✅      |
| `onChanges()`             |    ✅   |  ✅      |  ✅      |
| `doCheck()`               |    ✅   |  ✅      |  ✅      |
| `afterViewChecked()`      |    ✅   |  ✅      |  ✅      |
| `afterViewInit()`         |    ✅   |  ✅      |  ✅      |
| `afterContentChecked()`   |    ✅   |  ✅      |  ✅      |
| `afterContentInit()`      |    ✅   |  ✅      |  ✅      |
| listener teardown         |    ✅   |  ✅      |  ✅      |



### `@Query`
| Feature                         | Runtime | Spec     | Compiler |
| ------------------------------- | ------- | -------- | -------- |
| `@Query(descendants)`           |  ✅     |  ✅      |  n/a      |
| `@Query(one)`                   |  ✅     |  ✅      |  n/a      |
| `@Query(read)`                  |  ✅     |  ✅      |  n/a      |
| `@Query(selector)`              |  ✅     |  ✅      |  n/a      |
| `@Query(Type)`                  |  ✅     |  ✅      |  n/a      |
| `@ContentChildred`              |  ✅     |  ✅      |  ❌       |
| `@ContentChild`                 |  ✅     |  ✅      |  ✅       |
| `@ViewChildren`                 |  ✅     |  ✅      |  ❌       |
| `@ViewChild`                    |  ✅     |  ✅      |  ✅       |



### Content Projection
| Feature                         | Runtime | Spec     | Compiler |
| ------------------------------- | ------- | -------- | -------- |
| `<ng-content>`                  |  ✅     |  ✅      |  ✅      |
| `<ng-content selector="...">`   |  ✅     |  ✅      |  ✅      |
| container `projectAs`           |  ✅     |  ✅      |  ❌      |



### Injection Features
| Feature                             | Runtime | Spec     | Compiler |
| ----------------------------------- | ------- | -------- | -------- |
| `inject(Type)`                      |  ✅     |  ✅      |  ✅      |
| `directiveInject(Type)`             |  ✅     |  ✅      |  ❌      |
| `inject(Type, SkipSelf)`            |  ❌     |  ❌      |  ❌      |
| `attribute('name')`                 |  ✅     |  ✅      |  ❌      |
| `injectChangeDetectionRef()`        |  ✅     |  ✅      |  ❌      |
| `injectElementRef()`                |  ✅     |  ✅      |  ✅      |
| `injectViewContainerRef()`          |  ✅     |  ✅      |  ✅      |
| `injectTemplateRef()`               |  ✅     |  ✅      |  ✅      |
| default `inject()` with no injector |  ❌     |  ❌      |  ❌      |
| sanitization with no injector       |  ✅     |  ✅      |  ❌      |


### I18N
| Feature                             | Runtime | Spec     | Compiler |
| ----------------------------------- | ------- | -------- | -------- |
| translate text literals             |  ❌     |  ❌      |  ❌      |
| rearrange text nodes                |  ❌     |  ❌      |  ❌      |
| ICU                                 |  ❌     |  ❌      |  ❌      |


### View Encapsulation
| Feature                             | Runtime | Spec     | Compiler |
| ----------------------------------- | ------- | -------- | -------- |
| Render3.None                        |  ✅     |  ✅       |  ✅      |
| Render2.None                        |  ✅     |  ✅       |  ✅      |
| Render2.Emulated                    |  ❌     |  ❌       |  ❌      |
| Render2.Native                      |  ❌     |  ❌       |  ❌      |



### `______Ref`s
| Method                 | View Container Ref | Template Ref | Embeded View Ref | View Ref | Element Ref | Change Detection Ref |
| ---------------------- | ------------------ | ------------ | ---------------- | -------- | ----------- | -------------------- |
| `clear()`              |  ❌                | n/a          | n/a              | n/a      | n/a         | n/a                  |
| `get()`                |  ❌                | n/a          | n/a              | n/a      | n/a         | n/a                  |
| `createEmbededView()`  |  ✅                | ✅           | n/a              | n/a      | n/a         | n/a                  |
| `createComponent()`    |  ✅                | n/a          | n/a              | n/a      | n/a         | n/a                  |
| `insert()`             |  ✅                | n/a          | n/a              | n/a      | n/a         | n/a                  |
| `move()`               |  ❌                | n/a          | n/a              | n/a      | n/a         | n/a                  |
| `indexOf()`            |  ❌                | n/a          | n/a              | n/a      | n/a         | n/a                  |
| `destroy()`            | n/a                | n/a          |  ❌              | ❌       | n/a         | n/a                  |
| `destroyed`            | n/a                | n/a          |  ❌              | ❌       | n/a         | n/a                  |
| `onDestroy()`          | n/a                | n/a          |  ❌              | ❌       | n/a         | n/a                  |
| `markForCheck()`       | n/a                | n/a          |  ❌              | n/a      | n/a         | ✅                   |
| `detach()`             |  ❌                | n/a          |  ❌              | n/a      | n/a         | ✅                   |
| `detachChanges()`      | n/a                | n/a          |  ❌              | n/a      | n/a         | ✅                   |
| `checkNoChanges()`     | n/a                | n/a          |  ❌              | n/a      | n/a         | ✅                   |
| `reattach()`           | n/a                | n/a          |  ❌              | n/a      | n/a         | ✅                   |
| `nativeElement()`      | n/a                | n/a          | n/a              | n/a      |  ✅         | n/a                  |
