Passed
Push — master ( c6d404...885f37 )
by Théo
02:15
created

SimpleScoper::createSerializablePatchers()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 9
c 2
b 0
f 0
nc 2
nop 1
dl 0
loc 18
rs 9.9666
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the box project.
7
 *
8
 * (c) Kevin Herrera <[email protected]>
9
 *     Théo Fidry <[email protected]>
10
 *
11
 * This source file is subject to the MIT license that is bundled
12
 * with this source code in the file LICENSE.
13
 */
14
15
namespace KevinGH\Box\PhpScoper;
16
17
use Humbug\PhpScoper\Configuration\Configuration as PhpScoperConfiguration;
18
use Humbug\PhpScoper\Container as PhpScoperContainer;
19
use Humbug\PhpScoper\Patcher\Patcher;
20
use Humbug\PhpScoper\Patcher\PatcherChain;
21
use Humbug\PhpScoper\Scoper\FileWhitelistScoper;
22
use Humbug\PhpScoper\Scoper\Scoper as PhpScoper;
23
use Humbug\PhpScoper\Symbol\SymbolsRegistry;
24
use Opis\Closure\SerializableClosure;
25
use function array_map;
26
use function count;
27
28
/**
29
 * @private
30
 */
31
final class SimpleScoper implements Scoper
32
{
33
    private PhpScoperConfiguration $scoperConfig;
34
    private PhpScoperContainer $scoperContainer;
35
    private PhpScoper $scoper;
36
    private SymbolsRegistry $symbolsRegistry;
37
38
    /**
39
     * @var list<string>
0 ignored issues
show
Bug introduced by
The type KevinGH\Box\PhpScoper\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
40
     */
41
    private array $whitelistedFilePaths;
42
43
    public function __construct(
44
        PhpScoperConfiguration $scoperConfig,
45
        string ...$whitelistedFilePaths
46
    ) {
47
        $this->scoperConfig = new PhpScoperConfiguration(
48
            $scoperConfig->getPath(),
49
            $scoperConfig->getPrefix(),
50
            $scoperConfig->getFilesWithContents(),
51
            $scoperConfig->getWhitelistedFilesWithContents(),
52
            self::createSerializablePatchers($scoperConfig->getPatcher()),
53
            $scoperConfig->getSymbolsConfiguration(),
54
            $scoperConfig->getInternalClasses(),
55
            $scoperConfig->getInternalFunctions(),
56
            $scoperConfig->getInternalConstants(),
57
        );
58
        $this->whitelistedFilePaths = $whitelistedFilePaths;
0 ignored issues
show
Documentation Bug introduced by
It seems like $whitelistedFilePaths of type array<integer,string> is incompatible with the declared type KevinGH\Box\PhpScoper\list of property $whitelistedFilePaths.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
59
        $this->symbolsRegistry = new SymbolsRegistry();
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function scope(string $filePath, string $contents): string
66
    {
67
        return $this->getScoper()->scope(
68
            $filePath,
69
            $contents,
70
        );
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function changeSymbolsRegistry(SymbolsRegistry $symbolsRegistry): void
77
    {
78
        $this->symbolsRegistry = $symbolsRegistry;
79
80
        unset($this->scoper);
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    public function getSymbolsRegistry(): SymbolsRegistry
87
    {
88
        return $this->symbolsRegistry;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function getPrefix(): string
95
    {
96
        return $this->scoperConfig->getPrefix();
97
    }
98
99
    private function getScoper(): PhpScoper
100
    {
101
        if (isset($this->scoper)) {
102
            return $this->scoper;
103
        }
104
105
        if (!isset($this->scoperContainer)) {
106
            $this->scoperContainer = new PhpScoperContainer();
107
        }
108
109
        $scoper = (new PhpScoperContainer())
110
            ->getScoperFactory()
111
            ->createScoper(
112
                $this->scoperConfig,
113
                $this->symbolsRegistry,
114
            );
115
116
        if (count($this->whitelistedFilePaths) !== 0) {
117
            $scoper = new FileWhitelistScoper(
118
                $scoper,
119
                ...$this->whitelistedFilePaths,
120
            );
121
        }
122
123
        $this->scoper = $scoper;
124
125
        return $this->scoper;
126
    }
127
128
    /**
129
     * @param callable[] $patcher
130
     *
131
     * @retunr SerializableClosure[]
132
     */
133
    private static function createSerializablePatchers(Patcher $patcher): Patcher
134
    {
135
        if (!($patcher instanceof PatcherChain)) {
136
            return $patcher;
137
        }
138
139
        $serializablePatchers = array_map(
140
            static function (callable $patcher): SerializableClosure {
141
                if ($patcher instanceof Patcher) {
142
                    $patcher = static fn (string $filePath, string $prefix, string $contents) => $patcher($filePath, $prefix, $contents);
143
                }
144
145
                return new SerializableClosure($patcher);
146
            },
147
            $patcher->getPatchers(),
148
        );
149
150
        return new PatcherChain($serializablePatchers);
151
    }
152
153
    public function __wakeup()
154
    {
155
        // We need to make sure that a fresh Scoper & PHP-Parser Parser/Lexer
156
        // is used within a sub-process.
157
        // Otherwise, there is a risk of data corruption or that a compatibility
158
        // layer of some sorts (such as the tokens for PHP-Paser) is not
159
        // triggered in the sub-process resulting in obscure errors
160
        unset($this->scoper);
161
        unset($this->scoperContainer);
162
    }
163
}
164