Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
97.06% covered (success)
97.06%
33 / 34
CRAP
99.66% covered (success)
99.66%
290 / 291
OptionsResolver
0.00% covered (danger)
0.00%
0 / 1
97.06% covered (success)
97.06%
33 / 34
157
99.66% covered (success)
99.66%
290 / 291
 setDefault
100.00% covered (success)
100.00%
1 / 1
16
100.00% covered (success)
100.00%
26 / 26
 setDefaults
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 hasDefault
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setRequired
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
6 / 6
 isRequired
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getRequiredOptions
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 isMissing
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 getMissingOptions
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setDefined
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
5 / 5
 isDefined
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getDefinedOptions
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 isNested
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setDeprecated
100.00% covered (success)
100.00%
1 / 1
6
100.00% covered (success)
100.00%
11 / 11
 isDeprecated
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setNormalizer
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
7 / 7
 addNormalizer
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
9 / 9
 setAllowedValues
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
7 / 7
 addAllowedValues
100.00% covered (success)
100.00%
1 / 1
5
100.00% covered (success)
100.00%
11 / 11
 setAllowedTypes
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
7 / 7
 addAllowedTypes
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
9 / 9
 remove
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
6 / 6
 clear
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
13 / 13
 resolve
100.00% covered (success)
100.00%
1 / 1
8
100.00% covered (success)
100.00%
20 / 20
 offsetGet
100.00% covered (success)
100.00%
1 / 1
44
100.00% covered (success)
100.00%
93 / 93
 verifyTypes
100.00% covered (success)
100.00%
1 / 1
12
100.00% covered (success)
100.00%
12 / 12
 offsetExists
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 offsetSet
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 offsetUnset
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 count
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 formatTypeOf
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 formatValue
100.00% covered (success)
100.00%
1 / 1
8
100.00% covered (success)
100.00%
15 / 15
 formatValues
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 formatOptions
0.00% covered (danger)
0.00%
0 / 1
3.03
85.71% covered (warning)
85.71%
6 / 7
 getParameterClassName
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
3 / 3
<?php
/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace Symfony\Component\OptionsResolver;
use Symfony\Component\OptionsResolver\Exception\AccessException;
use Symfony\Component\OptionsResolver\Exception\InvalidArgumentException;
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
use Symfony\Component\OptionsResolver\Exception\MissingOptionsException;
use Symfony\Component\OptionsResolver\Exception\NoSuchOptionException;
use Symfony\Component\OptionsResolver\Exception\OptionDefinitionException;
use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException;
/**
 * Validates options and merges them with default values.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 * @author Tobias Schultze <http://tobion.de>
 */
class OptionsResolver implements Options
{
    /**
     * The names of all defined options.
     */
    private $defined = [];
    /**
     * The default option values.
     */
    private $defaults = [];
    /**
     * A list of closure for nested options.
     *
     * @var \Closure[][]
     */
    private $nested = [];
    /**
     * The names of required options.
     */
    private $required = [];
    /**
     * The resolved option values.
     */
    private $resolved = [];
    /**
     * A list of normalizer closures.
     *
     * @var \Closure[][]
     */
    private $normalizers = [];
    /**
     * A list of accepted values for each option.
     */
    private $allowedValues = [];
    /**
     * A list of accepted types for each option.
     */
    private $allowedTypes = [];
    /**
     * A list of closures for evaluating lazy options.
     */
    private $lazy = [];
    /**
     * A list of lazy options whose closure is currently being called.
     *
     * This list helps detecting circular dependencies between lazy options.
     */
    private $calling = [];
    /**
     * A list of deprecated options.
     */
    private $deprecated = [];
    /**
     * The list of options provided by the user.
     */
    private $given = [];
    /**
     * Whether the instance is locked for reading.
     *
     * Once locked, the options cannot be changed anymore. This is
     * necessary in order to avoid inconsistencies during the resolving
     * process. If any option is changed after being read, all evaluated
     * lazy options that depend on this option would become invalid.
     */
    private $locked = false;
    private $parentsOptions = [];
    private static $typeAliases = [
        'boolean' => 'bool',
        'integer' => 'int',
        'double' => 'float',
    ];
    /**
     * Sets the default value of a given option.
     *
     * If the default value should be set based on other options, you can pass
     * a closure with the following signature:
     *
     *     function (Options $options) {
     *         // ...
     *     }
     *
     * The closure will be evaluated when {@link resolve()} is called. The
     * closure has access to the resolved values of other options through the
     * passed {@link Options} instance:
     *
     *     function (Options $options) {
     *         if (isset($options['port'])) {
     *             // ...
     *         }
     *     }
     *
     * If you want to access the previously set default value, add a second
     * argument to the closure's signature:
     *
     *     $options->setDefault('name', 'Default Name');
     *
     *     $options->setDefault('name', function (Options $options, $previousValue) {
     *         // 'Default Name' === $previousValue
     *     });
     *
     * This is mostly useful if the configuration of the {@link Options} object
     * is spread across different locations of your code, such as base and
     * sub-classes.
     *
     * If you want to define nested options, you can pass a closure with the
     * following signature:
     *
     *     $options->setDefault('database', function (OptionsResolver $resolver) {
     *         $resolver->setDefined(['dbname', 'host', 'port', 'user', 'pass']);
     *     }
     *
     * To get access to the parent options, add a second argument to the closure's
     * signature:
     *
     *     function (OptionsResolver $resolver, Options $parent) {
     *         // 'default' === $parent['connection']
     *     }
     *
     * @param string $option The name of the option
     * @param mixed  $value  The default value of the option
     *
     * @return $this
     *
     * @throws AccessException If called from a lazy option or normalizer
     */
    public function setDefault(string $option, $value)
    {
        // Setting is not possible once resolving starts, because then lazy
        // options could manipulate the state of the object, leading to
        // inconsistent results.
        if ($this->locked) {
            throw new AccessException('Default values cannot be set from a lazy option or normalizer.');
        }
        // If an option is a closure that should be evaluated lazily, store it
        // in the "lazy" property.
        if ($value instanceof \Closure) {