PhpVersion.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. <?php declare(strict_types=1);
  2. namespace PhpParser;
  3. /**
  4. * A PHP version, representing only the major and minor version components.
  5. */
  6. class PhpVersion {
  7. /** @var int Version ID in PHP_VERSION_ID format */
  8. public int $id;
  9. /** @var int[] Minimum versions for builtin types */
  10. private const BUILTIN_TYPE_VERSIONS = [
  11. 'array' => 50100,
  12. 'callable' => 50400,
  13. 'bool' => 70000,
  14. 'int' => 70000,
  15. 'float' => 70000,
  16. 'string' => 70000,
  17. 'iterable' => 70100,
  18. 'void' => 70100,
  19. 'object' => 70200,
  20. 'null' => 80000,
  21. 'false' => 80000,
  22. 'mixed' => 80000,
  23. 'never' => 80100,
  24. 'true' => 80200,
  25. ];
  26. private function __construct(int $id) {
  27. $this->id = $id;
  28. }
  29. /**
  30. * Create a PhpVersion object from major and minor version components.
  31. */
  32. public static function fromComponents(int $major, int $minor): self {
  33. return new self($major * 10000 + $minor * 100);
  34. }
  35. /**
  36. * Get the newest PHP version supported by this library. Support for this version may be partial,
  37. * if it is still under development.
  38. */
  39. public static function getNewestSupported(): self {
  40. return self::fromComponents(8, 2);
  41. }
  42. /**
  43. * Get the host PHP version, that is the PHP version we're currently running on.
  44. */
  45. public static function getHostVersion(): self {
  46. return self::fromComponents(\PHP_MAJOR_VERSION, \PHP_MINOR_VERSION);
  47. }
  48. /**
  49. * Parse the version from a string like "8.1".
  50. */
  51. public static function fromString(string $version): self {
  52. if (!preg_match('/^(\d+)\.(\d+)/', $version, $matches)) {
  53. throw new \LogicException("Invalid PHP version \"$version\"");
  54. }
  55. return self::fromComponents((int) $matches[1], (int) $matches[2]);
  56. }
  57. /**
  58. * Check whether two versions are the same.
  59. */
  60. public function equals(PhpVersion $other): bool {
  61. return $this->id === $other->id;
  62. }
  63. /**
  64. * Check whether this version is greater than or equal to the argument.
  65. */
  66. public function newerOrEqual(PhpVersion $other): bool {
  67. return $this->id >= $other->id;
  68. }
  69. /**
  70. * Check whether this version is older than the argument.
  71. */
  72. public function older(PhpVersion $other): bool {
  73. return $this->id < $other->id;
  74. }
  75. /**
  76. * Check whether this is the host PHP version.
  77. */
  78. public function isHostVersion(): bool {
  79. return $this->equals(self::getHostVersion());
  80. }
  81. /**
  82. * Check whether this PHP version supports the given builtin type. Type name must be lowercase.
  83. */
  84. public function supportsBuiltinType(string $type): bool {
  85. $minVersion = self::BUILTIN_TYPE_VERSIONS[$type] ?? null;
  86. return $minVersion !== null && $this->id >= $minVersion;
  87. }
  88. /**
  89. * Whether this version supports [] array literals.
  90. */
  91. public function supportsShortArraySyntax(): bool {
  92. return $this->id >= 50400;
  93. }
  94. /**
  95. * Whether this version supports [] for destructuring.
  96. */
  97. public function supportsShortArrayDestructuring(): bool {
  98. return $this->id >= 70100;
  99. }
  100. /**
  101. * Whether this version supports flexible heredoc/nowdoc.
  102. */
  103. public function supportsFlexibleHeredoc(): bool {
  104. return $this->id >= 70300;
  105. }
  106. /**
  107. * Whether this version supports trailing commas in parameter lists.
  108. */
  109. public function supportsTrailingCommaInParamList(): bool {
  110. return $this->id >= 80000;
  111. }
  112. /**
  113. * Whether this version allows "$var =& new Obj".
  114. */
  115. public function allowsAssignNewByReference(): bool {
  116. return $this->id < 70000;
  117. }
  118. /**
  119. * Whether this version allows invalid octals like "08".
  120. */
  121. public function allowsInvalidOctals(): bool {
  122. return $this->id < 70000;
  123. }
  124. /**
  125. * Whether this version allows DEL (\x7f) to occur in identifiers.
  126. */
  127. public function allowsDelInIdentifiers(): bool {
  128. return $this->id < 70100;
  129. }
  130. /**
  131. * Whether this version supports yield in expression context without parentheses.
  132. */
  133. public function supportsYieldWithoutParentheses(): bool {
  134. return $this->id >= 70000;
  135. }
  136. /**
  137. * Whether this version supports unicode escape sequences in strings.
  138. */
  139. public function supportsUnicodeEscapes(): bool {
  140. return $this->id >= 70000;
  141. }
  142. }