Skip to content

[WIP] Use callable typehints #14330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions UPGRADE-3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,36 @@ UPGRADE FROM 2.x to 3.0
`DebugClassLoader`. The difference is that the constructor now takes a
loader to wrap.

### Config

* Any `callable` can now be used as an argument with the builder methods that
previously only accepted closures. The signatures of these methods need to
be changed in any overriding custom builder class.

Before:

```php
use Symfony\Component\Config\Definition\Builder;

Builder\ExprBuilder::always(\Closure $closure)
Builder\ExprBuilder::ifTrue(\Closure $closure)
Builder\ExprBuilder::then(\Closure $closure)
Builder\NormalizationBuilder::before(\Closure $closure)
Builder\ValidationBuilder::rule(\Closure $closure)
```

After:

```php
use Symfony\Component\Config\Definition\Builder;

Builder\ExprBuilder::always(callable $callback)
Builder\ExprBuilder::ifTrue(callable $callback)
Builder\ExprBuilder::then(callable $callback)
Builder\NormalizationBuilder::before(callable $callback)
Builder\ValidationBuilder::rule(callable $callback)
```

### Console

* The `dialog` helper has been removed in favor of the `question` helper.
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/Config/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ CHANGELOG
-----

* removed `ReferenceDumper` class
* [BC BREAK] Any `callable` is now an allowed argument for methods `ExprBuilder::always()`,
`ExprBuilder::ifTrue()`, `ExprBuilder::then()`, `NormalizationBuilder::before()` and
`ValidationBuilder::rule()` instead of just closures. The BC break only affects custom
implementations of these methods in extended builders, where the method argument type hint
needs to be changed from `\Closure` to `callable`.

2.7.0
-----
Expand Down
26 changes: 13 additions & 13 deletions src/Symfony/Component/Config/Definition/Builder/ExprBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ public function __construct(NodeDefinition $node)
/**
* Marks the expression as being always used.
*
* @param \Closure $then
* @param callable $then
*
* @return ExprBuilder
*/
public function always(\Closure $then = null)
public function always(callable $then = null)
{
$this->ifPart = function ($v) { return true; };

Expand All @@ -54,21 +54,21 @@ public function always(\Closure $then = null)
}

/**
* Sets a closure to use as tests.
* Sets a callback to use as tests.
*
* The default one tests if the value is true.
*
* @param \Closure $closure
* @param callable $callback
*
* @return ExprBuilder
*/
public function ifTrue(\Closure $closure = null)
public function ifTrue(callable $callback = null)
{
if (null === $closure) {
$closure = function ($v) { return true === $v; };
if (null === $callback) {
$callback = function ($v) { return true === $v; };
}

$this->ifPart = $closure;
$this->ifPart = $callback;

return $this;
}
Expand Down Expand Up @@ -138,15 +138,15 @@ public function ifNotInArray(array $array)
}

/**
* Sets the closure to run if the test pass.
* Sets the callback to run if the test pass.
*
* @param \Closure $closure
* @param callable $callback
*
* @return ExprBuilder
*/
public function then(\Closure $closure)
public function then(callable $callback)
{
$this->thenPart = $closure;
$this->thenPart = $callback;

return $this;
}
Expand Down Expand Up @@ -228,7 +228,7 @@ public static function buildExpressions(array $expressions)
$if = $expr->ifPart;
$then = $expr->thenPart;
$expressions[$k] = function ($v) use ($if, $then) {
return $if($v) ? $then($v) : $v;
return call_user_func($if, $v) ? call_user_func($then, $v) : $v;
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ public function remap($key, $plural = null)
}

