Skip to content

Commit

Permalink
Lexical "this" capture
Browse files Browse the repository at this point in the history
  • Loading branch information
ef4 committed Jan 10, 2025
1 parent c7f8e59 commit 1dc9739
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -210,4 +210,21 @@ module('[glimmer-compiler] precompile', ({ test }) => {
let elementName = openElementExpr[1];
assert.strictEqual(elementName, 'rental', 'element name is correct');
});

test('when "this" in in locals, it compiles to GetLexicalSymbol', (assert) => {
let target = { message: 'hello' };
let _wire: ReturnType<typeof compile>;
(function() {
_wire = compile(`{{this.message}}`, ['this'], (source) => eval(source));
}).call(target)
let wire = _wire!;
assert.deepEqual(wire.scope?.(), [target]);
assert.deepEqual(wire.block[0], [[SexpOpcodes.Append,[SexpOpcodes.GetLexicalSymbol,0,["message"]]]])
});

test('when "this" is not in locals, it compiles to GetSymbol', (assert) => {
let wire = compile(`{{this.message}}`, [], (source) => eval(source));
assert.strictEqual(wire.scope, undefined);
assert.deepEqual(wire.block[0], [[SexpOpcodes.Append,[SexpOpcodes.GetSymbol,0,["message"]]]])
});
});
1 change: 0 additions & 1 deletion packages/@glimmer/syntax/lib/v2/builders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ export class Builder {
isTemplateLocal: boolean,
loc: SourceSpan
): ASTv2.VariableReference {
assert(name !== 'this', `You called builders.var() with 'this'. Call builders.this instead`);
assert(
name[0] !== '@',
`You called builders.var() with '${name}'. Call builders.at('${name}') instead`
Expand Down
4 changes: 4 additions & 0 deletions packages/@glimmer/syntax/lib/v2/normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ class ExpressionNormalizer {

switch (head.type) {
case 'ThisHead':
if (block.hasBinding('this')) {
let [symbol, isRoot] = table.get('this');
return block.builder.localVar('this', symbol, isRoot, offsets);
}
return builder.self(offsets);
case 'AtHead': {
let symbol = table.allocateNamed(head.name);
Expand Down

0 comments on commit 1dc9739

Please sign in to comment.