|
7 | 7 | use PhpParser\Node; |
8 | 8 | use PhpParser\Node\Scalar\Float_; |
9 | 9 | use PhpParser\Node\Scalar\Int_; |
| 10 | +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; |
10 | 11 | use Rector\Contract\Rector\ConfigurableRectorInterface; |
11 | | -use Rector\NodeTypeResolver\Node\AttributeKey; |
| 12 | +use Rector\Exception\ShouldNotHappenException; |
12 | 13 | use Rector\Rector\AbstractRector; |
13 | | -use Rector\Util\StringUtils; |
14 | 14 | use Rector\ValueObject\PhpVersionFeature; |
15 | 15 | use Rector\VersionBonding\Contract\MinPhpVersionInterface; |
16 | 16 | use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; |
17 | 17 | use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; |
18 | | -use Webmozart\Assert\Assert; |
19 | 18 |
|
20 | 19 | /** |
21 | 20 | * Taking the most generic use case to the account: https://wiki.php.net/rfc/numeric_literal_separator#should_it_be_the_role_of_an_ide_to_group_digits |
22 | 21 | * The final check should be done manually |
23 | 22 | * |
24 | | - * @see \Rector\Tests\Php74\Rector\LNumber\AddLiteralSeparatorToNumberRector\AddLiteralSeparatorToNumberRectorTest |
| 23 | + * @deprecated as opinionated and group size depends on context. Cannot be automated. Use manually where neeed isntead. |
25 | 24 | */ |
26 | | -final class AddLiteralSeparatorToNumberRector extends AbstractRector implements MinPhpVersionInterface, ConfigurableRectorInterface |
| 25 | +final class AddLiteralSeparatorToNumberRector extends AbstractRector implements MinPhpVersionInterface, ConfigurableRectorInterface, DeprecatedInterface |
27 | 26 | { |
28 | 27 | /** |
29 | 28 | * @api |
30 | 29 | * @var string |
31 | 30 | */ |
32 | 31 | public const LIMIT_VALUE = 'limit_value'; |
33 | 32 |
|
34 | | - /** |
35 | | - * @var int |
36 | | - */ |
37 | | - private const GROUP_SIZE = 3; |
38 | | - |
39 | | - /** |
40 | | - * @var int |
41 | | - */ |
42 | | - private const DEFAULT_LIMIT_VALUE = 1_000_000; |
43 | | - |
44 | | - private int $limitValue = self::DEFAULT_LIMIT_VALUE; |
45 | | - |
46 | 33 | /** |
47 | 34 | * @param array<string, mixed> $configuration |
48 | 35 | */ |
49 | 36 | public function configure(array $configuration): void |
50 | 37 | { |
51 | | - $limitValue = $configuration[self::LIMIT_VALUE] ?? self::DEFAULT_LIMIT_VALUE; |
52 | | - Assert::integer($limitValue); |
53 | | - |
54 | | - $this->limitValue = $limitValue; |
55 | 38 | } |
56 | 39 |
|
57 | 40 | public function getRuleDefinition(): RuleDefinition |
@@ -103,86 +86,14 @@ public function getNodeTypes(): array |
103 | 86 | */ |
104 | 87 | public function refactor(Node $node): ?Node |
105 | 88 | { |
106 | | - $rawValue = $node->getAttribute(AttributeKey::RAW_VALUE); |
107 | | - |
108 | | - if ($this->shouldSkip($node, $rawValue)) { |
109 | | - return null; |
110 | | - } |
111 | | - |
112 | | - if (\str_contains((string) $rawValue, '.')) { |
113 | | - [$mainPart, $decimalPart] = explode('.', (string) $rawValue); |
114 | | - |
115 | | - $chunks = $this->strSplitNegative($mainPart, self::GROUP_SIZE); |
116 | | - $literalSeparatedNumber = implode('_', $chunks) . '.' . $decimalPart; |
117 | | - } else { |
118 | | - $chunks = $this->strSplitNegative($rawValue, self::GROUP_SIZE); |
119 | | - $literalSeparatedNumber = implode('_', $chunks); |
120 | | - |
121 | | - // PHP converts: (string) 1000.0 -> "1000"! |
122 | | - if (is_float($node->value)) { |
123 | | - $literalSeparatedNumber .= '.0'; |
124 | | - } |
125 | | - } |
126 | | - |
127 | | - // this cannot be integer directly to $node->value, as PHPStan sees it as error type |
128 | | - // @see https://github.com/rectorphp/rector/issues/7454 |
129 | | - $node->setAttribute(AttributeKey::RAW_VALUE, $literalSeparatedNumber); |
130 | | - $node->setAttribute(AttributeKey::REPRINT_RAW_VALUE, true); |
131 | | - $node->setAttribute(AttributeKey::ORIGINAL_NODE, null); |
132 | | - |
133 | | - return $node; |
| 89 | + throw new ShouldNotHappenException(sprintf( |
| 90 | + '%s is deprecated as opinonated and group size depends on context. Cannot be automated. Use manually where needed instead', |
| 91 | + self::class |
| 92 | + )); |
134 | 93 | } |
135 | 94 |
|
136 | 95 | public function provideMinPhpVersion(): int |
137 | 96 | { |
138 | 97 | return PhpVersionFeature::LITERAL_SEPARATOR; |
139 | 98 | } |
140 | | - |
141 | | - private function shouldSkip(Int_ | Float_ $node, mixed $rawValue): bool |
142 | | - { |
143 | | - if (! is_string($rawValue)) { |
144 | | - return true; |
145 | | - } |
146 | | - |
147 | | - // already contains separator |
148 | | - if (str_contains($rawValue, '_')) { |
149 | | - return true; |
150 | | - } |
151 | | - |
152 | | - if ($node->value < $this->limitValue) { |
153 | | - return true; |
154 | | - } |
155 | | - |
156 | | - $kind = $node->getAttribute(AttributeKey::KIND); |
157 | | - if (in_array($kind, [Int_::KIND_BIN, Int_::KIND_OCT, Int_::KIND_HEX], true)) { |
158 | | - return true; |
159 | | - } |
160 | | - |
161 | | - // e+/e- |
162 | | - if (StringUtils::isMatch($rawValue, '#e#i')) { |
163 | | - return true; |
164 | | - } |
165 | | - |
166 | | - // too short |
167 | | - return strlen($rawValue) <= self::GROUP_SIZE; |
168 | | - } |
169 | | - |
170 | | - /** |
171 | | - * @param int<1, max> $length |
172 | | - * @return string[] |
173 | | - */ |
174 | | - private function strSplitNegative(string $string, int $length): array |
175 | | - { |
176 | | - $inversed = strrev($string); |
177 | | - |
178 | | - /** @var string[] $chunks */ |
179 | | - $chunks = str_split($inversed, $length); |
180 | | - |
181 | | - $chunks = array_reverse($chunks); |
182 | | - foreach ($chunks as $key => $chunk) { |
183 | | - $chunks[$key] = strrev($chunk); |
184 | | - } |
185 | | - |
186 | | - return $chunks; |
187 | | - } |
188 | 99 | } |
0 commit comments