NewDynamicAccessToStaticSniff.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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 dynamic access to static methods and properties, as well as class constants.
  16. *
  17. * As of PHP 5.3, static properties and methods as well as class constants
  18. * can be accessed using a dynamic (variable) class name.
  19. *
  20. * PHP version 5.3
  21. *
  22. * @link https://www.php.net/manual/en/migration53.new-features.php
  23. *
  24. * @since 8.1.0
  25. * @since 9.0.0 Renamed from `DynamicAccessToStaticSniff` to `NewDynamicAccessToStaticSniff`.
  26. */
  27. class NewDynamicAccessToStaticSniff extends Sniff
  28. {
  29. /**
  30. * Returns an array of tokens this test wants to listen for.
  31. *
  32. * @since 8.1.0
  33. *
  34. * @return array
  35. */
  36. public function register()
  37. {
  38. return array(
  39. \T_DOUBLE_COLON,
  40. );
  41. }
  42. /**
  43. * Processes this test, when one of its tokens is encountered.
  44. *
  45. * @since 8.1.0
  46. *
  47. * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
  48. * @param int $stackPtr The position of the current token in the
  49. * stack passed in $tokens.
  50. *
  51. * @return void
  52. */
  53. public function process(File $phpcsFile, $stackPtr)
  54. {
  55. if ($this->supportsBelow('5.2') === false) {
  56. return;
  57. }
  58. $tokens = $phpcsFile->getTokens();
  59. $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
  60. // Disregard `static::` as well. Late static binding is reported by another sniff.
  61. if ($tokens[$prevNonEmpty]['code'] === \T_SELF
  62. || $tokens[$prevNonEmpty]['code'] === \T_PARENT
  63. || $tokens[$prevNonEmpty]['code'] === \T_STATIC
  64. ) {
  65. return;
  66. }
  67. if ($tokens[$prevNonEmpty]['code'] === \T_STRING) {
  68. $prevPrevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($prevNonEmpty - 1), null, true);
  69. if ($tokens[$prevPrevNonEmpty]['code'] !== \T_OBJECT_OPERATOR) {
  70. return;
  71. }
  72. }
  73. $phpcsFile->addError(
  74. 'Static class properties and methods, as well as class constants, could not be accessed using a dynamic (variable) classname in PHP 5.2 or earlier.',
  75. $stackPtr,
  76. 'Found'
  77. );
  78. }
  79. }