| Total Complexity | 115 |
| Total Lines | 719 |
| Duplicated Lines | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Complex classes like BinaryOperatorSpacesFixer often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use BinaryOperatorSpacesFixer, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 36 | final class BinaryOperatorSpacesFixer extends AbstractFixer implements ConfigurableFixerInterface |
||
| 37 | { |
||
| 38 | /** |
||
| 39 | * @internal |
||
| 40 | */ |
||
| 41 | public const SINGLE_SPACE = 'single_space'; |
||
| 42 | |||
| 43 | /** |
||
| 44 | * @internal |
||
| 45 | */ |
||
| 46 | public const NO_SPACE = 'no_space'; |
||
| 47 | |||
| 48 | /** |
||
| 49 | * @internal |
||
| 50 | */ |
||
| 51 | public const ALIGN = 'align'; |
||
| 52 | |||
| 53 | /** |
||
| 54 | * @internal |
||
| 55 | */ |
||
| 56 | public const ALIGN_SINGLE_SPACE = 'align_single_space'; |
||
| 57 | |||
| 58 | /** |
||
| 59 | * @internal |
||
| 60 | */ |
||
| 61 | public const ALIGN_SINGLE_SPACE_MINIMAL = 'align_single_space_minimal'; |
||
| 62 | |||
| 63 | /** |
||
| 64 | * @internal |
||
| 65 | * @const Placeholder used as anchor for right alignment. |
||
| 66 | */ |
||
| 67 | public const ALIGN_PLACEHOLDER = "\x2 ALIGNABLE%d \x3"; |
||
| 68 | |||
| 69 | /** |
||
| 70 | * @var string[] |
||
| 71 | */ |
||
| 72 | private const SUPPORTED_OPERATORS = [ |
||
| 73 | '=', |
||
| 74 | '*', |
||
| 75 | '/', |
||
| 76 | '%', |
||
| 77 | '<', |
||
| 78 | '>', |
||
| 79 | '|', |
||
| 80 | '^', |
||
| 81 | '+', |
||
| 82 | '-', |
||
| 83 | '&', |
||
| 84 | '&=', |
||
| 85 | '&&', |
||
| 86 | '||', |
||
| 87 | '.=', |
||
| 88 | '/=', |
||
| 89 | '=>', |
||
| 90 | '==', |
||
| 91 | '>=', |
||
| 92 | '===', |
||
| 93 | '!=', |
||
| 94 | '<>', |
||
| 95 | '!==', |
||
| 96 | '<=', |
||
| 97 | 'and', |
||
| 98 | 'or', |
||
| 99 | 'xor', |
||
| 100 | '-=', |
||
| 101 | '%=', |
||
| 102 | '*=', |
||
| 103 | '|=', |
||
| 104 | '+=', |
||
| 105 | '<<', |
||
| 106 | '<<=', |
||
| 107 | '>>', |
||
| 108 | '>>=', |
||
| 109 | '^=', |
||
| 110 | '**', |
||
| 111 | '**=', |
||
| 112 | '<=>', |
||
| 113 | '??', |
||
| 114 | '??=', |
||
| 115 | ]; |
||
| 116 | |||
| 117 | /** |
||
| 118 | * Keep track of the deepest level ever achieved while |
||
| 119 | * parsing the code. Used later to replace alignment |
||
| 120 | * placeholders with spaces. |
||
| 121 | * |
||
| 122 | * @var int |
||
| 123 | */ |
||
| 124 | private $deepestLevel; |
||
| 125 | |||
| 126 | /** |
||
| 127 | * Level counter of the current nest level. |
||
| 128 | * So one level alignments are not mixed with |
||
| 129 | * other level ones. |
||
| 130 | * |
||
| 131 | * @var int |
||
| 132 | */ |
||
| 133 | private $currentLevel; |
||
| 134 | |||
| 135 | private static $allowedValues = [ |
||
| 136 | self::ALIGN, |
||
| 137 | self::ALIGN_SINGLE_SPACE, |
||
| 138 | self::ALIGN_SINGLE_SPACE_MINIMAL, |
||
| 139 | self::SINGLE_SPACE, |
||
| 140 | self::NO_SPACE, |
||
| 141 | null, |
||
| 142 | ]; |
||
| 143 | |||
| 144 | /** |
||
| 145 | * @var TokensAnalyzer |
||
| 146 | */ |
||
| 147 | private $tokensAnalyzer; |
||
| 148 | |||
| 149 | /** |
||
| 150 | * @var array<string, string> |
||
| 151 | */ |
||
| 152 | private $alignOperatorTokens = []; |
||
| 153 | |||
| 154 | /** |
||
| 155 | * @var array<string, string> |
||
| 156 | */ |
||
| 157 | private $operators = []; |
||
| 158 | |||
| 159 | /** |
||
| 160 | * {@inheritdoc} |
||
| 161 | */ |
||
| 162 | public function configure(array $configuration): void |
||
| 163 | { |
||
| 164 | parent::configure($configuration); |
||
| 165 | |||
| 166 | $this->operators = $this->resolveOperatorsFromConfig(); |
||
| 167 | } |
||
| 168 | |||
| 169 | /** |
||
| 170 | * {@inheritdoc} |
||
| 171 | */ |
||
| 172 | public function getDefinition(): FixerDefinitionInterface |
||
| 173 | { |
||
| 174 | return new FixerDefinition( |
||
| 175 | 'Binary operators should be surrounded by space as configured.', |
||
| 176 | [ |
||
| 177 | new CodeSample( |
||
| 178 | "<?php\n\$a= 1 + \$b^ \$d !== \$e or \$f;\n" |
||
| 179 | ), |
||
| 180 | new CodeSample( |
||
| 181 | '<?php |
||
| 182 | $aa= 1; |
||
| 183 | $b=2; |
||
| 184 | |||
| 185 | $c = $d xor $e; |
||
| 186 | $f -= 1; |
||
| 187 | ', |
||
| 188 | ['operators' => ['=' => 'align', 'xor' => null]] |
||
| 189 | ), |
||
| 190 | new CodeSample( |
||
| 191 | '<?php |
||
| 192 | $a = $b +=$c; |
||
| 193 | $d = $ee+=$f; |
||
| 194 | |||
| 195 | $g = $b +=$c; |
||
| 196 | $h = $ee+=$f; |
||
| 197 | ', |
||
| 198 | ['operators' => ['+=' => 'align_single_space']] |
||
| 199 | ), |
||
| 200 | new CodeSample( |
||
| 201 | '<?php |
||
| 202 | $a = $b===$c; |
||
| 203 | $d = $f === $g; |
||
| 204 | $h = $i=== $j; |
||
| 205 | ', |
||
| 206 | ['operators' => ['===' => 'align_single_space_minimal']] |
||
| 207 | ), |
||
| 208 | new CodeSample( |
||
| 209 | '<?php |
||
| 210 | $foo = \json_encode($bar, JSON_PRESERVE_ZERO_FRACTION | JSON_PRETTY_PRINT); |
||
| 211 | ', |
||
| 212 | ['operators' => ['|' => 'no_space']] |
||
| 213 | ), |
||
| 214 | new CodeSample( |
||
| 215 | '<?php |
||
| 216 | $array = [ |
||
| 217 | "foo" => 1, |
||
| 218 | "baaaaaaaaaaar" => 11, |
||
| 219 | ]; |
||
| 220 | ', |
||
| 221 | ['operators' => ['=>' => 'single_space']] |
||
| 222 | ), |
||
| 223 | new CodeSample( |
||
| 224 | '<?php |
||
| 225 | $array = [ |
||
| 226 | "foo" => 12, |
||
| 227 | "baaaaaaaaaaar" => 13, |
||
| 228 | ]; |
||
| 229 | ', |
||
| 230 | ['operators' => ['=>' => 'align']] |
||
| 231 | ), |
||
| 232 | new CodeSample( |
||
| 233 | '<?php |
||
| 234 | $array = [ |
||
| 235 | "foo" => 12, |
||
| 236 | "baaaaaaaaaaar" => 13, |
||
| 237 | ]; |
||
| 238 | ', |
||
| 239 | ['operators' => ['=>' => 'align_single_space']] |
||
| 240 | ), |
||
| 241 | new CodeSample( |
||
| 242 | '<?php |
||
| 243 | $array = [ |
||
| 244 | "foo" => 12, |
||
| 245 | "baaaaaaaaaaar" => 13, |
||
| 246 | ]; |
||
| 247 | ', |
||
| 248 | ['operators' => ['=>' => 'align_single_space_minimal']] |
||
| 249 | ), |
||
| 250 | ] |
||
| 251 | ); |
||
| 252 | } |
||
| 253 | |||
| 254 | /** |
||
| 255 | * {@inheritdoc} |
||
| 256 | * |
||
| 257 | * Must run after ArrayIndentationFixer, ArraySyntaxFixer, ListSyntaxFixer, NoMultilineWhitespaceAroundDoubleArrowFixer, NoUnsetCastFixer, PowToExponentiationFixer, StandardizeNotEqualsFixer, StrictComparisonFixer. |
||
| 258 | */ |
||
| 259 | public function getPriority(): int |
||
| 260 | { |
||
| 261 | return -32; |
||
| 262 | } |
||
| 263 | |||
| 264 | /** |
||
| 265 | * {@inheritdoc} |
||
| 266 | */ |
||
| 267 | public function isCandidate(Tokens $tokens): bool |
||
| 268 | { |
||
| 269 | return true; |
||
| 270 | } |
||
| 271 | |||
| 272 | /** |
||
| 273 | * {@inheritdoc} |
||
| 274 | */ |
||
| 275 | protected function applyFix(\SplFileInfo $file, Tokens $tokens): void |
||
| 276 | { |
||
| 277 | $this->tokensAnalyzer = new TokensAnalyzer($tokens); |
||
| 278 | |||
| 279 | // last and first tokens cannot be an operator |
||
| 280 | for ($index = $tokens->count() - 2; $index > 0; --$index) { |
||
| 281 | if (!$this->tokensAnalyzer->isBinaryOperator($index)) { |
||
| 282 | continue; |
||
| 283 | } |
||
| 284 | |||
| 285 | if ('=' === $tokens[$index]->getContent()) { |
||
| 286 | $isDeclare = $this->isEqualPartOfDeclareStatement($tokens, $index); |
||
| 287 | if (false === $isDeclare) { |
||
| 288 | $this->fixWhiteSpaceAroundOperator($tokens, $index); |
||
| 289 | } else { |
||
| 290 | $index = $isDeclare; // skip `declare(foo ==bar)`, see `declare_equal_normalize` |
||
| 291 | } |
||
| 292 | } else { |
||
| 293 | $this->fixWhiteSpaceAroundOperator($tokens, $index); |
||
| 294 | } |
||
| 295 | |||
| 296 | // previous of binary operator is now never an operator / previous of declare statement cannot be an operator |
||
| 297 | --$index; |
||
| 298 | } |
||
| 299 | |||
| 300 | if (\count($this->alignOperatorTokens)) { |
||
| 301 | $this->fixAlignment($tokens, $this->alignOperatorTokens); |
||
| 302 | } |
||
| 303 | } |
||
| 304 | |||
| 305 | /** |
||
| 306 | * {@inheritdoc} |
||
| 307 | */ |
||
| 308 | protected function createConfigurationDefinition(): FixerConfigurationResolverInterface |
||
| 309 | { |
||
| 310 | return new FixerConfigurationResolver([ |
||
| 311 | (new FixerOptionBuilder('default', 'Default fix strategy.')) |
||
| 312 | ->setDefault(self::SINGLE_SPACE) |
||
| 313 | ->setAllowedValues(self::$allowedValues) |
||
| 314 | ->getOption(), |
||
| 315 | (new FixerOptionBuilder('operators', 'Dictionary of `binary operator` => `fix strategy` values that differ from the default strategy.')) |
||
| 316 | ->setAllowedTypes(['array']) |
||
| 317 | ->setAllowedValues([static function (array $option) { |
||
| 318 | foreach ($option as $operator => $value) { |
||
| 319 | if (!\in_array($operator, self::SUPPORTED_OPERATORS, true)) { |
||
| 320 | throw new InvalidOptionsException( |
||
| 321 | sprintf( |
||
| 322 | 'Unexpected "operators" key, expected any of "%s", got "%s".', |
||
| 323 | implode('", "', self::SUPPORTED_OPERATORS), |
||
| 324 | \gettype($operator).'#'.$operator |
||
| 325 | ) |
||
| 326 | ); |
||
| 327 | } |
||
| 328 | |||
| 329 | if (!\in_array($value, self::$allowedValues, true)) { |
||
| 330 | throw new InvalidOptionsException( |
||
| 331 | sprintf( |
||
| 332 | 'Unexpected value for operator "%s", expected any of "%s", got "%s".', |
||
| 333 | $operator, |
||
| 334 | implode('", "', self::$allowedValues), |
||
| 335 | \is_object($value) ? \get_class($value) : (null === $value ? 'null' : \gettype($value).'#'.$value) |
||
| 336 | ) |
||
| 337 | ); |
||
| 338 | } |
||
| 339 | } |
||
| 340 | |||
| 341 | return true; |
||
| 342 | }]) |
||
| 343 | ->setDefault([]) |
||
| 344 | ->getOption(), |
||
| 345 | ]); |
||
| 346 | } |
||
| 347 | |||
| 348 | private function fixWhiteSpaceAroundOperator(Tokens $tokens, int $index): void |
||
| 349 | { |
||
| 350 | $tokenContent = strtolower($tokens[$index]->getContent()); |
||
| 351 | |||
| 352 | if (!\array_key_exists($tokenContent, $this->operators)) { |
||
| 353 | return; // not configured to be changed |
||
| 354 | } |
||
| 355 | |||
| 356 | if (self::SINGLE_SPACE === $this->operators[$tokenContent]) { |
||
| 357 | $this->fixWhiteSpaceAroundOperatorToSingleSpace($tokens, $index); |
||
| 358 | |||
| 359 | return; |
||
| 360 | } |
||
| 361 | |||
| 362 | if (self::NO_SPACE === $this->operators[$tokenContent]) { |
||
| 363 | $this->fixWhiteSpaceAroundOperatorToNoSpace($tokens, $index); |
||
| 364 | |||
| 365 | return; |
||
| 366 | } |
||
| 367 | |||
| 368 | // schedule for alignment |
||
| 369 | $this->alignOperatorTokens[$tokenContent] = $this->operators[$tokenContent]; |
||
| 370 | |||
| 371 | if (self::ALIGN === $this->operators[$tokenContent]) { |
||
| 372 | return; |
||
| 373 | } |
||
| 374 | |||
| 375 | // fix white space after operator |
||
| 376 | if ($tokens[$index + 1]->isWhitespace()) { |
||
| 377 | if (self::ALIGN_SINGLE_SPACE_MINIMAL === $this->operators[$tokenContent]) { |
||
| 378 | $tokens[$index + 1] = new Token([T_WHITESPACE, ' ']); |
||
| 379 | } |
||
| 380 | |||
| 381 | return; |
||
| 382 | } |
||
| 383 | |||
| 384 | $tokens->insertAt($index + 1, new Token([T_WHITESPACE, ' '])); |
||
| 385 | } |
||
| 386 | |||
| 387 | private function fixWhiteSpaceAroundOperatorToSingleSpace(Tokens $tokens, int $index): void |
||
| 388 | { |
||
| 389 | // fix white space after operator |
||
| 390 | if ($tokens[$index + 1]->isWhitespace()) { |
||
| 391 | $content = $tokens[$index + 1]->getContent(); |
||
| 392 | if (' ' !== $content && false === strpos($content, "\n") && !$tokens[$tokens->getNextNonWhitespace($index + 1)]->isComment()) { |
||
| 393 | $tokens[$index + 1] = new Token([T_WHITESPACE, ' ']); |
||
| 394 | } |
||
| 395 | } else { |
||
| 396 | $tokens->insertAt($index + 1, new Token([T_WHITESPACE, ' '])); |
||
| 397 | } |
||
| 398 | |||
| 399 | // fix white space before operator |
||
| 400 | if ($tokens[$index - 1]->isWhitespace()) { |
||
| 401 | $content = $tokens[$index - 1]->getContent(); |
||
| 402 | if (' ' !== $content && false === strpos($content, "\n") && !$tokens[$tokens->getPrevNonWhitespace($index - 1)]->isComment()) { |
||
| 403 | $tokens[$index - 1] = new Token([T_WHITESPACE, ' ']); |
||
| 404 | } |
||
| 405 | } else { |
||
| 406 | $tokens->insertAt($index, new Token([T_WHITESPACE, ' '])); |
||
| 407 | } |
||
| 408 | } |
||
| 409 | |||
| 410 | private function fixWhiteSpaceAroundOperatorToNoSpace(Tokens $tokens, int $index): void |
||
| 411 | { |
||
| 412 | // fix white space after operator |
||
| 413 | if ($tokens[$index + 1]->isWhitespace()) { |
||
| 414 | $content = $tokens[$index + 1]->getContent(); |
||
| 415 | if (false === strpos($content, "\n") && !$tokens[$tokens->getNextNonWhitespace($index + 1)]->isComment()) { |
||
| 416 | $tokens->clearAt($index + 1); |
||
| 417 | } |
||
| 418 | } |
||
| 419 | |||
| 420 | // fix white space before operator |
||
| 421 | if ($tokens[$index - 1]->isWhitespace()) { |
||
| 422 | $content = $tokens[$index - 1]->getContent(); |
||
| 423 | if (false === strpos($content, "\n") && !$tokens[$tokens->getPrevNonWhitespace($index - 1)]->isComment()) { |
||
| 424 | $tokens->clearAt($index - 1); |
||
| 425 | } |
||
| 426 | } |
||
| 427 | } |
||
| 428 | |||
| 429 | /** |
||
| 430 | * @return false|int index of T_DECLARE where the `=` belongs to or `false` |
||
| 431 | */ |
||
| 432 | private function isEqualPartOfDeclareStatement(Tokens $tokens, int $index) |
||
| 433 | { |
||
| 434 | $prevMeaningfulIndex = $tokens->getPrevMeaningfulToken($index); |
||
| 435 | if ($tokens[$prevMeaningfulIndex]->isGivenKind(T_STRING)) { |
||
| 436 | $prevMeaningfulIndex = $tokens->getPrevMeaningfulToken($prevMeaningfulIndex); |
||
|
|
|||
| 437 | if ($tokens[$prevMeaningfulIndex]->equals('(')) { |
||
| 438 | $prevMeaningfulIndex = $tokens->getPrevMeaningfulToken($prevMeaningfulIndex); |
||
| 439 | if ($tokens[$prevMeaningfulIndex]->isGivenKind(T_DECLARE)) { |
||
| 440 | return $prevMeaningfulIndex; |
||
| 441 | } |
||
| 442 | } |
||
| 443 | } |
||
| 444 | |||
| 445 | return false; |
||
| 446 | } |
||
| 447 | |||
| 448 | /** |
||
| 449 | * @return array<string, string> |
||
| 450 | */ |
||
| 451 | private function resolveOperatorsFromConfig(): array |
||
| 475 | } |
||
| 476 | |||
| 477 | // Alignment logic related methods |
||
| 478 | |||
| 479 | /** |
||
| 480 | * @param array<string, string> $toAlign |
||
| 481 | */ |
||
| 482 | private function fixAlignment(Tokens $tokens, array $toAlign): void |
||
| 483 | { |
||
| 484 | $this->deepestLevel = 0; |
||
| 485 | $this->currentLevel = 0; |
||
| 486 | |||
| 487 | foreach ($toAlign as $tokenContent => $alignStrategy) { |
||
| 488 | // This fixer works partially on Tokens and partially on string representation of code. |
||
| 489 | // During the process of fixing internal state of single Token may be affected by injecting ALIGN_PLACEHOLDER to its content. |
||
| 490 | // The placeholder will be resolved by `replacePlaceholders` method by removing placeholder or changing it into spaces. |
||
| 491 | // That way of fixing the code causes disturbances in marking Token as changed - if code is perfectly valid then placeholder |
||
| 492 | // still be injected and removed, which will cause the `changed` flag to be set. |
||
| 493 | // To handle that unwanted behavior we work on clone of Tokens collection and then override original collection with fixed collection. |
||
| 494 | $tokensClone = clone $tokens; |
||
| 495 | |||
| 496 | if ('=>' === $tokenContent) { |
||
| 497 | $this->injectAlignmentPlaceholdersForArrow($tokensClone, 0, \count($tokens)); |
||
| 498 | } else { |
||
| 499 | $this->injectAlignmentPlaceholders($tokensClone, 0, \count($tokens), $tokenContent); |
||
| 500 | } |
||
| 501 | |||
| 502 | // for all tokens that should be aligned but do not have anything to align with, fix spacing if needed |
||
| 503 | if (self::ALIGN_SINGLE_SPACE === $alignStrategy || self::ALIGN_SINGLE_SPACE_MINIMAL === $alignStrategy) { |
||
| 504 | if ('=>' === $tokenContent) { |
||
| 505 | for ($index = $tokens->count() - 2; $index > 0; --$index) { |
||
| 506 | if ($tokens[$index]->isGivenKind(T_DOUBLE_ARROW)) { // always binary operator, never part of declare statement |
||
| 507 | $this->fixWhiteSpaceBeforeOperator($tokensClone, $index, $alignStrategy); |
||
| 508 | } |
||
| 509 | } |
||
| 510 | } elseif ('=' === $tokenContent) { |
||
| 511 | for ($index = $tokens->count() - 2; $index > 0; --$index) { |
||
| 512 | if ('=' === $tokens[$index]->getContent() && !$this->isEqualPartOfDeclareStatement($tokens, $index) && $this->tokensAnalyzer->isBinaryOperator($index)) { |
||
| 513 | $this->fixWhiteSpaceBeforeOperator($tokensClone, $index, $alignStrategy); |
||
| 514 | } |
||
| 515 | } |
||
| 516 | } else { |
||
| 517 | for ($index = $tokens->count() - 2; $index > 0; --$index) { |
||
| 518 | $content = $tokens[$index]->getContent(); |
||
| 519 | if (strtolower($content) === $tokenContent && $this->tokensAnalyzer->isBinaryOperator($index)) { // never part of declare statement |
||
| 520 | $this->fixWhiteSpaceBeforeOperator($tokensClone, $index, $alignStrategy); |
||
| 521 | } |
||
| 522 | } |
||
| 523 | } |
||
| 524 | } |
||
| 525 | |||
| 526 | $tokens->setCode($this->replacePlaceholders($tokensClone, $alignStrategy)); |
||
| 527 | } |
||
| 528 | } |
||
| 529 | |||
| 530 | private function injectAlignmentPlaceholders(Tokens $tokens, int $startAt, int $endAt, string $tokenContent): void |
||
| 531 | { |
||
| 532 | for ($index = $startAt; $index < $endAt; ++$index) { |
||
| 533 | $token = $tokens[$index]; |
||
| 534 | |||
| 535 | $content = $token->getContent(); |
||
| 536 | if ( |
||
| 537 | strtolower($content) === $tokenContent |
||
| 538 | && $this->tokensAnalyzer->isBinaryOperator($index) |
||
| 539 | && ('=' !== $content || !$this->isEqualPartOfDeclareStatement($tokens, $index)) |
||
| 540 | ) { |
||
| 541 | $tokens[$index] = new Token(sprintf(self::ALIGN_PLACEHOLDER, $this->deepestLevel).$content); |
||
| 542 | |||
| 543 | continue; |
||
| 544 | } |
||
| 545 | |||
| 546 | if ($token->isGivenKind(T_FUNCTION)) { |
||
| 547 | ++$this->deepestLevel; |
||
| 548 | |||
| 549 | continue; |
||
| 550 | } |
||
| 551 | |||
| 552 | if ($token->equals('(')) { |
||
| 553 | $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index); |
||
| 554 | |||
| 555 | continue; |
||
| 556 | } |
||
| 557 | |||
| 558 | if ($token->equals('[')) { |
||
| 559 | $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $index); |
||
| 560 | |||
| 561 | continue; |
||
| 562 | } |
||
| 563 | |||
| 564 | if ($token->isGivenKind(CT::T_ARRAY_SQUARE_BRACE_OPEN)) { |
||
| 565 | $index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $index); |
||
| 566 | |||
| 567 | continue; |
||
| 568 | } |
||
| 569 | } |
||
| 570 | } |
||
| 571 | |||
| 572 | private function injectAlignmentPlaceholdersForArrow(Tokens $tokens, int $startAt, int $endAt): void |
||
| 646 | } |
||
| 647 | } |
||
| 648 | } |
||
| 649 | } |
||
| 650 | |||
| 651 | private function injectArrayAlignmentPlaceholders(Tokens $tokens, int $from, int $until): void |
||
| 659 | } |
||
| 660 | } |
||
| 661 | |||
| 662 | private function fixWhiteSpaceBeforeOperator(Tokens $tokens, int $index, string $alignStrategy): void |
||
| 663 | { |
||
| 664 | // fix white space after operator is not needed as BinaryOperatorSpacesFixer took care of this (if strategy is _not_ ALIGN) |
||
| 665 | if (!$tokens[$index - 1]->isWhitespace()) { |
||
| 666 | $tokens->insertAt($index, new Token([T_WHITESPACE, ' '])); |
||
| 667 | |||
| 668 | return; |
||
| 669 | } |
||
| 670 | |||
| 671 | if (self::ALIGN_SINGLE_SPACE_MINIMAL !== $alignStrategy || $tokens[$tokens->getPrevNonWhitespace($index - 1)]->isComment()) { |
||
| 672 | return; |
||
| 673 | } |
||
| 674 | |||
| 675 | $content = $tokens[$index - 1]->getContent(); |
||
| 676 | if (' ' !== $content && false === strpos($content, "\n")) { |
||
| 677 | $tokens[$index - 1] = new Token([T_WHITESPACE, ' ']); |
||
| 678 | } |
||
| 679 | } |
||
| 680 | |||
| 681 | /** |
||
| 682 | * Look for group of placeholders and provide vertical alignment. |
||
| 683 | */ |
||
| 684 | private function replacePlaceholders(Tokens $tokens, string $alignStrategy): string |
||
| 755 | } |
||
| 756 | } |
||
| 757 |