ExplicitIndirectVariableFixer.php 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4. * This file is part of PHP CS Fixer.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. * Dariusz Rumiński <dariusz.ruminski@gmail.com>
  8. *
  9. * This source file is subject to the MIT license that is bundled
  10. * with this source code in the file LICENSE.
  11. */
  12. namespace PhpCsFixer\Fixer\LanguageConstruct;
  13. use PhpCsFixer\AbstractFixer;
  14. use PhpCsFixer\FixerDefinition\CodeSample;
  15. use PhpCsFixer\FixerDefinition\FixerDefinition;
  16. use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
  17. use PhpCsFixer\Tokenizer\CT;
  18. use PhpCsFixer\Tokenizer\Token;
  19. use PhpCsFixer\Tokenizer\Tokens;
  20. /**
  21. * @author Filippo Tessarotto <zoeslam@gmail.com>
  22. */
  23. final class ExplicitIndirectVariableFixer extends AbstractFixer
  24. {
  25. public function getDefinition(): FixerDefinitionInterface
  26. {
  27. return new FixerDefinition(
  28. 'Add curly braces to indirect variables to make them clear to understand. Requires PHP >= 7.0.',
  29. [
  30. new CodeSample(
  31. <<<'EOT'
  32. <?php
  33. echo $$foo;
  34. echo $$foo['bar'];
  35. echo $foo->$bar['baz'];
  36. echo $foo->$callback($baz);
  37. EOT
  38. ),
  39. ]
  40. );
  41. }
  42. public function isCandidate(Tokens $tokens): bool
  43. {
  44. return $tokens->isTokenKindFound(T_VARIABLE);
  45. }
  46. protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
  47. {
  48. for ($index = $tokens->count() - 1; $index > 1; --$index) {
  49. $token = $tokens[$index];
  50. if (!$token->isGivenKind(T_VARIABLE)) {
  51. continue;
  52. }
  53. $prevIndex = $tokens->getPrevMeaningfulToken($index);
  54. $prevToken = $tokens[$prevIndex];
  55. if (!$prevToken->equals('$') && !$prevToken->isObjectOperator()) {
  56. continue;
  57. }
  58. $openingBrace = CT::T_DYNAMIC_VAR_BRACE_OPEN;
  59. $closingBrace = CT::T_DYNAMIC_VAR_BRACE_CLOSE;
  60. if ($prevToken->isObjectOperator()) {
  61. $openingBrace = CT::T_DYNAMIC_PROP_BRACE_OPEN;
  62. $closingBrace = CT::T_DYNAMIC_PROP_BRACE_CLOSE;
  63. }
  64. $tokens->overrideRange($index, $index, [
  65. new Token([$openingBrace, '{']),
  66. new Token([T_VARIABLE, $token->getContent()]),
  67. new Token([$closingBrace, '}']),
  68. ]);
  69. }
  70. }
  71. }