diff --git a/packages/ember-template-compiler/lib/plugins/transform-attrs-into-args.ts b/packages/ember-template-compiler/lib/plugins/transform-attrs-into-args.ts
index 8f7ea8c50ad..b04932d28a8 100644
--- a/packages/ember-template-compiler/lib/plugins/transform-attrs-into-args.ts
+++ b/packages/ember-template-compiler/lib/plugins/transform-attrs-into-args.ts
@@ -33,14 +33,27 @@ export default function transformAttrsIntoArgs(env: EmberASTPluginEnvironment):
let stack: string[][] = [[]];
+ function updateBlockParamsStack(blockParams: string[]) {
+ let parent = stack[stack.length - 1];
+ stack.push(parent.concat(blockParams));
+ }
+
return {
name: 'transform-attrs-into-args',
visitor: {
Program: {
enter(node: AST.Program) {
- let parent = stack[stack.length - 1];
- stack.push(parent.concat(node.blockParams));
+ updateBlockParamsStack(node.blockParams);
+ },
+ exit() {
+ stack.pop();
+ },
+ },
+
+ ElementNode: {
+ enter(node: AST.ElementNode) {
+ updateBlockParamsStack(node.blockParams);
},
exit() {
stack.pop();
diff --git a/packages/ember-template-compiler/tests/plugins/transform-attrs-into-args-test.js b/packages/ember-template-compiler/tests/plugins/transform-attrs-into-args-test.js
new file mode 100644
index 00000000000..3db58637b56
--- /dev/null
+++ b/packages/ember-template-compiler/tests/plugins/transform-attrs-into-args-test.js
@@ -0,0 +1,62 @@
+import TransformTestCase from '../utils/transform-test-case';
+import { moduleFor, RenderingTestCase } from 'internal-test-helpers';
+
+moduleFor(
+ 'ember-template-compiler: transforming attrs into @args',
+ class extends TransformTestCase {
+ ['@test it transforms attrs into @args']() {
+ expectDeprecation(() => {
+ this.assertTransformed(`{{attrs.foo}}`, `{{@foo}}`);
+ }, /Using {{attrs}} to reference named arguments has been deprecated. {{attrs.foo}} should be updated to {{@foo}}./);
+
+ expectDeprecation(() => {
+ this.assertTransformed(`{{attrs.foo.bar}}`, `{{@foo.bar}}`);
+ }, /Using {{attrs}} to reference named arguments has been deprecated. {{attrs.foo.bar}} should be updated to {{@foo.bar}}./);
+
+ expectDeprecation(() => {
+ this.assertTransformed(`{{if attrs.foo "foo"}}`, `{{if @foo "foo"}}`);
+ }, /Using {{attrs}} to reference named arguments has been deprecated. {{attrs.foo}} should be updated to {{@foo}}./);
+
+ expectDeprecation(() => {
+ this.assertTransformed(`{{#if attrs.foo}}{{/if}}`, `{{#if @foo}}{{/if}}`);
+ }, /Using {{attrs}} to reference named arguments has been deprecated. {{attrs.foo}} should be updated to {{@foo}}./);
+
+ expectDeprecation(() => {
+ this.assertTransformed(`{{deeply (nested attrs.foo.bar)}}`, `{{deeply (nested @foo.bar)}}`);
+ }, /Using {{attrs}} to reference named arguments has been deprecated. {{attrs.foo.bar}} should be updated to {{@foo.bar}}./);
+
+ expectDeprecation(() => {
+ this.assertTransformed(`{{this.attrs.foo}}`, `{{@foo}}`);
+ }, /Using {{attrs}} to reference named arguments has been deprecated. {{attrs.foo}} should be updated to {{@foo}}./);
+ }
+ }
+);
+
+moduleFor(
+ 'ember-template-compiler: not transforming block params named "attrs" into @args',
+ class extends RenderingTestCase {
+ ["@test it doesn't transform block params"]() {
+ this.registerComponent('foo', {
+ template: '{{#let "foo" as |attrs|}}{{attrs}}{{/let}}',
+ });
+ this.render('');
+ this.assertComponentElement(this.firstChild, { content: 'foo' });
+ }
+
+ ["@test it doesn't transform component block params"]() {
+ this.registerComponent('foo', {
+ template: '{{yield "foo"}}',
+ });
+ this.render('{{attrs}}');
+ this.assertComponentElement(this.firstChild, { content: 'foo' });
+ }
+
+ ["@test it doesn't transform block params with nested keys"]() {
+ this.registerComponent('foo', {
+ template: '{{yield (hash bar="baz")}}',
+ });
+ this.render('{{attrs.bar}}');
+ this.assertComponentElement(this.firstChild, { content: 'baz' });
+ }
+ }
+);