diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js index edbc4e56acb..5fdd2305aff 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/curly-components-test.js @@ -1256,13 +1256,17 @@ moduleFor( this.assertText('somecomponent'); } - ['@test non-block with properties on attrs']() { - expectDeprecation( - "Using {{attrs}} to reference named arguments has been deprecated. {{attrs.someProp}} should be updated to {{@someProp}}. ('my-app/templates/components/non-block.hbs' @ L1:C24) " - ); + ['@test non-block with properties access via attrs is asserted against']() { + expectAssertion(() => { + this.registerComponent('non-block', { + template: 'In layout - someProp: {{attrs.someProp}}', + }); + }, "Using {{attrs}} to reference named arguments is not supported. {{attrs.someProp}} should be updated to {{@someProp}}. ('my-app/templates/components/non-block.hbs' @ L1:C24) "); + } + ['@test non-block with properties on this.attrs']() { this.registerComponent('non-block', { - template: 'In layout - someProp: {{attrs.someProp}}', + template: 'In layout - someProp: {{this.attrs.someProp}}', }); this.render('{{non-block someProp=this.prop}}', { @@ -1469,32 +1473,13 @@ moduleFor( ); } - ['@test this.attrs.foo === attrs.foo === @foo === foo']() { - expectDeprecation( - "Using {{attrs}} to reference named arguments has been deprecated. {{attrs.value}} should be updated to {{@value}}. ('my-app/templates/components/foo-bar.hbs' @ L1:C8) " - ); - - expectDeprecation( - "Using {{attrs}} to reference named arguments has been deprecated. {{attrs.value}} should be updated to {{@value}}. ('my-app/templates/components/foo-bar.hbs' @ L1:C31) " - ); - - expectDeprecation( - "Using {{attrs}} to reference named arguments has been deprecated. {{attrs.items}} should be updated to {{@items}}. ('my-app/templates/components/foo-bar.hbs' @ L1:C82) " - ); - - expectDeprecation( - "Using {{attrs}} to reference named arguments has been deprecated. {{attrs.items}} should be updated to {{@items}}. ('my-app/templates/components/foo-bar.hbs' @ L1:C135) " - ); - + ['@test this.attrs.foo === @foo === foo']() { this.registerComponent('foo-bar', { template: strip` - Args: {{this.attrs.value}} | {{attrs.value}} | {{@value}} | {{this.value}} + Args: {{this.attrs.value}} | {{@value}} | {{this.value}} {{#each this.attrs.items as |item|}} {{item}} {{/each}} - {{#each attrs.items as |item|}} - {{item}} - {{/each}} {{#each @items as |item|}} {{item}} {{/each}} @@ -1518,11 +1503,11 @@ moduleFor( this.context.set('model.items', [1]); }); - this.assertText(strip`Args: lul | lul | lul | lul1111`); + this.assertText(strip`Args: lul | lul | lul111`); runTask(() => this.context.set('model', { value: 'wat', items: [1, 2, 3] })); - this.assertText('Args: wat | wat | wat | wat123123123123'); + this.assertText('Args: wat | wat | wat123123123'); } ['@test non-block with properties on self']() { @@ -1579,13 +1564,17 @@ moduleFor( this.assertText('In layout - someProp: something here - In template'); } - ['@test block with properties on attrs']() { - expectDeprecation( - "Using {{attrs}} to reference named arguments has been deprecated. {{attrs.someProp}} should be updated to {{@someProp}}. ('my-app/templates/components/with-block.hbs' @ L1:C24) " - ); + ['@test block with properties on attrs is asserted against']() { + expectAssertion(() => { + this.registerComponent('with-block', { + template: 'In layout - someProp: {{attrs.someProp}} - {{yield}}', + }); + }, "Using {{attrs}} to reference named arguments is not supported. {{attrs.someProp}} should be updated to {{@someProp}}. ('my-app/templates/components/with-block.hbs' @ L1:C24) "); + } + ['@test block with properties on this.attrs']() { this.registerComponent('with-block', { - template: 'In layout - someProp: {{attrs.someProp}} - {{yield}}', + template: 'In layout - someProp: {{this.attrs.someProp}} - {{yield}}', }); this.render( @@ -3298,21 +3287,29 @@ moduleFor( this.assertText('hello'); } - ['@test using attrs for positional params']() { - expectDeprecation( - "Using {{attrs}} to reference named arguments has been deprecated. {{attrs.myVar}} should be updated to {{@myVar}}. ('my-app/templates/components/foo-bar.hbs' @ L1:C10) " - ); - expectDeprecation( - "Using {{attrs}} to reference named arguments has been deprecated. {{attrs.myVar2}} should be updated to {{@myVar2}}. ('my-app/templates/components/foo-bar.hbs' @ L1:C65) " - ); + ['@test using attrs for positional params is asserted against']() { + let MyComponent = Component.extend(); + + expectAssertion(() => { + this.registerComponent('foo-bar', { + ComponentClass: MyComponent.reopenClass({ + positionalParams: ['myVar'], + }), + template: + 'MyVar1: {{attrs.myVar}} {{this.myVar}} MyVar2: {{this.myVar2}} {{attrs.myVar2}}', + }); + }, "Using {{attrs}} to reference named arguments is not supported. {{attrs.myVar}} should be updated to {{@myVar}}. ('my-app/templates/components/foo-bar.hbs' @ L1:C10) "); + } + ['@test using this.attrs for positional params']() { let MyComponent = Component.extend(); this.registerComponent('foo-bar', { ComponentClass: MyComponent.reopenClass({ positionalParams: ['myVar'], }), - template: 'MyVar1: {{attrs.myVar}} {{this.myVar}} MyVar2: {{this.myVar2}} {{attrs.myVar2}}', + template: + 'MyVar1: {{this.attrs.myVar}} {{this.myVar}} MyVar2: {{this.myVar2}} {{this.attrs.myVar2}}', }); this.render('{{foo-bar 1 myVar2=2}}'); diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/closure-action-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/closure-action-test.js index f394240e137..a75b22e0f20 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/helpers/closure-action-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/closure-action-test.js @@ -250,14 +250,10 @@ moduleFor( }, /An action could not be made for `.*` in .*\. Please confirm that you are using either a quoted action name \(i\.e\. `\(action '.*'\)`\) or a function available in .*\./); } - ['@test [#12718] a nice error is shown when a bound action function is undefined and it is passed as attrs.foo']() { - expectDeprecation( - "Using {{attrs}} to reference named arguments has been deprecated. {{attrs.external-action}} should be updated to {{@external-action}}. ('my-app/templates/components/inner-component.hbs' @ L1:C43) " - ); - + ['@test [#12718] a nice error is shown when a bound action function is undefined and it is passed as @foo']() { this.registerComponent('inner-component', { template: - '', + '', }); this.registerComponent('outer-component', { diff --git a/packages/ember-template-compiler/lib/plugins/transform-attrs-into-args.ts b/packages/ember-template-compiler/lib/plugins/assert-against-attrs.ts similarity index 63% rename from packages/ember-template-compiler/lib/plugins/transform-attrs-into-args.ts rename to packages/ember-template-compiler/lib/plugins/assert-against-attrs.ts index 177887af5f0..1b610f6dfbf 100644 --- a/packages/ember-template-compiler/lib/plugins/transform-attrs-into-args.ts +++ b/packages/ember-template-compiler/lib/plugins/assert-against-attrs.ts @@ -1,4 +1,4 @@ -import { deprecate } from '@ember/debug'; +import { assert } from '@ember/debug'; import { AST, ASTPlugin } from '@glimmer/syntax'; import calculateLocationDisplay from '../system/calculate-location-display'; import { EmberASTPluginEnvironment } from '../types'; @@ -8,26 +8,19 @@ import { EmberASTPluginEnvironment } from '../types'; */ /** - A Glimmer2 AST transformation that replaces all instances of + A Glimmer2 AST transformation that asserts against ```handlebars - {{attrs.foo.bar}} + {{attrs.foo.bar}} ``` - to - - ```handlebars - {{@foo.bar}} - ``` - - as well as `{{#if attrs.foo}}`, `{{deeply (nested attrs.foobar.baz)}}`, - `{{this.attrs.foo}}` etc + ...as well as `{{#if attrs.foo}}`, `{{deeply (nested attrs.foobar.baz)}}`. @private - @class TransformAttrsToProps + @class AssertAgainstAttrs */ -export default function transformAttrsIntoArgs(env: EmberASTPluginEnvironment): ASTPlugin { +export default function assertAgainstAttrs(env: EmberASTPluginEnvironment): ASTPlugin { let { builders: b } = env.syntax; let moduleName = env.meta?.moduleName; @@ -39,7 +32,7 @@ export default function transformAttrsIntoArgs(env: EmberASTPluginEnvironment): } return { - name: 'transform-attrs-into-args', + name: 'assert-against-attrs', visitor: { Program: { @@ -64,28 +57,15 @@ export default function transformAttrsIntoArgs(env: EmberASTPluginEnvironment): if (isAttrs(node, stack[stack.length - 1])) { let path = b.path(node.original.substr(6)) as AST.PathExpression; - deprecate( - `Using {{attrs}} to reference named arguments has been deprecated. {{attrs.${ + assert( + `Using {{attrs}} to reference named arguments is not supported. {{attrs.${ path.original }}} should be updated to {{@${path.original}}}. ${calculateLocationDisplay( moduleName, node.loc )}`, - false, - { - id: 'attrs-arg-access', - url: 'https://deprecations.emberjs.com/v3.x/#toc_attrs-arg-access', - until: '4.0.0', - for: 'ember-source', - since: { - enabled: '3.26.0', - }, - } + node.this !== false ); - - path.original = `@${path.original}`; - path.data = true; - return path; } }, }, diff --git a/packages/ember-template-compiler/lib/plugins/index.ts b/packages/ember-template-compiler/lib/plugins/index.ts index b9c74da1d48..06d4b3b5c05 100644 --- a/packages/ember-template-compiler/lib/plugins/index.ts +++ b/packages/ember-template-compiler/lib/plugins/index.ts @@ -1,3 +1,4 @@ +import AssertAgainstAttrs from './assert-against-attrs'; import AssertAgainstDynamicHelpersModifiers from './assert-against-dynamic-helpers-modifiers'; import AssertAgainstNamedBlocks from './assert-against-named-blocks'; import AssertAgainstNamedOutlets from './assert-against-named-outlets'; @@ -5,7 +6,6 @@ import AssertInputHelperWithoutBlock from './assert-input-helper-without-block'; import AssertReservedNamedArguments from './assert-reserved-named-arguments'; import AssertSplattributeExpressions from './assert-splattribute-expression'; import TransformActionSyntax from './transform-action-syntax'; -import TransformAttrsIntoArgs from './transform-attrs-into-args'; import TransformEachInIntoEach from './transform-each-in-into-each'; import TransformEachTrackArray from './transform-each-track-array'; import TransformInElement from './transform-in-element'; @@ -24,7 +24,7 @@ export const RESOLUTION_MODE_TRANSFORMS = Object.freeze( TransformQuotedBindingsIntoJustBindings, AssertReservedNamedArguments, TransformActionSyntax, - TransformAttrsIntoArgs, + AssertAgainstAttrs, TransformEachInIntoEach, TransformLinkTo, AssertInputHelperWithoutBlock, diff --git a/packages/ember-template-compiler/tests/plugins/assert-against-attrs-test.js b/packages/ember-template-compiler/tests/plugins/assert-against-attrs-test.js new file mode 100644 index 00000000000..30f5c32fbd9 --- /dev/null +++ b/packages/ember-template-compiler/tests/plugins/assert-against-attrs-test.js @@ -0,0 +1,71 @@ +import TransformTestCase from '../utils/transform-test-case'; +import { moduleFor, RenderingTestCase } from 'internal-test-helpers'; + +moduleFor( + 'ember-template-compiler: assert against attrs', + class extends TransformTestCase { + ['@test it asserts against attrs']() { + expectAssertion(() => { + this.assertTransformed(`{{attrs.foo}}`, `{{attrs.foo}}`); + }, /Using {{attrs}} to reference named arguments is not supported. {{attrs.foo}} should be updated to {{@foo}}./); + + expectAssertion(() => { + this.assertTransformed(`{{attrs.foo.bar}}`, `{{attrs.foo.bar}}`); + }, /Using {{attrs}} to reference named arguments is not supported. {{attrs.foo.bar}} should be updated to {{@foo.bar}}./); + + expectAssertion(() => { + this.assertTransformed(`{{if attrs.foo "foo"}}`, `{{if attrs.foo "foo"}}`); + }, /Using {{attrs}} to reference named arguments is not supported. {{attrs.foo}} should be updated to {{@foo}}./); + + expectAssertion(() => { + this.assertTransformed(`{{#if attrs.foo}}{{/if}}`, `{{#if attrs.foo}}{{/if}}`); + }, /Using {{attrs}} to reference named arguments is not supported. {{attrs.foo}} should be updated to {{@foo}}./); + + expectAssertion(() => { + this.assertTransformed( + `{{deeply (nested attrs.foo.bar)}}`, + `{{deeply (nested attrs.foo.bar)}}` + ); + }, /Using {{attrs}} to reference named arguments is not supported. {{attrs.foo.bar}} should be updated to {{@foo.bar}}./); + } + + ['@test it does not assert against this.attrs']() { + this.assertTransformed(`{{this.attrs.foo}}`, `{{this.attrs.foo}}`); + this.assertTransformed(`{{if this.attrs.foo "foo"}}`, `{{if this.attrs.foo "foo"}}`); + this.assertTransformed(`{{#if this.attrs.foo}}{{/if}}`, `{{#if this.attrs.foo}}{{/if}}`); + this.assertTransformed( + `{{deeply (nested this.attrs.foo.bar)}}`, + `{{deeply (nested this.attrs.foo.bar)}}` + ); + } + } +); + +moduleFor( + 'ember-template-compiler: not asserting against block params named "attrs"', + class extends RenderingTestCase { + ["@test it doesn't assert block params"]() { + this.registerComponent('foo', { + template: '{{#let "foo" as |attrs|}}{{attrs}}{{/let}}', + }); + this.render(''); + this.assertComponentElement(this.firstChild, { content: 'foo' }); + } + + ["@test it doesn't assert component block params"]() { + this.registerComponent('foo', { + template: '{{yield "foo"}}', + }); + this.render('{{attrs}}'); + this.assertComponentElement(this.firstChild, { content: 'foo' }); + } + + ["@test it doesn't assert block params with nested keys"]() { + this.registerComponent('foo', { + template: '{{yield (hash bar="baz")}}', + }); + this.render('{{attrs.bar}}'); + this.assertComponentElement(this.firstChild, { content: 'baz' }); + } + } +); 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 deleted file mode 100644 index 3db58637b56..00000000000 --- a/packages/ember-template-compiler/tests/plugins/transform-attrs-into-args-test.js +++ /dev/null @@ -1,62 +0,0 @@ -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' }); - } - } -);