Skip to content

Commit 47c1926

Browse files
committed
Added optional chaining for $var->elem?[1]
1 parent ed60fef commit 47c1926

File tree

4 files changed

+16
-4
lines changed

4 files changed

+16
-4
lines changed

src/Latte/Compiler/PhpWriter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,14 +295,14 @@ public function optionalChainingPass(MacroTokens $tokens): MacroTokens
295295

296296
do {
297297
if ($tokens->nextToken('?')) {
298-
if ($tokens->isNext() && (!$tokens->isNext($tokens::T_CHAR) || $tokens->isNext('(', '[', '{', ':', '!', '@'))) { // is it ternary operator?
298+
if ($tokens->isNext() && (!$tokens->isNext($tokens::T_CHAR) || $tokens->isNext('(', '{', ':', '!', '@'))) { // is it ternary operator?
299299
$expr->append($addBraces . ' ?');
300300
break;
301301
}
302302

303303
$rescue = [$res->tokens, $expr->tokens, $tokens->position, $addBraces];
304304

305-
if (!$tokens->isNext('->')) {
305+
if (!$tokens->isNext('->', '[')) {
306306
$expr->prepend('(');
307307
$expr->append(' ?? null)' . $addBraces);
308308
break;

tests/Latte/PhpWriter.formatArgs().phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ test(function () { // optionalChainingPass
137137
Assert::same('$a', formatArgs('$a'));
138138
Assert::same('($a ?? null)', formatArgs('$a?'));
139139
Assert::same('(($a ?? null))', formatArgs('($a?)'));
140+
Assert::same('(($_tmp = $foo ?? null) === null ? null : $_tmp[1])', formatArgs('$foo?[1]'));
140141
Assert::same('$var->prop->elem[1]->call(2)->item', formatArgs('$var->prop->elem[1]->call(2)->item'));
141142
Assert::same('(($_tmp = $var ?? null) === null ? null : (($_tmp = $_tmp->prop ?? null) === null ? null : (($_tmp = $_tmp->elem[1] ?? null) === null ? null : (($_tmp = $_tmp->call(2) ?? null) === null ? null : ($_tmp->item ?? null)))))', formatArgs('$var?->prop?->elem[1]?->call(2)?->item?'));
142143
});

tests/Latte/PhpWriter.formatModifiers().phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ test(function () { // depth
7070
test(function () { // optionalChainingPass
7171
Assert::same('($this->filters->mod)(@, ($a ?? null))', formatModifiers('@', 'mod:$a?'));
7272
Assert::same('($this->filters->mod)(@, (($a ?? null)))', formatModifiers('@', 'mod:($a?)'));
73+
Assert::same('($this->filters->mod)(@, (($_tmp = $foo ?? null) === null ? null : $_tmp[1]))', formatModifiers('@', 'mod:$foo?[1]'));
7374
Assert::same('($this->filters->mod)(@, (($_tmp = $var ?? null) === null ? null : (($_tmp = $_tmp->prop ?? null) === null ? null : (($_tmp = $_tmp->elem[1] ?? null) === null ? null : (($_tmp = $_tmp->call(2) ?? null) === null ? null : ($_tmp->item ?? null))))))', formatModifiers('@', 'mod:$var?->prop?->elem[1]?->call(2)?->item?'));
7475
});
7576

tests/Latte/PhpWriter.optionalChainingPass().phpt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,15 @@ test(function () {
2222
Assert::same('($a ?? null)', optionalChaining('$a?'));
2323
Assert::same('(($a ?? null))', optionalChaining('($a?)'));
2424
Assert::same('a?', optionalChaining('a?'));
25+
Assert::same('(($_tmp = $foo ?? null) === null ? null : $_tmp[1])', optionalChaining('$foo?[1]'));
2526
Assert::same('($foo[1] ?? null)', optionalChaining('$foo[1]?'));
27+
Assert::same('(($_tmp = $foo ?? null) === null ? null : ($_tmp[1] ?? null))', optionalChaining('$foo?[1]?'));
28+
Assert::same('(($_tmp = $foo ?? null) === null ? null : ($_tmp[1] ?? null)) + 10', optionalChaining('$foo?[1]? + 10'));
2629
Assert::same('(($foo[1] ?? null))', optionalChaining('($foo[1]?)'));
30+
Assert::same('((($_tmp = $foo ?? null) === null ? null : $_tmp[1]))', optionalChaining('($foo?[1])'));
31+
Assert::same('[(($_tmp = $foo ?? null) === null ? null : ($_tmp[1] ?? null))]', optionalChaining('[$foo?[1]?]'));
32+
Assert::same('(($_tmp = $foo ?? null) === null ? null : ($_tmp[ ($a ?? null) ] ?? null))', optionalChaining('$foo?[ $a? ]?'));
33+
Assert::same('(($_tmp = $foo ?? null) === null ? null : ($_tmp[ (($_tmp = $a ?? null) === null ? null : ($_tmp[2] ?? null)) ] ?? null))', optionalChaining('$foo?[ $a?[2]? ]?'));
2734

2835
Assert::same('(($_tmp = $foo ?? null) === null ? null : $_tmp->prop)', optionalChaining('$foo?->prop'));
2936
Assert::same('($foo->prop ?? null)', optionalChaining('$foo->prop?'));
@@ -50,17 +57,20 @@ test(function () {
5057
Assert::same('$var->prop->elem[1]->call(2)->item', optionalChaining('$var->prop->elem[1]->call(2)->item'));
5158
Assert::same('(($_tmp = $var ?? null) === null ? null : $_tmp->prop->elem[1]->call(2)->item)', optionalChaining('$var?->prop->elem[1]->call(2)->item'));
5259
Assert::same('(($_tmp = $var->prop ?? null) === null ? null : $_tmp->elem[1]->call(2)->item)', optionalChaining('$var->prop?->elem[1]->call(2)->item'));
60+
Assert::same('(($_tmp = $var->prop->elem ?? null) === null ? null : $_tmp[1]->call(2)->item)', optionalChaining('$var->prop->elem?[1]->call(2)->item'));
5361
Assert::same('(($_tmp = $var->prop->elem[1] ?? null) === null ? null : $_tmp->call(2)->item)', optionalChaining('$var->prop->elem[1]?->call(2)->item'));
5462
Assert::same('(($_tmp = $var->prop->elem[1]->call(2) ?? null) === null ? null : $_tmp->item)', optionalChaining('$var->prop->elem[1]->call(2)?->item'));
5563
Assert::same('($var->prop->elem[1]->call(2)->item ?? null)', optionalChaining('$var->prop->elem[1]->call(2)->item?'));
64+
Assert::same(
65+
'(($_tmp = $var ?? null) === null ? null : (($_tmp = $_tmp->prop ?? null) === null ? null : (($_tmp = $_tmp->elem ?? null) === null ? null : (($_tmp = $_tmp[1] ?? null) === null ? null : (($_tmp = $_tmp->call(2) ?? null) === null ? null : ($_tmp->item ?? null))))))',
66+
optionalChaining('$var?->prop?->elem?[1]?->call(2)?->item?')
67+
);
5668
});
5769

5870

5971
test(function () { // not allowed
6072
Assert::same('$foo ?(hello)', optionalChaining('$foo?(hello)'));
6173
Assert::same('$foo->foo ?(hello)', optionalChaining('$foo->foo?(hello)'));
62-
63-
Assert::same('$foo ?[1]', optionalChaining('$foo?[1]')); // not allowed due to collision with short ternary
6474
});
6575

6676

0 commit comments

Comments
 (0)