ReservedWordsSniff.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Sniffs\NamingConventions;
  7. use PHP_CodeSniffer\Sniffs\Sniff;
  8. use PHP_CodeSniffer\Files\File;
  9. /**
  10. * Validates that class name is not reserved word.
  11. */
  12. class ReservedWordsSniff implements Sniff
  13. {
  14. /**
  15. * The following words cannot be used to name a class, interface or trait,
  16. * and they are also prohibited from being used in namespaces.
  17. *
  18. * @link http://php.net/manual/en/reserved.other-reserved-words.php
  19. *
  20. * @var string[]
  21. */
  22. protected $reservedWords = [
  23. 'int' => '7',
  24. 'float' => '7',
  25. 'bool' => '7',
  26. 'string' => '7',
  27. 'true' => '7',
  28. 'false' => '7',
  29. 'null' => '7',
  30. 'void' => '7.1',
  31. 'iterable' => '7.1',
  32. 'resource' => '7',
  33. 'object' => '7',
  34. 'mixed' => '7',
  35. 'numeric' => '7',
  36. ];
  37. /**
  38. * @inheritdoc
  39. */
  40. public function register()
  41. {
  42. return [T_CLASS, T_INTERFACE, T_TRAIT, T_NAMESPACE];
  43. }
  44. /**
  45. * Check all namespace parts
  46. *
  47. * @param File $sourceFile
  48. * @param int $stackPtr
  49. * @return void
  50. */
  51. protected function validateNamespace(File $sourceFile, $stackPtr)
  52. {
  53. $stackPtr += 2;
  54. $tokens = $sourceFile->getTokens();
  55. while ($stackPtr < $sourceFile->numTokens && $tokens[$stackPtr]['code'] !== T_SEMICOLON) {
  56. if ($tokens[$stackPtr]['code'] === T_WHITESPACE || $tokens[$stackPtr]['code'] === T_NS_SEPARATOR) {
  57. $stackPtr++; //skip "namespace" and whitespace
  58. continue;
  59. }
  60. $namespacePart = $tokens[$stackPtr]['content'];
  61. if (isset($this->reservedWords[strtolower($namespacePart)])) {
  62. $sourceFile->addError(
  63. 'Cannot use "%s" in namespace as it is reserved since PHP %s',
  64. $stackPtr,
  65. 'Namespace',
  66. [$namespacePart, $this->reservedWords[strtolower($namespacePart)]]
  67. );
  68. }
  69. $stackPtr++;
  70. }
  71. }
  72. /**
  73. * Check class name not having reserved words
  74. *
  75. * @param File $sourceFile
  76. * @param int $stackPtr
  77. * @return void
  78. */
  79. protected function validateClass(File $sourceFile, $stackPtr)
  80. {
  81. $tokens = $sourceFile->getTokens();
  82. $stackPtr += 2; //skip "class" and whitespace
  83. $className = strtolower($tokens[$stackPtr]['content']);
  84. if (isset($this->reservedWords[$className])) {
  85. $sourceFile->addError(
  86. 'Cannot use "%s" as class name as it is reserved since PHP %s',
  87. $stackPtr,
  88. 'Class',
  89. [$className, $this->reservedWords[$className]]
  90. );
  91. }
  92. }
  93. /**
  94. * @inheritdoc
  95. */
  96. public function process(File $sourceFile, $stackPtr)
  97. {
  98. $tokens = $sourceFile->getTokens();
  99. switch ($tokens[$stackPtr]['code']) {
  100. case T_CLASS:
  101. case T_INTERFACE:
  102. case T_TRAIT:
  103. $this->validateClass($sourceFile, $stackPtr);
  104. break;
  105. case T_NAMESPACE:
  106. $this->validateNamespace($sourceFile, $stackPtr);
  107. break;
  108. }
  109. }
  110. }