Skip to content

Commit 5705f08

Browse files
committed
Fix compilation of complex path with hash argument
1 parent 7b0b412 commit 5705f08

3 files changed

Lines changed: 25 additions & 3 deletions

File tree

src/Compiler.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,11 @@ private function BlockStatement(BlockStatement $block): string
188188
return $this->compileInvertedSection($block, $var, $escapedName);
189189
}
190190

191-
// Non-simple path with params: invoke as a dynamic block helper call
192-
if ($block->params) {
191+
// Non-simple path with params or hash: invoke as a dynamic block helper call
192+
if ($block->params || $block->hash !== null) {
193+
if ($this->context->options->knownHelpersOnly) {
194+
$this->throwKnownHelpersOnly((string) $block->path->original);
195+
}
193196
return $this->compileDynamicBlockHelper($block, (string) $block->path->original, $var);
194197
}
195198

@@ -294,7 +297,7 @@ private function compileBlockHelper(BlockStatement $block, string $name): string
294297
$fnProgram = $block->program ?? $block->inverse;
295298
assert($fnProgram !== null);
296299

297-
// Inline if/unless as ternary — eliminates hbbch dispatch and HelperOptions allocation.
300+
// Inline if/unless as ternary — eliminates helper dispatch and HelperOptions allocation.
298301
// Safe because if/unless don't change scope, so $cx and $in are already correct.
299302
// Negate for 'unless' in a normal block, or 'if' in an inverted block (swapped semantics).
300303
if ($this->canInlineConditional($block, $name, $fnProgram->blockParams)) {

tests/ErrorTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,16 @@ public static function errorProvider(): array
256256
'options' => new Options(knownHelpers: ['if' => false], knownHelpersOnly: true),
257257
'expected' => 'You specified knownHelpersOnly, but used the unknown helper if',
258258
],
259+
'knownHelpersOnly rejects multi-segment path with hash' => [
260+
'template' => '{{#obj.fn prop=val}}BODY{{/obj.fn}}',
261+
'options' => new Options(knownHelpersOnly: true),
262+
'expected' => 'You specified knownHelpersOnly, but used the unknown helper obj.fn',
263+
],
264+
'knownHelpersOnly rejects depth path with hash' => [
265+
'template' => '{{#../flag prop=val}}BODY{{/../flag}}',
266+
'options' => new Options(knownHelpersOnly: true),
267+
'expected' => 'You specified knownHelpersOnly, but used the unknown helper ../flag',
268+
],
259269
'unknown decorator throws' => [
260270
'template' => '{{#*help me}}{{/help}}',
261271
'expected' => 'Unknown decorator: "help"',

tests/RegressionTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,15 @@ public static function sectionProvider(): array
19571957
],
19581958
'expected' => 'x:BODY',
19591959
],
1960+
'complex path with hash passes hash to closure via HelperOptions' => [
1961+
'template' => '{{#obj.fn prop="x"}}BODY{{/obj.fn}}',
1962+
'data' => [
1963+
'obj' => [
1964+
'fn' => fn(HelperOptions $options) => $options->hash['prop'] . ':' . $options->fn(),
1965+
],
1966+
],
1967+
'expected' => 'x:BODY',
1968+
],
19601969
'lambda at complex path in inverted block is called with no arguments' => [
19611970
'template' => '{{^obj.fn}}BODY{{/obj.fn}}',
19621971
'data' => [

0 commit comments

Comments
 (0)