diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts index 0f8e6a374d..98cdd94271 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts @@ -1138,7 +1138,7 @@ describe('compiler compliance: bindings', () => { … hostBindings: function MyDirective_HostBindings(rf, ctx) { if (rf & 1) { - $r3$.ɵɵlistener("mousedown", function MyDirective_mousedown_HostBindingHandler($event) { return ctx.mousedown(); })("mouseup", function MyDirective_mouseup_HostBindingHandler($event) { return ctx.mouseup(); })("click", function MyDirective_click_HostBindingHandler($event) { return ctx.click(); }); + $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(); }); } } `; @@ -1171,7 +1171,7 @@ describe('compiler compliance: bindings', () => { … hostBindings: function MyComponent_HostBindings(rf, ctx) { if (rf & 1) { - $r3$.ɵɵcomponentHostSyntheticListener("@animation.done", function MyComponent_animation_animation_done_HostBindingHandler($event) { return ctx.done(); })("@animation.start", function MyComponent_animation_animation_start_HostBindingHandler($event) { return ctx.start(); }); + $r3$.ɵɵcomponentHostSyntheticListener("@animation.done", function MyComponent_animation_animation_done_HostBindingHandler() { return ctx.done(); })("@animation.start", function MyComponent_animation_animation_start_HostBindingHandler() { return ctx.start(); }); } } `; @@ -1209,8 +1209,8 @@ describe('compiler compliance: bindings', () => { … hostBindings: function MyComponent_HostBindings(rf, ctx) { if (rf & 1) { - $r3$.ɵɵcomponentHostSyntheticListener("@animation.done", function MyComponent_animation_animation_done_HostBindingHandler($event) { return ctx.done(); })("@animation.start", function MyComponent_animation_animation_start_HostBindingHandler($event) { return ctx.start(); }); - $r3$.ɵɵlistener("mousedown", function MyComponent_mousedown_HostBindingHandler($event) { return ctx.mousedown(); })("mouseup", function MyComponent_mouseup_HostBindingHandler($event) { return ctx.mouseup(); })("click", function MyComponent_click_HostBindingHandler($event) { return ctx.click(); }); + $r3$.ɵɵcomponentHostSyntheticListener("@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/r3_view_compiler_directives_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts index cbeb283d64..918ef6701e 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts @@ -398,7 +398,7 @@ describe('compiler compliance: directives', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { $r3$.ɵɵelementStart(0, "div", 0); - $r3$.ɵɵlistener("someDirective", function MyComponent_Template_div_someDirective_0_listener($event) { return ctx.noop(); }); + $r3$.ɵɵlistener("someDirective", function MyComponent_Template_div_someDirective_0_listener() { return ctx.noop(); }); $r3$.ɵɵelementEnd(); } }, diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts index 1d4c89145f..556d3385d7 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts @@ -1807,7 +1807,7 @@ describe('i18n support in the template compiler', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { $r3$.ɵɵelementStart(0, "div", 0); - $r3$.ɵɵlistener("click", function MyComponent_Template_div_click_0_listener($event) { return ctx.onClick(); }); + $r3$.ɵɵlistener("click", function MyComponent_Template_div_click_0_listener() { return ctx.onClick(); }); $r3$.ɵɵi18n(1, $I18N_1$); $r3$.ɵɵelementEnd(); } diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts index f0fa2488ed..9534349ef4 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts @@ -138,14 +138,14 @@ describe('compiler compliance: listen()', () => { const $s$ = $r3$.ɵɵgetCurrentView(); $r3$.ɵɵelementStart(0, "div"); $r3$.ɵɵelementStart(1, "div", 1); - $r3$.ɵɵlistener("click", function MyComponent_div_0_Template_div_click_1_listener($event) { + $r3$.ɵɵlistener("click", function MyComponent_div_0_Template_div_click_1_listener() { $r3$.ɵɵrestoreView($s$); const $comp$ = $r3$.ɵɵnextContext(); return $comp$.onClick($comp$.foo); }); $r3$.ɵɵelementEnd(); $r3$.ɵɵelementStart(2, "button", 1); - $r3$.ɵɵlistener("click", function MyComponent_div_0_Template_button_click_2_listener($event) { + $r3$.ɵɵlistener("click", function MyComponent_div_0_Template_button_click_2_listener() { $r3$.ɵɵrestoreView($s$); const $comp2$ = $r3$.ɵɵnextContext(); return $comp2$.onClick2($comp2$.bar); @@ -204,7 +204,7 @@ describe('compiler compliance: listen()', () => { if (rf & 1) { const $s$ = $r3$.ɵɵgetCurrentView(); $r3$.ɵɵelementStart(0, "button", 0); - $r3$.ɵɵlistener("click", function MyComponent_Template_button_click_0_listener($event) { + $r3$.ɵɵlistener("click", function MyComponent_Template_button_click_0_listener() { $r3$.ɵɵrestoreView($s$); const $user$ = $r3$.ɵɵreference(3); return ctx.onClick($user$.value); @@ -254,9 +254,9 @@ describe('compiler compliance: listen()', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { $r3$.ɵɵelementStart(0, "div", 0); - $r3$.ɵɵlistener("click", function MyComponent_Template_div_click_0_listener($event) { + $r3$.ɵɵlistener("click", function MyComponent_Template_div_click_0_listener() { return ctx.click(); - })("change", function MyComponent_Template_div_change_0_listener($event) { + })("change", function MyComponent_Template_div_change_0_listener() { return ctx.change(); }); $r3$.ɵɵelementEnd(); @@ -296,10 +296,10 @@ describe('compiler compliance: listen()', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { $r3$.ɵɵelementStart(0, "div", 0); - $r3$.ɵɵlistener("click", function MyComponent_Template_div_click_0_listener($event) { return ctx.click(); })("change", function MyComponent_Template_div_change_0_listener($event) { return ctx.change(); }); + $r3$.ɵɵlistener("click", function MyComponent_Template_div_click_0_listener() { return ctx.click(); })("change", function MyComponent_Template_div_change_0_listener() { return ctx.change(); }); $r3$.ɵɵelementEnd(); $r3$.ɵɵelementStart(1, "some-comp", 1); - $r3$.ɵɵlistener("update", function MyComponent_Template_some_comp_update_1_listener($event) { return ctx.update(); })("delete", function MyComponent_Template_some_comp_delete_1_listener($event) { return ctx.delete(); }); + $r3$.ɵɵlistener("update", function MyComponent_Template_some_comp_update_1_listener() { return ctx.update(); })("delete", function MyComponent_Template_some_comp_delete_1_listener() { return ctx.delete(); }); $r3$.ɵɵelementEnd(); } } @@ -334,7 +334,7 @@ describe('compiler compliance: listen()', () => { template: function MyComponent_Template(rf, ctx) { if (rf & 1) { $r3$.ɵɵtemplate(0, MyComponent_ng_template_0_Template, 0, 0, "ng-template", 0); - $r3$.ɵɵlistener("click", function MyComponent_Template_ng_template_click_0_listener($event) { return ctx.click(); })("change", function MyComponent_Template_ng_template_change_0_listener($event) { return ctx.change(); }); + $r3$.ɵɵlistener("click", function MyComponent_Template_ng_template_click_0_listener() { return ctx.click(); })("change", function MyComponent_Template_ng_template_change_0_listener() { return ctx.change(); }); } } `; @@ -343,5 +343,108 @@ describe('compiler compliance: listen()', () => { expectEmit(result.source, template, 'Incorrect template'); }); + it('should not generate the $event argument if it is not being used in a template', () => { + const files = { + app: { + 'spec.ts': ` + import {Component} from '@angular/core'; + + @Component({ + template: \`
\` + }) + export class MyComponent { + onClick() {} + } + ` + } + }; + + const template = ` + … + consts: [[${AttributeMarker.Bindings}, "click"]], + template: function MyComponent_Template(rf, ctx) { + if (rf & 1) { + $r3$.ɵɵelementStart(0, "div", 0); + $r3$.ɵɵlistener("click", function MyComponent_Template_div_click_0_listener() { + return ctx.onClick(); + }); + $r3$.ɵɵelementEnd(); + } + } + `; + + const result = compile(files, angularFiles); + + expectEmit(result.source, template, 'Incorrect template'); + }); + + it('should not generate the $event argument if it is not being used in a host listener', () => { + const files = { + app: { + 'spec.ts': ` + import {Component, HostListener} from '@angular/core'; + + @Component({ + template: '', + host: { + '(mousedown)': 'mousedown()' + } + }) + export class MyComponent { + mousedown() {} + + @HostListener('click') + click() {} + } + ` + } + }; + + const template = ` + … + hostBindings: function MyComponent_HostBindings(rf, ctx) { + if (rf & 1) { + i0.ɵɵlistener("mousedown", function MyComponent_mousedown_HostBindingHandler() { + return ctx.mousedown(); + })("click", function MyComponent_click_HostBindingHandler() { + return ctx.click(); + }); + } + } + `; + + const result = compile(files, angularFiles); + expectEmit(result.source, template, 'Incorrect host bindings'); + }); + + it('should generate the $event argument if it is being used in a host listener', () => { + const files = { + app: { + 'spec.ts': ` + import {Directive, HostListener} from '@angular/core'; + + @Directive() + export class MyComponent { + @HostListener('click', ['$event.target']) + click(t: EventTarget) {} + } + ` + } + }; + + const template = ` + … + hostBindings: function MyComponent_HostBindings(rf, ctx) { + if (rf & 1) { + i0.ɵɵlistener("click", function MyComponent_click_HostBindingHandler($event) { + return ctx.click($event.target); + }); + } + } + `; + + const result = compile(files, angularFiles); + expectEmit(result.source, template, 'Incorrect host bindings'); + }); }); diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts index 64a5aaaa40..ba79859605 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts @@ -336,7 +336,7 @@ describe('compiler compliance: styling', () => { hostVars: 1, hostBindings: function MyAnimDir_HostBindings(rf, ctx) { if (rf & 1) { - $r3$.ɵɵcomponentHostSyntheticListener("@myAnim.start", function MyAnimDir_animation_myAnim_start_HostBindingHandler($event) { return ctx.onStart(); })("@myAnim.done", function MyAnimDir_animation_myAnim_done_HostBindingHandler($event) { return ctx.onDone(); }); + $r3$.ɵɵcomponentHostSyntheticListener("@myAnim.start", function MyAnimDir_animation_myAnim_start_HostBindingHandler() { return ctx.onStart(); })("@myAnim.done", function MyAnimDir_animation_myAnim_done_HostBindingHandler() { return ctx.onDone(); }); } if (rf & 2) { $r3$.ɵɵupdateSyntheticHostBinding("@myAnim", ctx.myAnimState); } diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts index 5377f95615..2ae7af80e0 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts @@ -54,7 +54,7 @@ describe('compiler compliance: template', () => { if (rf & 1) { const $s$ = $i0$.ɵɵgetCurrentView(); $i0$.ɵɵelementStart(0, "div", 2); - $i0$.ɵɵlistener("click", function MyComponent_ul_0_li_1_div_1_Template_div_click_0_listener($event){ + $i0$.ɵɵlistener("click", function MyComponent_ul_0_li_1_div_1_Template_div_click_0_listener(){ $i0$.ɵɵrestoreView($s$); const $inner$ = ctx.$implicit; const $middle$ = $i0$.ɵɵnextContext().$implicit; @@ -146,7 +146,7 @@ describe('compiler compliance: template', () => { if (rf & 1) { const $s$ = $r3$.ɵɵgetCurrentView(); $r3$.ɵɵelementStart(0, "div", 1); - $r3$.ɵɵlistener("click", function MyComponent_div_0_Template_div_click_0_listener($event) { + $r3$.ɵɵlistener("click", function MyComponent_div_0_Template_div_click_0_listener() { $r3$.ɵɵrestoreView($s$); const $d$ = ctx.$implicit; const $i$ = ctx.index; @@ -201,7 +201,7 @@ describe('compiler compliance: template', () => { if (rf & 1) { const $_r2$ = i0.ɵɵgetCurrentView(); $r3$.ɵɵelementStart(0, "div", 2); - $r3$.ɵɵlistener("click", function MyComponent_div_0_Template_div_click_0_listener($event) { + $r3$.ɵɵlistener("click", function MyComponent_div_0_Template_div_click_0_listener() { i0.ɵɵrestoreView($_r2$); const $ctx_r1$ = i0.ɵɵnextContext(); return $ctx_r1$.greet($ctx_r1$); diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 4d2f21eaf5..e838b3e12f 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -2504,7 +2504,7 @@ runInEachFileSystem(os => { const hostBindingsFn = ` hostBindings: function FooCmp_HostBindings(rf, ctx) { if (rf & 1) { - i0.ɵɵlistener("click", function FooCmp_click_HostBindingHandler($event) { return ctx.onClick(); })("click", function FooCmp_click_HostBindingHandler($event) { return ctx.onDocumentClick($event.target); }, false, i0.ɵɵresolveDocument)("scroll", function FooCmp_scroll_HostBindingHandler($event) { return ctx.onWindowScroll(); }, false, i0.ɵɵresolveWindow); + i0.ɵɵlistener("click", function FooCmp_click_HostBindingHandler() { return ctx.onClick(); })("click", function FooCmp_click_HostBindingHandler($event) { return ctx.onDocumentClick($event.target); }, false, i0.ɵɵresolveDocument)("scroll", function FooCmp_scroll_HostBindingHandler() { return ctx.onWindowScroll(); }, false, i0.ɵɵresolveWindow); } } `; @@ -2635,7 +2635,7 @@ runInEachFileSystem(os => { hostVars: 4, hostBindings: function FooCmp_HostBindings(rf, ctx) { if (rf & 1) { - i0.ɵɵlistener("click", function FooCmp_click_HostBindingHandler($event) { return ctx.onClick($event); })("click", function FooCmp_click_HostBindingHandler($event) { return ctx.onBodyClick($event); }, false, i0.ɵɵresolveBody)("change", function FooCmp_change_HostBindingHandler($event) { return ctx.onChange(ctx.arg1, ctx.arg2, ctx.arg3); }); + i0.ɵɵlistener("click", function FooCmp_click_HostBindingHandler($event) { return ctx.onClick($event); })("click", function FooCmp_click_HostBindingHandler($event) { return ctx.onBodyClick($event); }, false, i0.ɵɵresolveBody)("change", function FooCmp_change_HostBindingHandler() { return ctx.onChange(ctx.arg1, ctx.arg2, ctx.arg3); }); } if (rf & 2) { i0.ɵɵhostProperty("prop", ctx.bar); @@ -2703,7 +2703,7 @@ runInEachFileSystem(os => { selector: '[test]', }) class Dir { - @HostListener('change', ['arg']) + @HostListener('change', ['$event', 'arg']) onChange(event: any, arg: any): void {} } `); @@ -2713,7 +2713,7 @@ runInEachFileSystem(os => { const hostBindingsFn = ` hostBindings: function Dir_HostBindings(rf, ctx) { if (rf & 1) { - i0.ɵɵlistener("change", function Dir_change_HostBindingHandler($event) { return ctx.onChange(ctx.arg); }); + i0.ɵɵlistener("change", function Dir_change_HostBindingHandler($event) { return ctx.onChange($event, ctx.arg); }); } } `; diff --git a/packages/compiler/src/compiler_util/expression_converter.ts b/packages/compiler/src/compiler_util/expression_converter.ts index 87cfaabe0b..b446f6a750 100644 --- a/packages/compiler/src/compiler_util/expression_converter.ts +++ b/packages/compiler/src/compiler_util/expression_converter.ts @@ -70,7 +70,8 @@ export type InterpolationFunction = (args: o.Expression[]) => o.Expression; export function convertActionBinding( localResolver: LocalResolver | null, implicitReceiver: o.Expression, action: cdAst.AST, bindingId: string, interpolationFunction?: InterpolationFunction, - baseSourceSpan?: ParseSourceSpan): ConvertActionBindingResult { + baseSourceSpan?: ParseSourceSpan, + implicitReceiverAccesses?: Set