This PR was merged into the 3.x branch.
Discussion
----------
Support short-circuiting in null-safe operator chains
This PR adds short-circuiting for null-safe operator chains, using the same rules as PHP, `PropertyAccess`, and the `ExpressionLanguage`.
Previously, only the immediate null-safe access was guarded. With this change, as soon as a `null` is encountered at a null-safe access, the rest of the chain is skipped.
My approach was to move the null check outside of the `getAttribute()` calls so the expression can immediately return `null`, eg:
```twig
foo?.bar.baz
```
Before:
```php
yield $this->env
->getRuntime('Twig\Runtime\EscaperRuntime')
->escape(
CoreExtension::getAttribute(
$this->env,
$this->source,
(
null === (
$_v0 = (
isset($context['foo']) || array_key_exists('foo', $context)
? $context['foo']
: throw new RuntimeError('Variable "foo" does not exist.', 3, $this->source)
)
)
? null
: CoreExtension::getAttribute(
$this->env,
$this->source,
$_v0,
'bar',
[],
'any',
false,
false,
false,
3
)
),
'baz',
[],
'any',
false,
false,
false,
3
),
'html',
null,
true
);
```
Now:
```php
yield $this->env
->getRuntime('Twig\Runtime\EscaperRuntime')
->escape(
(
null === (
$_v0 = (
isset($context['foo']) || array_key_exists('foo', $context)
? $context['foo']
: throw new RuntimeError('Variable "foo" does not exist.', 3, $this->source)
)
)
? null
: CoreExtension::getAttribute(
$this->env,
$this->source,
CoreExtension::getAttribute(
$this->env,
$this->source,
$_v0,
'bar',
[],
'any',
false,
false,
false,
3
),
'baz',
[],
'any',
false,
false,
false,
3
)
),
'html',
null,
true
);
```
Commits
-------
d56e8e2dba Support short-circuiting in null-safe operator chains