Skip to content

Commit

Permalink
Merge pull request #1293 from glimmerjs/bugfix/nested-dynamic-helper-…
Browse files Browse the repository at this point in the history
…calls

Fix nested calls to helpers in dynamic helpers
  • Loading branch information
chancancode committed Apr 15, 2021
2 parents 83664b8 + b832ff2 commit a3091ee
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 7 deletions.
@@ -1,4 +1,11 @@
import { RenderTest, test, jitSuite, GlimmerishComponent, defineSimpleHelper } from '../..';
import {
RenderTest,
test,
jitSuite,
GlimmerishComponent,
defineSimpleHelper,
defineComponent,
} from '../..';

class DynamicHelpersResolutionModeTest extends RenderTest {
static suiteName = 'dynamic helpers in resolution mode';
Expand Down Expand Up @@ -35,6 +42,41 @@ class DynamicHelpersResolutionModeTest extends RenderTest {
/The `x\.foo` property path was used in the `.*` template without using `this`/
);
}

@test
'Can use a dynamic helper with nested helpers'() {
const foo = defineSimpleHelper(() => 'world!');
const bar = defineSimpleHelper((value: string) => 'Hello, ' + value);
const Bar = defineComponent(
{ foo },
'{{this.bar (foo)}}',
class extends GlimmerishComponent {
bar = bar;
}
);

this.renderComponent(Bar);
this.assertHTML('Hello, world!');
this.assertStableRerender();
}

@test
'Can use a dynamic helper with nested dynamic helpers'() {
const foo = defineSimpleHelper(() => 'world!');
const bar = defineSimpleHelper((value: string) => 'Hello, ' + value);
const Bar = defineComponent(
{},
'{{this.bar (this.foo)}}',
class extends GlimmerishComponent {
foo = foo;
bar = bar;
}
);

this.renderComponent(Bar);
this.assertHTML('Hello, world!');
this.assertStableRerender();
}
}

jitSuite(DynamicHelpersResolutionModeTest);
Expand Up @@ -5,6 +5,8 @@ import {
defineSimpleModifier,
syntaxErrorFor,
GlimmerishComponent,
defineSimpleHelper,
defineComponent,
} from '../..';

class DynamicModifiersResolutionModeTest extends RenderTest {
Expand Down Expand Up @@ -131,6 +133,45 @@ class DynamicModifiersResolutionModeTest extends RenderTest {
this.registerComponent('TemplateOnly', 'Bar', '<div {{x.foo}}></div>');
}, syntaxErrorFor('You attempted to invoke a path (`{{#x.foo}}`) as a modifier, but x was not in scope. Try adding `this` to the beginning of the path', '{{x.foo}}', 'an unknown module', 1, 5));
}

@test
'Can use a dynamic modifier with a nested helper'() {
const foo = defineSimpleHelper(() => 'Hello, world!');
const bar = defineSimpleModifier(
(element: Element, value: string) => (element.innerHTML = value)
);
const Bar = defineComponent(
{ foo },
'<div {{this.bar (foo)}}></div>',
class extends GlimmerishComponent {
bar = bar;
}
);

this.renderComponent(Bar);
this.assertHTML('<div>Hello, world!</div>');
this.assertStableRerender();
}

@test
'Can use a dynamic modifier with a nested dynamic helper'() {
const foo = defineSimpleHelper(() => 'Hello, world!');
const bar = defineSimpleModifier(
(element: Element, value: string) => (element.innerHTML = value)
);
const Bar = defineComponent(
{},
'<div {{this.bar (this.foo)}}></div>',
class extends GlimmerishComponent {
foo = foo;
bar = bar;
}
);

this.renderComponent(Bar);
this.assertHTML('<div>Hello, world!</div>');
this.assertStableRerender();
}
}

jitSuite(DynamicModifiersResolutionModeTest);
@@ -1,4 +1,4 @@
import { $v0 } from '@glimmer/vm';
import { $fp, $v0 } from '@glimmer/vm';
import {
Option,
Op,
Expand Down Expand Up @@ -79,13 +79,13 @@ export function CallDynamic(
named: WireFormat.Core.Hash,
append?: () => void
): void {
op(Op.Load, $v0);
op(MachineOp.PushFrame);
SimpleArgs(op, positional, named, false);
op(Op.DynamicHelper, $v0);
op(Op.Dup, $fp, 1);
op(Op.DynamicHelper);
if (append) {
op(Op.Fetch, $v0);
append?.();
append();
op(MachineOp.PopFrame);
} else {
op(MachineOp.PopFrame);
Expand Down
4 changes: 2 additions & 2 deletions packages/@glimmer/runtime/lib/compiled/opcodes/expressions.ts
Expand Up @@ -73,10 +73,10 @@ APPEND_OPCODES.add(Op.Curry, (vm, { op1: type, op2: _isStrict }) => {
);
});

APPEND_OPCODES.add(Op.DynamicHelper, (vm, { op1: _definitionRegister }) => {
APPEND_OPCODES.add(Op.DynamicHelper, (vm) => {
let stack = vm.stack;
let ref = check(stack.popJs(), CheckReference);
let args = check(stack.popJs(), CheckArguments).capture();
let ref = vm.fetchValue<Reference>(_definitionRegister);

let helperRef: Reference;
let initialOwner: Owner = vm.getOwner();
Expand Down

0 comments on commit a3091ee

Please sign in to comment.