Skip to content

RFC#998 - {{fn}} as keyword#21299

Merged
NullVoxPopuli merged 6 commits intoemberjs:mainfrom
NullVoxPopuli-ai-agent:nvp/fn-as-keyword
Apr 8, 2026
Merged

RFC#998 - {{fn}} as keyword#21299
NullVoxPopuli merged 6 commits intoemberjs:mainfrom
NullVoxPopuli-ai-agent:nvp/fn-as-keyword

Conversation

@NullVoxPopuli-ai-agent
Copy link
Copy Markdown
Contributor

Summary

  • Adds fn to the built-in keywords map so it no longer needs to be imported in strict-mode (gjs/gts) templates
  • Extends the auto-import-builtins AST plugin to handle SubExpression and MustacheStatement nodes for fn
  • Extracts a shared rewriteKeyword helper to reduce duplication with the existing on keyword logic
  • Adds integration tests (keyword works, runtime compiler, shadowing) and smoke tests mirroring the on PR (RFC#997 - {{on}} as keyword #21068)

Implements RFC 0998.

Test plan

  • All existing tests pass (9139 tests, 0 failures)
  • New fn-test.ts: fn works when explicitly in scope, works with runtime compiler, can be shadowed
  • New fn-runtime-test.ts: explicit scope, implicit scope (eval), no eval and no scope (static block)
  • New smoke tests: fn-as-keyword-test.gjs and fn-as-keyword-but-its-shadowed-test.gjs
  • Lints pass (prettier, docs, eslint on changed files)

🤖 Generated with Claude Code

Make the `fn` helper a built-in keyword so it no longer needs to be
explicitly imported in strict-mode templates (gjs/gts).

Building on the infrastructure from RFC#997 ({{on}}), this adds `fn`
to the keywords map and extends the auto-import-builtins AST plugin
to handle SubExpression and MustacheStatement nodes. The existing `on`
rewrite logic is extracted into a shared `rewriteKeyword` helper.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NullVoxPopuli and others added 3 commits April 7, 2026 10:15
Use regular functions instead of helper managers for the fn shadow
tests, since only scope shadowing is being verified.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The shadowed fn must return a function since its return value is
passed to the on modifier as the callback argument.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Same fix as the integration test — the shadowed fn must return a
function since its return value is passed to the on modifier.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NullVoxPopuli
NullVoxPopuli previously approved these changes Apr 7, 2026
Test fn in attribute position (e.g. <Child @callback={{fn greet "hello"}} />)
to cover the MustacheStatement visitor path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add empty scope to satisfy the ExplicitTemplateOnlyOptions overload
when neither eval nor component is provided.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@NullVoxPopuli NullVoxPopuli merged commit a6513b6 into emberjs:main Apr 8, 2026
37 of 38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants