minor #29065 [OptionsResolver] Micro optimizations and simplifications (yceruto)
This PR was merged into the 4.2-dev branch.
Discussion
----------
[OptionsResolver] Micro optimizations and simplifications
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | https://github.com/symfony/symfony/issues/29055
| License | MIT
| Doc PR | -
As we know, this component has a big impact on the workflow of the `Form` component. I'm a newcomer in Blackfire, so there could be other optimizations that I can't able to see, but here we go.
For now, we've less code to maintain ![commit-changes](https://user-images.githubusercontent.com/2028198/47917083-c3619d00-de7e-11e8-826a-0c3009948d93.png) and a micro-optimizacion of performance. It'd be great if someone could try these changes in a real project to see their real value.
![orbf](https://user-images.githubusercontent.com/2028198/47915644-e2116500-de79-11e8-8648-a5e619fcd3eb.png)
![metrics](https://user-images.githubusercontent.com/2028198/47917598-61a23280-de80-11e8-9153-3ea60317f1a5.png)
https://blackfire.io/profiles/compare/a04a13d3-7f60-4434-a2b8-0762efb8fbd6/graph
https://github.com/yceruto/orbf The sample takes into account only the core extensions.
Cheers!
Commits
-------
24c2213b3d
Optimizations and simplifications OMG Blackfire!
This commit is contained in:
commit
1b82e563fe
@ -800,7 +800,7 @@ class OptionsResolver implements Options
|
||||
$triggerDeprecation = 1 === \func_num_args() || \func_get_arg(1);
|
||||
|
||||
// Shortcut for resolved options
|
||||
if (array_key_exists($option, $this->resolved)) {
|
||||
if (isset($this->resolved[$option]) || array_key_exists($option, $this->resolved)) {
|
||||
if ($triggerDeprecation && isset($this->deprecated[$option]) && (isset($this->given[$option]) || $this->calling) && \is_string($this->deprecated[$option])) {
|
||||
@trigger_error(strtr($this->deprecated[$option], array('%name%' => $option)), E_USER_DEPRECATED);
|
||||
}
|
||||
@ -809,7 +809,7 @@ class OptionsResolver implements Options
|
||||
}
|
||||
|
||||
// Check whether the option is set at all
|
||||
if (!array_key_exists($option, $this->defaults)) {
|
||||
if (!isset($this->defaults[$option]) && !array_key_exists($option, $this->defaults)) {
|
||||
if (!isset($this->defined[$option])) {
|
||||
throw new NoSuchOptionException(sprintf('The option "%s" does not exist. Defined options are: "%s".', $option, implode('", "', array_keys($this->defined))));
|
||||
}
|
||||
@ -827,7 +827,7 @@ class OptionsResolver implements Options
|
||||
}
|
||||
|
||||
if (!\is_array($value)) {
|
||||
throw new InvalidOptionsException(sprintf('The nested option "%s" with value %s is expected to be of type array, but is of type "%s".', $option, $this->formatValue($value), $this->formatTypeOf($value, 'array')));
|
||||
throw new InvalidOptionsException(sprintf('The nested option "%s" with value %s is expected to be of type array, but is of type "%s".', $option, $this->formatValue($value), $this->formatTypeOf($value)));
|
||||
}
|
||||
|
||||
// The following section must be protected from cyclic calls.
|
||||
@ -872,7 +872,7 @@ class OptionsResolver implements Options
|
||||
$invalidTypes = array();
|
||||
|
||||
foreach ($this->allowedTypes[$option] as $type) {
|
||||
$type = isset(self::$typeAliases[$type]) ? self::$typeAliases[$type] : $type;
|
||||
$type = self::$typeAliases[$type] ?? $type;
|
||||
|
||||
if ($valid = $this->verifyTypes($type, $value, $invalidTypes)) {
|
||||
break;
|
||||
@ -987,60 +987,35 @@ class OptionsResolver implements Options
|
||||
return $value;
|
||||
}
|
||||
|
||||
private function verifyTypes(string $type, $value, array &$invalidTypes): bool
|
||||
private function verifyTypes(string $type, $value, array &$invalidTypes, int $level = 0): bool
|
||||
{
|
||||
if (\is_array($value) && '[]' === substr($type, -2)) {
|
||||
return $this->verifyArrayType($type, $value, $invalidTypes);
|
||||
$type = substr($type, 0, -2);
|
||||
|
||||
foreach ($value as $val) {
|
||||
if (!$this->verifyTypes($type, $val, $invalidTypes, $level + 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (self::isValueValidType($type, $value)) {
|
||||
if (('null' === $type && null === $value) || (\function_exists($func = 'is_'.$type) && $func($value)) || $value instanceof $type) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$invalidTypes) {
|
||||
$invalidTypes[$this->formatTypeOf($value, null)] = true;
|
||||
$suffix = '';
|
||||
while (\strlen($suffix) < $level * 2) {
|
||||
$suffix .= '[]';
|
||||
}
|
||||
$invalidTypes[$this->formatTypeOf($value).$suffix] = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function verifyArrayType(string $type, array $value, array &$invalidTypes, int $level = 0): bool
|
||||
{
|
||||
$type = substr($type, 0, -2);
|
||||
|
||||
$suffix = '[]';
|
||||
while (\strlen($suffix) <= $level * 2) {
|
||||
$suffix .= '[]';
|
||||
}
|
||||
|
||||
if ('[]' === substr($type, -2)) {
|
||||
$success = true;
|
||||
foreach ($value as $item) {
|
||||
if (!\is_array($item)) {
|
||||
$invalidTypes[$this->formatTypeOf($item, null).$suffix] = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->verifyArrayType($type, $item, $invalidTypes, $level + 1)) {
|
||||
$success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
foreach ($value as $item) {
|
||||
if (!self::isValueValidType($type, $item)) {
|
||||
$invalidTypes[$this->formatTypeOf($item, $type).$suffix] = $value;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a resolved option with the given name exists.
|
||||
*
|
||||
@ -1104,40 +1079,13 @@ class OptionsResolver implements Options
|
||||
/**
|
||||
* Returns a string representation of the type of the value.
|
||||
*
|
||||
* This method should be used if you pass the type of a value as
|
||||
* message parameter to a constraint violation. Note that such
|
||||
* parameters should usually not be included in messages aimed at
|
||||
* non-technical people.
|
||||
*
|
||||
* @param mixed $value The value to return the type of
|
||||
*
|
||||
* @return string The type of the value
|
||||
*/
|
||||
private function formatTypeOf($value, ?string $type): string
|
||||
private function formatTypeOf($value): string
|
||||
{
|
||||
$suffix = '';
|
||||
|
||||
if (null !== $type && '[]' === substr($type, -2)) {
|
||||
$suffix = '[]';
|
||||
$type = substr($type, 0, -2);
|
||||
while ('[]' === substr($type, -2)) {
|
||||
$type = substr($type, 0, -2);
|
||||
$value = array_shift($value);
|
||||
if (!\is_array($value)) {
|
||||
break;
|
||||
}
|
||||
$suffix .= '[]';
|
||||
}
|
||||
|
||||
if (\is_array($value)) {
|
||||
$subTypes = array();
|
||||
foreach ($value as $val) {
|
||||
$subTypes[$this->formatTypeOf($val, null)] = true;
|
||||
}
|
||||
|
||||
return implode('|', array_keys($subTypes)).$suffix;
|
||||
}
|
||||
}
|
||||
|
||||
return (\is_object($value) ? \get_class($value) : \gettype($value)).$suffix;
|
||||
return \is_object($value) ? \get_class($value) : \gettype($value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1198,9 +1146,4 @@ class OptionsResolver implements Options
|
||||
|
||||
return implode(', ', $values);
|
||||
}
|
||||
|
||||
private static function isValueValidType(string $type, $value): bool
|
||||
{
|
||||
return (\function_exists($isFunction = 'is_'.$type) && $isFunction($value)) || $value instanceof $type;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user