Skip to content

Commit cb23986

Browse files
authored
Add support for regexes for excluded symbols (#660)
1 parent 8feb2ae commit cb23986

17 files changed

+136
-165
lines changed

docs/configuration.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,9 @@ Symbols can be marked as excluded as follows:
186186

187187
return [
188188
'exclude-namespaces' => [ 'WP', '/regex/' ],
189-
'exclude-classes' => ['Stringeable'],
190-
'exclude-functions' => ['str_contains'],
191-
'exclude-constants' => ['PHP_EOL'],
189+
'exclude-classes' => ['Stringeable', '/regex/'],
190+
'exclude-functions' => ['str_contains', '/regex/'],
191+
'exclude-constants' => ['PHP_EOL', '/regex/'],
192192
];
193193
```
194194

docs/further-reading.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,7 @@ return [
4747
],
4848
'exclude-constants' => [
4949
// Symfony global constants
50-
// TODO: switch to the following regex once regexes are supported here
51-
// https://github.com/humbug/php-scoper/issues/634
5250
'/^SYMFONY\_[\p{L}_]+$/',
53-
// Meanwhile:
54-
'SYMFONY_GRAPHEME_CLUSTER_RX',
5551
],
5652
'exclude-files' => [
5753
...$polyfillsBootstraps,

fixtures/set020-infection/scoper.inc.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@
3333
],
3434
'exclude-constants' => [
3535
// Symfony global constants
36-
// TODO: switch to the following regex once regexes are supported here
37-
// https://github.com/humbug/php-scoper/issues/634
3836
'/^SYMFONY\_[\p{L}_]+$/',
39-
'SYMFONY_GRAPHEME_CLUSTER_RX',
4037
],
4138
'exclude-files' => [
4239
...$polyfillsBootstraps,

scoper.inc.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,7 @@
7777
],
7878
'exclude-constants' => [
7979
// Symfony global constants
80-
// TODO: switch to the following regex once regexes are supported here
81-
// https://github.com/humbug/php-scoper/issues/634
8280
'/^SYMFONY\_[\p{L}_]+$/',
83-
'SYMFONY_GRAPHEME_CLUSTER_RX',
8481
],
8582
'exclude-files' => [
8683
...$jetBrainStubs,

src/Configuration/SymbolsConfiguration.php

Lines changed: 25 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,10 @@ final class SymbolsConfiguration
3030
private SymbolRegistry $exposedFunctions;
3131
private SymbolRegistry $exposedConstants;
3232

33-
/**
34-
* @var string[]
35-
*/
36-
private array $excludedClassNames;
37-
38-
/**
39-
* @var string[]
40-
*/
41-
private array $excludedFunctionNames;
42-
43-
/**
44-
* @var string[]
45-
*/
46-
private array $excludedConstantNames;
47-
48-
/**
49-
* @param string[] $excludedClassNames
50-
* @param string[] $excludedFunctionNames
51-
* @param string[] $excludedConstantNames
52-
*/
33+
private SymbolRegistry $excludedClasses;
34+
private SymbolRegistry $excludedFunctions;
35+
private SymbolRegistry $excludedConstants;
36+
5337
public static function create(
5438
bool $exposeGlobalConstants = false,
5539
bool $exposeGlobalClasses = false,
@@ -58,12 +42,12 @@ public static function create(
5842
// Does not contain the list of excluded symbols which go to the
5943
// Reflector (which has no notion of namespaces)
6044
?NamespaceRegistry $exposedNamespaces = null,
61-
SymbolRegistry $exposedClasses = null,
62-
SymbolRegistry $exposedFunctions = null,
63-
SymbolRegistry $exposedConstants = null,
64-
array $excludedClassNames = [],
65-
array $excludedFunctionNames = [],
66-
array $excludedConstantNames = []
45+
?SymbolRegistry $exposedClasses = null,
46+
?SymbolRegistry $exposedFunctions = null,
47+
?SymbolRegistry $exposedConstants = null,
48+
?SymbolRegistry $excludedClasses = null,
49+
?SymbolRegistry $excludedFunctions = null,
50+
?SymbolRegistry $excludedConstants = null
6751
): self {
6852
return new self(
6953
$exposeGlobalConstants,
@@ -74,17 +58,12 @@ public static function create(
7458
$exposedClasses ?? SymbolRegistry::create(),
7559
$exposedFunctions ?? SymbolRegistry::create(),
7660
$exposedConstants ?? SymbolRegistry::createForConstants(),
77-
$excludedClassNames,
78-
$excludedFunctionNames,
79-
$excludedConstantNames,
61+
$excludedClasses ?? SymbolRegistry::create(),
62+
$excludedFunctions ?? SymbolRegistry::create(),
63+
$excludedConstants ?? SymbolRegistry::createForConstants(),
8064
);
8165
}
8266

83-
/**
84-
* @param string[] $excludedClassNames
85-
* @param string[] $excludedFunctionNames
86-
* @param string[] $excludedConstantNames
87-
*/
8867
private function __construct(
8968
bool $exposeGlobalConstants,
9069
bool $exposeGlobalClasses,
@@ -94,9 +73,9 @@ private function __construct(
9473
SymbolRegistry $exposedClasses,
9574
SymbolRegistry $exposedFunctions,
9675
SymbolRegistry $exposedConstants,
97-
array $excludedClassNames,
98-
array $excludedFunctionNames,
99-
array $excludedConstantNames
76+
SymbolRegistry $excludedClasses,
77+
SymbolRegistry $excludedFunctions,
78+
SymbolRegistry $excludedConstants
10079
) {
10180
$this->exposeGlobalConstants = $exposeGlobalConstants;
10281
$this->exposeGlobalClasses = $exposeGlobalClasses;
@@ -106,9 +85,9 @@ private function __construct(
10685
$this->exposedClasses = $exposedClasses;
10786
$this->exposedFunctions = $exposedFunctions;
10887
$this->exposedConstants = $exposedConstants;
109-
$this->excludedClassNames = $excludedClassNames;
110-
$this->excludedFunctionNames = $excludedFunctionNames;
111-
$this->excludedConstantNames = $excludedConstantNames;
88+
$this->excludedClasses = $excludedClasses;
89+
$this->excludedFunctions = $excludedFunctions;
90+
$this->excludedConstants = $excludedConstants;
11291
}
11392

11493
public function shouldExposeGlobalConstants(): bool
@@ -151,27 +130,18 @@ public function getExposedConstants(): SymbolRegistry
151130
return $this->exposedConstants;
152131
}
153132

154-
/**
155-
* @return string[]
156-
*/
157-
public function getExcludedClassNames(): array
133+
public function getExcludedClasses(): SymbolRegistry
158134
{
159-
return $this->excludedClassNames;
135+
return $this->excludedClasses;
160136
}
161137

162-
/**
163-
* @return string[]
164-
*/
165-
public function getExcludedFunctionNames(): array
138+
public function getExcludedFunctions(): SymbolRegistry
166139
{
167-
return $this->excludedFunctionNames;
140+
return $this->excludedFunctions;
168141
}
169142

170-
/**
171-
* @return string[]
172-
*/
173-
public function getExcludedConstantNames(): array
143+
public function getExcludedConstants(): SymbolRegistry
174144
{
175-
return $this->excludedConstantNames;
145+
return $this->excludedConstants;
176146
}
177147
}

src/Configuration/SymbolsConfigurationFactory.php

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,27 @@ public function createSymbolsConfiguration(array $config): SymbolsConfiguration
9393
ConfigurationKeys::EXPOSE_CONSTANTS_SYMBOLS_KEYWORD,
9494
);
9595

96+
$excludedClasses = SymbolRegistry::create(
97+
...$this->retrieveElements(
98+
$config,
99+
ConfigurationKeys::CLASSES_INTERNAL_SYMBOLS_KEYWORD,
100+
),
101+
);
102+
103+
$excludedFunctions = SymbolRegistry::create(
104+
...$this->retrieveElements(
105+
$config,
106+
ConfigurationKeys::FUNCTIONS_INTERNAL_SYMBOLS_KEYWORD,
107+
),
108+
);
109+
110+
$excludedConstants = SymbolRegistry::createForConstants(
111+
...$this->retrieveElements(
112+
$config,
113+
ConfigurationKeys::CONSTANTS_INTERNAL_SYMBOLS_KEYWORD,
114+
),
115+
);
116+
96117
return SymbolsConfiguration::create(
97118
$exposeGlobalConstants,
98119
$exposeGlobalClasses,
@@ -135,7 +156,9 @@ public function createSymbolsConfiguration(array $config): SymbolsConfiguration
135156
$legacyExposedSymbolsPatterns,
136157
),
137158
),
138-
...self::retrieveAllExcludedSymbols($config),
159+
$excludedClasses,
160+
$excludedFunctions,
161+
$excludedConstants,
139162
);
140163
}
141164

@@ -253,18 +276,6 @@ private function retrieveElements(array $config, string $key): array
253276
];
254277
}
255278

256-
/**
257-
* @return array{string[], string[], string[]}
258-
*/
259-
private static function retrieveAllExcludedSymbols(array $config): array
260-
{
261-
return [
262-
self::retrieveExcludedSymbols($config, ConfigurationKeys::CLASSES_INTERNAL_SYMBOLS_KEYWORD),
263-
self::retrieveExcludedSymbols($config, ConfigurationKeys::FUNCTIONS_INTERNAL_SYMBOLS_KEYWORD),
264-
self::retrieveExcludedSymbols($config, ConfigurationKeys::CONSTANTS_INTERNAL_SYMBOLS_KEYWORD),
265-
];
266-
}
267-
268279
/**
269280
* @deprecated
270281
*
@@ -421,20 +432,4 @@ private static function lowerCaseConstantName(string $name): string
421432

422433
return implode('\\', $parts);
423434
}
424-
425-
/**
426-
* @return string[]
427-
*/
428-
private static function retrieveExcludedSymbols(array $config, string $key): array
429-
{
430-
if (!array_key_exists($key, $config)) {
431-
return [];
432-
}
433-
434-
$symbols = $config[$key];
435-
436-
self::assertIsArrayOfStrings($symbols, $key);
437-
438-
return $symbols;
439-
}
440435
}

src/Symbol/EnrichedReflectorFactory.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ public function __construct(Reflector $reflector)
1717

1818
public function create(SymbolsConfiguration $symbolsConfiguration): EnrichedReflector
1919
{
20-
$configuredReflector = $this->reflector->withSymbols(
21-
$symbolsConfiguration->getExcludedClassNames(),
22-
$symbolsConfiguration->getExcludedFunctionNames(),
23-
$symbolsConfiguration->getExcludedConstantNames(),
20+
$configuredReflector = $this->reflector->withAdditionalSymbols(
21+
$symbolsConfiguration->getExcludedClasses(),
22+
$symbolsConfiguration->getExcludedFunctions(),
23+
$symbolsConfiguration->getExcludedConstants(),
2424
);
2525

2626
return new EnrichedReflector(

src/Symbol/Reflector.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -633,21 +633,16 @@ private function __construct(
633633
$this->constants = $constants;
634634
}
635635

636-
/**
637-
* @param string[] $classNames
638-
* @param string[] $functionNames
639-
* @param string[] $constantNames
640-
*/
641-
public function withSymbols(
642-
array $classNames,
643-
array $functionNames,
644-
array $constantNames
636+
public function withAdditionalSymbols(
637+
SymbolRegistry $classNames,
638+
SymbolRegistry $functionNames,
639+
SymbolRegistry $constantNames
645640
): self
646641
{
647642
return new self(
648-
$this->classes->withAdditionalSymbols($classNames),
649-
$this->functions->withAdditionalSymbols($functionNames),
650-
$this->constants->withAdditionalSymbols($constantNames),
643+
$this->classes->merge($classNames),
644+
$this->functions->merge($functionNames),
645+
$this->constants->merge($constantNames),
651646
);
652647
}
653648

src/Symbol/SymbolRegistry.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Humbug\PhpScoper\Symbol;
66

7+
use InvalidArgumentException;
78
use function array_key_exists;
89
use function array_keys;
910
use function array_map;
@@ -107,20 +108,20 @@ public function matches(string $symbol): bool
107108
return false;
108109
}
109110

110-
/**
111-
* @param string[] $names
112-
* @param string[] $regexes
113-
*/
114-
public function withAdditionalSymbols(array $names = [], array $regexes = []): self
111+
public function merge(SymbolRegistry $registry): self
115112
{
113+
if ($this->constants !== $registry->constants) {
114+
throw new InvalidArgumentException('Cannot merge registries of different symbol types');
115+
}
116+
116117
$args = [
117118
[
118119
...$this->getNames(),
119-
...$names,
120+
...$registry->getNames(),
120121
],
121122
[
122123
...$this->getRegexes(),
123-
...$regexes,
124+
...$registry->getRegexes(),
124125
],
125126
];
126127

src/scoper.inc.php.tpl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ return [
7676
// '~^$~', // The root namespace only
7777
// '', // Any namespace
7878
],
79-
// Warning: regexes are not supported there (yet)
80-
// See https://github.com/humbug/php-scoper/issues/634
8179
'exclude-classes' => [
8280
// 'ReflectionClassConstant',
8381
],

tests/Console/Command/AddPrefixCommandIntegrationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
use function Safe\file_put_contents;
3030
use function Safe\preg_replace;
3131
use function Safe\realpath;
32-
use function str_replace;
3332
use function Safe\sprintf;
33+
use function str_replace;
3434
use const DIRECTORY_SEPARATOR;
3535

3636
/**

tests/Scoper/PhpScoperSpecTest.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,10 @@ private static function createScoper(
280280

281281
$reflector = Reflector
282282
::createWithPhpStormStubs()
283-
->withSymbols(
284-
$symbolsConfiguration->getExcludedClassNames(),
285-
$symbolsConfiguration->getExcludedFunctionNames(),
286-
$symbolsConfiguration->getExcludedConstantNames(),
283+
->withAdditionalSymbols(
284+
$symbolsConfiguration->getExcludedClasses(),
285+
$symbolsConfiguration->getExcludedFunctions(),
286+
$symbolsConfiguration->getExcludedConstants(),
287287
);
288288

289289
$enrichedReflector = new EnrichedReflector(
@@ -451,9 +451,9 @@ private static function createSpecMessage(
451451
$formattedFunctionsToExpose = self::formatSymbolRegistry($symbolsConfiguration->getExposedFunctions());
452452
$formattedConstantsToExpose = self::formatSymbolRegistry($symbolsConfiguration->getExposedConstants());
453453

454-
$formattedInternalClasses = self::formatSimpleList($symbolsConfiguration->getExcludedClassNames());
455-
$formattedInternalFunctions = self::formatSimpleList($symbolsConfiguration->getExcludedFunctionNames());
456-
$formattedInternalConstants = self::formatSimpleList($symbolsConfiguration->getExcludedConstantNames());
454+
$formattedInternalClasses = self::formatSymbolRegistry($symbolsConfiguration->getExcludedClasses());
455+
$formattedInternalFunctions = self::formatSymbolRegistry($symbolsConfiguration->getExcludedFunctions());
456+
$formattedInternalConstants = self::formatSymbolRegistry($symbolsConfiguration->getExcludedConstants());
457457

458458
$formattedExpectedRegisteredClasses = self::formatTupleList($expectedRegisteredClasses);
459459
$formattedExpectedRegisteredFunctions = self::formatTupleList($expectedRegisteredFunctions);

tests/Symbol/ConstantSymbolRegistryTest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,11 @@ public function test_it_can_create_an_augmented_instance(): void
8989
['/^Acme\\\\Foo$/'],
9090
);
9191

92-
$augmentedRegistry = $registry->withAdditionalSymbols(
93-
['Acme\Bar'],
94-
['/^Acme\\\\Bar/'],
92+
$augmentedRegistry = $registry->merge(
93+
SymbolRegistry::createForConstants(
94+
['Acme\Bar'],
95+
['/^Acme\\\\Bar/'],
96+
),
9597
);
9698

9799
SymbolRegistryAssertions::assertStateIs(

0 commit comments

Comments
 (0)