NewGroupUseDeclarationsSniff.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <?php
  2. /**
  3. * PHPCompatibility, an external standard for PHP_CodeSniffer.
  4. *
  5. * @package PHPCompatibility
  6. * @copyright 2012-2019 PHPCompatibility Contributors
  7. * @license https://opensource.org/licenses/LGPL-3.0 LGPL3
  8. * @link https://github.com/PHPCompatibility/PHPCompatibility
  9. */
  10. namespace PHPCompatibility\Sniffs\UseDeclarations;
  11. use PHPCompatibility\Sniff;
  12. use PHP_CodeSniffer_File as File;
  13. use PHP_CodeSniffer_Tokens as Tokens;
  14. /**
  15. * Detect group use declarations as introduced in PHP 7.0.
  16. *
  17. * Checks for:
  18. * - Group use statements as introduced in PHP 7.0.
  19. * - Trailing comma's in group use statements as allowed since PHP 7.2.
  20. *
  21. * PHP version 7.0
  22. * PHP version 7.2
  23. *
  24. * @link https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.group-use-declarations
  25. * @link https://www.php.net/manual/en/migration72.new-features.php#migration72.new-features.trailing-comma-in-grouped-namespaces
  26. * @link https://wiki.php.net/rfc/group_use_declarations
  27. * @link https://wiki.php.net/rfc/list-syntax-trailing-commas
  28. * @link https://www.php.net/manual/en/language.namespaces.importing.php#language.namespaces.importing.group
  29. *
  30. * @since 7.0.0
  31. * @since 8.0.1 Now also checks for trailing comma's in group `use` declarations.
  32. */
  33. class NewGroupUseDeclarationsSniff extends Sniff
  34. {
  35. /**
  36. * Returns an array of tokens this test wants to listen for.
  37. *
  38. * @since 7.0.0
  39. *
  40. * @return array
  41. */
  42. public function register()
  43. {
  44. if (\defined('T_OPEN_USE_GROUP')) {
  45. return array(\T_OPEN_USE_GROUP);
  46. } else {
  47. return array(\T_USE);
  48. }
  49. }
  50. /**
  51. * Processes this test, when one of its tokens is encountered.
  52. *
  53. * @since 7.0.0
  54. *
  55. * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
  56. * @param int $stackPtr The position of the current token in
  57. * the stack passed in $tokens.
  58. *
  59. * @return void
  60. */
  61. public function process(File $phpcsFile, $stackPtr)
  62. {
  63. if ($this->supportsBelow('7.1') === false) {
  64. return;
  65. }
  66. $tokens = $phpcsFile->getTokens();
  67. $token = $tokens[$stackPtr];
  68. // Deal with PHPCS pre-2.6.0.
  69. if ($token['code'] === \T_USE) {
  70. $hasCurlyBrace = $phpcsFile->findNext(\T_OPEN_CURLY_BRACKET, ($stackPtr + 1), null, false, null, true);
  71. if ($hasCurlyBrace === false) {
  72. return;
  73. }
  74. $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($hasCurlyBrace - 1), null, true);
  75. if ($prevToken === false || $tokens[$prevToken]['code'] !== \T_NS_SEPARATOR) {
  76. return;
  77. }
  78. $stackPtr = $hasCurlyBrace;
  79. }
  80. // Still here ? In that case, it is a group use statement.
  81. if ($this->supportsBelow('5.6') === true) {
  82. $phpcsFile->addError(
  83. 'Group use declarations are not allowed in PHP 5.6 or earlier',
  84. $stackPtr,
  85. 'Found'
  86. );
  87. }
  88. $closers = array(\T_CLOSE_CURLY_BRACKET);
  89. if (\defined('T_CLOSE_USE_GROUP')) {
  90. $closers[] = \T_CLOSE_USE_GROUP;
  91. }
  92. $closeCurly = $phpcsFile->findNext($closers, ($stackPtr + 1), null, false, null, true);
  93. if ($closeCurly === false) {
  94. return;
  95. }
  96. $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($closeCurly - 1), null, true);
  97. if ($tokens[$prevToken]['code'] === \T_COMMA) {
  98. $phpcsFile->addError(
  99. 'Trailing comma\'s are not allowed in group use statements in PHP 7.1 or earlier',
  100. $prevToken,
  101. 'TrailingCommaFound'
  102. );
  103. }
  104. }
  105. }