diff --git a/packages/@ember/-internals/glimmer/index.ts b/packages/@ember/-internals/glimmer/index.ts
index 6361a67283d..d3e2baac667 100644
--- a/packages/@ember/-internals/glimmer/index.ts
+++ b/packages/@ember/-internals/glimmer/index.ts
@@ -112,6 +112,7 @@
@for Ember.Templates.helpers
@param {Object} options
@return {String} HTML string
+ @deprecated Use '{{#let}}' instead
@public
*/
diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/angle-bracket-invocation-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/angle-bracket-invocation-test.js
index d8deb91f577..73f4591cc96 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/components/angle-bracket-invocation-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/components/angle-bracket-invocation-test.js
@@ -569,9 +569,9 @@ moduleFor(
this.registerComponent('foo-bar', { template: 'hello' });
this.render(strip`
- {{#with (component 'foo-bar') as |Other|}}
+ {{#let (component 'foo-bar') as |Other|}}
- {{/with}}
+ {{/let}}
`);
this.assertComponentElement(this.firstChild, { content: 'hello' });
diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/contextual-components-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/contextual-components-test.js
index efdaea036a6..b4d9541177e 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/components/contextual-components-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/components/contextual-components-test.js
@@ -272,9 +272,9 @@ moduleFor(
this.render(
strip`
- {{#with (hash comp=(component "-looked-up" greeting=this.model.greeting)) as |my|}}
+ {{#let (hash comp=(component "-looked-up" greeting=this.model.greeting)) as |my|}}
{{#my.comp}}{{/my.comp}}
- {{/with}}`,
+ {{/let}}`,
{
model: {
greeting: 'Hodi',
@@ -340,11 +340,11 @@ moduleFor(
this.render(
strip`
- {{#with (component "-looked-up" greeting="Hola" name="Dolores" age=33) as |first|}}
- {{#with (component first greeting="Hej" name="Sigmundur") as |second|}}
+ {{#let (component "-looked-up" greeting="Hola" name="Dolores" age=33) as |first|}}
+ {{#let (component first greeting="Hej" name="Sigmundur") as |second|}}
{{component second greeting=this.model.greeting}}
- {{/with}}
- {{/with}}`,
+ {{/let}}
+ {{/let}}`,
{
model: {
greeting: 'Hodi',
@@ -616,9 +616,9 @@ moduleFor(
});
this.render(strip`
- {{#with (hash lookedup=(component "-looked-up")) as |object|}}
+ {{#let (hash lookedup=(component "-looked-up")) as |object|}}
{{object.lookedup}}
- {{/with}}`);
+ {{/let}}`);
this.assertText(expectedText);
@@ -635,9 +635,9 @@ moduleFor(
this.render(
strip`
- {{#with (hash lookedup=(component "-looked-up")) as |object|}}
+ {{#let (hash lookedup=(component "-looked-up")) as |object|}}
{{object.lookedup expectedText=this.model.expectedText}}
- {{/with}}`,
+ {{/let}}`,
{
model: {
expectedText,
@@ -668,9 +668,9 @@ moduleFor(
this.render(
strip`
- {{#with (hash lookedup=(component "-looked-up" expectedText=this.model.expectedText)) as |object|}}
+ {{#let (hash lookedup=(component "-looked-up" expectedText=this.model.expectedText)) as |object|}}
{{object.lookedup}}
- {{/with}}`,
+ {{/let}}`,
{
model: {
expectedText,
@@ -705,9 +705,9 @@ moduleFor(
this.render(
strip`
- {{#with (hash lookedup=(component "-looked-up")) as |object|}}
+ {{#let (hash lookedup=(component "-looked-up")) as |object|}}
{{object.lookedup this.model.expectedText "Hola"}}
- {{/with}}`,
+ {{/let}}`,
{
model: {
expectedText,
@@ -748,9 +748,9 @@ moduleFor(
this.render(
strip`
- {{#with (hash my-component=(component 'my-component' first)) as |c|}}
+ {{#let (hash my-component=(component 'my-component' first)) as |c|}}
{{c.my-component}}
- {{/with}}`,
+ {{/let}}`,
{ first: 'first' }
);
@@ -946,9 +946,9 @@ moduleFor(
this.render(
strip`
- {{#with (hash ctxCmp=(component "my-comp" isOpen=isOpen)) as |thing|}}
+ {{#let (hash ctxCmp=(component "my-comp" isOpen=isOpen)) as |thing|}}
{{#thing.ctxCmp}}This is a contextual component{{/thing.ctxCmp}}
- {{/with}}
+ {{/let}}
`,
{
isOpen: true,
@@ -1010,9 +1010,9 @@ moduleFor(
this.render(
strip`
- {{#with (hash ctxCmp=(component compName isOpen=isOpen)) as |thing|}}
+ {{#let (hash ctxCmp=(component compName isOpen=isOpen)) as |thing|}}
{{#thing.ctxCmp}}This is a contextual component{{/thing.ctxCmp}}
- {{/with}}
+ {{/let}}
`,
{
compName: 'my-comp',
@@ -1088,9 +1088,9 @@ moduleFor(
this.render(
strip`
- {{#with (hash ctxCmp=(component compName isOpen=isOpen)) as |thing|}}
+ {{#let (hash ctxCmp=(component compName isOpen=isOpen)) as |thing|}}
{{#thing.ctxCmp}}This is a contextual component{{/thing.ctxCmp}}
- {{/with}}
+ {{/let}}
`,
{
compName: 'my-comp',
@@ -1198,7 +1198,7 @@ moduleFor(
});
this.render(
- '{{#with (hash link=(component "my-link")) as |c|}}{{c.link params=allParams}}{{/with}}',
+ '{{#let (hash link=(component "my-link")) as |c|}}{{c.link params=allParams}}{{/let}}',
{
allParams: emberA(['a', 'b']),
}
diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/array-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/array-test.js
index fa0b5fa0e03..c3957d04c30 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/helpers/array-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/array-test.js
@@ -9,11 +9,11 @@ moduleFor(
class extends RenderingTestCase {
['@test returns an array']() {
this.render(strip`
- {{#with (array "Sergio") as |people|}}
+ {{#let (array "Sergio") as |people|}}
{{#each people as |personName|}}
{{personName}}
{{/each}}
- {{/with}}`);
+ {{/let}}`);
this.assertText('Sergio');
@@ -22,11 +22,11 @@ moduleFor(
['@test can have more than one value']() {
this.render(strip`
- {{#with (array "Sergio" "Robert") as |people|}}
+ {{#let (array "Sergio" "Robert") as |people|}}
{{#each people as |personName|}}
{{personName}},
{{/each}}
- {{/with}}`);
+ {{/let}}`);
this.assertText('Sergio,Robert,');
@@ -35,11 +35,11 @@ moduleFor(
['@test binds values when variables are used']() {
this.render(
- strip`{{#with (array personOne) as |people|}}
+ strip`{{#let (array personOne) as |people|}}
{{#each people as |personName|}}
{{personName}}
{{/each}}
- {{/with}}`,
+ {{/let}}`,
{
personOne: 'Tom',
}
@@ -58,11 +58,11 @@ moduleFor(
['@test binds multiple values when variables are used']() {
this.render(
- strip`{{#with (array personOne personTwo) as |people|}}
+ strip`{{#let (array personOne personTwo) as |people|}}
{{#each people as |personName|}}
{{personName}},
{{/each}}
- {{/with}}`,
+ {{/let}}`,
{
personOne: 'Tom',
personTwo: 'Yehuda',
@@ -91,14 +91,14 @@ moduleFor(
['@test array helpers can be nested']() {
this.render(
- strip`{{#with (array (array personOne personTwo)) as |listOfPeople|}}
+ strip`{{#let (array (array personOne personTwo)) as |listOfPeople|}}
{{#each listOfPeople as |people|}}
List:
{{#each people as |personName|}}
{{personName}},
{{/each}}
{{/each}}
- {{/with}}`,
+ {{/let}}`,
{
personOne: 'Tom',
personTwo: 'Yehuda',
diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/element-action-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/element-action-test.js
index 2719f227280..a52abc9c7b0 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/helpers/element-action-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/element-action-test.js
@@ -777,7 +777,7 @@ moduleFor(
this.assert.equal(editHandlerWasCalled, true, 'the event handler was called');
}
- ['@test it should work properly in a {{#with foo as |bar|}} block']() {
+ ['@test it should work properly in a {{#let foo as |bar|}} block']() {
let editHandlerWasCalled = false;
let ExampleComponent = Component.extend({
@@ -792,7 +792,7 @@ moduleFor(
this.registerComponent('example-component', {
ComponentClass: ExampleComponent,
template:
- '{{#with something as |somethingElse|}}click me{{/with}}',
+ '{{#let something as |somethingElse|}}click me{{/let}}',
});
this.render('{{example-component}}');
diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js
index 1329b91fb4e..bb78e043ee9 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js
@@ -8,7 +8,7 @@ moduleFor(
'Helpers test: {{hash}}',
class extends RenderingTestCase {
['@test returns a hash with the right key-value']() {
- this.render(`{{#with (hash name="Sergio") as |person|}}{{person.name}}{{/with}}`);
+ this.render(`{{#let (hash name="Sergio") as |person|}}{{person.name}}{{/let}}`);
this.assertText('Sergio');
@@ -19,7 +19,7 @@ moduleFor(
['@test can have more than one key-value']() {
this.render(
- `{{#with (hash name="Sergio" lastName="Arbeo") as |person|}}{{person.name}} {{person.lastName}}{{/with}}`
+ `{{#let (hash name="Sergio" lastName="Arbeo") as |person|}}{{person.name}} {{person.lastName}}{{/let}}`
);
this.assertText('Sergio Arbeo');
@@ -31,7 +31,7 @@ moduleFor(
['@test binds values when variables are used']() {
this.render(
- `{{#with (hash name=this.model.firstName lastName="Arbeo") as |person|}}{{person.name}} {{person.lastName}}{{/with}}`,
+ `{{#let (hash name=this.model.firstName lastName="Arbeo") as |person|}}{{person.name}} {{person.lastName}}{{/let}}`,
{
model: {
firstName: 'Marisa',
@@ -56,7 +56,7 @@ moduleFor(
['@test binds multiple values when variables are used']() {
this.render(
- `{{#with (hash name=this.model.firstName lastName=this.model.lastName) as |person|}}{{person.name}} {{person.lastName}}{{/with}}`,
+ `{{#let (hash name=this.model.firstName lastName=this.model.lastName) as |person|}}{{person.name}} {{person.lastName}}{{/let}}`,
{
model: {
firstName: 'Marisa',
@@ -91,7 +91,7 @@ moduleFor(
['@test hash helpers can be nested']() {
this.render(
- `{{#with (hash person=(hash name=this.model.firstName)) as |ctx|}}{{ctx.person.name}}{{/with}}`,
+ `{{#let (hash person=(hash name=this.model.firstName)) as |ctx|}}{{ctx.person.name}}{{/let}}`,
{
model: { firstName: 'Balint' },
}
diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/partial-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/partial-test.js
index 82f119ea77d..96e44c0514b 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/helpers/partial-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/partial-test.js
@@ -125,15 +125,15 @@ moduleFor(
this.assertText('apple: apple |orange: orange |banana: banana |');
}
- ['@test partial using `{{get` on data from {{#with}}']() {
+ ['@test partial using `{{get` on data from {{#let}}']() {
this.registerPartial('show-id', '{{get item "id"}}');
expectDeprecation(() => {
this.render(
strip`
- {{#with this.model as |item|}}
+ {{#let this.model as |item|}}
{{item.name}}: {{partial 'show-id'}}
- {{/with}}`,
+ {{/let}}`,
{
model: { id: 1, name: 'foo' },
}
@@ -258,40 +258,40 @@ moduleFor(
this.assertText('0: [outer: Alex] [inner: Alex]1: [outer: Ben] [inner: Ben]');
}
- ['@test nested partials within nested `{{#with}}` blocks']() {
+ ['@test nested partials within nested `{{#let}}` blocks']() {
this.registerPartial(
'_person2-partial',
strip`
- {{#with 'Ben' as |person2|}}
+ {{#let 'Ben' as |person2|}}
Hi {{person1}} (aged {{age}}) and {{person2}}. {{partial 'person3-partial'}}
- {{/with}}
+ {{/let}}
`
);
this.registerPartial(
'_person3-partial',
strip`
- {{#with 'Alex' as |person3|}}
+ {{#let 'Alex' as |person3|}}
Hi {{person1}} (aged {{age}}), {{person2}} and {{person3}}. {{partial 'person4-partial'}}
- {{/with}}
+ {{/let}}
`
);
this.registerPartial(
'_person4-partial',
strip`
- {{#with 'Sarah' as |person4|}}
+ {{#let 'Sarah' as |person4|}}
Hi {{person1}} (aged {{age}}), {{person2}}, {{person3}} and {{person4}}.
- {{/with}}
+ {{/let}}
`
);
expectDeprecation(() => {
this.render(
strip`
- {{#with 'Sophie' as |person1|}}
+ {{#let 'Sophie' as |person1|}}
Hi {{person1}} (aged {{age}}). {{partial 'person2-partial'}}
- {{/with}}`,
+ {{/let}}`,
{ age: 0 }
);
}, /The use of `{{partial}}` is deprecated, please refactor the "person(2|3|4)-partial" partial to a component/);
@@ -352,24 +352,54 @@ moduleFor(
this.assertText('number: EVEN0number: ODD1number: EVEN2number: ODD3');
}
- ['@test dynamic partials in {{#with}}']() {
+ ['@test [DEPRECATED] dynamic partials in {{#with}}']() {
+ this.registerPartial('_thing', '{{t}}');
+
+ expectDeprecation(() => {
+ this.render(
+ strip`
+ {{#with item.thing as |t|}}
+ {{partial t}}
+ {{else}}
+ Nothing!
+ {{/with}}`,
+ {
+ item: { thing: false },
+ }
+ );
+ }, /`{{#with}}` is deprecated\./);
+
+ this.assertStableRerender();
+
+ this.assertText('Nothing!');
+
+ expectDeprecation(() => {
+ runTask(() => set(this.context, 'item.thing', 'thing'));
+ }, 'The use of `{{partial}}` is deprecated, please refactor the "thing" partial to a component');
+
+ this.assertText('thing');
+
+ runTask(() => set(this.context, 'item', { thing: false }));
+
+ this.assertText('Nothing!');
+ }
+
+ ['@test dynamic partials in {{#let}}']() {
this.registerPartial('_thing', '{{t}}');
this.render(
strip`
- {{#with item.thing as |t|}}
+ {{#let item.thing as |t|}}
{{partial t}}
- {{else}}
- Nothing!
- {{/with}}`,
+ {{/let}}`,
{
- item: { thing: false },
+ item: { thing: null },
}
);
this.assertStableRerender();
- this.assertText('Nothing!');
+ this.assertText('');
expectDeprecation(() => {
runTask(() => set(this.context, 'item.thing', 'thing'));
@@ -377,9 +407,9 @@ moduleFor(
this.assertText('thing');
- runTask(() => set(this.context, 'item', { thing: false }));
+ runTask(() => set(this.context, 'item', { thing: null }));
- this.assertText('Nothing!');
+ this.assertText('');
}
['@test partials which contain contextual components']() {
diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/yield-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/yield-test.js
index 51b13c6730f..6efa12652e7 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/helpers/yield-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/yield-test.js
@@ -203,7 +203,7 @@ moduleFor(
template: '
{{boundText}}
{{yield}}
',
});
- this.render('{{#with boundText as |item|}}{{#kiwi-comp}}{{item}}{{/kiwi-comp}}{{/with}}', {
+ this.render('{{#let boundText as |item|}}{{#kiwi-comp}}{{item}}{{/kiwi-comp}}{{/let}}', {
boundText: 'Outer',
});
this.assertText('InnerOuter');
@@ -222,7 +222,7 @@ moduleFor(
this.registerComponent('kiwi-comp', {
ComponentClass: KiwiCompComponent,
- template: '{{#with boundText as |item|}}{{item}}
{{yield}}
{{/with}}',
+ template: '{{#let boundText as |item|}}{{item}}
{{yield}}
{{/let}}',
});
this.render('{{#kiwi-comp}}{{item}}{{/kiwi-comp}}', { item: 'Outer' });
@@ -243,7 +243,7 @@ moduleFor(
});
this.render(
- '{{#with boundText as |item|}}{{#kiwi-comp content=item}}{{item}}{{/kiwi-comp}}{{/with}}',
+ '{{#let boundText as |item|}}{{#kiwi-comp content=item}}{{item}}{{/kiwi-comp}}{{/let}}',
{ boundText: 'Outer' }
);
this.assertText('OuterOuter');
diff --git a/packages/@ember/-internals/glimmer/tests/integration/refinements-test.js b/packages/@ember/-internals/glimmer/tests/integration/refinements-test.js
index d97364e0046..3626311f848 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/refinements-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/refinements-test.js
@@ -10,45 +10,45 @@ moduleFor(
this.render(
strip`
- {{#with var as |foo|}}
+ {{#let var as |foo|}}
{{foo}}
- {{/with}}
+ {{/let}}
---
- {{#with var as |outlet|}}
+ {{#let var as |outlet|}}
{{outlet}}
- {{/with}}
+ {{/let}}
---
- {{#with var as |mount|}}
+ {{#let var as |mount|}}
{{mount}}
- {{/with}}
+ {{/let}}
---
- {{#with var as |component|}}
+ {{#let var as |component|}}
{{component}}
- {{/with}}
+ {{/let}}
---
- {{#with var as |input|}}
+ {{#let var as |input|}}
{{input}}
- {{/with}}
+ {{/let}}
---
- {{#with var as |-with-dynamic-vars|}}
+ {{#let var as |-with-dynamic-vars|}}
{{-with-dynamic-vars}}
- {{/with}}
+ {{/let}}
---
- {{#with var as |-in-element|}}
+ {{#let var as |-in-element|}}
{{-in-element}}
- {{/with}}`,
+ {{/let}}`,
{ var: 'var' }
);
diff --git a/packages/@ember/-internals/glimmer/tests/integration/syntax/with-test.js b/packages/@ember/-internals/glimmer/tests/integration/syntax/with-test.js
index 5943f61f02e..a841ba07c99 100644
--- a/packages/@ember/-internals/glimmer/tests/integration/syntax/with-test.js
+++ b/packages/@ember/-internals/glimmer/tests/integration/syntax/with-test.js
@@ -8,6 +8,10 @@ import { IfUnlessWithSyntaxTest } from '../../utils/shared-conditional-tests';
moduleFor(
'Syntax test: {{#with}}',
class extends IfUnlessWithSyntaxTest {
+ beforeEach() {
+ expectDeprecation(/^`{{#with}}` is deprecated\./);
+ }
+
templateFor({ cond, truthy, falsy }) {
return `{{#with ${cond}}}${truthy}{{else}}${falsy}{{/with}}`;
}
@@ -17,6 +21,10 @@ moduleFor(
moduleFor(
'Syntax test: {{#with as}}',
class extends IfUnlessWithSyntaxTest {
+ beforeEach() {
+ expectDeprecation(/^`{{#with}}` is deprecated\./);
+ }
+
templateFor({ cond, truthy, falsy }) {
return `{{#with ${cond} as |test|}}${truthy}{{else}}${falsy}{{/with}}`;
}
@@ -247,6 +255,10 @@ moduleFor(
moduleFor(
'Syntax test: Multiple {{#with as}} helpers',
class extends RenderingTestCase {
+ beforeEach() {
+ expectDeprecation(/^`{{#with}}` is deprecated\./);
+ }
+
['@test re-using the same variable with different {{#with}} blocks does not override each other']() {
this.render(
`Admin: {{#with admin as |person|}}{{person.name}}{{/with}} User: {{#with user as |person|}}{{person.name}}{{/with}}`,
diff --git a/packages/ember-template-compiler/lib/plugins/deprecate-with.ts b/packages/ember-template-compiler/lib/plugins/deprecate-with.ts
new file mode 100644
index 00000000000..f4452652057
--- /dev/null
+++ b/packages/ember-template-compiler/lib/plugins/deprecate-with.ts
@@ -0,0 +1,189 @@
+import { assert, deprecate } from '@ember/debug';
+import { AST, ASTPlugin } from '@glimmer/syntax';
+import calculateLocationDisplay from '../system/calculate-location-display';
+import { EmberASTPluginEnvironment } from '../types';
+import { isPath } from './utils';
+
+/**
+ @module ember
+*/
+
+/**
+ A Glimmer2 AST transformation that deprecates `{{#with}}` and replace it
+ with `{{#let}}` and `{{#if}}` as per RFC 445.
+
+ Transforms:
+
+ ```handlebars
+ {{#with this.foo as |bar|}}
+ ...
+ {{/with}}
+ ```
+
+ Into:
+
+ ```handlebars
+ {{#let this.foo as |bar|}}
+ {{#if bar}}
+ ...
+ {{/if}}
+ {{/let}}
+ ```
+
+ And:
+
+ ```handlebars
+ {{#with this.foo as |bar|}}
+ ...
+ {{else}}
+ ...
+ {{/with}}
+ ```
+
+ Into:
+
+ ```handlebars
+ {{#let this.foo as |bar|}}
+ {{#if bar}}
+ ...
+ {{else}}
+ ...
+ {{/if}}
+ {{/let}}
+ ```
+
+ And issues a deprecation message.
+
+ @private
+ @class DeprecateWith
+*/
+export default function deprecateWith(env: EmberASTPluginEnvironment): ASTPlugin {
+ let { moduleName } = env.meta;
+ let { builders: b } = env.syntax;
+
+ return {
+ name: 'deprecate-with',
+
+ visitor: {
+ BlockStatement(node: AST.BlockStatement) {
+ if (!isPath(node.path) || node.path.original !== 'with') return;
+
+ let { params, hash, program, inverse, loc, openStrip, inverseStrip, closeStrip } = node;
+
+ let sourceInformation = calculateLocationDisplay(moduleName, node.loc);
+
+ assert(
+ `\`{{#with}}\` takes a single positional argument (the path to alias), received ${displayParams(
+ params
+ )}. ${sourceInformation}`,
+ params.length === 1
+ );
+
+ assert(
+ `\`{{#with}}\` does not take any named arguments, received ${displayHash(
+ hash
+ )}. ${sourceInformation}`,
+ hash.pairs.length === 0
+ );
+
+ assert(
+ `\`{{#with}}\` yields a single block param, received ${displayBlockParams(
+ program.blockParams
+ )}. ${sourceInformation}`,
+ program.blockParams.length <= 1
+ );
+
+ let recommendation;
+
+ if (program.blockParams.length === 0) {
+ recommendation = 'Use `{{#if}}` instead.';
+ } else if (inverse) {
+ recommendation = 'Use `{{#let}}` together with `{{#if}} instead.';
+ } else {
+ recommendation =
+ 'If you always want the block to render, replace `{{#with}}` with `{{#let}}`. ' +
+ 'If you want to conditionally render the block, use `{{#let}}` together with `{{#if}} instead.';
+ }
+
+ deprecate(`\`{{#with}}\` is deprecated. ${recommendation} ${sourceInformation}`, false, {
+ id: 'ember-glimmer.with-syntax',
+ until: '4.0.0',
+ for: 'ember-source',
+ since: {
+ enabled: '3.26.0-beta.1',
+ },
+ });
+
+ if (program.blockParams.length === 0) {
+ return b.block(
+ 'if',
+ params,
+ null,
+ program,
+ inverse,
+ loc,
+ openStrip,
+ inverseStrip,
+ closeStrip
+ );
+ } else {
+ return b.block(
+ 'let',
+ params,
+ null,
+ b.blockItself(
+ [
+ b.block(
+ 'if',
+ [b.path(program.blockParams[0])],
+ null,
+ b.blockItself(program.body, [], program.chained, program.loc),
+ inverse,
+ loc,
+ openStrip,
+ inverseStrip,
+ closeStrip
+ ),
+ ],
+ program.blockParams,
+ false,
+ loc
+ ),
+ null,
+ loc,
+ openStrip,
+ inverseStrip,
+ closeStrip
+ );
+ }
+ },
+ },
+ };
+}
+
+function displayParams(params: AST.Expression[]): string {
+ if (params.length === 0) {
+ return 'no positional arguments';
+ } else {
+ let display = params.map((param) => `\`${JSON.stringify(param)}\``).join(', ');
+ return `${params.length} positional arguments: ${display}`;
+ }
+}
+
+function displayHash({ pairs }: AST.Hash): string {
+ if (pairs.length === 0) {
+ return 'no named arguments';
+ } else {
+ let display = pairs.map((pair) => `\`${pair.key}\``).join(', ');
+ return `${pairs.length} named arguments: ${display}`;
+ }
+}
+
+function displayBlockParams(blockParams: string[]): string {
+ if (blockParams.length === 0) {
+ return 'no block params';
+ } else {
+ let display = blockParams.map((param) => `\`${param}\``).join(', ');
+ return `${blockParams.length} block params: ${display}`;
+ }
+}
diff --git a/packages/ember-template-compiler/lib/plugins/index.ts b/packages/ember-template-compiler/lib/plugins/index.ts
index 756d528d0f1..4b8ac4fe831 100644
--- a/packages/ember-template-compiler/lib/plugins/index.ts
+++ b/packages/ember-template-compiler/lib/plugins/index.ts
@@ -4,6 +4,7 @@ import AssertInputHelperWithoutBlock from './assert-input-helper-without-block';
import AssertReservedNamedArguments from './assert-reserved-named-arguments';
import AssertSplattributeExpressions from './assert-splattribute-expression';
import DeprecateSendAction from './deprecate-send-action';
+import DeprecateWith from './deprecate-with';
import TransformActionSyntax from './transform-action-syntax';
import TransformAttrsIntoArgs from './transform-attrs-into-args';
import TransformEachInIntoEach from './transform-each-in-into-each';
@@ -34,6 +35,7 @@ export const RESOLUTION_MODE_TRANSFORMS = Object.freeze(
AssertSplattributeExpressions,
TransformEachTrackArray,
TransformWrapMountAndOutlet,
+ DeprecateWith,
SEND_ACTION ? DeprecateSendAction : null,
!EMBER_NAMED_BLOCKS ? AssertAgainstNamedBlocks : null,
!EMBER_DYNAMIC_HELPERS_AND_MODIFIERS ? AssertAgainstDynamicHelpersModifiers : null,
@@ -50,6 +52,7 @@ export const STRICT_MODE_TRANSFORMS = Object.freeze(
AssertSplattributeExpressions,
TransformEachTrackArray,
TransformWrapMountAndOutlet,
+ DeprecateWith,
SEND_ACTION ? DeprecateSendAction : null,
!EMBER_NAMED_BLOCKS ? AssertAgainstNamedBlocks : null,
!EMBER_DYNAMIC_HELPERS_AND_MODIFIERS ? AssertAgainstDynamicHelpersModifiers : null,