TraverserFactory::create()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 9
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
nc 1
nop 1
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 1
rs 10
c 9
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the humbug/php-scoper package.
7
 *
8
 * Copyright (c) 2017 Théo FIDRY <[email protected]>,
9
 *                    Pádraic Brady <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Humbug\PhpScoper\PhpParser;
16
17
use Humbug\PhpScoper\PhpParser\NodeVisitor\NamespaceStmt\NamespaceStmtCollection;
18
use Humbug\PhpScoper\PhpParser\NodeVisitor\Resolver\IdentifierResolver;
19
use Humbug\PhpScoper\PhpParser\NodeVisitor\UseStmt\UseStmtCollection;
20
use Humbug\PhpScoper\Scoper\PhpScoper;
21
use Humbug\PhpScoper\Symbol\EnrichedReflector;
22
use Humbug\PhpScoper\Symbol\SymbolsRegistry;
23
use PhpParser\NodeTraverser as PhpParserNodeTraverser;
24
use PhpParser\NodeTraverserInterface;
25
use PhpParser\NodeVisitor as PhpParserNodeVisitor;
26
use PhpParser\NodeVisitor\NameResolver;
27
28
/**
29
 * @private
30
 */
31
class TraverserFactory
32 555
{
33
    private EnrichedReflector $reflector;
34 555
    private string $prefix;
35
    private SymbolsRegistry $symbolsRegistry;
36
37 550
    public function __construct(
38
        EnrichedReflector $reflector,
39 550
        string $prefix,
40
        SymbolsRegistry $symbolsRegistry
41 550
    ) {
42 550
        $this->reflector = $reflector;
43
        $this->prefix = $prefix;
44 550
        $this->symbolsRegistry = $symbolsRegistry;
45
    }
46 550
47
    public function create(PhpScoper $scoper): NodeTraverserInterface
48 550
    {
49
        return self::createTraverser(
50 550
            self::createNodeVisitors(
51 550
                $this->prefix,
52
                $this->reflector,
53 550
                $scoper,
54 550
                $this->symbolsRegistry,
55 550
            ),
56 550
        );
57 550
    }
58 550
59
    /**
60 550
     * @param PhpParserNodeVisitor[] $nodeVisitors
61 550
     */
62
    private static function createTraverser(array $nodeVisitors): NodeTraverserInterface
63 550
    {
64
        $traverser = new NodeTraverser(
65
            new PhpParserNodeTraverser(),
66
        );
67
68
        foreach ($nodeVisitors as $nodeVisitor) {
69
            $traverser->addVisitor($nodeVisitor);
70
        }
71
72
        return $traverser;
73
    }
74
75
    /**
76
     * @return PhpParserNodeVisitor[]
77
     */
78
    private static function createNodeVisitors(
79
        string $prefix,
80
        EnrichedReflector $reflector,
81
        PhpScoper $scoper,
82
        SymbolsRegistry $symbolsRegistry
83
    ): array {
84
        $namespaceStatements = new NamespaceStmtCollection();
85
        $useStatements = new UseStmtCollection();
86
87
        $nameResolver = new NameResolver(
88
            null,
89
            ['preserveOriginalNames' => true],
90
        );
91
        $identifierResolver = new IdentifierResolver($nameResolver);
92
        $stringNodePrefixer = new StringNodePrefixer($scoper);
93
94
        return [
95
            $nameResolver,
96
            new NodeVisitor\ParentNodeAppender(),
97
            new NodeVisitor\IdentifierNameAppender($identifierResolver),
98
99
            new NodeVisitor\NamespaceStmt\NamespaceStmtPrefixer(
100
                $prefix,
101
                $reflector,
102
                $namespaceStatements,
103
            ),
104
105
            new NodeVisitor\UseStmt\UseStmtCollector(
106
                $namespaceStatements,
107
                $useStatements,
108
            ),
109
            new NodeVisitor\UseStmt\UseStmtPrefixer(
110
                $prefix,
111
                $reflector,
112
            ),
113
114
            new NodeVisitor\NamespaceStmt\FunctionIdentifierRecorder(
115
                $prefix,
116
                $identifierResolver,
117
                $symbolsRegistry,
118
                $reflector,
119
            ),
120
            new NodeVisitor\ClassIdentifierRecorder(
121
                $prefix,
122
                $identifierResolver,
123
                $symbolsRegistry,
124
                $reflector,
125
            ),
126
            new NodeVisitor\NameStmtPrefixer(
127
                $prefix,
128
                $namespaceStatements,
129
                $useStatements,
130
                $reflector,
131
            ),
132
            new NodeVisitor\StringScalarPrefixer(
133
                $prefix,
134
                $reflector,
135
            ),
136
            new NodeVisitor\NewdocPrefixer($stringNodePrefixer),
137
            new NodeVisitor\EvalPrefixer($stringNodePrefixer),
138
139
            new NodeVisitor\ClassAliasStmtAppender(
140
                $prefix,
141
                $reflector,
142
                $identifierResolver,
143
            ),
144
            new NodeVisitor\MultiConstStmtReplacer(),
145
            new NodeVisitor\ConstStmtReplacer(
146
                $identifierResolver,
147
                $reflector,
148
            ),
149
        ];
150
    }
151
}
152