Skip to content

Commit 5645d7b

Browse files
committed
operator 'in' supports strings
- InRangeNode renamed to InNode
1 parent f9ae68d commit 5645d7b

File tree

7 files changed

+51
-14
lines changed

7 files changed

+51
-14
lines changed

src/Latte/Compiler/Nodes/Php/Expression/InRangeNode.php src/Latte/Compiler/Nodes/Php/Expression/InNode.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Latte\Compiler\PrintContext;
1515

1616

17-
class InRangeNode extends ExpressionNode
17+
class InNode extends ExpressionNode
1818
{
1919
public function __construct(
2020
public ExpressionNode $needle,
@@ -26,11 +26,11 @@ public function __construct(
2626

2727
public function print(PrintContext $context): string
2828
{
29-
return 'in_array('
29+
return 'LR\Filters::contains('
3030
. $this->needle->print($context)
3131
. ', '
3232
. $this->haystack->print($context)
33-
. ', true)';
33+
. ')';
3434
}
3535

3636

src/Latte/Compiler/TagParserData.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ protected function reduce(int $rule, int $pos): void
482482
124 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '<<', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position),
483483
125 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '>>', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position),
484484
126 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '**', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position),
485-
127 => fn() => $this->semValue = new Expression\InRangeNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position),
485+
127 => fn() => $this->semValue = new Expression\InNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position),
486486
128 => fn() => $this->semValue = new Expression\UnaryOpNode($this->semStack[$pos], '+', $this->startTokenStack[$pos - 1]->position),
487487
129 => fn() => $this->semValue = new Expression\UnaryOpNode($this->semStack[$pos], '-', $this->startTokenStack[$pos - 1]->position),
488488
130, 131 => fn() => $this->semValue = new Expression\NotNode($this->semStack[$pos], $this->startTokenStack[$pos - 1]->position),

src/Latte/Runtime/Filters.php

+11
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,17 @@ public static function escapeHtmlRawText($s): string
174174
}
175175

176176

177+
/**
178+
* Determine if a string or array contains a given needle.
179+
*/
180+
public static function contains(mixed $needle, array|string $haystack): bool
181+
{
182+
return is_array($haystack)
183+
? in_array($needle, $haystack, true)
184+
: str_contains($haystack, (string) $needle);
185+
}
186+
187+
177188
/**
178189
* Converts ... to ...
179190
*/

tests/common/TagParser.parseArguments().phpt

+4-4
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@ test('inline modifiers', function () {
9494

9595

9696
test('in operator', function () {
97-
Assert::same("in_array(\$a, ['a', 'b'], true), 1", formatArgs('$a in [a, b], 1'));
98-
Assert::same('$a, in_array($b->func(), [1, 2], true)', formatArgs('$a, $b->func() in [1, 2]'));
99-
Assert::same('$a, in_array($b[1], [1, 2], true)', formatArgs('$a, $b[1] in [1, 2]'));
100-
Assert::same('in_array($b, [1, [2], 3], true)', formatArgs('$b in [1, [2], 3]'));
97+
Assert::same("LR\\Filters::contains(\$a, ['a', 'b']), 1", formatArgs('$a in [a, b], 1'));
98+
Assert::same('$a, LR\Filters::contains($b->func(), [1, 2])', formatArgs('$a, $b->func() in [1, 2]'));
99+
Assert::same('$a, LR\Filters::contains($b[1], [1, 2])', formatArgs('$a, $b[1] in [1, 2]'));
100+
Assert::same('LR\Filters::contains($b, [1, [2], 3])', formatArgs('$b in [1, [2], 3]'));
101101
});
102102

103103

tests/filters/contains.phpt

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/**
4+
* Test: Latte\Runtime\Filters::contains
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
use Latte\Runtime\Filters;
10+
use Tester\Assert;
11+
12+
require __DIR__ . '/../bootstrap.php';
13+
14+
15+
Assert::false(Filters::contains(null, []));
16+
Assert::true(Filters::contains(null, [null]));
17+
Assert::false(Filters::contains(1, ['1']));
18+
Assert::true(Filters::contains(1, [1]));
19+
20+
Assert::true(Filters::contains('', ''));
21+
Assert::true(Filters::contains('', 'abcd'));
22+
Assert::false(Filters::contains('bc', ''));
23+
Assert::true(Filters::contains('bc', 'abcd'));
24+
Assert::true(Filters::contains(null, ''));
25+
Assert::true(Filters::contains(1, '123'));
26+
Assert::false(Filters::contains(1, '23'));

tests/phpParser/in.phpt

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ __halt_compiler();
2727
Latte\Compiler\Nodes\Php\Expression\ArrayNode
2828
items: array (3)
2929
| 0 => Latte\Compiler\Nodes\Php\Expression\ArrayItemNode
30-
| | value: Latte\Compiler\Nodes\Php\Expression\InRangeNode
30+
| | value: Latte\Compiler\Nodes\Php\Expression\InNode
3131
| | | needle: Latte\Compiler\Nodes\Php\Expression\VariableNode
3232
| | | | name: 'a'
3333
| | | | position: 1:1 (offset 0)
@@ -41,7 +41,7 @@ Latte\Compiler\Nodes\Php\Expression\ArrayNode
4141
| | position: 1:1 (offset 0)
4242
| 1 => Latte\Compiler\Nodes\Php\Expression\ArrayItemNode
4343
| | value: Latte\Compiler\Nodes\Php\Expression\BinaryOpNode
44-
| | | left: Latte\Compiler\Nodes\Php\Expression\InRangeNode
44+
| | | left: Latte\Compiler\Nodes\Php\Expression\InNode
4545
| | | | needle: Latte\Compiler\Nodes\Php\Expression\VariableNode
4646
| | | | | name: 'a'
4747
| | | | | position: 4:1 (offset 28)
@@ -50,7 +50,7 @@ Latte\Compiler\Nodes\Php\Expression\ArrayNode
5050
| | | | | position: 4:7 (offset 34)
5151
| | | | position: 4:1 (offset 28)
5252
| | | operator: '||'
53-
| | | right: Latte\Compiler\Nodes\Php\Expression\InRangeNode
53+
| | | right: Latte\Compiler\Nodes\Php\Expression\InNode
5454
| | | | needle: Latte\Compiler\Nodes\Php\Expression\VariableNode
5555
| | | | | name: 'c'
5656
| | | | | position: 4:13 (offset 40)
@@ -69,7 +69,7 @@ Latte\Compiler\Nodes\Php\Expression\ArrayNode
6969
| | | | name: 'a'
7070
| | | | position: 5:1 (offset 50)
7171
| | | expr: Latte\Compiler\Nodes\Php\Expression\NotNode
72-
| | | | expr: Latte\Compiler\Nodes\Php\Expression\InRangeNode
72+
| | | | expr: Latte\Compiler\Nodes\Php\Expression\InNode
7373
| | | | | needle: Latte\Compiler\Nodes\Php\Expression\BinaryOpNode
7474
| | | | | | left: Latte\Compiler\Nodes\Php\Scalar\IntegerNode
7575
| | | | | | | value: 10

tests/phpPrint/operators.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ $a xor $b,
154154
$a or $b,
155155
$a instanceof Foo,
156156
$a instanceof $b,
157-
in_array($a, $b, true),
158-
in_array(!$a, $b, true) && !in_array($a + 2, $b, true),
157+
LR\Filters::contains($a, $b),
158+
LR\Filters::contains(!$a, $b) && !LR\Filters::contains($a + 2, $b),
159159
!$a,
160160
!($a > $b) && !($c == !$d)

0 commit comments

Comments
 (0)