NewFunctionCallTrailingCommaSniff.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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\Syntax;
  11. use PHPCompatibility\Sniff;
  12. use PHP_CodeSniffer_File as File;
  13. use PHP_CodeSniffer_Tokens as Tokens;
  14. /**
  15. * Detect trailing comma's in function calls, `isset()` and `unset()` as allowed since PHP 7.3.
  16. *
  17. * PHP version 7.3
  18. *
  19. * @link https://www.php.net/manual/en/migration73.new-features.php#migration73.new-features.core.trailing-commas
  20. * @link https://wiki.php.net/rfc/trailing-comma-function-calls
  21. *
  22. * @since 8.2.0
  23. * @since 9.0.0 Renamed from `NewTrailingCommaSniff` to `NewFunctionCallTrailingCommaSniff`.
  24. */
  25. class NewFunctionCallTrailingCommaSniff extends Sniff
  26. {
  27. /**
  28. * Returns an array of tokens this test wants to listen for.
  29. *
  30. * @since 8.2.0
  31. *
  32. * @return array
  33. */
  34. public function register()
  35. {
  36. return array(
  37. \T_STRING,
  38. \T_VARIABLE,
  39. \T_ISSET,
  40. \T_UNSET,
  41. );
  42. }
  43. /**
  44. * Processes this test, when one of its tokens is encountered.
  45. *
  46. * @since 8.2.0
  47. *
  48. * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
  49. * @param int $stackPtr The position of the current token in
  50. * the stack passed in $tokens.
  51. *
  52. * @return void
  53. */
  54. public function process(File $phpcsFile, $stackPtr)
  55. {
  56. if ($this->supportsBelow('7.2') === false) {
  57. return;
  58. }
  59. $tokens = $phpcsFile->getTokens();
  60. $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
  61. if ($tokens[$nextNonEmpty]['code'] !== \T_OPEN_PARENTHESIS
  62. || isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false
  63. ) {
  64. return;
  65. }
  66. if ($tokens[$stackPtr]['code'] === \T_STRING) {
  67. $ignore = array(
  68. \T_FUNCTION => true,
  69. \T_CONST => true,
  70. \T_USE => true,
  71. );
  72. $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
  73. if (isset($ignore[$tokens[$prevNonEmpty]['code']]) === true) {
  74. // Not a function call.
  75. return;
  76. }
  77. }
  78. $closer = $tokens[$nextNonEmpty]['parenthesis_closer'];
  79. $lastInParenthesis = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($closer - 1), $nextNonEmpty, true);
  80. if ($tokens[$lastInParenthesis]['code'] !== \T_COMMA) {
  81. return;
  82. }
  83. $data = array();
  84. switch ($tokens[$stackPtr]['code']) {
  85. case \T_ISSET:
  86. $data[] = 'calls to isset()';
  87. $errorCode = 'FoundInIsset';
  88. break;
  89. case \T_UNSET:
  90. $data[] = 'calls to unset()';
  91. $errorCode = 'FoundInUnset';
  92. break;
  93. default:
  94. $data[] = 'function calls';
  95. $errorCode = 'FoundInFunctionCall';
  96. break;
  97. }
  98. $phpcsFile->addError(
  99. 'Trailing comma\'s are not allowed in %s in PHP 7.2 or earlier',
  100. $lastInParenthesis,
  101. $errorCode,
  102. $data
  103. );
  104. }
  105. }