annotate vendor/psy/psysh/src/CodeCleaner/NamespacePass.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
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\CodeCleaner;
Chris@13 13
Chris@13 14 use PhpParser\Node\Name;
Chris@13 15 use PhpParser\Node\Stmt\Namespace_;
Chris@13 16 use Psy\CodeCleaner;
Chris@13 17
Chris@13 18 /**
Chris@13 19 * Provide implicit namespaces for subsequent execution.
Chris@13 20 *
Chris@13 21 * The namespace pass remembers the last standalone namespace line encountered:
Chris@13 22 *
Chris@13 23 * namespace Foo\Bar;
Chris@13 24 *
Chris@13 25 * ... which it then applies implicitly to all future evaluated code, until the
Chris@13 26 * namespace is replaced by another namespace. To reset to the top level
Chris@13 27 * namespace, enter `namespace {}`. This is a bit ugly, but it does the trick :)
Chris@13 28 */
Chris@13 29 class NamespacePass extends CodeCleanerPass
Chris@13 30 {
Chris@13 31 private $namespace = null;
Chris@13 32 private $cleaner;
Chris@13 33
Chris@13 34 /**
Chris@13 35 * @param CodeCleaner $cleaner
Chris@13 36 */
Chris@13 37 public function __construct(CodeCleaner $cleaner)
Chris@13 38 {
Chris@13 39 $this->cleaner = $cleaner;
Chris@13 40 }
Chris@13 41
Chris@13 42 /**
Chris@13 43 * If this is a standalone namespace line, remember it for later.
Chris@13 44 *
Chris@13 45 * Otherwise, apply remembered namespaces to the code until a new namespace
Chris@13 46 * is encountered.
Chris@13 47 *
Chris@13 48 * @param array $nodes
Chris@13 49 */
Chris@13 50 public function beforeTraverse(array $nodes)
Chris@13 51 {
Chris@13 52 if (empty($nodes)) {
Chris@13 53 return $nodes;
Chris@13 54 }
Chris@13 55
Chris@17 56 $last = \end($nodes);
Chris@13 57
Chris@13 58 if ($last instanceof Namespace_) {
Chris@13 59 $kind = $last->getAttribute('kind');
Chris@13 60
Chris@13 61 // Treat all namespace statements pre-PHP-Parser v3.1.2 as "open",
Chris@13 62 // even though we really have no way of knowing.
Chris@13 63 if ($kind === null || $kind === Namespace_::KIND_SEMICOLON) {
Chris@13 64 // Save the current namespace for open namespaces
Chris@13 65 $this->setNamespace($last->name);
Chris@13 66 } else {
Chris@13 67 // Clear the current namespace after a braced namespace
Chris@13 68 $this->setNamespace(null);
Chris@13 69 }
Chris@13 70
Chris@13 71 return $nodes;
Chris@13 72 }
Chris@13 73
Chris@13 74 return $this->namespace ? [new Namespace_($this->namespace, $nodes)] : $nodes;
Chris@13 75 }
Chris@13 76
Chris@13 77 /**
Chris@13 78 * Remember the namespace and (re)set the namespace on the CodeCleaner as
Chris@13 79 * well.
Chris@13 80 *
Chris@13 81 * @param null|Name $namespace
Chris@13 82 */
Chris@13 83 private function setNamespace($namespace)
Chris@13 84 {
Chris@13 85 $this->namespace = $namespace;
Chris@13 86 $this->cleaner->setNamespace($namespace === null ? null : $namespace->parts);
Chris@13 87 }
Chris@13 88 }