From 8b432758f61f2c65dd3035704986487fbed92a5f Mon Sep 17 00:00:00 2001
From: Lorenz <lorenzschaef@gmail.com>
Date: Thu, 26 Dec 2024 20:11:14 +0100
Subject: [PATCH 1/9] invoke filter

---
 src/Extension/CoreExtension.php    | 15 +++++++++++++++
 tests/Fixtures/filters/invoke.test | 14 ++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 tests/Fixtures/filters/invoke.test

diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php
index 01e7285669..5b900877b6 100644
--- a/src/Extension/CoreExtension.php
+++ b/src/Extension/CoreExtension.php
@@ -266,6 +266,7 @@ public function getFilters(): array
             // iteration and runtime
             new TwigFilter('default', [self::class, 'default'], ['node_class' => DefaultFilter::class]),
             new TwigFilter('keys', [self::class, 'keys']),
+            new TwigFilter('invoke', [self::class, 'invoke']),
         ];
     }
 
@@ -915,6 +916,20 @@ public static function keys($array): array
         return array_keys($array);
     }
 
+    /**
+     * Invokes a callable
+     *
+     * @param callable $callable
+     * @param ...$arguments
+     * @return mixed
+     *
+     * @internal
+     */
+    public static function invoke(callable $callable, ...$arguments): mixed
+    {
+        return $callable(...$arguments);
+    }
+
     /**
      * Reverses a variable.
      *
diff --git a/tests/Fixtures/filters/invoke.test b/tests/Fixtures/filters/invoke.test
new file mode 100644
index 0000000000..b4a707b97a
--- /dev/null
+++ b/tests/Fixtures/filters/invoke.test
@@ -0,0 +1,14 @@
+--TEST--
+"invoke" filter
+--TEMPLATE--
+{% set func = x => 'Hello '~x %}
+{{ func|invoke('World') }}
+{% set func2 = (x, y) => x+y %}
+{{ func2|invoke(3, 2) }}
+--DATA--
+return []
+--CONFIG--
+return []
+--EXPECT--
+Hello World
+5

From f27115857d7b4a674ba0dc26536c1fc992811555 Mon Sep 17 00:00:00 2001
From: Lorenz <lorenzschaef@gmail.com>
Date: Mon, 30 Dec 2024 09:59:23 +0100
Subject: [PATCH 2/9] checkArrow, typehints

---
 src/Extension/CoreExtension.php | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php
index 5b900877b6..82db0ec3a5 100644
--- a/src/Extension/CoreExtension.php
+++ b/src/Extension/CoreExtension.php
@@ -266,7 +266,7 @@ public function getFilters(): array
             // iteration and runtime
             new TwigFilter('default', [self::class, 'default'], ['node_class' => DefaultFilter::class]),
             new TwigFilter('keys', [self::class, 'keys']),
-            new TwigFilter('invoke', [self::class, 'invoke']),
+            new TwigFilter('invoke', [self::class, 'invoke'], ['needs_environment' => true]),
         ];
     }
 
@@ -919,15 +919,15 @@ public static function keys($array): array
     /**
      * Invokes a callable
      *
-     * @param callable $callable
-     * @param ...$arguments
-     * @return mixed
+     * @param \Closure $arrow
      *
      * @internal
      */
-    public static function invoke(callable $callable, ...$arguments): mixed
+    public static function invoke(Environment $env, $arrow, ...$arguments): mixed
     {
-        return $callable(...$arguments);
+        self::checkArrow($env, $arrow, 'invoke', 'filter');
+
+        return $arrow(...$arguments);
     }
 
     /**

From edecc13f0829e9fb2f787dd04f31ef4ffa87cbba Mon Sep 17 00:00:00 2001
From: Lorenz <lorenzschaef@gmail.com>
Date: Tue, 7 Jan 2025 18:33:17 +0100
Subject: [PATCH 3/9] typehint instead of checkArrow

---
 src/Extension/CoreExtension.php | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php
index 82db0ec3a5..e9976c1390 100644
--- a/src/Extension/CoreExtension.php
+++ b/src/Extension/CoreExtension.php
@@ -266,7 +266,7 @@ public function getFilters(): array
             // iteration and runtime
             new TwigFilter('default', [self::class, 'default'], ['node_class' => DefaultFilter::class]),
             new TwigFilter('keys', [self::class, 'keys']),
-            new TwigFilter('invoke', [self::class, 'invoke'], ['needs_environment' => true]),
+            new TwigFilter('invoke', [self::class, 'invoke']),
         ];
     }
 
@@ -919,14 +919,10 @@ public static function keys($array): array
     /**
      * Invokes a callable
      *
-     * @param \Closure $arrow
-     *
      * @internal
      */
