Adding support for the ...spread operator on arrays and hashes

This commit is contained in:
Ryan Weaver
2023-05-05 06:54:25 -04:00
committed by Fabien Potencier
parent 3fd3645601
commit ba4fe3ba34
14 changed files with 253 additions and 62 deletions
+85 -36
View File
@@ -93,80 +93,108 @@ class ExpressionParserTest extends TestCase
return [
// simple array
['{{ [1, 2] }}', new ArrayExpression([
new ConstantExpression(0, 1),
new ConstantExpression(1, 1),
$this->createConstantExpression(0, false),
$this->createConstantExpression(1),
new ConstantExpression(1, 1),
new ConstantExpression(2, 1),
$this->createConstantExpression(1, false),
$this->createConstantExpression(2),
], 1),
],
// array with trailing ,
['{{ [1, 2, ] }}', new ArrayExpression([
new ConstantExpression(0, 1),
new ConstantExpression(1, 1),
$this->createConstantExpression(0, false),
$this->createConstantExpression(1),
new ConstantExpression(1, 1),
new ConstantExpression(2, 1),
$this->createConstantExpression(1, false),
$this->createConstantExpression(2),
], 1),
],
// simple hash
['{{ {"a": "b", "b": "c"} }}', new ArrayExpression([
new ConstantExpression('a', 1),
new ConstantExpression('b', 1),
$this->createConstantExpression('a', true),
$this->createConstantExpression('b'),
new ConstantExpression('b', 1),
new ConstantExpression('c', 1),
$this->createConstantExpression('b', true),
$this->createConstantExpression('c'),
], 1),
],
// hash with trailing ,
['{{ {"a": "b", "b": "c", } }}', new ArrayExpression([
new ConstantExpression('a', 1),
new ConstantExpression('b', 1),
$this->createConstantExpression('a', true),
$this->createConstantExpression('b'),
new ConstantExpression('b', 1),
new ConstantExpression('c', 1),
$this->createConstantExpression('b', true),
$this->createConstantExpression('c'),
], 1),
],
// hash in an array
['{{ [1, {"a": "b", "b": "c"}] }}', new ArrayExpression([
new ConstantExpression(0, 1),
new ConstantExpression(1, 1),
$this->createConstantExpression(0, false),
$this->createConstantExpression(1),
new ConstantExpression(1, 1),
new ArrayExpression([
new ConstantExpression('a', 1),
new ConstantExpression('b', 1),
$this->createConstantExpression(1, false),
new ArrayExpression([
$this->createConstantExpression('a', true),
$this->createConstantExpression('b'),
new ConstantExpression('b', 1),
new ConstantExpression('c', 1),
], 1),
$this->createConstantExpression('b', true),
$this->createConstantExpression('c'),
], 1),
], 1),
],
// array in a hash
['{{ {"a": [1, 2], "b": "c"} }}', new ArrayExpression([
new ConstantExpression('a', 1),
new ArrayExpression([
new ConstantExpression(0, 1),
new ConstantExpression(1, 1),
$this->createConstantExpression('a', true),
new ArrayExpression([
$this->createConstantExpression(0, false),
$this->createConstantExpression(1),
new ConstantExpression(1, 1),
new ConstantExpression(2, 1),
], 1),
new ConstantExpression('b', 1),
new ConstantExpression('c', 1),
$this->createConstantExpression(1, false),
$this->createConstantExpression(2),
], 1),
$this->createConstantExpression('b', true),
$this->createConstantExpression('c'),
], 1),
],
['{{ {a, b} }}', new ArrayExpression([
new ConstantExpression('a', 1),
$this->createConstantExpression('a', true),
new NameExpression('a', 1),
new ConstantExpression('b', 1),
$this->createConstantExpression('b', true),
new NameExpression('b', 1),
], 1)],
// array with spread operator
['{{ [1, 2, ...foo] }}',
new ArrayExpression([
$this->createConstantExpression(0, false),
$this->createConstantExpression(1),
$this->createConstantExpression(1, false),
$this->createConstantExpression(2),
$this->createConstantExpression(2, false),
$this->createNameExpression('foo', ['spread' => true]),
], 1)],
// hash with spread operator
['{{ {"a": "b", "b": "c", ...otherLetters} }}',
new ArrayExpression([
$this->createConstantExpression('a', true),
$this->createConstantExpression('b'),
$this->createConstantExpression('b', true),
$this->createConstantExpression('c'),
$this->createConstantExpression(0, false),
$this->createNameExpression('otherLetters', ['spread' => true]),
], 1)],
];
}
@@ -387,4 +415,25 @@ class ExpressionParserTest extends TestCase
$parser->parse($env->tokenize(new Source('{{ 1 is foobar }}', 'index')));
}
private function createNameExpression(string $name, array $attributes)
{
$expression = new NameExpression($name, 1);
foreach ($attributes as $key => $value) {
$expression->setAttribute($key, $value);
}
return $expression;
}
private function createConstantExpression($value, ?bool $indexSpecified = null)
{
$constant = new ConstantExpression($value, 1);
if (null !== $indexSpecified) {
$constant->setAttribute('index_specified', $indexSpecified);
}
return $constant;
}
}