Skip to content

Commit e5c589b

Browse files
committed
Restore original ReflectionProvider and PhpVersion into their static accessors dutifully
1 parent 7c92ff9 commit e5c589b

File tree

7 files changed

+168
-134
lines changed

7 files changed

+168
-134
lines changed

build/phpstan.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ parameters:
6464
- 'PHPStan\Reflection\MissingPropertyFromReflectionException'
6565
- 'PHPStan\Reflection\MissingConstantFromReflectionException'
6666
- 'PHPStan\Type\CircularTypeAliasDefinitionException'
67+
- 'PHPStan\Reflection\MissingStaticAccessorInstanceException'
6768
- 'LogicException'
6869
- 'Error'
6970
check:

src/DependencyInjection/ContainerFactory.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
use PHPStan\Reflection\ReflectionProvider;
3131
use PHPStan\Reflection\ReflectionProviderStaticAccessor;
3232
use PHPStan\ShouldNotHappenException;
33-
use PHPStan\Type\ObjectType;
3433
use function array_diff_key;
3534
use function array_intersect;
3635
use function array_key_exists;
@@ -195,7 +194,6 @@ public static function postInitializeContainer(Container $container): void
195194

196195
ReflectionProviderStaticAccessor::registerInstance($container->getByType(ReflectionProvider::class));
197196
PhpVersionStaticAccessor::registerInstance($container->getByType(PhpVersion::class));
198-
ObjectType::resetCaches();
199197
$container->getService('typeSpecifier');
200198

201199
BleedingEdgeToggle::setBleedingEdge($container->getParameter('featureToggles')['bleedingEdge']);

src/DependencyInjection/ValidateIgnoredErrorsExtension.php

