Mercurial > hg > isophonics-drupal-site
comparison vendor/psy/psysh/src/Psy/CodeCleaner/UseStatementPass.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 /* | |
4 * This file is part of Psy Shell. | |
5 * | |
6 * (c) 2012-2017 Justin Hileman | |
7 * | |
8 * For the full copyright and license information, please view the LICENSE | |
9 * file that was distributed with this source code. | |
10 */ | |
11 | |
12 namespace Psy\CodeCleaner; | |
13 | |
14 use PhpParser\Node; | |
15 use PhpParser\Node\Name; | |
16 use PhpParser\Node\Name\FullyQualified as FullyQualifiedName; | |
17 use PhpParser\Node\Stmt\GroupUse; | |
18 use PhpParser\Node\Stmt\Namespace_; | |
19 use PhpParser\Node\Stmt\Use_; | |
20 | |
21 /** | |
22 * Provide implicit use statements for subsequent execution. | |
23 * | |
24 * The use statement pass remembers the last use statement line encountered: | |
25 * | |
26 * use Foo\Bar as Baz; | |
27 * | |
28 * ... which it then applies implicitly to all future evaluated code, until the | |
29 * current namespace is replaced by another namespace. | |
30 */ | |
31 class UseStatementPass extends CodeCleanerPass | |
32 { | |
33 private $aliases = array(); | |
34 private $lastAliases = array(); | |
35 private $lastNamespace = null; | |
36 | |
37 /** | |
38 * Re-load the last set of use statements on re-entering a namespace. | |
39 * | |
40 * This isn't how namespaces normally work, but because PsySH has to spin | |
41 * up a new namespace for every line of code, we do this to make things | |
42 * work like you'd expect. | |
43 * | |
44 * @param Node $node | |
45 */ | |
46 public function enterNode(Node $node) | |
47 { | |
48 if ($node instanceof Namespace_) { | |
49 // If this is the same namespace as last namespace, let's do ourselves | |
50 // a favor and reload all the aliases... | |
51 if (strtolower($node->name) === strtolower($this->lastNamespace)) { | |
52 $this->aliases = $this->lastAliases; | |
53 } | |
54 } | |
55 } | |
56 | |
57 /** | |
58 * If this statement is a namespace, forget all the aliases we had. | |
59 * | |
60 * If it's a use statement, remember the alias for later. Otherwise, apply | |
61 * remembered aliases to the code. | |
62 * | |
63 * @param Node $node | |
64 */ | |
65 public function leaveNode(Node $node) | |
66 { | |
67 if ($node instanceof Use_) { | |
68 // Store a reference to every "use" statement, because we'll need | |
69 // them in a bit. | |
70 foreach ($node->uses as $use) { | |
71 $this->aliases[strtolower($use->alias)] = $use->name; | |
72 } | |
73 | |
74 return false; | |
75 } elseif ($node instanceof GroupUse) { | |
76 // Expand every "use" statement in the group into a full, standalone | |
77 // "use" and store 'em with the others. | |
78 foreach ($node->uses as $use) { | |
79 $this->aliases[strtolower($use->alias)] = Name::concat($node->prefix, $use->name, array( | |
80 'startLine' => $node->prefix->getAttribute('startLine'), | |
81 'endLine' => $use->name->getAttribute('endLine'), | |
82 )); | |
83 } | |
84 | |
85 return false; | |
86 } elseif ($node instanceof Namespace_) { | |
87 // Start fresh, since we're done with this namespace. | |
88 $this->lastNamespace = $node->name; | |
89 $this->lastAliases = $this->aliases; | |
90 $this->aliases = array(); | |
91 } else { | |
92 foreach ($node as $name => $subNode) { | |
93 if ($subNode instanceof Name) { | |
94 // Implicitly thunk all aliases. | |
95 if ($replacement = $this->findAlias($subNode)) { | |
96 $node->$name = $replacement; | |
97 } | |
98 } | |
99 } | |
100 | |
101 return $node; | |
102 } | |
103 } | |
104 | |
105 /** | |
106 * Find class/namespace aliases. | |
107 * | |
108 * @param Name $name | |
109 * | |
110 * @return FullyQualifiedName|null | |
111 */ | |
112 private function findAlias(Name $name) | |
113 { | |
114 $that = strtolower($name); | |
115 foreach ($this->aliases as $alias => $prefix) { | |
116 if ($that === $alias) { | |
117 return new FullyQualifiedName($prefix->toString()); | |
118 } elseif (substr($that, 0, strlen($alias) + 1) === $alias . '\\') { | |
119 return new FullyQualifiedName($prefix->toString() . substr($name, strlen($alias))); | |
120 } | |
121 } | |
122 } | |
123 } |