Skip to content

Commit 1dc9739

Browse files
committed
Lexical "this" capture
1 parent c7f8e59 commit 1dc9739

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

packages/@glimmer-workspace/integration-tests/test/compiler/compile-options-test.ts

+17
Original file line numberDiff line numberDiff line change
@@ -210,4 +210,21 @@ module('[glimmer-compiler] precompile', ({ test }) => {
210210
let elementName = openElementExpr[1];
211211
assert.strictEqual(elementName, 'rental', 'element name is correct');
212212
});
213+
214+
test('when "this" in in locals, it compiles to GetLexicalSymbol', (assert) => {
215+
let target = { message: 'hello' };
216+
let _wire: ReturnType<typeof compile>;
217+
(function() {
218+
_wire = compile(`{{this.message}}`, ['this'], (source) => eval(source));
219+
}).call(target)
220+
let wire = _wire!;
221+
assert.deepEqual(wire.scope?.(), [target]);
222+
assert.deepEqual(wire.block[0], [[SexpOpcodes.Append,[SexpOpcodes.GetLexicalSymbol,0,["message"]]]])
223+
});
224+
225+
test('when "this" is not in locals, it compiles to GetSymbol', (assert) => {
226+
let wire = compile(`{{this.message}}`, [], (source) => eval(source));
227+
assert.strictEqual(wire.scope, undefined);
228+
assert.deepEqual(wire.block[0], [[SexpOpcodes.Append,[SexpOpcodes.GetSymbol,0,["message"]]]])
229+
});
213230
});

packages/@glimmer/syntax/lib/v2/builders.ts

-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,6 @@ export class Builder {
208208
isTemplateLocal: boolean,
209209
loc: SourceSpan
210210
): ASTv2.VariableReference {
211-
assert(name !== 'this', `You called builders.var() with 'this'. Call builders.this instead`);
212211
assert(
213212
name[0] !== '@',
214213
`You called builders.var() with '${name}'. Call builders.at('${name}') instead`

packages/@glimmer/syntax/lib/v2/normalize.ts

+4
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,10 @@ class ExpressionNormalizer {
323323

324324
switch (head.type) {
325325
case 'ThisHead':
326+
if (block.hasBinding('this')) {
327+
let [symbol, isRoot] = table.get('this');
328+
return block.builder.localVar('this', symbol, isRoot, offsets);
329+
}
326330
return builder.self(offsets);
327331
case 'AtHead': {
328332
let symbol = table.allocateNamed(head.name);

0 commit comments

Comments
 (0)