This PR was merged into the 3.x branch.
Discussion
----------
Compare the date formatter prototype pattern with the derived one once per pattern
Commits
-------
10fe9808bb Compare the date formatter prototype pattern with the derived one once per pattern
This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Fix split trailing newline
Commits
-------
00861d50ab Fix split trailing newline
This PR was merged into the 3.x branch.
Discussion
----------
Speed up adding extensions to an environment
`Environment::addExtension()` recomputes the options hash on every call, JSON-encoding the class names of all the extensions registered so far. This computes it only when a template class name is needed. With the 24 extensions TwigBundle registers on the Symfony Demo, building the environment drops from 87µs to 19µs, and calling `setExtensions()` once instead brings nothing more.
Merge-up to 4.x: the property is typed there, so it has to become `private ?string $optionsHash = null;` (I ran the 4.x suite with that change). The CHANGELOG entry doesn't go to 4.x.
Commits
-------
d3d13f9b1a Speed up adding extensions to an environment
This PR was merged into the 3.x branch.
Discussion
----------
Reuse the already resolved callable when compiling call arguments
Commits
-------
16be8af8f5 Reuse the already resolved callable when compiling call arguments
This PR was merged into the 3.x branch.
Discussion
----------
Compile the generator guard as an unreachable yield instead of a yield from
Commits
-------
4d5d233776 Compile the generator guard as an unreachable yield instead of a yield from
This PR was merged into the 3.x branch.
Discussion
----------
Speed up loading a template that the environment has already loaded
`Environment::load()` allocated a fresh `TemplateWrapper` on every call, even when the template was already loaded. Since `TemplateWrapper` is immutable, the same instance can be reused.
**Performance** (PHP 8.5, interleaved A/B, min of 5 runs):
| Workload | Before | After | |
|---|---:|---:|---:|
| Repeated `load()` of a loaded template | ~800 ns | ~610 ns | **−24%** |
| Page render: layout + 41 `include()` calls | 133 µs | 127 µs | **−5%** |
Commits
-------
6f94a47ce1 Reuse the template wrapper of an already loaded template
This PR was merged into the 3.x branch.
Discussion
----------
Stop the escaping safe analysis from retaining every analyzed node
Commits
-------
8274571d04 Stop the escaping safe analysis from retaining every analyzed node
This PR was merged into the 3.x branch.
Discussion
----------
Allow to call `TemplateWrapper::unwrap()` without arguments
Fixes#4935, symfony/symfony#66193.
#4910 changed an internal API that has famously been used by Symfony since almost forever. We would now need to change Symfony's 5.4 branch which is security-only. Because of that, I'd like to propose to allow calling `TemplateWrapper::unwrap()` without parameters again. This should allow running Symfony 5.4 with the latest Twig 3 again.
We can revert my change on the 4.x branch.
Commits
-------
bfbe89e3a3 Allow to call TemplateWrapper::unwrap() without arguments
This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Expose the escaping strategy a template was compiled with
Compiled templates now record the escaping strategy they were compiled with and expose it via `TemplateWrapper::getDefaultEscapeStrategy()`, so the strategy of a template can be known without deriving it again from its name, which is both slower and can disagree with how its content was actually escaped.
Commits
-------
26812ebc0d Expose the escaping strategy a template was compiled with
This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Improve macro call performance
This is mostly about getting back to the same performance we had in 3.28.
Commits
-------
a8ee6dd762 Improve macro call performance
This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Fix IntlExtension inheriting values derived by ICU from a date formatter prototype
Commits
-------
6671288259 Fix IntlExtension inheriting values derived by ICU from a date formatter prototype
This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Fix array access with a Stringable key on subclasses of ArrayObject and ArrayIterator
Commits
-------
4aae99e92c Fix array access with a Stringable key on subclasses of ArrayObject and ArrayIterator
This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Report a clear error when a string cannot be split into characters
Commits
-------
1ee9dae55a Cover and document the matches operator throwing on an invalid UTF-8 subject
5c1be030c5 Report a clear error when a string cannot be split into characters
This PR was merged into the 3.x branch.
Discussion
----------
Deprecate cloning a Twig environment
Commits
-------
55afb2e084 Deprecate cloning a Twig environment
This PR was merged into the 3.x branch.
Discussion
----------
Report the macro call parentheses deprecation once per call site and name the macro
Commits
-------
40d57c6445 Report the macro call parentheses deprecation once per call site and name the macro
This PR was squashed before being merged into the 3.x branch.
Discussion
----------
Reject template wrappers from another environment
Twig now rejects `TemplateWrapper` instances created by another `Environment`.
This prevents templates from unexpectedly using another environment's loader, extensions, globals, or sandbox policy.
Commits
-------
83e8f7e123 Reject cross-environment template wrappers in block chains
c1fc112047 Reject cross-environment template wrappers
This PR was merged into the 3.x branch.
Discussion
----------
Report a clear error when using macros imported in a template body that was not rendered
Commits
-------
72c2f669bd Report a clear error when using macros imported in a template body that was not rendered
This PR was merged into the 3.x branch.
Discussion
----------
Allow block chains to be composed of other block chains
This is something that is needed by Symfony (and other OSS projects), so better to have it directly in Twig.
Commits
-------
d6b81f9074 Allow block chains to be composed of other block chains
This PR was merged into the 3.x branch.
Discussion
----------
Resolve block chains against the render context
While working on the Symfony PR for #4917, I realize that the performance was worse with the Twig's way. #4924 fixes part of the performance "regression". This one closes the gap.
`BlockChain` currently freezes each template's lineage by cloning it, so the block map and `parent()` both resolve `{% extends %}` against the constructor context.
This PR changes that to resolve the chain against the render context instead. `hasBlock()` and `getBlockNames()` take a context, like `TemplateWrapper` already does, and the third constructor argument becomes a default the render context can override. A lineage whose templates all have a fixed parent (none, or constant) is resolved once and cached, so the common case costs nothing; a dynamic `{% extends %}` re-resolves per call (not use by Symfony anyway).
This fixes also an inconsistency: a chained template with a dynamic parent now behaves exactly as it does when rendered directly. It also removes all changes in the "core" logic of Template.
```
construct render 1 chain + 40 renders
Symfony's engine today 13.44us 0.78us 50.3us
#4917 ~70us 0.96us ~117us
this PR 0.61us 0.84us 53.0us
```
Commits
-------
897717d78f Resolve block chains against the render context instead of freezing lineages