Lines changed: 111 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use PHPStan\PhpDocParser\Parser\TypeParser;
2525
use PHPStan\PhpDocParser\ParserConfig;
2626
use PHPStan\Reflection\InitializerExprTypeResolver;
27+
use PHPStan\Reflection\MissingStaticAccessorInstanceException;
2728
use PHPStan\Reflection\PhpVersionStaticAccessor;
2829
use PHPStan\Reflection\ReflectionProvider\DirectReflectionProviderProvider;
2930
use PHPStan\Reflection\ReflectionProvider\DummyReflectionProvider;
@@ -66,120 +67,143 @@ public function loadConfiguration(): void
6667
$parser = Llk::load(new Read(__DIR__ . '/../../resources/RegexGrammar.pp'));
6768
$reflectionProvider = new DummyReflectionProvider();
6869
$reflectionProviderProvider = new DirectReflectionProviderProvider($reflectionProvider);
70+
71+
try {
72+
$originalReflectionProvider = ReflectionProviderStaticAccessor::getInstance();
73+
} catch (MissingStaticAccessorInstanceException) {
74+
$originalReflectionProvider = null;
75+
}
76+
77+
try {
78+
$originalPhpVersion = PhpVersionStaticAccessor::getInstance();
79+
} catch (MissingStaticAccessorInstanceException) {
80+
$originalPhpVersion = null;
81+
}
82+
6983
ReflectionProviderStaticAccessor::registerInstance($reflectionProvider);
7084
PhpVersionStaticAccessor::registerInstance(new PhpVersion(PHP_VERSION_ID));
71-
$composerPhpVersionFactory = new ComposerPhpVersionFactory([]);
72-
$constantResolver = new ConstantResolver($reflectionProviderProvider, [], null, $composerPhpVersionFactory, null);
73-
74-
$phpDocParserConfig = new ParserConfig([]);
75-
$ignoredRegexValidator = new IgnoredRegexValidator(
76-
$parser,
77-
new TypeStringResolver(
78-
new Lexer($phpDocParserConfig),
79-
new TypeParser($phpDocParserConfig, new ConstExprParser($phpDocParserConfig)),
80-
new TypeNodeResolver(
81-
new DirectTypeNodeResolverExtensionRegistryProvider(
82-
new class implements TypeNodeResolverExtensionRegistry {
83-
84-
public function getExtensions(): array
85+
86+
try {
87+
$composerPhpVersionFactory = new ComposerPhpVersionFactory([]);
88+
$constantResolver = new ConstantResolver($reflectionProviderProvider, [], null, $composerPhpVersionFactory, null);
89+
90+
$phpDocParserConfig = new ParserConfig([]);
91+
$ignoredRegexValidator = new IgnoredRegexValidator(
92+
$parser,
93+
new TypeStringResolver(
94+
new Lexer($phpDocParserConfig),
95+
new TypeParser($phpDocParserConfig, new ConstExprParser($phpDocParserConfig)),
96+
new TypeNodeResolver(
97+
new DirectTypeNodeResolverExtensionRegistryProvider(
98+
new class implements TypeNodeResolverExtensionRegistry {
99+
100+
public function getExtensions(): array
101+
{
102+
return [];
103+
}
104+
105+
},
106+
),
107+
$reflectionProviderProvider,
108+
new DirectTypeAliasResolverProvider(new class implements TypeAliasResolver {
109+
110+
public function hasTypeAlias(string $aliasName, ?string $classNameScope): bool
85111
{
86-
return [];
112+
return false;
87113
}
88114

89-
},
90-
),
91-
$reflectionProviderProvider,
92-
new DirectTypeAliasResolverProvider(new class implements TypeAliasResolver {
93-
94-
public function hasTypeAlias(string $aliasName, ?string $classNameScope): bool
95-
{
96-
return false;
97-
}
98-
99-
public function resolveTypeAlias(string $aliasName, NameScope $nameScope): ?Type
100-
{
101-
return null;
102-
}
115+
public function resolveTypeAlias(string $aliasName, NameScope $nameScope): ?Type
116+
{
117+
return null;
118+
}
103119

104-
}),
105-
$constantResolver,
106-
new InitializerExprTypeResolver($constantResolver, $reflectionProviderProvider, new PhpVersion(PHP_VERSION_ID), new class implements OperatorTypeSpecifyingExtensionRegistryProvider {
120+
}),
121+
$constantResolver,
122+
new InitializerExprTypeResolver($constantResolver, $reflectionProviderProvider, new PhpVersion(PHP_VERSION_ID), new class implements OperatorTypeSpecifyingExtensionRegistryProvider {
107123

108-
public function getRegistry(): OperatorTypeSpecifyingExtensionRegistry
109-
{
110-
return new OperatorTypeSpecifyingExtensionRegistry([]);
111-
}
124+
public function getRegistry(): OperatorTypeSpecifyingExtensionRegistry
125+
{
126+
return new OperatorTypeSpecifyingExtensionRegistry([]);
127+
}
112128

113-
}, new OversizedArrayBuilder(), true),
129+
}, new OversizedArrayBuilder(), true),
130+
),
114131
),
115-
),
116-
);
132+
);
117133

118-
$errors = [];
119-
foreach ($ignoreErrors as $ignoreError) {
120-
if (is_array($ignoreError)) {
121-
if (isset($ignoreError['count'])) {
122-
continue; // ignoreError coming from baseline will be correct
123-
}
124-
if (isset($ignoreError['messages'])) {
125-
$ignoreMessages = $ignoreError['messages'];
126-
} elseif (isset($ignoreError['message'])) {
127-
$ignoreMessages = [$ignoreError['message']];
134+
$errors = [];
135+
foreach ($ignoreErrors as $ignoreError) {
136+
if (is_array($ignoreError)) {
137+
if (isset($ignoreError['count'])) {
138+
continue; // ignoreError coming from baseline will be correct
139+
}
140+
if (isset($ignoreError['messages'])) {
141+
$ignoreMessages = $ignoreError['messages'];
142+
} elseif (isset($ignoreError['message'])) {
143+
$ignoreMessages = [$ignoreError['message']];
144+
} else {
145+
continue;
146+
}
128147
} else {
129-
continue;
148+
$ignoreMessages = [$ignoreError];
130149
}
131-
} else {
132-
$ignoreMessages = [$ignoreError];
133-
}
134150

135-
foreach ($ignoreMessages as $ignoreMessage) {
136-
$error = $this->validateMessage($ignoredRegexValidator, $ignoreMessage);
137-
if ($error === null) {
138-
continue;
151+
foreach ($ignoreMessages as $ignoreMessage) {
152+
$error = $this->validateMessage($ignoredRegexValidator, $ignoreMessage);
153+
if ($error === null) {
154+
continue;
155+
}
156+
$errors[] = $error;
139157
}
140-
$errors[] = $error;
141158
}
142-
}
143159

144-
$reportUnmatched = (bool) $builder->parameters['reportUnmatchedIgnoredErrors'];
160+
$reportUnmatched = (bool) $builder->parameters['reportUnmatchedIgnoredErrors'];
145161

146-
if ($reportUnmatched) {
147-
foreach ($ignoreErrors as $ignoreError) {
148-
if (!is_array($ignoreError)) {
149-
continue;
150-
}
162+
if ($reportUnmatched) {
163+
foreach ($ignoreErrors as $ignoreError) {
164+
if (!is_array($ignoreError)) {
165+
continue;
166+
}
151167

152-
if (isset($ignoreError['path'])) {
153-
$ignorePaths = [$ignoreError['path']];
154-
} elseif (isset($ignoreError['paths'])) {
155-
$ignorePaths = $ignoreError['paths'];
156-
} else {
157-
continue;
158-
}
168+
if (isset($ignoreError['path'])) {
169+
$ignorePaths = [$ignoreError['path']];
170+
} elseif (isset($ignoreError['paths'])) {
171+
$ignorePaths = $ignoreError['paths'];
172+
} else {
173+
continue;
174+
}
159175

160-
foreach ($ignorePaths as $ignorePath) {
161-
if (FileExcluder::isAbsolutePath($ignorePath)) {
162-
if (is_dir($ignorePath)) {
163-
continue;
176+
foreach ($ignorePaths as $ignorePath) {
177+
if (FileExcluder::isAbsolutePath($ignorePath)) {
178+
if (is_dir($ignorePath)) {
179+
continue;
180+
}
181+
if (is_file($ignorePath)) {
182+
continue;
183+
}
164184
}
165-
if (is_file($ignorePath)) {
185+
if (FileExcluder::isFnmatchPattern($ignorePath)) {
166186
continue;
167187
}
168-
}
169-
if (FileExcluder::isFnmatchPattern($ignorePath)) {
170-
continue;
171-
}
172188

173-
$errors[] = sprintf('Path "%s" is neither a directory, nor a file path, nor a fnmatch pattern.', $ignorePath);
189+
$errors[] = sprintf('Path "%s" is neither a directory, nor a file path, nor a fnmatch pattern.', $ignorePath);
190+
}
174191
}
175192
}
176-
}
177193

178-
if (count($errors) === 0) {
179-
return;
180-
}
194+
if (count($errors) === 0) {
195+
return;
196+
}
181197

182-
throw new InvalidIgnoredErrorPatternsException($errors);
198+
throw new InvalidIgnoredErrorPatternsException($errors);
199+
} finally {
200+
if ($originalReflectionProvider !== null) {
201+
ReflectionProviderStaticAccessor::registerInstance($originalReflectionProvider);
202+
}
203+
if ($originalPhpVersion !== null) {
204+
PhpVersionStaticAccessor::registerInstance($originalPhpVersion);
205+
}
206+
}
183207
}
184208

185209
private function validateMessage(IgnoredRegexValidator $ignoredRegexValidator, string $ignoreMessage): ?string

src/PhpDoc/StubValidator.php

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@
9797
use PHPStan\Rules\Properties\MissingPropertyTypehintRule;
9898
use PHPStan\Rules\Registry as RuleRegistry;
9999
use PHPStan\Type\FileTypeMapper;
100-
use PHPStan\Type\ObjectType;
101100
use Throwable;
102101
use function array_fill_keys;
103102
use function count;
@@ -125,56 +124,58 @@ public function validate(array $stubFiles, bool $debug): array
125124

126125
$originalReflectionProvider = ReflectionProviderStaticAccessor::getInstance();
127126
$originalPhpVersion = PhpVersionStaticAccessor::getInstance();
128-
$container = $this->derivativeContainerFactory->create([
129-
__DIR__ . '/../../conf/config.stubValidator.neon',
130-
]);
131127

132-
$ruleRegistry = $this->getRuleRegistry($container);
133-
$collectorRegistry = $this->getCollectorRegistry($container);
128+
try {
129+
$container = $this->derivativeContainerFactory->create([
130+
__DIR__ . '/../../conf/config.stubValidator.neon',
131+
]);
134132

135-
$fileAnalyser = $container->getByType(FileAnalyser::class);
133+
$ruleRegistry = $this->getRuleRegistry($container);
134+
$collectorRegistry = $this->getCollectorRegistry($container);
136135

137-
$nodeScopeResolver = $container->getByType(NodeScopeResolver::class);
138-
$nodeScopeResolver->setAnalysedFiles($stubFiles);
136+
$fileAnalyser = $container->getByType(FileAnalyser::class);
139137

140-
$pathRoutingParser = $container->getService('pathRoutingParser');
141-
$pathRoutingParser->setAnalysedFiles($stubFiles);
138+
$nodeScopeResolver = $container->getByType(NodeScopeResolver::class);
139+
$nodeScopeResolver->setAnalysedFiles($stubFiles);
142140

143-
$analysedFiles = array_fill_keys($stubFiles, true);
141+
$pathRoutingParser = $container->getService('pathRoutingParser');
142+
$pathRoutingParser->setAnalysedFiles($stubFiles);
144143

145-
$errors = [];
146-
foreach ($stubFiles as $stubFile) {
147-
try {
148-
$tmpErrors = $fileAnalyser->analyseFile(
149-
$stubFile,
150-
$analysedFiles,
151-
$ruleRegistry,
152-
$collectorRegistry,
153-
static function (): void {
154-
},
155-
)->getErrors();
156-
foreach ($tmpErrors as $tmpError) {
157-
$errors[] = $tmpError->withoutTip()->doNotIgnore();
158-
}
159-
} catch (Throwable $e) {
160-
if ($debug) {
161-
throw $e;
162-
}
144+
$analysedFiles = array_fill_keys($stubFiles, true);
145+
146+
$errors = [];
147+
foreach ($stubFiles as $stubFile) {
148+
try {
149+
$tmpErrors = $fileAnalyser->analyseFile(
150+
$stubFile,
151+
$analysedFiles,
152+
$ruleRegistry,
153+
$collectorRegistry,
154+
static function (): void {
155+
},
156+
)->getErrors();
157+
foreach ($tmpErrors as $tmpError) {
158+
$errors[] = $tmpError->withoutTip()->doNotIgnore();
159+
}
160+
} catch (Throwable $e) {
161+
if ($debug) {
162+
throw $e;
163+
}
163164

164-
$internalErrorMessage = sprintf('Internal error: %s', $e->getMessage());
165-
$errors[] = (new Error($internalErrorMessage, $stubFile, canBeIgnored: $e))
166-
->withIdentifier('phpstan.internal')
167-
->withMetadata([
168-
InternalError::STACK_TRACE_METADATA_KEY => InternalError::prepareTrace($e),
169-
InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString(),
170-
]);
165+
$internalErrorMessage = sprintf('Internal error: %s', $e->getMessage());
166+
$errors[] = (new Error($internalErrorMessage, $stubFile, canBeIgnored: $e))
167+
->withIdentifier('phpstan.internal')
168+
->withMetadata([
169+
InternalError::STACK_TRACE_METADATA_KEY => InternalError::prepareTrace($e),
170+
InternalError::STACK_TRACE_AS_STRING_METADATA_KEY => $e->getTraceAsString(),
171+
]);
172+
}
171173
}
174+
} finally {
175+
ReflectionProviderStaticAccessor::registerInstance($originalReflectionProvider);
176+
PhpVersionStaticAccessor::registerInstance($originalPhpVersion);
172177
}
173178

174-
ReflectionProviderStaticAccessor::registerInstance($originalReflectionProvider);
175-
PhpVersionStaticAccessor::registerInstance($originalPhpVersion);
176-
ObjectType::resetCaches();
177-
178179
return $errors;
179180
}
180181

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Reflection;
4+
5+
use Exception;
6+
7+
final class MissingStaticAccessorInstanceException extends Exception
8+
{
9+
10+
}

src/Reflection/PhpVersionStaticAccessor.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace PHPStan\Reflection;
44

55
use PHPStan\Php\PhpVersion;
6-
use PHPStan\ShouldNotHappenException;
76

87
final class PhpVersionStaticAccessor
98
{
@@ -22,7 +21,7 @@ public static function registerInstance(PhpVersion $phpVersion): void
2221
public static function getInstance(): PhpVersion
2322
{
2423
if (self::$instance === null) {
25-
throw new ShouldNotHappenException();
24+
throw new MissingStaticAccessorInstanceException();
2625
}
2726
return self::$instance;
2827
}

0 commit comments

Comments
 (0)