Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

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