diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js
new file mode 100644
index 0000000000..c343a21038
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js
@@ -0,0 +1,334 @@
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.myTitle = 'hello';
+ this.buttonId = 'special-button';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: `
+
+ `
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ myTitle: string;
+ buttonId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_single_interpolation.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.myTitle = 'hello';
+ this.buttonId = 'special-button';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: `
+
+ `
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_single_interpolation.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ myTitle: string;
+ buttonId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_mixed.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: `
+
+ `
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_mixed.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_bindings_with_interpolations.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: `
+ `
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_bindings_with_interpolations.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_for_multiple_elements.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.myTitle = 'hello';
+ this.buttonId = 'special-button';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
+
+
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: `
+
+
+
+ `
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_for_multiple_elements.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ myTitle: string;
+ buttonId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_with_child_elements.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.myTitle = 'hello';
+ this.buttonId = 'special-button';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: `
+ `
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_with_child_elements.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ myTitle: string;
+ buttonId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: exclude_bindings_from_consts.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ doThings() { }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-app", ngImport: i0, template: { source: ``, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-app',
+ template: ``
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: exclude_bindings_from_consts.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ doThings(): void;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: interpolated_attributes.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.name = 'John Doe';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-app", ngImport: i0, template: { source: `
+
+
+
+
+
+
+
+
+
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-app',
+ template: `
+
+
+
+
+
+
+
+
+
+
+ `
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: interpolated_attributes.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ name: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/TEST_CASES.json
new file mode 100644
index 0000000000..5ba9e33bf5
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/TEST_CASES.json
@@ -0,0 +1,117 @@
+{
+ "$schema": "../../test_case_schema.json",
+ "cases": [
+ {
+ "description": "should chain multiple attribute bindings into a single instruction",
+ "inputFiles": [
+ "chain_multiple_bindings.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_bindings.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple single-interpolation attribute bindings into one instruction",
+ "inputFiles": [
+ "chain_multiple_single_interpolation.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_single_interpolation.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain attribute bindings in the presence of other bindings",
+ "inputFiles": [
+ "chain_multiple_bindings_mixed.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_bindings_mixed.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should not add interpolated attributes to the attribute instruction chain",
+ "inputFiles": [
+ "chain_bindings_with_interpolations.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_bindings_with_interpolations.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple attribute bindings when there are multiple elements",
+ "inputFiles": [
+ "chain_multiple_bindings_for_multiple_elements.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_bindings_for_multiple_elements.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple attribute bindings when there are child elements",
+ "inputFiles": [
+ "chain_multiple_bindings_with_child_elements.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_bindings_with_child_elements.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should exclude attribute bindings from the attributes array",
+ "inputFiles": [
+ "exclude_bindings_from_consts.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect attribute array",
+ "files": [
+ "exclude_bindings_from_consts.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should generate the proper update instructions for interpolated attributes",
+ "inputFiles": [
+ "interpolated_attributes.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect handling of interpolated attributes",
+ "files": [
+ "interpolated_attributes.js"
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_bindings_with_interpolations.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_bindings_with_interpolations.js
new file mode 100644
index 0000000000..dea91e1b3b
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_bindings_with_interpolations.js
@@ -0,0 +1,8 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵattributeInterpolate1("tabindex", "prefix-", 0 + 3, "");
+ $r3$.ɵɵattributeInterpolate2("aria-label", "hello-", 1 + 3, "-", 2 + 3, "");
+ $r3$.ɵɵattribute("title", 1)("id", 2);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_bindings_with_interpolations.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_bindings_with_interpolations.ts
new file mode 100644
index 0000000000..8df23ea769
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_bindings_with_interpolations.ts
@@ -0,0 +1,12 @@
+import {Component} from '@angular/core';
+
+@Component({
+ template: `
+ `
+})
+export class MyComponent {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings.js
new file mode 100644
index 0000000000..a5bbd418b8
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings.js
@@ -0,0 +1,6 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵattribute("title", ctx.myTitle)("id", ctx.buttonId)("tabindex", 1);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings.ts
new file mode 100644
index 0000000000..3731965125
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings.ts
@@ -0,0 +1,11 @@
+import {Component} from '@angular/core';
+
+@Component({
+ template: `
+
+ `
+})
+export class MyComponent {
+ myTitle = 'hello';
+ buttonId = 'special-button';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements.js
new file mode 100644
index 0000000000..f5fab7731a
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements.js
@@ -0,0 +1,10 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵattribute("title", ctx.myTitle)("id", ctx.buttonId)("tabindex", 1);
+ $r3$.ɵɵadvance(1);
+ $r3$.ɵɵattribute("id", 1)("title", "hello")("some-attr", 1 + 2);
+ $r3$.ɵɵadvance(1);
+ $r3$.ɵɵattribute("some-attr", "one")("some-other-attr", 2);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements.ts
new file mode 100644
index 0000000000..0b5873405c
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_for_multiple_elements.ts
@@ -0,0 +1,13 @@
+import {Component} from '@angular/core';
+
+@Component({
+ template: `
+
+
+
+ `
+})
+export class MyComponent {
+ myTitle = 'hello';
+ buttonId = 'special-button';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_mixed.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_mixed.js
new file mode 100644
index 0000000000..f0e3782031
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_mixed.js
@@ -0,0 +1,8 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵattributeInterpolate1("aria-label", "prefix-", 1 + 3, "");
+ $r3$.ɵɵproperty("id", 2);
+ $r3$.ɵɵattribute("title", 1)("tabindex", 3);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_mixed.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_mixed.ts
new file mode 100644
index 0000000000..71d4711d2d
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_mixed.ts
@@ -0,0 +1,10 @@
+import {Component} from '@angular/core';
+
+@Component({
+ template: `
+
+ `
+})
+export class MyComponent {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements.js
new file mode 100644
index 0000000000..513bdb8987
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements.js
@@ -0,0 +1,8 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵattribute("title", ctx.myTitle)("id", ctx.buttonId)("tabindex", 1);
+ $r3$.ɵɵadvance(1);
+ $r3$.ɵɵattribute("id", 1)("title", "hello")("some-attr", 1 + 2);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements.ts
new file mode 100644
index 0000000000..d7a8c62e36
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_bindings_with_child_elements.ts
@@ -0,0 +1,12 @@
+import {Component} from '@angular/core';
+
+@Component({
+ template: `
+ `
+})
+export class MyComponent {
+ myTitle = 'hello';
+ buttonId = 'special-button';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_single_interpolation.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_single_interpolation.js
new file mode 100644
index 0000000000..a5bbd418b8
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_single_interpolation.js
@@ -0,0 +1,6 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵattribute("title", ctx.myTitle)("id", ctx.buttonId)("tabindex", 1);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_single_interpolation.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_single_interpolation.ts
new file mode 100644
index 0000000000..5df3e265d2
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/chain_multiple_single_interpolation.ts
@@ -0,0 +1,11 @@
+import {Component} from '@angular/core';
+
+@Component({
+ template: `
+
+ `
+})
+export class MyComponent {
+ myTitle = 'hello';
+ buttonId = 'special-button';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/exclude_bindings_from_consts.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/exclude_bindings_from_consts.js
new file mode 100644
index 0000000000..e5c6038ee8
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/exclude_bindings_from_consts.js
@@ -0,0 +1,3 @@
+
+consts: [["target", "_blank", "aria-label", "link", __AttributeMarker.Bindings__, "title", "id", "customEvent"]],
+…
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/exclude_bindings_from_consts.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/exclude_bindings_from_consts.ts
new file mode 100644
index 0000000000..46b31f12bf
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/exclude_bindings_from_consts.ts
@@ -0,0 +1,21 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-app',
+ template: ``
+})
+export class MyComponent {
+ doThings() {}
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/interpolated_attributes.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/interpolated_attributes.js
new file mode 100644
index 0000000000..d6d2d6d664
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/interpolated_attributes.js
@@ -0,0 +1,22 @@
+if (rf & 2) {
+ i0.ɵɵattributeInterpolateV("title", ["a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i", ctx.nine, "j"]);
+ i0.ɵɵadvance(1);
+ i0.ɵɵattributeInterpolate8("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i");
+ i0.ɵɵadvance(1);
+ i0.ɵɵattributeInterpolate7("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h");
+ i0.ɵɵadvance(1);
+ i0.ɵɵattributeInterpolate6("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g");
+ i0.ɵɵadvance(1);
+ i0.ɵɵattributeInterpolate5("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f");
+ i0.ɵɵadvance(1);
+ i0.ɵɵattributeInterpolate4("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e");
+ i0.ɵɵadvance(1);
+ i0.ɵɵattributeInterpolate3("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d");
+ i0.ɵɵadvance(1);
+ i0.ɵɵattributeInterpolate2("title", "a", ctx.one, "b", ctx.two, "c");
+ i0.ɵɵadvance(1);
+ i0.ɵɵattributeInterpolate1("title", "a", ctx.one, "b");
+ i0.ɵɵadvance(1);
+ i0.ɵɵattribute("title", ctx.one);
+}
+…
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/interpolated_attributes.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/interpolated_attributes.ts
new file mode 100644
index 0000000000..cc32ff7225
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/interpolated_attributes.ts
@@ -0,0 +1,24 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-app',
+ template: `
+
+
+
+
+
+
+
+
+
+
+ `
+})
+export class MyComponent {
+ name = 'John Doe';
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/GOLDEN_PARTIAL.js
new file mode 100644
index 0000000000..f634c56e46
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/GOLDEN_PARTIAL.js
@@ -0,0 +1,591 @@
+/****************************************************************************************************
+ * PARTIAL FILE: host_bindings.js
+ ****************************************************************************************************/
+import { Directive, HostBinding, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class HostBindingDir {
+ constructor() {
+ this.dirId = 'some id';
+ }
+}
+HostBindingDir.ɵfac = function HostBindingDir_Factory(t) { return new (t || HostBindingDir)(); };
+HostBindingDir.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: HostBindingDir, selector: "[hostBindingDir]", host: { properties: { "id": "dirId" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(HostBindingDir, [{
+ type: Directive,
+ args: [{ selector: '[hostBindingDir]' }]
+ }], null, { dirId: [{
+ type: HostBinding,
+ args: ['id']
+ }] }); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [HostBindingDir] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [HostBindingDir] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_bindings.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class HostBindingDir {
+ dirId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_bindings_with_temporaries.js
+ ****************************************************************************************************/
+import { Directive, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class HostBindingDir {
+}
+HostBindingDir.ɵfac = function HostBindingDir_Factory(t) { return new (t || HostBindingDir)(); };
+HostBindingDir.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: HostBindingDir, selector: "[hostBindingDir]", host: { properties: { "id": "getData()?.id" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(HostBindingDir, [{
+ type: Directive,
+ args: [{ selector: '[hostBindingDir]', host: { '[id]': 'getData()?.id' } }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [HostBindingDir] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [HostBindingDir] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_bindings_with_temporaries.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class HostBindingDir {
+ getData?: () => {
+ id: number;
+ };
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_bindings_with_pure_functions.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class HostBindingComp {
+ constructor() {
+ this.id = 'some id';
+ }
+}
+HostBindingComp.ɵfac = function HostBindingComp_Factory(t) { return new (t || HostBindingComp)(); };
+HostBindingComp.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: HostBindingComp, selector: "host-binding-comp", host: { properties: { "id": "[\"red\", id]" } }, ngImport: i0, template: { source: '', isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(HostBindingComp, [{
+ type: Component,
+ args: [{ selector: 'host-binding-comp', host: { '[id]': '["red", id]' }, template: '' }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [HostBindingComp] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [HostBindingComp] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_bindings_with_pure_functions.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class HostBindingComp {
+ id: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_attribute_bindings.js
+ ****************************************************************************************************/
+import { Directive, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class HostAttributeDir {
+ constructor() {
+ this.required = true;
+ }
+}
+HostAttributeDir.ɵfac = function HostAttributeDir_Factory(t) { return new (t || HostAttributeDir)(); };
+HostAttributeDir.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: HostAttributeDir, selector: "[hostAttributeDir]", host: { properties: { "attr.required": "required" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(HostAttributeDir, [{
+ type: Directive,
+ args: [{ selector: '[hostAttributeDir]', host: { '[attr.required]': 'required' } }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [HostAttributeDir] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [HostAttributeDir] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_attribute_bindings.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class HostAttributeDir {
+ required: boolean;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_attributes.js
+ ****************************************************************************************************/
+import { Directive, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class HostAttributeDir {
+}
+HostAttributeDir.ɵfac = function HostAttributeDir_Factory(t) { return new (t || HostAttributeDir)(); };
+HostAttributeDir.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: HostAttributeDir, selector: "[hostAttributeDir]", host: { attributes: { "aria-label": "label" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(HostAttributeDir, [{
+ type: Directive,
+ args: [{ selector: '[hostAttributeDir]', host: { 'aria-label': 'label' } }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [HostAttributeDir] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [HostAttributeDir] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_attributes.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class HostAttributeDir {
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_attributes_with_classes_and_styles.js
+ ****************************************************************************************************/
+import { Component, Directive, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class HostAttributeComp {
+}
+HostAttributeComp.ɵfac = function HostAttributeComp_Factory(t) { return new (t || HostAttributeComp)(); };
+HostAttributeComp.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: HostAttributeComp, selector: "my-host-attribute-component", host: { attributes: { "title": "hello there from component" }, styleAttribute: "opacity:1" }, ngImport: i0, template: { source: '...', isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(HostAttributeComp, [{
+ type: Component,
+ args: [{
+ selector: 'my-host-attribute-component',
+ template: '...',
+ host: { 'title': 'hello there from component', 'style': 'opacity:1' }
+ }]
+ }], null, null); })();
+export class HostAttributeDir {
+}
+HostAttributeDir.ɵfac = function HostAttributeDir_Factory(t) { return new (t || HostAttributeDir)(); };
+HostAttributeDir.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: HostAttributeDir, selector: "[hostAttributeDir]", host: { attributes: { "title": "hello there from directive" }, properties: { "style.opacity": "true", "class.three": "true" }, styleAttribute: "width: 200px; height: 500px", classAttribute: "one two" }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(HostAttributeDir, [{
+ type: Directive,
+ args: [{
+ selector: '[hostAttributeDir]',
+ host: {
+ 'style': 'width: 200px; height: 500px',
+ '[style.opacity]': 'true',
+ 'class': 'one two',
+ '[class.three]': 'true',
+ 'title': 'hello there from directive',
+ }
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [HostAttributeComp, HostAttributeDir] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [HostAttributeComp, HostAttributeDir] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: host_attributes_with_classes_and_styles.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class HostAttributeComp {
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class HostAttributeDir {
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_property_bindings.js
+ ****************************************************************************************************/
+import { Directive } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyDirective {
+ constructor() {
+ this.myTitle = 'hello';
+ this.myId = 'special-directive';
+ }
+}
+MyDirective.ɵfac = function MyDirective_Factory(t) { return new (t || MyDirective)(); };
+MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: MyDirective, selector: "[my-dir]", host: { properties: { "title": "myTitle", "tabindex": "1", "id": "myId" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyDirective, [{
+ type: Directive,
+ args: [{ selector: '[my-dir]', host: { '[title]': 'myTitle', '[tabindex]': '1', '[id]': 'myId' } }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_property_bindings.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyDirective {
+ myTitle: string;
+ myId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_property_bindings_all.js
+ ****************************************************************************************************/
+import { Directive, HostBinding } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyDirective {
+ constructor() {
+ this.myTitle = 'hello';
+ this.myId = 'special-directive';
+ }
+}
+MyDirective.ɵfac = function MyDirective_Factory(t) { return new (t || MyDirective)(); };
+MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: MyDirective, selector: "[my-dir]", host: { properties: { "tabindex": "1", "title": "myTitle", "id": "myId" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyDirective, [{
+ type: Directive,
+ args: [{ selector: '[my-dir]', host: { '[tabindex]': '1' } }]
+ }], null, { myTitle: [{
+ type: HostBinding,
+ args: ['title']
+ }], myId: [{
+ type: HostBinding,
+ args: ['id']
+ }] }); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_property_bindings_all.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyDirective {
+ myTitle: string;
+ myId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_property_bindings_mixed.js
+ ****************************************************************************************************/
+import { Directive } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyDirective {
+}
+MyDirective.ɵfac = function MyDirective_Factory(t) { return new (t || MyDirective)(); };
+MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: MyDirective, selector: "[my-dir]", host: { properties: { "title": "\"my title\"", "attr.tabindex": "1", "id": "\"my-id\"" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyDirective, [{
+ type: Directive,
+ args: [{
+ selector: '[my-dir]',
+ host: { '[title]': '"my title"', '[attr.tabindex]': '1', '[id]': '"my-id"' }
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_property_bindings_mixed.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyDirective {
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_synthetic_properties.js
+ ****************************************************************************************************/
+import { Directive } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyDirective {
+ constructor() {
+ this.expandedState = 'collapsed';
+ this.isSmall = true;
+ }
+}
+MyDirective.ɵfac = function MyDirective_Factory(t) { return new (t || MyDirective)(); };
+MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: MyDirective, selector: "[my-dir]", host: { properties: { "@expand": "expandedState", "@fadeOut": "true", "@shrink": "isSmall" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyDirective, [{
+ type: Directive,
+ args: [{
+ selector: '[my-dir]',
+ host: { '[@expand]': 'expandedState', '[@fadeOut]': 'true', '[@shrink]': 'isSmall' }
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_synthetic_properties.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyDirective {
+ expandedState: string;
+ isSmall: boolean;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_attribute_bindings.js
+ ****************************************************************************************************/
+import { Directive } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyDirective {
+ constructor() {
+ this.myTitle = 'hello';
+ this.myId = 'special-directive';
+ }
+}
+MyDirective.ɵfac = function MyDirective_Factory(t) { return new (t || MyDirective)(); };
+MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: MyDirective, selector: "[my-dir]", host: { properties: { "attr.title": "myTitle", "attr.tabindex": "1", "attr.id": "myId" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyDirective, [{
+ type: Directive,
+ args: [{
+ selector: '[my-dir]',
+ host: { '[attr.title]': 'myTitle', '[attr.tabindex]': '1', '[attr.id]': 'myId' }
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_attribute_bindings.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyDirective {
+ myTitle: string;
+ myId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_attribute_bindings_all.js
+ ****************************************************************************************************/
+import { Directive, HostBinding } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyDirective {
+ constructor() {
+ this.myTitle = 'hello';
+ this.myId = 'special-directive';
+ }
+}
+MyDirective.ɵfac = function MyDirective_Factory(t) { return new (t || MyDirective)(); };
+MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: MyDirective, selector: "[my-dir]", host: { properties: { "attr.tabindex": "1", "attr.title": "myTitle", "attr.id": "myId" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyDirective, [{
+ type: Directive,
+ args: [{ selector: '[my-dir]', host: { '[attr.tabindex]': '1' } }]
+ }], null, { myTitle: [{
+ type: HostBinding,
+ args: ['attr.title']
+ }], myId: [{
+ type: HostBinding,
+ args: ['attr.id']
+ }] }); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_attribute_bindings_all.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyDirective {
+ myTitle: string;
+ myId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_attribute_bindings_mixed.js
+ ****************************************************************************************************/
+import { Directive } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyDirective {
+}
+MyDirective.ɵfac = function MyDirective_Factory(t) { return new (t || MyDirective)(); };
+MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: MyDirective, selector: "[my-dir]", host: { properties: { "attr.title": "\"my title\"", "tabindex": "1", "attr.id": "\"my-id\"" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyDirective, [{
+ type: Directive,
+ args: [{
+ selector: '[my-dir]',
+ host: { '[attr.title]': '"my title"', '[tabindex]': '1', '[attr.id]': '"my-id"' }
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_attribute_bindings_mixed.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyDirective {
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_listeners.js
+ ****************************************************************************************************/
+import { Directive, HostListener } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyDirective {
+ mousedown() { }
+ mouseup() { }
+ click() {
+ }
+}
+MyDirective.ɵfac = function MyDirective_Factory(t) { return new (t || MyDirective)(); };
+MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: 1, type: MyDirective, selector: "[my-dir]", host: { listeners: { "mousedown": "mousedown()", "mouseup": "mouseup()", "click": "click()" } }, ngImport: i0 });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyDirective, [{
+ type: Directive,
+ args: [{
+ selector: '[my-dir]',
+ host: {
+ '(mousedown)': 'mousedown()',
+ '(mouseup)': 'mouseup()',
+ }
+ }]
+ }], null, { click: [{
+ type: HostListener,
+ args: ['click']
+ }] }); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_listeners.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyDirective {
+ mousedown(): void;
+ mouseup(): void;
+ click(): void;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵdir: i0.ɵɵDirectiveDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_synthetic_listeners.js
+ ****************************************************************************************************/
+import { Component, HostListener } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ start() {
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-comp", host: { listeners: { "@animation.done": "done()", "@animation.start": "start()" } }, ngImport: i0, template: { source: '', isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-comp',
+ template: '',
+ host: {
+ '(@animation.done)': 'done()',
+ }
+ }]
+ }], null, { start: [{
+ type: HostListener,
+ args: ['@animation.start']
+ }] }); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_synthetic_listeners.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ start(): void;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_synthetic_listeners_mixed.js
+ ****************************************************************************************************/
+import { Component, HostListener } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ start() {
+ }
+ click() {
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-comp", host: { listeners: { "mousedown": "mousedown()", "@animation.done": "done()", "mouseup": "mouseup()", "@animation.start": "start()", "click": "click()" } }, ngImport: i0, template: { source: '', isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-comp',
+ template: '',
+ host: {
+ '(mousedown)': 'mousedown()',
+ '(@animation.done)': 'done()',
+ '(mouseup)': 'mouseup()',
+ }
+ }]
+ }], null, { start: [{
+ type: HostListener,
+ args: ['@animation.start']
+ }], click: [{
+ type: HostListener,
+ args: ['click']
+ }] }); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_synthetic_listeners_mixed.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ start(): void;
+ click(): void;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json
new file mode 100644
index 0000000000..8ae3757e64
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/TEST_CASES.json
@@ -0,0 +1,229 @@
+{
+ "$schema": "../../test_case_schema.json",
+ "cases": [
+ {
+ "description": "should support host bindings",
+ "inputFiles": [
+ "host_bindings.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Invalid host binding code",
+ "files": [
+ "host_bindings.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should support host bindings with temporary expressions",
+ "inputFiles": [
+ "host_bindings_with_temporaries.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Invalid host binding code",
+ "files": [
+ "host_bindings_with_temporaries.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should support host bindings with pure functions",
+ "inputFiles": [
+ "host_bindings_with_pure_functions.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Invalid host binding code",
+ "files": [
+ "host_bindings_with_pure_functions.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should support host attribute bindings",
+ "inputFiles": [
+ "host_attribute_bindings.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Invalid host attribute code",
+ "files": [
+ "host_attribute_bindings.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should support host attributes",
+ "inputFiles": [
+ "host_attributes.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Invalid host attribute code",
+ "files": [
+ "host_attributes.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should support host attributes together with host classes and styles",
+ "inputFiles": [
+ "host_attributes_with_classes_and_styles.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Invalid host attribute code",
+ "files": [
+ "host_attributes_with_classes_and_styles.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple host property bindings into a single instruction",
+ "inputFiles": [
+ "chain_multiple_property_bindings.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_property_bindings.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain both host properties in the decorator and on the class",
+ "inputFiles": [
+ "chain_property_bindings_all.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_property_bindings_all.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple host property bindings in the presence of other bindings",
+ "inputFiles": [
+ "chain_property_bindings_mixed.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_property_bindings_mixed.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple synthetic properties into a single instruction call",
+ "inputFiles": [
+ "chain_synthetic_properties.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_synthetic_properties.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple host attribute bindings into a single instruction",
+ "inputFiles": [
+ "chain_multiple_attribute_bindings.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_attribute_bindings.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain both host attributes in the decorator and on the class",
+ "inputFiles": [
+ "chain_attribute_bindings_all.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_attribute_bindings_all.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple host attribute bindings in the presence of other bindings",
+ "inputFiles": [
+ "chain_attribute_bindings_mixed.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_attribute_bindings_mixed.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple host listeners into a single instruction",
+ "inputFiles": [
+ "chain_multiple_listeners.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_listeners.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple synthetic host listeners into a single instruction",
+ "inputFiles": [
+ "chain_synthetic_listeners.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_synthetic_listeners.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple regular and synthetic host listeners into two instructions",
+ "inputFiles": [
+ "chain_synthetic_listeners_mixed.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_synthetic_listeners_mixed.js"
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_all.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_all.js
new file mode 100644
index 0000000000..170f8c1946
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_all.js
@@ -0,0 +1,6 @@
+hostBindings: function MyDirective_HostBindings(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵattribute("tabindex", 1)("title", ctx.myTitle)("id", ctx.myId);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_all.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_all.ts
new file mode 100644
index 0000000000..6bf05cb4ea
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_all.ts
@@ -0,0 +1,8 @@
+import {Directive, HostBinding} from '@angular/core';
+
+@Directive({selector: '[my-dir]', host: {'[attr.tabindex]': '1'}})
+export class MyDirective {
+ @HostBinding('attr.title') myTitle = 'hello';
+
+ @HostBinding('attr.id') myId = 'special-directive';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_mixed.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_mixed.js
new file mode 100644
index 0000000000..e8e6b44e78
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_mixed.js
@@ -0,0 +1,7 @@
+hostBindings: function MyDirective_HostBindings(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵhostProperty("tabindex", 1);
+ $r3$.ɵɵattribute("title", "my title")("id", "my-id");
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_mixed.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_mixed.ts
new file mode 100644
index 0000000000..7c4b9412a2
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_attribute_bindings_mixed.ts
@@ -0,0 +1,8 @@
+import {Directive} from '@angular/core';
+
+@Directive({
+ selector: '[my-dir]',
+ host: {'[attr.title]': '"my title"', '[tabindex]': '1', '[attr.id]': '"my-id"'}
+})
+export class MyDirective {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_attribute_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_attribute_bindings.js
new file mode 100644
index 0000000000..0a832e2133
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_attribute_bindings.js
@@ -0,0 +1,6 @@
+hostBindings: function MyDirective_HostBindings(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵattribute("title", ctx.myTitle)("tabindex", 1)("id", ctx.myId);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_attribute_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_attribute_bindings.ts
new file mode 100644
index 0000000000..551aa51be2
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_attribute_bindings.ts
@@ -0,0 +1,10 @@
+import {Directive} from '@angular/core';
+
+@Directive({
+ selector: '[my-dir]',
+ host: {'[attr.title]': 'myTitle', '[attr.tabindex]': '1', '[attr.id]': 'myId'}
+})
+export class MyDirective {
+ myTitle = 'hello';
+ myId = 'special-directive';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_listeners.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_listeners.js
new file mode 100644
index 0000000000..2a60b6933b
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_listeners.js
@@ -0,0 +1,5 @@
+hostBindings: function MyDirective_HostBindings(rf, ctx) {
+ if (rf & 1) {
+ $r3$.ɵɵlistener("mousedown", function MyDirective_mousedown_HostBindingHandler() { return ctx.mousedown(); })("mouseup", function MyDirective_mouseup_HostBindingHandler() { return ctx.mouseup(); })("click", function MyDirective_click_HostBindingHandler() { return ctx.click(); });
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_listeners.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_listeners.ts
new file mode 100644
index 0000000000..ab7457369c
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_listeners.ts
@@ -0,0 +1,17 @@
+import {Directive, HostListener} from '@angular/core';
+
+@Directive({
+ selector: '[my-dir]',
+ host: {
+ '(mousedown)': 'mousedown()',
+ '(mouseup)': 'mouseup()',
+ }
+})
+export class MyDirective {
+ mousedown() {}
+ mouseup() {}
+
+ @HostListener('click')
+ click() {
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_property_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_property_bindings.js
new file mode 100644
index 0000000000..8185111026
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_property_bindings.js
@@ -0,0 +1,6 @@
+hostBindings: function MyDirective_HostBindings(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵhostProperty("title", ctx.myTitle)("tabindex", 1)("id", ctx.myId);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_property_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_property_bindings.ts
new file mode 100644
index 0000000000..ce547798b6
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_multiple_property_bindings.ts
@@ -0,0 +1,7 @@
+import {Directive} from '@angular/core';
+
+@Directive({selector: '[my-dir]', host: {'[title]': 'myTitle', '[tabindex]': '1', '[id]': 'myId'}})
+export class MyDirective {
+ myTitle = 'hello';
+ myId = 'special-directive';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_all.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_all.js
new file mode 100644
index 0000000000..3c61c71182
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_all.js
@@ -0,0 +1,6 @@
+hostBindings: function MyDirective_HostBindings(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵhostProperty("tabindex", 1)("title", ctx.myTitle)("id", ctx.myId);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_all.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_all.ts
new file mode 100644
index 0000000000..c9079c2fca
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_all.ts
@@ -0,0 +1,8 @@
+import {Directive, HostBinding} from '@angular/core';
+
+@Directive({selector: '[my-dir]', host: {'[tabindex]': '1'}})
+export class MyDirective {
+ @HostBinding('title') myTitle = 'hello';
+
+ @HostBinding('id') myId = 'special-directive';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_mixed.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_mixed.js
new file mode 100644
index 0000000000..99df909115
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_mixed.js
@@ -0,0 +1,7 @@
+hostBindings: function MyDirective_HostBindings(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵhostProperty("title", "my title")("id", "my-id");
+ $r3$.ɵɵattribute("tabindex", 1);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_mixed.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_mixed.ts
new file mode 100644
index 0000000000..1821cec0b8
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_property_bindings_mixed.ts
@@ -0,0 +1,8 @@
+import {Directive} from '@angular/core';
+
+@Directive({
+ selector: '[my-dir]',
+ host: {'[title]': '"my title"', '[attr.tabindex]': '1', '[id]': '"my-id"'}
+})
+export class MyDirective {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners.js
new file mode 100644
index 0000000000..eb57e1ca92
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners.js
@@ -0,0 +1,5 @@
+hostBindings: function MyComponent_HostBindings(rf, ctx) {
+ if (rf & 1) {
+ $r3$.ɵɵsyntheticHostListener("@animation.done", function MyComponent_animation_animation_done_HostBindingHandler() { return ctx.done(); })("@animation.start", function MyComponent_animation_animation_start_HostBindingHandler() { return ctx.start(); });
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners.ts
new file mode 100644
index 0000000000..cbfd318930
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners.ts
@@ -0,0 +1,14 @@
+import {Component, HostListener} from '@angular/core';
+
+@Component({
+ selector: 'my-comp',
+ template: '',
+ host: {
+ '(@animation.done)': 'done()',
+ }
+})
+export class MyComponent {
+ @HostListener('@animation.start')
+ start() {
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners_mixed.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners_mixed.js
new file mode 100644
index 0000000000..a00968e63c
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners_mixed.js
@@ -0,0 +1,6 @@
+hostBindings: function MyComponent_HostBindings(rf, ctx) {
+ if (rf & 1) {
+ $r3$.ɵɵsyntheticHostListener("@animation.done", function MyComponent_animation_animation_done_HostBindingHandler() { return ctx.done(); })("@animation.start", function MyComponent_animation_animation_start_HostBindingHandler() { return ctx.start(); });
+ $r3$.ɵɵlistener("mousedown", function MyComponent_mousedown_HostBindingHandler() { return ctx.mousedown(); })("mouseup", function MyComponent_mouseup_HostBindingHandler() { return ctx.mouseup(); })("click", function MyComponent_click_HostBindingHandler() { return ctx.click(); });
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners_mixed.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners_mixed.ts
new file mode 100644
index 0000000000..0a4e809633
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_listeners_mixed.ts
@@ -0,0 +1,20 @@
+import {Component, HostListener} from '@angular/core';
+
+@Component({
+ selector: 'my-comp',
+ template: '',
+ host: {
+ '(mousedown)': 'mousedown()',
+ '(@animation.done)': 'done()',
+ '(mouseup)': 'mouseup()',
+ }
+})
+export class MyComponent {
+ @HostListener('@animation.start')
+ start() {
+ }
+
+ @HostListener('click')
+ click() {
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_properties.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_properties.js
new file mode 100644
index 0000000000..4dac1d6a77
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_properties.js
@@ -0,0 +1,6 @@
+hostBindings: function MyDirective_HostBindings(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵsyntheticHostProperty("@expand", ctx.expandedState)("@fadeOut", true)("@shrink", ctx.isSmall);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_properties.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_properties.ts
new file mode 100644
index 0000000000..00a6d001f6
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/chain_synthetic_properties.ts
@@ -0,0 +1,10 @@
+import {Directive} from '@angular/core';
+
+@Directive({
+ selector: '[my-dir]',
+ host: {'[@expand]': 'expandedState', '[@fadeOut]': 'true', '[@shrink]': 'isSmall'}
+})
+export class MyDirective {
+ expandedState = 'collapsed';
+ isSmall = true;
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attribute_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attribute_bindings.js
new file mode 100644
index 0000000000..493c66543c
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attribute_bindings.js
@@ -0,0 +1,11 @@
+
+HostAttributeDir.ɵdir = $r3$.ɵɵdefineDirective({
+ type: HostAttributeDir,
+ selectors: [["", "hostAttributeDir", ""]],
+ hostVars: 1,
+ hostBindings: function HostAttributeDir_HostBindings(rf, ctx) {
+ if (rf & 2) {
+ $r3$.ɵɵattribute("required", ctx.required);
+ }
+ }
+});
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attribute_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attribute_bindings.ts
new file mode 100644
index 0000000000..6c2279a01d
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attribute_bindings.ts
@@ -0,0 +1,10 @@
+import {Directive, NgModule} from '@angular/core';
+
+@Directive({selector: '[hostAttributeDir]', host: {'[attr.required]': 'required'}})
+export class HostAttributeDir {
+ required = true;
+}
+
+@NgModule({declarations: [HostAttributeDir]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes.js
new file mode 100644
index 0000000000..e999a71436
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes.js
@@ -0,0 +1,6 @@
+
+HostAttributeDir.ɵdir = $r3$.ɵɵdefineDirective({
+ type: HostAttributeDir,
+ selectors: [["", "hostAttributeDir", ""]],
+ hostAttrs: ["aria-label", "label"]
+});
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes.ts
new file mode 100644
index 0000000000..6704c71204
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes.ts
@@ -0,0 +1,9 @@
+import {Directive, NgModule} from '@angular/core';
+
+@Directive({selector: '[hostAttributeDir]', host: {'aria-label': 'label'}})
+export class HostAttributeDir {
+}
+
+@NgModule({declarations: [HostAttributeDir]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes_with_classes_and_styles.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes_with_classes_and_styles.js
new file mode 100644
index 0000000000..88e7fe89b5
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes_with_classes_and_styles.js
@@ -0,0 +1,14 @@
+
+HostAttributeComp.ɵcmp = $r3$.ɵɵdefineComponent({
+ type: HostAttributeComp,
+ selectors: [["my-host-attribute-component"]],
+ hostAttrs: ["title", "hello there from component", __AttributeMarker.Styles__, "opacity", "1"],
+…
+HostAttributeDir.ɵdir = $r3$.ɵɵdefineDirective({
+ type: HostAttributeDir,
+ selectors: [["", "hostAttributeDir", ""]],
+ hostAttrs: ["title", "hello there from directive", __AttributeMarker.Classes__, "one", "two", __AttributeMarker.Styles__, "width", "200px", "height", "500px"],
+ hostVars: 4,
+ hostBindings: function HostAttributeDir_HostBindings(rf, ctx) {
+ …
+ }
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes_with_classes_and_styles.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes_with_classes_and_styles.ts
new file mode 100644
index 0000000000..b97c23d0e5
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_attributes_with_classes_and_styles.ts
@@ -0,0 +1,26 @@
+import {Component, Directive, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-host-attribute-component',
+ template: '...',
+ host: {'title': 'hello there from component', 'style': 'opacity:1'}
+})
+export class HostAttributeComp {
+}
+
+@Directive({
+ selector: '[hostAttributeDir]',
+ host: {
+ 'style': 'width: 200px; height: 500px',
+ '[style.opacity]': 'true',
+ 'class': 'one two',
+ '[class.three]': 'true',
+ 'title': 'hello there from directive',
+ }
+})
+export class HostAttributeDir {
+}
+
+@NgModule({declarations: [HostAttributeComp, HostAttributeDir]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings.js
new file mode 100644
index 0000000000..9154b33d2f
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings.js
@@ -0,0 +1,11 @@
+
+HostBindingDir.ɵdir = $r3$.ɵɵdefineDirective({
+ type: HostBindingDir,
+ selectors: [["", "hostBindingDir", ""]],
+ hostVars: 1,
+ hostBindings: function HostBindingDir_HostBindings(rf, ctx) {
+ if (rf & 2) {
+ $r3$.ɵɵhostProperty("id", ctx.dirId);
+ }
+ }
+ });
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings.ts
new file mode 100644
index 0000000000..7078ea02ee
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings.ts
@@ -0,0 +1,10 @@
+import {Directive, HostBinding, NgModule} from '@angular/core';
+
+@Directive({selector: '[hostBindingDir]'})
+export class HostBindingDir {
+ @HostBinding('id') dirId = 'some id';
+}
+
+@NgModule({declarations: [HostBindingDir]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_pure_functions.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_pure_functions.js
new file mode 100644
index 0000000000..ecce45ae02
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_pure_functions.js
@@ -0,0 +1,17 @@
+
+const $ff$ = function ($v$) { return ["red", $v$]; };
+…
+HostBindingComp.ɵcmp = $r3$.ɵɵdefineComponent({
+ type: HostBindingComp,
+ selectors: [["host-binding-comp"]],
+ hostVars: 3,
+ hostBindings: function HostBindingComp_HostBindings(rf, ctx) {
+ if (rf & 2) {
+ $r3$.ɵɵhostProperty("id", $r3$.ɵɵpureFunction1(1, $ff$, ctx.id));
+ }
+ },
+ decls: 0,
+ vars: 0,
+ template: function HostBindingComp_Template(rf, ctx) {},
+ encapsulation: 2
+});
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_pure_functions.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_pure_functions.ts
new file mode 100644
index 0000000000..bcb1faf9d4
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_pure_functions.ts
@@ -0,0 +1,10 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({selector: 'host-binding-comp', host: {'[id]': '["red", id]'}, template: ''})
+export class HostBindingComp {
+ id = 'some id';
+}
+
+@NgModule({declarations: [HostBindingComp]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_temporaries.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_temporaries.js
new file mode 100644
index 0000000000..bbeb539af1
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_temporaries.js
@@ -0,0 +1,12 @@
+
+HostBindingDir.ɵdir = $r3$.ɵɵdefineDirective({
+ type: HostBindingDir,
+ selectors: [["", "hostBindingDir", ""]],
+ hostVars: 1,
+ hostBindings: function HostBindingDir_HostBindings(rf, ctx) {
+ if (rf & 2) {
+ let $tmp0$ = null;
+ $r3$.ɵɵhostProperty("id", ($tmp0$ = ctx.getData()) == null ? null : $tmp0$.id);
+ }
+ }
+ });
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_temporaries.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_temporaries.ts
new file mode 100644
index 0000000000..cd492941c9
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/host_bindings/host_bindings_with_temporaries.ts
@@ -0,0 +1,12 @@
+import {Directive, NgModule} from '@angular/core';
+
+@Directive({selector: '[hostBindingDir]', host: {'[id]': 'getData()?.id'}})
+export class HostBindingDir {
+ getData?: () => {
+ id: number
+ };
+}
+
+@NgModule({declarations: [HostBindingDir]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/GOLDEN_PARTIAL.js
new file mode 100644
index 0000000000..3b6fbb1ea6
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/GOLDEN_PARTIAL.js
@@ -0,0 +1,202 @@
+/****************************************************************************************************
+ * PARTIAL FILE: local_ref_on_host.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.name = 'John Doe';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-app", ngImport: i0, template: { source: `
+
+ Hello {{ name }}!
+
+ {{ myRef.id }}
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-app',
+ template: `
+
+ Hello {{ name }}!
+
+ {{ myRef.id }}
+ `
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: local_ref_on_host.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ name: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: local_ref_on_nested.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.name = 'John Doe';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-app", ngImport: i0, template: { source: `
+
+ {{ myInput.value }}
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-app',
+ template: `
+
+ {{ myInput.value }}
+
+ `
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: local_ref_on_nested.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ name: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: property_bindings_and_listeners.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.name = 'John Doe';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-app", ngImport: i0, template: { source: `
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-app',
+ template: `
+
+ `
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: property_bindings_and_listeners.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ name: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: no_child_elements.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.name = 'John Doe';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-app", ngImport: i0, template: { source: `
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-app',
+ template: `
+
+ `
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: no_child_elements.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ name: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/TEST_CASES.json
new file mode 100644
index 0000000000..ec12b5ef93
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/TEST_CASES.json
@@ -0,0 +1,61 @@
+{
+ "$schema": "../../test_case_schema.json",
+ "cases": [
+ {
+ "description": "should keep local ref for host element",
+ "inputFiles": [
+ "local_ref_on_host.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect handling of local refs for host element",
+ "files": [
+ "local_ref_on_host.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should not have local refs for nested elements",
+ "inputFiles": [
+ "local_ref_on_nested.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect handling of local refs for nested elements",
+ "files": [
+ "local_ref_on_nested.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should not process property bindings and listeners",
+ "inputFiles": [
+ "property_bindings_and_listeners.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect handling of property bindings and listeners",
+ "files": [
+ "property_bindings_and_listeners.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should not generate extra instructions for elements with no children",
+ "inputFiles": [
+ "no_child_elements.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect handling of elements with no children",
+ "files": [
+ "no_child_elements.js"
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_host.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_host.js
new file mode 100644
index 0000000000..a60c148073
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_host.js
@@ -0,0 +1,18 @@
+consts: [["id", "my-id"], ["myRef", ""]],
+template:function MyComponent_Template(rf, $ctx$){
+ if (rf & 1) {
+ $i0$.ɵɵelementStart(0, "b", 0, 1);
+ $i0$.ɵɵdisableBindings();
+ $i0$.ɵɵelementStart(2, "i");
+ $i0$.ɵɵtext(3, "Hello {{ name }}!");
+ $i0$.ɵɵelementEnd();
+ $i0$.ɵɵenableBindings();
+ $i0$.ɵɵelementEnd();
+ $i0$.ɵɵtext(4);
+ }
+ if (rf & 2) {
+ const $_r0$ = $i0$.ɵɵreference(1);
+ $r3$.ɵɵadvance(4);
+ $i0$.ɵɵtextInterpolate1(" ", $_r0$.id, " ");
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_host.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_host.ts
new file mode 100644
index 0000000000..bd82749cd4
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_host.ts
@@ -0,0 +1,18 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-app',
+ template: `
+
+ Hello {{ name }}!
+
+ {{ myRef.id }}
+ `
+})
+export class MyComponent {
+ name = 'John Doe';
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_nested.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_nested.js
new file mode 100644
index 0000000000..b0eeecdca5
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_nested.js
@@ -0,0 +1,10 @@
+consts: [["value", "one", "#myInput", ""]],
+template:function MyComponent_Template(rf, $ctx$){
+ if (rf & 1) {
+ $i0$.ɵɵelementStart(0, "div");
+ $i0$.ɵɵdisableBindings();
+ $i0$.ɵɵelement(1, "input", 0);
+ $i0$.ɵɵtext(2, " {{ myInput.value }} ");
+ $i0$.ɵɵenableBindings();
+ $i0$.ɵɵelementEnd();
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_nested.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_nested.ts
new file mode 100644
index 0000000000..8dca738fa0
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/local_ref_on_nested.ts
@@ -0,0 +1,17 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-app',
+ template: `
+
+ {{ myInput.value }}
+
+ `
+})
+export class MyComponent {
+ name = 'John Doe';
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/no_child_elements.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/no_child_elements.js
new file mode 100644
index 0000000000..a419c4776f
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/no_child_elements.js
@@ -0,0 +1,6 @@
+
+template:function MyComponent_Template(rf, $ctx$){
+ if (rf & 1) {
+ $i0$.ɵɵelement(0, "div");
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/no_child_elements.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/no_child_elements.ts
new file mode 100644
index 0000000000..1a47319d0d
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/no_child_elements.ts
@@ -0,0 +1,15 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-app',
+ template: `
+
+ `
+})
+export class MyComponent {
+ name = 'John Doe';
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/property_bindings_and_listeners.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/property_bindings_and_listeners.js
new file mode 100644
index 0000000000..ba38bad9de
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/property_bindings_and_listeners.js
@@ -0,0 +1,9 @@
+consts: [["[id]", "my-id", "(click)", "onclick"]],
+template:function MyComponent_Template(rf, $ctx$){
+ if (rf & 1) {
+ $i0$.ɵɵelementStart(0, "div");
+ $i0$.ɵɵdisableBindings();
+ $i0$.ɵɵelement(1, "div", 0);
+ $i0$.ɵɵenableBindings();
+ $i0$.ɵɵelementEnd();
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/property_bindings_and_listeners.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/property_bindings_and_listeners.ts
new file mode 100644
index 0000000000..f40e94e33a
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/non_bindable_behavior/property_bindings_and_listeners.ts
@@ -0,0 +1,17 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-app',
+ template: `
+
+ `
+})
+export class MyComponent {
+ name = 'John Doe';
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/GOLDEN_PARTIAL.js
new file mode 100644
index 0000000000..0cf5378dde
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/GOLDEN_PARTIAL.js
@@ -0,0 +1,456 @@
+/****************************************************************************************************
+ * PARTIAL FILE: bind.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.title = 'Hello World';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-app", ngImport: i0, template: { source: '', isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{ selector: 'my-app', template: '' }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: bind.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ title: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: interpolation.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.name = 'World';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-component',
+ template: `
+ `
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: interpolation.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ name: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: interpolated_properties.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.name = 'John Doe';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-app", ngImport: i0, template: { source: `
+
+
+
+
+
+
+
+
+
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-app',
+ template: `
+
+
+
+
+
+
+
+
+
+
+ `
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: interpolated_properties.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ name: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: special_property_remapping.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.forValue = 'some-input';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-component',
+ template: `
+ `
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: special_property_remapping.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ forValue: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: temporary_variables.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+// https://github.com/angular/angular/issues/37194
+// Verifies that temporary expressions used for expressions with potential side-effects in
+// the LHS of a safe navigation access are emitted within the binding expression itself, to
+// ensure that these temporaries are evaluated during the evaluation of the binding. This
+// is important for when the LHS contains a pipe, as pipe evaluation depends on the current
+// binding index.
+export class MyComponent {
+ constructor() {
+ this.myTitle = 'hello';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: '', isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: ''
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: temporary_variables.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ myTitle: string;
+ auth?: () => {
+ identity(): any;
+ };
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.myTitle = 'hello';
+ this.buttonId = 'special-button';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: '', isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{ template: '' }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ myTitle: string;
+ buttonId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_mixed.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: '', isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{ template: '' }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_mixed.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_bindings_with_interpolations.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: '', isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: ''
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_bindings_with_interpolations.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_synthetic_bindings.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.expansionState = 'expanded';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: `
+
+ `
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_synthetic_bindings.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ expansionState: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_ngtemplate_bindings.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.myTitle = 'hello';
+ this.buttonId = 'custom-id';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: '', isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{ template: '' }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_ngtemplate_bindings.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ myTitle: string;
+ buttonId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_for_multiple_elements.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.myTitle = 'hello';
+ this.buttonId = 'special-button';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
+
+
+
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: `
+
+
+
+ `
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_for_multiple_elements.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ myTitle: string;
+ buttonId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_with_child_elements.js
+ ****************************************************************************************************/
+import { Component } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.myTitle = 'hello';
+ this.buttonId = 'special-button';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "ng-component", ngImport: i0, template: { source: `
+ `, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ template: `
+ `
+ }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: chain_multiple_bindings_with_child_elements.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ myTitle: string;
+ buttonId: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/TEST_CASES.json
new file mode 100644
index 0000000000..a9b34b62c7
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/TEST_CASES.json
@@ -0,0 +1,173 @@
+{
+ "$schema": "../../test_case_schema.json",
+ "cases": [
+ {
+ "description": "should generate bind instruction",
+ "inputFiles": [
+ "bind.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect property binding",
+ "files": [
+ "bind.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should generate interpolation instruction for {{...}} bindings",
+ "inputFiles": [
+ "interpolation.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect interpolated property binding",
+ "files": [
+ "interpolation.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should generate the proper update instructions for interpolated properties",
+ "inputFiles": [
+ "interpolated_properties.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect handling of interpolated properties",
+ "files": [
+ "interpolated_properties.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should not remap property names whose names do not correspond to their attribute names",
+ "inputFiles": [
+ "special_property_remapping.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "special_property_remapping.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should emit temporary evaluation within the binding expression for in-order execution",
+ "inputFiles": [
+ "temporary_variables.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "temporary_variables.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple property bindings into a single instruction",
+ "inputFiles": [
+ "chain_multiple_bindings.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_bindings.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain property bindings in the presence of other bindings",
+ "inputFiles": [
+ "chain_multiple_bindings_mixed.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_bindings_mixed.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should not add interpolated properties to the property instruction chain",
+ "inputFiles": [
+ "chain_bindings_with_interpolations.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_bindings_with_interpolations.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain synthetic property bindings together with regular property bindings",
+ "inputFiles": [
+ "chain_synthetic_bindings.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_synthetic_bindings.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple property bindings on an ng-template",
+ "inputFiles": [
+ "chain_ngtemplate_bindings.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_ngtemplate_bindings.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple property bindings when there are multiple elements",
+ "inputFiles": [
+ "chain_multiple_bindings_for_multiple_elements.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_bindings_for_multiple_elements.js"
+ ]
+ }
+ ]
+ },
+ {
+ "description": "should chain multiple property bindings when there are child elements",
+ "inputFiles": [
+ "chain_multiple_bindings_with_child_elements.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect template",
+ "files": [
+ "chain_multiple_bindings_with_child_elements.js"
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/bind.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/bind.js
new file mode 100644
index 0000000000..437c34ace7
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/bind.js
@@ -0,0 +1,9 @@
+consts: [[__AttributeMarker.Bindings__, "title"]],
+template:function MyComponent_Template(rf, $ctx$){
+ if (rf & 1) {
+ $i0$.ɵɵelement(0, "a", 0);
+ }
+ if (rf & 2) {
+ $i0$.ɵɵproperty("title", $ctx$.title);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/bind.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/bind.ts
new file mode 100644
index 0000000000..3aeb4a1588
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/bind.ts
@@ -0,0 +1,10 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({selector: 'my-app', template: ''})
+export class MyComponent {
+ title = 'Hello World';
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_bindings_with_interpolations.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_bindings_with_interpolations.js
new file mode 100644
index 0000000000..4fd71f7dbf
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_bindings_with_interpolations.js
@@ -0,0 +1,8 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵpropertyInterpolate("tabindex", 0 + 3);
+ $r3$.ɵɵpropertyInterpolate2("aria-label", "hello-", 1 + 3, "-", 2 + 3, "");
+ $r3$.ɵɵproperty("title", 1)("id", 2);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_bindings_with_interpolations.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_bindings_with_interpolations.ts
new file mode 100644
index 0000000000..6b54c973e5
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_bindings_with_interpolations.ts
@@ -0,0 +1,8 @@
+import {Component} from '@angular/core';
+
+@Component({
+ template:
+ ''
+})
+export class MyComponent {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings.js
new file mode 100644
index 0000000000..815ee167b2
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings.js
@@ -0,0 +1,6 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵproperty("title", ctx.myTitle)("id", ctx.buttonId)("tabindex", 1);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings.ts
new file mode 100644
index 0000000000..91a349dae2
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings.ts
@@ -0,0 +1,7 @@
+import {Component} from '@angular/core';
+
+@Component({template: ''})
+export class MyComponent {
+ myTitle = 'hello';
+ buttonId = 'special-button';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_for_multiple_elements.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_for_multiple_elements.js
new file mode 100644
index 0000000000..6e92717fce
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_for_multiple_elements.js
@@ -0,0 +1,10 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵproperty("title", ctx.myTitle)("id", ctx.buttonId)("tabindex", 1);
+ $r3$.ɵɵadvance(1);
+ $r3$.ɵɵproperty("id", 1)("title", "hello")("someProp", 1 + 2);
+ $r3$.ɵɵadvance(1);
+ $r3$.ɵɵproperty("prop", "one")("otherProp", 2);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_for_multiple_elements.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_for_multiple_elements.ts
new file mode 100644
index 0000000000..6fa16b4a24
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_for_multiple_elements.ts
@@ -0,0 +1,13 @@
+import {Component} from '@angular/core';
+
+@Component({
+ template: `
+
+
+
+ `
+})
+export class MyComponent {
+ myTitle = 'hello';
+ buttonId = 'special-button';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_mixed.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_mixed.js
new file mode 100644
index 0000000000..454b53217f
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_mixed.js
@@ -0,0 +1,8 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵpropertyInterpolate("aria-label", 1 + 3);
+ $r3$.ɵɵproperty("title", 1)("tabindex", 3);
+ $r3$.ɵɵattribute("id", 2);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_mixed.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_mixed.ts
new file mode 100644
index 0000000000..51008fe513
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_mixed.ts
@@ -0,0 +1,6 @@
+import {Component} from '@angular/core';
+
+@Component(
+ {template: ''})
+export class MyComponent {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_with_child_elements.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_with_child_elements.js
new file mode 100644
index 0000000000..03e141c8dc
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_with_child_elements.js
@@ -0,0 +1,8 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵproperty("title", ctx.myTitle)("id", ctx.buttonId)("tabindex", 1);
+ $r3$.ɵɵadvance(1);
+ $r3$.ɵɵproperty("id", 1)("title", "hello")("someProp", 1 + 2);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_with_child_elements.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_with_child_elements.ts
new file mode 100644
index 0000000000..8a8a9c366d
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_multiple_bindings_with_child_elements.ts
@@ -0,0 +1,12 @@
+import {Component} from '@angular/core';
+
+@Component({
+ template: `
+ `
+})
+export class MyComponent {
+ myTitle = 'hello';
+ buttonId = 'special-button';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_ngtemplate_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_ngtemplate_bindings.js
new file mode 100644
index 0000000000..815ee167b2
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_ngtemplate_bindings.js
@@ -0,0 +1,6 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵproperty("title", ctx.myTitle)("id", ctx.buttonId)("tabindex", 1);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_ngtemplate_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_ngtemplate_bindings.ts
new file mode 100644
index 0000000000..682f026b86
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_ngtemplate_bindings.ts
@@ -0,0 +1,8 @@
+import {Component} from '@angular/core';
+
+@Component(
+ {template: ''})
+export class MyComponent {
+ myTitle = 'hello';
+ buttonId = 'custom-id';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_synthetic_bindings.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_synthetic_bindings.js
new file mode 100644
index 0000000000..c762e458c0
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_synthetic_bindings.js
@@ -0,0 +1,6 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ $r3$.ɵɵproperty("title", ctx.myTitle)("@expand", ctx.expansionState)("tabindex", 1)("@fade", "out");
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_synthetic_bindings.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_synthetic_bindings.ts
new file mode 100644
index 0000000000..5d4c37e20d
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/chain_synthetic_bindings.ts
@@ -0,0 +1,14 @@
+import {Component} from '@angular/core';
+
+@Component({
+ template: `
+
+ `
+})
+export class MyComponent {
+ expansionState = 'expanded';
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/empty_binding.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/empty_binding.js
new file mode 100644
index 0000000000..020b1a40eb
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/empty_binding.js
@@ -0,0 +1,7 @@
+…
+consts: [[__AttributeMarker.Bindings__, "someProp"]],
+template:function MyComponent_Template(rf, $ctx$){
+ if (rf & 1) {
+ $i0$.ɵɵelement(0, "a", 0);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/empty_binding.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/empty_binding.ts
new file mode 100644
index 0000000000..50fe40ede3
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/empty_binding.ts
@@ -0,0 +1,5 @@
+import {Component} from '@angular/core';
+
+@Component({selector: 'test', template: ''})
+export class FooCmp {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolated_properties.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolated_properties.js
new file mode 100644
index 0000000000..68810eb96e
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolated_properties.js
@@ -0,0 +1,22 @@
+if (rf & 2) {
+ i0.ɵɵpropertyInterpolateV("title", ["a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i", ctx.nine, "j"]);
+ i0.ɵɵadvance(1);
+ i0.ɵɵpropertyInterpolate8("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i");
+ i0.ɵɵadvance(1);
+ i0.ɵɵpropertyInterpolate7("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h");
+ i0.ɵɵadvance(1);
+ i0.ɵɵpropertyInterpolate6("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g");
+ i0.ɵɵadvance(1);
+ i0.ɵɵpropertyInterpolate5("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f");
+ i0.ɵɵadvance(1);
+ i0.ɵɵpropertyInterpolate4("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e");
+ i0.ɵɵadvance(1);
+ i0.ɵɵpropertyInterpolate3("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d");
+ i0.ɵɵadvance(1);
+ i0.ɵɵpropertyInterpolate2("title", "a", ctx.one, "b", ctx.two, "c");
+ i0.ɵɵadvance(1);
+ i0.ɵɵpropertyInterpolate1("title", "a", ctx.one, "b");
+ i0.ɵɵadvance(1);
+ i0.ɵɵpropertyInterpolate("title", ctx.one);
+}
+…
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolated_properties.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolated_properties.ts
new file mode 100644
index 0000000000..c1e5a2de51
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolated_properties.ts
@@ -0,0 +1,24 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-app',
+ template: `
+
+
+
+
+
+
+
+
+
+
+ `
+})
+export class MyComponent {
+ name = 'John Doe';
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolation.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolation.js
new file mode 100644
index 0000000000..72cc83ed7d
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolation.js
@@ -0,0 +1,11 @@
+
+…
+consts: [[__AttributeMarker.Bindings__, "title"]],
+template:function MyComponent_Template(rf, $ctx$){
+ if (rf & 1) {
+ $i0$.ɵɵelement(0, "a", 0);
+ }
+ if (rf & 2) {
+ $i0$.ɵɵpropertyInterpolate1("title", "Hello ", $ctx$.name, "");
+ }
+}
\ No newline at end of file
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolation.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolation.ts
new file mode 100644
index 0000000000..95bf09eb8f
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/interpolation.ts
@@ -0,0 +1,14 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-component',
+ template: `
+ `
+})
+export class MyComponent {
+ name = 'World';
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/special_property_remapping.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/special_property_remapping.js
new file mode 100644
index 0000000000..09c572c2ea
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/special_property_remapping.js
@@ -0,0 +1,13 @@
+
+consts: [[__AttributeMarker.Bindings__, "for"]]
+
+// ...
+
+function MyComponent_Template(rf, ctx) {
+ if (rf & 1) {
+ $i0$.ɵɵelement(0, "label", 0);
+ }
+ if (rf & 2) {
+ $i0$.ɵɵproperty("for", ctx.forValue);
+ }
+}
\ No newline at end of file
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/special_property_remapping.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/special_property_remapping.ts
new file mode 100644
index 0000000000..898b37313c
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/special_property_remapping.ts
@@ -0,0 +1,14 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-component',
+ template: `
+ `
+})
+export class MyComponent {
+ forValue = 'some-input';
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/temporary_variables.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/temporary_variables.js
new file mode 100644
index 0000000000..fb38c1af01
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/temporary_variables.js
@@ -0,0 +1,7 @@
+template: function MyComponent_Template(rf, ctx) {
+ …
+ if (rf & 2) {
+ let $tmp0$ = null;
+ $r3$.ɵɵproperty("title", ctx.myTitle)("id", ($tmp0$ = $r3$.ɵɵpipeBind1(1, 3, ($tmp0$ = ctx.auth()) == null ? null : $tmp0$.identity())) == null ? null : $tmp0$.id)("tabindex", 1);
+ }
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/temporary_variables.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/temporary_variables.ts
new file mode 100644
index 0000000000..fd7bb37b92
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/temporary_variables.ts
@@ -0,0 +1,18 @@
+import {Component} from '@angular/core';
+
+// https://github.com/angular/angular/issues/37194
+// Verifies that temporary expressions used for expressions with potential side-effects in
+// the LHS of a safe navigation access are emitted within the binding expression itself, to
+// ensure that these temporaries are evaluated during the evaluation of the binding. This
+// is important for when the LHS contains a pipe, as pipe evaluation depends on the current
+// binding index.
+@Component({
+ template:
+ ''
+})
+export class MyComponent {
+ myTitle = 'hello';
+ auth?: () => {
+ identity(): any;
+ };
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/GOLDEN_PARTIAL.js
new file mode 100644
index 0000000000..8cf5440982
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/GOLDEN_PARTIAL.js
@@ -0,0 +1,45 @@
+/****************************************************************************************************
+ * PARTIAL FILE: interpolation.js
+ ****************************************************************************************************/
+import { Component, NgModule } from '@angular/core';
+import * as i0 from "@angular/core";
+export class MyComponent {
+ constructor() {
+ this.name = 'World';
+ }
+}
+MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
+MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: 1, type: MyComponent, selector: "my-component", ngImport: i0, template: { source: `
+ Hello {{ name }}
`, isInline: true } });
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyComponent, [{
+ type: Component,
+ args: [{
+ selector: 'my-component',
+ template: `
+ Hello {{ name }}
`
+ }]
+ }], null, null); })();
+export class MyModule {
+}
+MyModule.ɵmod = i0.ɵɵdefineNgModule({ type: MyModule });
+MyModule.ɵinj = i0.ɵɵdefineInjector({ factory: function MyModule_Factory(t) { return new (t || MyModule)(); } });
+(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(MyModule, { declarations: [MyComponent] }); })();
+/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MyModule, [{
+ type: NgModule,
+ args: [{ declarations: [MyComponent] }]
+ }], null, null); })();
+
+/****************************************************************************************************
+ * PARTIAL FILE: interpolation.d.ts
+ ****************************************************************************************************/
+import * as i0 from "@angular/core";
+export declare class MyComponent {
+ name: string;
+ static ɵfac: i0.ɵɵFactoryDef;
+ static ɵcmp: i0.ɵɵComponentDefWithMeta;
+}
+export declare class MyModule {
+ static ɵmod: i0.ɵɵNgModuleDefWithMeta;
+ static ɵinj: i0.ɵɵInjectorDef;
+}
+
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/TEST_CASES.json b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/TEST_CASES.json
new file mode 100644
index 0000000000..da352830b2
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/TEST_CASES.json
@@ -0,0 +1,19 @@
+{
+ "$schema": "../../test_case_schema.json",
+ "cases": [
+ {
+ "description": "should generate interpolation instruction",
+ "inputFiles": [
+ "interpolation.ts"
+ ],
+ "expectations": [
+ {
+ "failureMessage": "Incorrect interpolated text binding",
+ "files": [
+ "interpolation.js"
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/interpolation.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/interpolation.js
new file mode 100644
index 0000000000..6069ea26d1
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/interpolation.js
@@ -0,0 +1,12 @@
+
+template:function MyComponent_Template(rf, $ctx$){
+ if (rf & 1) {
+ $i0$.ɵɵelementStart(0, "div");
+ $i0$.ɵɵtext(1);
+ $i0$.ɵɵelementEnd();
+ }
+ if (rf & 2) {
+ $r3$.ɵɵadvance(1);
+ $i0$.ɵɵtextInterpolate1("Hello ", $ctx$.name, "");
+ }
+}
\ No newline at end of file
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/interpolation.ts b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/interpolation.ts
new file mode 100644
index 0000000000..8d85955209
--- /dev/null
+++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/text_bindings/interpolation.ts
@@ -0,0 +1,14 @@
+import {Component, NgModule} from '@angular/core';
+
+@Component({
+ selector: 'my-component',
+ template: `
+ Hello {{ name }}
`
+})
+export class MyComponent {
+ name = 'World';
+}
+
+@NgModule({declarations: [MyComponent]})
+export class MyModule {
+}