Passed
Pull Request — master (#565)
by Théo
02:31
created

SimpleScoper::getSymbolsRegistry()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
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 Humbug\PhpScoper\Whitelist;
25
use Opis\Closure\SerializableClosure;
26
use function array_map;
27
use function count;
28
29
/**
30
 * @private
31
 */
32
final class SimpleScoper implements Scoper
33
{
34
    private PhpScoperConfiguration $scoperConfig;
35
    private PhpScoperContainer $scoperContainer;
36
    private PhpScoper $scoper;
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->getWhitelist(),
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
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function scope(string $filePath, string $contents): string
65
    {
66
        return $this->getScoper()->scope(
67
            $filePath,
68
            $contents,
69
        );
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function setSymbolsRegistry(SymbolsRegistry $registry): void
76
    {
77
        $previousConfig = $this->scoperConfig;
78
79
        $this->scoperConfig = new PhpScoperConfiguration(
80
            $previousConfig->getPath(),
81
            $previousConfig->getPrefix(),
82
            $previousConfig->getFilesWithContents(),
83
            $previousConfig->getWhitelistedFilesWithContents(),
84
            $previousConfig->getPatcher(),
85
            $registry,
0 ignored issues
show
Bug introduced by
$registry of type Humbug\PhpScoper\Symbol\SymbolsRegistry is incompatible with the type Humbug\PhpScoper\Whitelist expected by parameter $whitelist of Humbug\PhpScoper\Configu...guration::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

85
            /** @scrutinizer ignore-type */ $registry,
Loading history...
86
            $previousConfig->getInternalClasses(),
87
            $previousConfig->getInternalFunctions(),
88
            $previousConfig->getInternalConstants(),
89
        );
90
91
        unset($this->scoper);
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function getSymbolsRegistry(): SymbolsRegistry
98
    {
99
        return $this->scoperConfig->getWhitelist();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->scoperConfig->getWhitelist() returns the type Humbug\PhpScoper\Whitelist which is incompatible with the type-hinted return Humbug\PhpScoper\Symbol\SymbolsRegistry.
Loading history...
100
    }
101
102
    /**
103
     * {@inheritdoc}
104
     */
105
    public function getPrefix(): string
106
    {
107
        return $this->scoperConfig->getPrefix();
108
    }
109
110
    private function getScoper(): PhpScoper
111
    {
112
        if (isset($this->scoper)) {
113
            return $this->scoper;
114
        }
115
116
        if (!isset($this->scoperContainer)) {
117
            $this->scoperContainer = new PhpScoperContainer();
118
        }
119
120
        $scoper = (new PhpScoperContainer())
121
            ->getScoperFactory()
122
            ->createScoper($this->scoperConfig);
123
124
        if (count($this->whitelistedFilePaths) !== 0) {
125
            $scoper = new FileWhitelistScoper(
126
                $scoper,
127
                ...$this->whitelistedFilePaths,
128
            );
129
        }
130
131
        $this->scoper = $scoper;
132
133
        return $this->scoper;
134
    }
135
136
    /**
137
     * @param callable[] $patcher
138
     *
139
     * @retunr SerializableClosure[]
140
     */
141
    private static function createSerializablePatchers(Patcher $patcher): Patcher
142
    {
143
        if (!($patcher instanceof PatcherChain)) {
144
            return $patcher;
145
        }
146
147
        $serializablePatchers = array_map(
148
            static function (callable $patcher): SerializableClosure {
149
                if ($patcher instanceof Patcher) {
150
                    $patcher = static fn (string $filePath, string $prefix, string $contents) => $patcher($filePath, $prefix, $contents);
151
                }
152
153
                return new SerializableClosure($patcher);
154
            },
155
            $patcher->getPatchers(),
156
        );
157
158
        return new PatcherChain($serializablePatchers);
159
    }
160
161
    public function __wakeup()
162
    {
163
        // We need to make sure that a fresh Scoper & PHP-Parser Parser/Lexer
164
        // is used within a sub-process.
165
        // Otherwise, there is a risk of data corruption or that a compatibility
166
        // layer of some sorts (such as the tokens for PHP-Paser) is not
167
        // triggered in the sub-process resulting in obscure errors
168
        unset($this->scoper);
169
        unset($this->scoperContainer);
170
    }
171
}
172