/**
* Registers a closure to run before the normalization or an expression builder to build it if null is provided.
* Registers a callback to run before the normalization or an expression builder to build it if null is provided.
*
* @param \Closure $closure
* @param callable $callback
*
* @return ExprBuilder|NormalizationBuilder
*/
public function before(\Closure $closure = null)
public function before(callable $callback = null)
{
if (null !== $closure) {
$this->before[] = $closure;
if (null !== $callback) {
$this->before[] = $callback;

return $this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ public function __construct(NodeDefinition $node)
}

/**
* Registers a closure to run as normalization or an expression builder to build it if null is provided.
* Registers a callback to run as normalization or an expression builder to build it if null is provided.
*
* @param \Closure $closure
* @param callable $callback
*
* @return ExprBuilder|ValidationBuilder
*/
public function rule(\Closure $closure = null)
public function rule(callable $callback = null)
{
if (null !== $closure) {
$this->rules[] = $closure;
if (null !== $callback) {
$this->rules[] = $callback;

return $this;
}
Expand Down
6 changes: 1 addition & 5 deletions src/Symfony/Component/Console/Command/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,8 @@ public function run(InputInterface $input, OutputInterface $output)
*
* @api
*/
public function setCode($code)
public function setCode(callable $code)
{
if (!is_callable($code)) {
throw new \InvalidArgumentException('Invalid callable provided to Command::setCode.');
}

$this->code = $code;

return $this;
Expand Down
10 changes: 0 additions & 10 deletions src/Symfony/Component/Console/Tests/Command/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -303,16 +303,6 @@ public function testSetCodeWithNonClosureCallable()
$this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay());
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Invalid callable provided to Command::setCode.
*/
public function testSetCodeWithNonCallable()
{
$command = new \TestCommand();
$command->setCode(array($this, 'nonExistentMethod'));
}

public function callableMethodCommand(InputInterface $input, OutputInterface $output)
{
$output->writeln('from the code...');
Expand Down
7 changes: 1 addition & 6 deletions src/Symfony/Component/Debug/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,9 @@ public function setLoggers(array $loggers)
* @param callable $handler A handler that will be called on Exception
*
* @return callable|null The previous exception handler
*
* @throws \InvalidArgumentException
*/
public function setExceptionHandler($handler)
public function setExceptionHandler(callable $handler = null)
{
if (null !== $handler && !is_callable($handler)) {
throw new \LogicException('The exception handler must be a valid PHP callable.');
}
$prev = $this->exceptionHandler;
$this->exceptionHandler = $handler;

Expand Down
5 changes: 1 addition & 4 deletions src/Symfony/Component/Debug/ExceptionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,8 @@ public static function register($debug = true, $charset = null, $fileLinkFormat
*
* @return callable|null The previous exception handler if any
*/
public function setHandler($handler)
public function setHandler(callable $handler = null)
{
if (null !== $handler && !is_callable($handler)) {
throw new \LogicException('The exception handler must be a valid PHP callable.');
}
$old = $this->handler;
$this->handler = $handler;

Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Component/DomCrawler/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

3.0.0
-----

* The first argument of `Crawler::each()` and `Crawler::reduce()` are type hinted with `callable` instead of `Closure`.

2.5.0
-----

Expand Down
22 changes: 11 additions & 11 deletions src/Symfony/Component/DomCrawler/Crawler.php
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,9 @@ public function eq($position)
}

/**
* Calls an anonymous function on each node of the list.
* Execute a callback on each node of the list.
*
* The anonymous function receives the position and the node wrapped
* The callback receives the position and the node wrapped
* in a Crawler instance as arguments.
*
* Example:
Expand All @@ -334,17 +334,17 @@ public function eq($position)
* return $node->text();
* });
*
* @param \Closure $closure An anonymous function
* @param callable $callback A callback
*
* @return array An array of values returned by the anonymous function
* @return array An array of values returned by the callback
*
* @api
*/
public function each(\Closure $closure)
public function each(callable $callback)
{
$data = array();
foreach ($this as $i => $node) {
$data[] = $closure(new static($node, $this->uri, $this->baseHref), $i);
$data[] = call_user_func($callback, new static($node, $this->uri, $this->baseHref), $i);
}

return $data;
Expand All @@ -364,21 +364,21 @@ public function slice($offset = 0, $length = -1)
}

/**
* Reduces the list of nodes by calling an anonymous function.
* Reduces the list of nodes by calling a callback.
*
* To remove a node from the list, the anonymous function must return false.
* To remove a node from the list, the callback must return false.
*
* @param \Closure $closure An anonymous function
* @param callable $callback A callback
*
* @return Crawler A Crawler instance with the selected nodes.
*
* @api
*/
public function reduce(\Closure $closure)
public function reduce(callable $callback)
{
$nodes = array();
foreach ($this as $i => $node) {
if (false !== $closure(new static($node, $this->uri, $this->baseHref), $i)) {
if (false !== call_user_func($callback, new static($node, $this->uri, $this->baseHref), $i)) {
$nodes[] = $node;
}
}
Expand Down
20 changes: 10 additions & 10 deletions src/Symfony/Component/Finder/Finder.php
Original file line number Diff line number Diff line change
Expand Up @@ -483,23 +483,23 @@ public static function addVCSPattern($pattern)
}

/**
* Sorts files and directories by an anonymous function.
* Sorts files and directories by a callback function.
*
* The anonymous function receives two \SplFileInfo instances to compare.
* The callback function receives two \SplFileInfo instances to compare.
*
* This can be slow as all the matching files and directories must be retrieved for comparison.
*
* @param \Closure $closure An anonymous function
* @param callable $callback A callback function
*
* @return Finder The current Finder instance
*
* @see SortableIterator
*
* @api
*/
public function sort(\Closure $closure)
public function sort(callable $callback)
{
$this->sort = $closure;
$this->sort = $callback;

return $this;
}
Expand Down Expand Up @@ -603,22 +603,22 @@ public function sortByModifiedTime()
}

/**
* Filters the iterator with an anonymous function.
* Filters the iterator with a callback function.
*
* The anonymous function receives a \SplFileInfo and must return false
* The callback function receives a \SplFileInfo and must return false
* to remove files.
*
* @param \Closure $closure An anonymous function
* @param callable $callback A callback function
*
* @return Finder The current Finder instance
*
* @see CustomFilterIterator
*
* @api
*/
public function filter(\Closure $closure)
public function filter(callable $callback)
{
$this->filters[] = $closure;
$this->filters[] = $callback;

return $this;
}
Expand Down
10 changes: 5 additions & 5 deletions src/Symfony/Component/Finder/Shell/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class Command
private $labels = array();

/**
* @var \Closure|null
* @var callable|null
*/
private $errorHandler;

Expand Down Expand Up @@ -218,19 +218,19 @@ public function length()
}

/**
* @param \Closure $errorHandler
* @param callable $errorHandler
*
* @return Command
*/
public function setErrorHandler(\Closure $errorHandler)
public function setErrorHandler(callable $errorHandler)
{
$this->errorHandler = $errorHandler;

return $this;
}

/**
* @return \Closure|null
* @return callable|null
*/
public function getErrorHandler()
{
Expand All @@ -253,7 +253,7 @@ public function execute()
$output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY);

if ($error = stream_get_contents($pipes[2])) {
$errorHandler($error);
call_user_func($errorHandler, $error);
}

proc_close($process);
Expand Down
Loading