-    public static function invoke(Environment $env, $arrow, ...$arguments): mixed
+    public static function invoke(\Closure $arrow, ...$arguments): mixed
     {
-        self::checkArrow($env, $arrow, 'invoke', 'filter');
-
         return $arrow(...$arguments);
     }
 

From d58ac9a1a8b2de91c2679c06e1d56b85508c841c Mon Sep 17 00:00:00 2001
From: Lorenz <lorenzschaef@gmail.com>
Date: Tue, 7 Jan 2025 18:45:57 +0100
Subject: [PATCH 4/9] docs and changelog

---
 CHANGELOG              |  1 +
 doc/filters/invoke.rst | 19 +++++++++++++++++++
 doc/templates.rst      |  6 ++++++
 3 files changed, 26 insertions(+)
 create mode 100644 doc/filters/invoke.rst

diff --git a/CHANGELOG b/CHANGELOG
index f1d757d20c..5b01ea7ffb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 # 3.19.0 (2025-XX-XX)
 
+ * Add the `invoke` filter
  * Make `{}` optional for the `types` tag
  * Add `LastModifiedExtensionInterface` and implementation in `AbstractExtension` to track modification of runtime classes
 
diff --git a/doc/filters/invoke.rst b/doc/filters/invoke.rst
new file mode 100644
index 0000000000..63db1c6aa2
--- /dev/null
+++ b/doc/filters/invoke.rst
@@ -0,0 +1,19 @@
+``invoke``
+=======
+
+The ``invoke`` filter invokes an arrow function with the the given arguments:
+
+.. code-block:: twig
+
+    {% set person = {first: "Bob", last: "Smith"} %}
+    {% set func = p => "#{p.first} #{p.last}" %}
+
+    {{ func|invoke(person) }}
+    {# outputs Bob Smith #}
+
+Note that the arrow function has access to the current context.
+
+Arguments
+---------
+
+All given arguments are passed to the arrow function
diff --git a/doc/templates.rst b/doc/templates.rst
index 3c9a5d134b..fc5a4d087e 100644
--- a/doc/templates.rst
+++ b/doc/templates.rst
@@ -1018,6 +1018,12 @@ The following operators don't fit into any of the other categories:
     Arrow function support for functions, macros, and method calls was added in
     Twig 3.15 (filters and tests were already supported).
 
+  Arrow functions can be invoked using the ``invoke`` filter.
+
+    .. versionadded:: 3.19
+
+    The ``invoke`` filter has been added in Twig 3.19.
+
 Operators
 ~~~~~~~~~
 

From 09c30c3ca238037b43660936e644a4aee2aa6b2d Mon Sep 17 00:00:00 2001
From: Lorenz <lorenzschaef@gmail.com>
Date: Tue, 7 Jan 2025 18:50:01 +0100
Subject: [PATCH 5/9] fix merge

---
 CHANGELOG | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG b/CHANGELOG
index 5b01ea7ffb..bd7dcb57e5 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,6 @@
 # 3.19.0 (2025-XX-XX)
 
+ * Add `LastModifiedExtensionInterface` and implementation in `AbstractExtension` to track modification of runtime classes
  * Add the `invoke` filter
  * Make `{}` optional for the `types` tag
  * Add `LastModifiedExtensionInterface` and implementation in `AbstractExtension` to track modification of runtime classes

From 2b95bd60925d0d03d15b8e1a6e63a68ec53e564e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lorenz=20Sch=C3=A4fer?= <lorenzschaefer@gmx.ch>
Date: Wed, 8 Jan 2025 08:07:19 +0100
Subject: [PATCH 6/9] typo

Co-authored-by: Christian Flothmann <christian.flothmann@gmail.com>
---
 doc/filters/invoke.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/filters/invoke.rst b/doc/filters/invoke.rst
index 63db1c6aa2..960f9949c0 100644
--- a/doc/filters/invoke.rst
+++ b/doc/filters/invoke.rst
@@ -1,7 +1,7 @@
 ``invoke``
 =======
 
-The ``invoke`` filter invokes an arrow function with the the given arguments:
+The ``invoke`` filter invokes an arrow function with the given arguments:
 
 .. code-block:: twig
 

From dacbe51b3acdde300f4b4539ec4781b340d3f352 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lorenz=20Sch=C3=A4fer?= <lorenzschaefer@gmx.ch>
Date: Thu, 9 Jan 2025 08:01:12 +0100
Subject: [PATCH 7/9] Apply suggestions from code review

Co-authored-by: Fabien Potencier <fabien@potencier.org>
---
 doc/filters/invoke.rst | 6 +++---
 doc/templates.rst      | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/doc/filters/invoke.rst b/doc/filters/invoke.rst
index 960f9949c0..71dc5349db 100644
--- a/doc/filters/invoke.rst
+++ b/doc/filters/invoke.rst
@@ -1,11 +1,11 @@
 ``invoke``
-=======
+==========
 
 The ``invoke`` filter invokes an arrow function with the given arguments:
 
 .. code-block:: twig
 
-    {% set person = {first: "Bob", last: "Smith"} %}
+    {% set person = { first: "Bob", last: "Smith" } %}
     {% set func = p => "#{p.first} #{p.last}" %}
 
     {{ func|invoke(person) }}
@@ -16,4 +16,4 @@ Note that the arrow function has access to the current context.
 Arguments
 ---------
 
-All given arguments are passed to the arrow function
+All given arguments are passed to the arrow function.
diff --git a/doc/templates.rst b/doc/templates.rst
index fc5a4d087e..47ac603641 100644
--- a/doc/templates.rst
+++ b/doc/templates.rst
@@ -1018,9 +1018,9 @@ The following operators don't fit into any of the other categories:
     Arrow function support for functions, macros, and method calls was added in
     Twig 3.15 (filters and tests were already supported).
 
-  Arrow functions can be invoked using the ``invoke`` filter.
+Arrow functions can be called using the ``invoke`` filter:
 
-    .. versionadded:: 3.19
+.. versionadded:: 3.19
 
     The ``invoke`` filter has been added in Twig 3.19.
 

From c4fd25fad51833cfd471d6af6a7273a1e6dff7bb Mon Sep 17 00:00:00 2001
From: Lorenz <lorenzschaef@gmail.com>
Date: Thu, 9 Jan 2025 08:02:15 +0100
Subject: [PATCH 8/9] fix indentation

---
 doc/templates.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/templates.rst b/doc/templates.rst
index 47ac603641..822f3f8319 100644
--- a/doc/templates.rst
+++ b/doc/templates.rst
@@ -1018,9 +1018,9 @@ The following operators don't fit into any of the other categories:
     Arrow function support for functions, macros, and method calls was added in
     Twig 3.15 (filters and tests were already supported).
 
-Arrow functions can be called using the ``invoke`` filter:
+  Arrow functions can be called using the ``invoke`` filter:
 
-.. versionadded:: 3.19
+  .. versionadded:: 3.19
 
     The ``invoke`` filter has been added in Twig 3.19.
 

From 3e93e91f5971b8f01627663993220b7d48c80c63 Mon Sep 17 00:00:00 2001
From: Fabien Potencier <fabien@potencier.org>
Date: Sun, 12 Jan 2025 18:48:19 +0100
Subject: [PATCH 9/9] Finish the work

---
 CHANGELOG              |  1 -
 doc/filters/invoke.rst | 11 ++++-------
 doc/templates.rst      |  3 ++-
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index bd7dcb57e5..5b01ea7ffb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,5 @@
 # 3.19.0 (2025-XX-XX)
 
- * Add `LastModifiedExtensionInterface` and implementation in `AbstractExtension` to track modification of runtime classes
  * Add the `invoke` filter
  * Make `{}` optional for the `types` tag
  * Add `LastModifiedExtensionInterface` and implementation in `AbstractExtension` to track modification of runtime classes
diff --git a/doc/filters/invoke.rst b/doc/filters/invoke.rst
index 71dc5349db..b8e1a4936b 100644
--- a/doc/filters/invoke.rst
+++ b/doc/filters/invoke.rst
@@ -1,6 +1,10 @@
 ``invoke``
 ==========
 
+.. versionadded:: 3.19
+
+    The ``invoke`` filter has been added in Twig 3.19.
+
 The ``invoke`` filter invokes an arrow function with the given arguments:
 
 .. code-block:: twig
@@ -10,10 +14,3 @@ The ``invoke`` filter invokes an arrow function with the given arguments:
 
     {{ func|invoke(person) }}
     {# outputs Bob Smith #}
-
-Note that the arrow function has access to the current context.
-
-Arguments
----------
-
-All given arguments are passed to the arrow function.
diff --git a/doc/templates.rst b/doc/templates.rst
index 822f3f8319..7bf2d15f59 100644
--- a/doc/templates.rst
+++ b/doc/templates.rst
@@ -1018,7 +1018,8 @@ The following operators don't fit into any of the other categories:
     Arrow function support for functions, macros, and method calls was added in
     Twig 3.15 (filters and tests were already supported).
 
-  Arrow functions can be called using the ``invoke`` filter:
+  Arrow functions can be called using the :doc:`invoke </filters/invoke>`
+  filter.
 
   .. versionadded:: 3.19