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