Skip to content

Make the low-level component scope able to be an object instead of an array#21224

Merged
NullVoxPopuli merged 10 commits intoemberjs:mainfrom
NullVoxPopuli-ai-agent:nvp/named-invocations
Mar 20, 2026
Merged

Make the low-level component scope able to be an object instead of an array#21224
NullVoxPopuli merged 10 commits intoemberjs:mainfrom
NullVoxPopuli-ai-agent:nvp/named-invocations

Conversation

@NullVoxPopuli-ai-agent
Copy link
Copy Markdown
Contributor

@NullVoxPopuli-ai-agent NullVoxPopuli-ai-agent commented Mar 17, 2026

Supersedes

good luck lil'bot

description from over there:


This was really bothering me when I was trying to debug my typedoc renderer

I need to build this ember and test it in that project before starting review.

As part of debugging this, I think I need a button on the inspector to just show the debugRenderTree node

Before

image

note for me http://localhost:4201/Runtime/util/page-nav

the failing test result in the first commit:

not ok 13 Chrome 145.0 - [9 ms] - [integration] jit :: Application test: debug render tree: strict-mode components without debug symbols preserve names from scope
    ---
        actual: >
            (unknown template-only component)
        expected: >
            HelloWorld
        stack: >

there is also a failing smoke test so we can e2e the whole setup:

test('scope-based components have correct names in debugRenderTree', async function (assert) {
  await render(<template><HelloWorld @arg="first" /></template>);

  let tree = captureRenderTree(this.owner);
  let names = tree.filter(n => n.type === 'component').map(n => n.name);
  assert.true(
    names.includes('HelloWorld'), 
    'HelloWorld component name is preserved in the render tree (found: ' + names.join(', ') + ')'
  );
});

this also fails


not ok 2 Chrome 145.0 - [47 ms] - Integration | captureRenderTree: scope-based components have correct names in debugRenderTree
    ---
        actual: >
            false
        expected: >
            true
        stack: >
                at Object.<anonymous> (http://localhost:7357/assets/tests-DjOElQH7.js:10419:16)
        message: >
            HelloWorld component name is preserved in the render tree (found: )

image

After

image

from my actual app with recursive type/typedoc rendering:

image

NullVoxPopuli and others added 4 commits March 17, 2026 16:38
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The captureRenderTree API returns a nested tree structure. Component
nodes are children of other nodes, so we need to recursively flatten
the tree before searching for component names.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@NullVoxPopuli NullVoxPopuli changed the title Failing test for better debugRenderTree names Make component scope able to be an object instead of an array Mar 17, 2026
@NullVoxPopuli NullVoxPopuli changed the title Make component scope able to be an object instead of an array Make the low-level component scope able to be an object instead of an array Mar 17, 2026
@NullVoxPopuli NullVoxPopuli marked this pull request as ready for review March 17, 2026 23:09
@NullVoxPopuli

This comment was marked as resolved.

NullVoxPopuli and others added 3 commits March 18, 2026 10:42
Add tests for:
- <this.dynamicComponent> invocations
- <@argComponent> invocations

Both currently produce '(unknown template-only component)' instead of
the expected component name because dynamic resolution at runtime
loses the invocation-site name information.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…RenderTree

For dynamic component invocations like `<this.Foo>` and `<@Greeting>`,
the debug render tree now shows the invocation-site name instead of
'(unknown template-only component)'.

This works by extracting the Reference's debugLabel in
VM_RESOLVE_DYNAMIC_COMPONENT_OP and VM_RESOLVE_CURRIED_COMPONENT_OP,
and setting it as the ComponentDefinition's debugName when no name
is already present.

- `<this.Foo>` → name: "Foo"
- `<@Greeting>` → name: "Greeting"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ames

Use the full debugLabel as the component name so users see exactly
how the component was invoked:

- `<this.Foo>` → name: "this.Foo"
- `<@Greeting>` → name: "@Greeting"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NullVoxPopuli and others added 2 commits March 18, 2026 11:38
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The invocation-site name propagation relies on ref.debugLabel which
is only available in DEBUG mode. Skip these tests in production builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@NullVoxPopuli
Copy link
Copy Markdown
Contributor

I'm actually surprised how small of a change this is to the vm code

@NullVoxPopuli NullVoxPopuli requested a review from ef4 March 19, 2026 14:37
@NullVoxPopuli NullVoxPopuli merged commit 2a5515d into emberjs:main Mar 20, 2026
35 checks passed
NullVoxPopuli-ai-agent pushed a commit to NullVoxPopuli-ai-agent/ember.js that referenced this pull request Mar 23, 2026
Now that the scope bag is a `Record<string, unknown>`, the lexical symbol
names are always carried alongside their values. This eliminates the need
for the `lexicalSymbols` slot in the wire format block (previously only
available when `debugSymbols` was enabled) and allows `meta()` to derive
`lexical` names and `scopeValues` directly from the scope object's keys
and values.

See also: upstream PR emberjs#21224, PR emberjs#21068.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NullVoxPopuli-ai-agent pushed a commit to NullVoxPopuli-ai-agent/ember.js that referenced this pull request Mar 23, 2026
Now that the scope bag is a `Record<string, unknown>`, the lexical symbol
names are always carried alongside their values. This eliminates the need
for the `lexicalSymbols` slot in the wire format block (previously only
available when `debugSymbols` was enabled) and allows `meta()` to derive
`lexical` names and `scopeValues` directly from the scope object's keys
and values.

See also: upstream PR emberjs#21224, PR emberjs#21068.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NullVoxPopuli-ai-agent pushed a commit to NullVoxPopuli-ai-agent/ember.js that referenced this pull request Mar 23, 2026
Now that the scope bag is a `Record<string, unknown>`, the lexical symbol
names are always carried alongside their values. This eliminates the need
for the `lexicalSymbols` slot in the wire format block (previously only
available when `debugSymbols` was enabled) and allows `meta()` to derive
`lexical` names and `scopeValues` directly from the scope object's keys
and values.

See also: upstream PR emberjs#21224, PR emberjs#21068.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
NullVoxPopuli-ai-agent pushed a commit to NullVoxPopuli-ai-agent/ember.js that referenced this pull request Mar 23, 2026
Now that the scope bag is a `Record<string, unknown>`, the lexical symbol
names are always carried alongside their values. This eliminates the need
for the `lexicalSymbols` slot in the wire format block (previously only
available when `debugSymbols` was enabled) and allows `meta()` to derive
`lexical` names and `scopeValues` directly from the scope object's keys
and values.

See also: upstream PR emberjs#21224, PR emberjs#21068.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

4 participants