• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

keradus / PHP-CS-Fixer / 17252691116

26 Aug 2025 11:09PM UTC coverage: 94.743% (-0.01%) from 94.755%
17252691116

push

github

keradus
chore: apply phpdoc_tag_no_named_arguments

28313 of 29884 relevant lines covered (94.74%)

45.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.07
/src/FixerConfiguration/FixerConfigurationResolver.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of PHP CS Fixer.
7
 *
8
 * (c) Fabien Potencier <fabien@symfony.com>
9
 *     Dariusz RumiƄski <dariusz.ruminski@gmail.com>
10
 *
11
 * This source file is subject to the MIT license that is bundled
12
 * with this source code in the file LICENSE.
13
 */
14

15
namespace PhpCsFixer\FixerConfiguration;
16

17
use PhpCsFixer\Preg;
18
use PhpCsFixer\Utils;
19
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
20
use Symfony\Component\OptionsResolver\OptionsResolver;
21

22
/**
23
 * @readonly
24
 *
25
 * @no-named-arguments Parameter names are not covered by the backward compatibility promise.
26
 */
27
final class FixerConfigurationResolver implements FixerConfigurationResolverInterface
28
{
29
    /**
30
     * @var list<FixerOptionInterface>
31
     *
32
     * @readonly
33
     */
34
    private array $options;
35

36
    /**
37
     * @param iterable<FixerOptionInterface> $options
38
     */
39
    public function __construct(iterable $options)
40
    {
41
        $fixerOptionSorter = new FixerOptionSorter();
14✔
42
        $this->validateOptions($options);
14✔
43

44
        $this->options = $fixerOptionSorter->sort($options);
12✔
45

46
        if (0 === \count($this->options)) {
12✔
47
            throw new \LogicException('Options cannot be empty.');
1✔
48
        }
49
    }
50

51
    public function getOptions(): array
52
    {
53
        return $this->options;
1✔
54
    }
55

56
    public function resolve(array $configuration): array
57
    {
58
        $resolver = new OptionsResolver();
10✔
59

60
        foreach ($this->options as $option) {
10✔
61
            $name = $option->getName();
10✔
62

63
            if ($option instanceof AliasedFixerOption) {
10✔
64
                $alias = $option->getAlias();
2✔
65

66
                if (\array_key_exists($alias, $configuration)) {
2✔
67
                    if (\array_key_exists($name, $configuration)) {
2✔
68
                        throw new InvalidOptionsException(\sprintf('Aliased option "%s"/"%s" is passed multiple times.', $name, $alias));
1✔
69
                    }
70

71
                    Utils::triggerDeprecation(new \RuntimeException(\sprintf(
1✔
72
                        'Option "%s" is deprecated, use "%s" instead.',
1✔
73
                        $alias,
1✔
74
                        $name
1✔
75
                    )));
1✔
76

77
                    $configuration[$name] = $configuration[$alias];
1✔
78
                    unset($configuration[$alias]);
1✔
79
                }
80
            }
81

82
            if ($option->hasDefault()) {
9✔
83
                $resolver->setDefault($name, $option->getDefault());
1✔
84
            } else {
85
                $resolver->setRequired($name);
8✔
86
            }
87

88
            $allowedValues = $option->getAllowedValues();
9✔
89
            if (null !== $allowedValues) {
9✔
90
                foreach ($allowedValues as &$allowedValue) {
2✔
91
                    if (\is_object($allowedValue) && \is_callable($allowedValue)) {
2✔
92
                        $allowedValue = static fn (/* mixed */ $values) => $allowedValue($values);
1✔
93
                    }
94
                }
95

96
                $resolver->setAllowedValues($name, $allowedValues);
2✔
97
            }
98

99
            $allowedTypes = $option->getAllowedTypes();
9✔
100
            if (null !== $allowedTypes) {
9✔
101
                $allowedTypesNormalised = array_map(
1✔
102
                    static function (string $type): string {
1✔
103
                        // Symfony OptionsResolver doesn't support `array<foo, bar>` natively, let's simplify the type
104
                        $matches = [];
1✔
105
                        if (true === Preg::match('/array<\w+,\s*(\??[\w\'|]+)>/', $type, $matches)) {
1✔
106
                            if ('?' === $matches[1][0]) {
×
107
                                return 'array';
×
108
                            }
109

110
                            if ("'" === $matches[1][0]) {
×
111
                                return 'string[]';
×
112
                            }
113

114
                            return $matches[1].'[]';
×
115
                        }
116

117
                        // Symfony OptionsResolver doesn't support 'class-string' natively, let's simplify the type
118
                        return str_replace('class-string', 'string', $type);
1✔
119
                    },
1✔
120
                    $allowedTypes,
1✔
121
                );
1✔
122

123
                $resolver->setAllowedTypes($name, $allowedTypesNormalised);
1✔
124
            }
125

126
            $normalizer = $option->getNormalizer();
9✔
127
            if (null !== $normalizer) {
9✔
128
                $resolver->setNormalizer($name, $normalizer);
1✔
129
            }
130
        }
131

132
        return $resolver->resolve($configuration);
9✔
133
    }
134

135
    /**
136
     * @param iterable<FixerOptionInterface> $options
137
     *
138
     * @throws \LogicException when the option is already defined
139
     */
140
    private function validateOptions(iterable $options): void
141
    {
142
        $names = [];
14✔
143

144
        foreach ($options as $option) {
14✔
145
            $name = $option->getName();
13✔
146

147
            if (\in_array($name, $names, true)) {
13✔
148
                throw new \LogicException(\sprintf('The "%s" option is defined multiple times.', $name));
2✔
149
            }
150

151
            $names[] = $name;
13✔
152
        }
153
    }
154
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc