Skip to content

Commit 8460cc9

Browse files
committed
bug symfony#61076 [ExpressionLanguage] Fix dumping of null safe operator (ivantsepp)
This PR was merged into the 6.4 branch. Discussion ---------- [ExpressionLanguage] Fix dumping of null safe operator | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | n/a | License | MIT I noticed that when you dump an expression that uses null safe operator, the returned string doesn't maintain the null safe operator. ```php > (new ExpressionLanguage())->parse('user?.foo', ['user'])->getNodes()->dump() = "user.foo" ``` I would have expected `user?.foo` to be returned instead. (I've also fixed some test data providers cases - `getDumpData` provider should only generate cases with 2 elements but some tests are including a third argument. So I went ahead and removed them) Commits ------- 7cafcd2 [ExpressionLanguage] Fix dumping of null safe operator
2 parents d524bc9 + 7cafcd2 commit 8460cc9

File tree

4 files changed

+12
-8
lines changed

4 files changed

+12
-8
lines changed

src/Symfony/Component/ExpressionLanguage/Node/GetAttrNode.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,13 @@ private function isShortCircuited(): bool
141141

142142
public function toArray(): array
143143
{
144+
$nullSafe = $this->nodes['attribute'] instanceof ConstantNode && $this->nodes['attribute']->isNullSafe;
144145
switch ($this->attributes['type']) {
145146
case self::PROPERTY_CALL:
146-
return [$this->nodes['node'], '.', $this->nodes['attribute']];
147+
return [$this->nodes['node'], $nullSafe ? '?.' : '.', $this->nodes['attribute']];
147148

148149
case self::METHOD_CALL:
149-
return [$this->nodes['node'], '.', $this->nodes['attribute'], '(', $this->nodes['arguments'], ')'];
150+
return [$this->nodes['node'], $nullSafe ? '?.' : '.', $this->nodes['attribute'], '(', $this->nodes['arguments'], ')'];
150151

151152
case self::ARRAY_CALL:
152153
return [$this->nodes['node'], '[', $this->nodes['attribute'], ']'];

src/Symfony/Component/ExpressionLanguage/Tests/ExpressionLanguageTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,9 @@ public function testNullSafeCompileFails($expression, $foo)
383383

384384
public static function provideInvalidNullSafe()
385385
{
386-
yield ['foo?.bar.baz', (object) ['bar' => null], 'Unable to get property "baz" of non-object "foo.bar".'];
387-
yield ['foo?.bar["baz"]', (object) ['bar' => null], 'Unable to get an item of non-array "foo.bar".'];
388-
yield ['foo?.bar["baz"].qux.quux', (object) ['bar' => ['baz' => null]], 'Unable to get property "qux" of non-object "foo.bar["baz"]".'];
386+
yield ['foo?.bar.baz', (object) ['bar' => null], 'Unable to get property "baz" of non-object "foo?.bar".'];
387+
yield ['foo?.bar["baz"]', (object) ['bar' => null], 'Unable to get an item of non-array "foo?.bar".'];
388+
yield ['foo?.bar["baz"].qux.quux', (object) ['bar' => ['baz' => null]], 'Unable to get property "qux" of non-object "foo?.bar["baz"]".'];
389389
}
390390

391391
/**

src/Symfony/Component/ExpressionLanguage/Tests/Node/FunctionNodeTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public static function getCompileData(): array
3434
public static function getDumpData(): array
3535
{
3636
return [
37-
['foo("bar")', new FunctionNode('foo', new Node([new ConstantNode('bar')])), ['foo' => static::getCallables()]],
37+
['foo("bar")', new FunctionNode('foo', new Node([new ConstantNode('bar')]))],
3838
];
3939
}
4040

src/Symfony/Component/ExpressionLanguage/Tests/Node/GetAttrNodeTest.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
1616
use Symfony\Component\ExpressionLanguage\Node\GetAttrNode;
1717
use Symfony\Component\ExpressionLanguage\Node\NameNode;
18+
use Symfony\Component\ExpressionLanguage\Node\ArgumentsNode;
1819

1920
class GetAttrNodeTest extends AbstractNodeTestCase
2021
{
@@ -50,10 +51,12 @@ public static function getDumpData(): array
5051
['foo[0]', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), self::getArrayNode(), GetAttrNode::ARRAY_CALL)],
5152
['foo["b"]', new GetAttrNode(new NameNode('foo'), new ConstantNode('b'), self::getArrayNode(), GetAttrNode::ARRAY_CALL)],
5253

53-
['foo.foo', new GetAttrNode(new NameNode('foo'), new NameNode('foo'), self::getArrayNode(), GetAttrNode::PROPERTY_CALL), ['foo' => new Obj()]],
54+
['foo.foo', new GetAttrNode(new NameNode('foo'), new NameNode('foo'), self::getArrayNode(), GetAttrNode::PROPERTY_CALL)],
5455

55-
['foo.foo({"b": "a", 0: "b"})', new GetAttrNode(new NameNode('foo'), new NameNode('foo'), self::getArrayNode(), GetAttrNode::METHOD_CALL), ['foo' => new Obj()]],
56+
['foo.foo({"b": "a", 0: "b"})', new GetAttrNode(new NameNode('foo'), new NameNode('foo'), self::getArrayNode(), GetAttrNode::METHOD_CALL)],
5657
['foo[index]', new GetAttrNode(new NameNode('foo'), new NameNode('index'), self::getArrayNode(), GetAttrNode::ARRAY_CALL)],
58+
59+
['foo?.foo()', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo', true, true), new ArgumentsNode(), GetAttrNode::METHOD_CALL)],
5760
];
5861
}
5962

0 commit comments

Comments
 (0)