You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.3 KiB

3 years ago
  1. <?php
  2. /*
  3. * This file is part of Psy Shell.
  4. *
  5. * (c) 2012-2020 Justin Hileman
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Psy;
  11. use PhpParser\Lexer;
  12. use PhpParser\Parser;
  13. use PhpParser\ParserFactory as OriginalParserFactory;
  14. /**
  15. * Parser factory to abstract over PHP parser library versions.
  16. */
  17. class ParserFactory
  18. {
  19. const ONLY_PHP5 = 'ONLY_PHP5';
  20. const ONLY_PHP7 = 'ONLY_PHP7';
  21. const PREFER_PHP5 = 'PREFER_PHP5';
  22. const PREFER_PHP7 = 'PREFER_PHP7';
  23. /**
  24. * Possible kinds of parsers for the factory, from PHP parser library.
  25. *
  26. * @return array
  27. */
  28. public static function getPossibleKinds()
  29. {
  30. return ['ONLY_PHP5', 'ONLY_PHP7', 'PREFER_PHP5', 'PREFER_PHP7'];
  31. }
  32. /**
  33. * Is this parser factory supports kinds?
  34. *
  35. * PHP parser < 2.0 doesn't support kinds, >= 2.0 does.
  36. *
  37. * @return bool
  38. */
  39. public function hasKindsSupport()
  40. {
  41. return \class_exists(OriginalParserFactory::class);
  42. }
  43. /**
  44. * Default kind (if supported, based on current interpreter's version).
  45. *
  46. * @return string|null
  47. */
  48. public function getDefaultKind()
  49. {
  50. if ($this->hasKindsSupport()) {
  51. return \version_compare(\PHP_VERSION, '7.0', '>=') ? static::ONLY_PHP7 : static::ONLY_PHP5;
  52. }
  53. }
  54. /**
  55. * New parser instance with given kind.
  56. *
  57. * @param string|null $kind One of class constants (only for PHP parser 2.0 and above)
  58. *
  59. * @return Parser
  60. */
  61. public function createParser($kind = null)
  62. {
  63. if ($this->hasKindsSupport()) {
  64. $originalFactory = new OriginalParserFactory();
  65. $kind = $kind ?: $this->getDefaultKind();
  66. if (!\in_array($kind, static::getPossibleKinds())) {
  67. throw new \InvalidArgumentException('Unknown parser kind');
  68. }
  69. $parser = $originalFactory->create(\constant(OriginalParserFactory::class.'::'.$kind));
  70. } else {
  71. if ($kind !== null) {
  72. throw new \InvalidArgumentException('Install PHP Parser v2.x to specify parser kind');
  73. }
  74. $parser = new Parser(new Lexer());
  75. }
  76. return $parser;
  77. }
  78. }