Passed
Push — master ( 4e77ba...f21ca5 )
by Théo
01:52
created

SimpleScoper::changeWhitelist()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 12
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 17
rs 9.8666
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 Exception;
18
use Humbug\PhpScoper\Container as PhpScoperContainer;
19
use Humbug\PhpScoper\Patcher\ComposerPatcher;
20
use Humbug\PhpScoper\Patcher\SymfonyPatcher;
21
use Humbug\PhpScoper\Scoper as PhpScoper;
22
use Humbug\PhpScoper\Scoper\FileWhitelistScoper;
23
use Humbug\PhpScoper\Whitelist;
24
use Humbug\PhpScoper\Configuration as PhpScoperConfiguration;
25
use Opis\Closure\SerializableClosure;
26
use Serializable;
27
use function array_map;
28
use function count;
29
use function var_dump;
30
31
/**
32
 * @private
33
 */
34
final class SimpleScoper implements Scoper
35
{
36
    private PhpScoperConfiguration $scoperConfig;
37
    private PhpScoperContainer $scoperContainer;
38
    private PhpScoper $scoper;
39
40
    /**
41
     * @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...
42
     */
43
    private array $whitelistedFilePaths;
44
45
    public function __construct(
46
        PhpScoperConfiguration $scoperConfig,
47
        string ...$whitelistedFilePaths
48
    ) {
49
        $this->scoperConfig = new PhpScoperConfiguration(
50
            $scoperConfig->getPath(),
51
            $scoperConfig->getPrefix(),
52
            $scoperConfig->getFilesWithContents(),
53
            $scoperConfig->getWhitelistedFilesWithContents(),
54
            self::createSerializablePatchers($scoperConfig->getPatchers()),
55
            $scoperConfig->getWhitelist(),
56
            $scoperConfig->getInternalClasses(),
57
            $scoperConfig->getInternalFunctions(),
58
            $scoperConfig->getInternalConstants(),
59
        );
60
        $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...
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function scope(string $filePath, string $contents): string
67
    {
68
        return $this->getScoper()->scope(
69
            $filePath,
70
            $contents,
71
        );
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function changeWhitelist(Whitelist $whitelist): void
78
    {
79
        $previousConfig = $this->scoperConfig;
80
81
        $this->scoperConfig = new PhpScoperConfiguration(
82
            $previousConfig->getPath(),
83
            $previousConfig->getPrefix(),
84
            $previousConfig->getFilesWithContents(),
85
            $previousConfig->getWhitelistedFilesWithContents(),
86
            $previousConfig->getPatchers(),
87
            $whitelist,
88
            $previousConfig->getInternalClasses(),
89
            $previousConfig->getInternalFunctions(),
90
            $previousConfig->getInternalConstants(),
91
        );
92
93
        unset($this->scoper);
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99
    public function getWhitelist(): Whitelist
100
    {
101
        return $this->scoperConfig->getWhitelist();
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function getPrefix(): string
108
    {
109
        return $this->scoperConfig->getPrefix();
110
    }
111
112
    private function getScoper(): PhpScoper
113
    {
114
        if (isset($this->scoper)) {
115
            return $this->scoper;
116
        }
117
118
        if (!isset($this->scoperContainer)) {
119
            $this->scoperContainer = new PhpScoperContainer();
120
        }
121
122
        $scoper = (new PhpScoperContainer())
123
            ->getScoperFactory()
124
            ->createScoper($this->scoperConfig);
125
126
        if (count($this->whitelistedFilePaths) !== 0) {
127
            $scoper = new FileWhitelistScoper(
128
                $scoper,
129
                ...$this->whitelistedFilePaths,
130
            );
131
        }
132
133
        $this->scoper = $scoper;
134
135
        return $this->scoper;
136
    }
137
138
    /**
139
     * @param callable[] $patchers
140
     *
141
     * @retunr SerializableClosure[]
142
     */
143
    private static function createSerializablePatchers(array $patchers): array
144
    {
145
        return array_map(
146
            static function (callable $patcher): SerializableClosure {
147
                if ($patcher instanceof SymfonyPatcher
148
                    || $patcher instanceof ComposerPatcher
149
                ) {
150
                    $patcher = static fn (string $filePath, string $prefix, string $contents) => $patcher($filePath, $prefix, $contents);
151
                }
152
153
                return new SerializableClosure($patcher);
154
            },
155
            $patchers,
156
        );
157
    }
158
159
    public function __wakeup()
160
    {
161
        // We need to make sure that a fresh Scoper & PHP-Parser Parser/Lexer
162
        // is used within a sub-process.
163
        // Otherwise, there is a risk of data corruption or that a compatibility
164
        // layer of some sorts (such as the tokens for PHP-Paser) is not
165
        // triggered in the sub-process resulting in obscure errors
166
        unset($this->scoper);
167
        unset($this->scoperContainer);
168
    }
169
}
170