Skip to content

Commit b009b8f

Browse files
committed
Merge branch 2.1.x into 2.2.x
2 parents ba069fb + b9839ac commit b009b8f

61 files changed

Lines changed: 193 additions & 215 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

conf/config.stubValidator.neon

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ parameters:
44
checkMissingTypehints: true
55
checkMissingCallableSignature: false
66
__validate: false
7+
reportMaybes: true
8+
reportStatic: true
9+
10+
extensions:
11+
stubValidatorRules: PHPStan\DependencyInjection\StubValidatorRuleServicesExtension
712

813
services:
914
-
@@ -19,6 +24,10 @@ services:
1924
nodeScopeResolverReflector:
2025
factory: @stubReflector
2126

27+
# overrides service from services.neon so that Reflector autowires to stubReflector
28+
originalBetterReflectionReflector!:
29+
factory: @stubReflector
30+
2231
# overrides service from services.neon
2332
reflectionProvider:
2433
factory: @stubBetterReflectionProvider

src/DependencyInjection/AutowiredAttributeServicesExtension.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\DependencyInjection;
44

55
use Nette\DI\CompilerExtension;
6+
use Nette\DI\ContainerBuilder;
67
use Nette\DI\Definitions\Reference;
78
use Nette\DI\Definitions\ServiceDefinition;
89
use Nette\DI\Definitions\Statement;
@@ -63,7 +64,7 @@ public function loadConfiguration(): void
6364
$definition->setFactory(new Statement([new Reference(substr($ref, 1)), $method]));
6465
}
6566

66-
$this->processConstructorParameters($class->name, $definition, $constructorParameters);
67+
self::processConstructorParameters($builder, $class->name, $definition, $constructorParameters);
6768

6869
foreach (ValidateServiceTagsExtension::INTERFACE_TAG_MAPPING as $interface => $tag) {
6970
if (!$reflection->implementsInterface($interface)) {
@@ -86,7 +87,7 @@ public function loadConfiguration(): void
8687
$definition->setFactory(new Statement([new Reference(substr($ref, 1)), $method]));
8788
}
8889

89-
$this->processConstructorParameters($class->name, $definition, $constructorParameters);
90+
self::processConstructorParameters($builder, $class->name, $definition, $constructorParameters);
9091
}
9192

9293
foreach (Attributes::findTargetClasses(GenerateFactory::class) as $class) {
@@ -99,7 +100,7 @@ public function loadConfiguration(): void
99100
}
100101

101102
$resultDefinition = $definition->getResultDefinition();
102-
$this->processConstructorParameters($class->name, $resultDefinition, $constructorParameters);
103+
self::processConstructorParameters($builder, $class->name, $resultDefinition, $constructorParameters);
103104
}
104105

105106
/** @var stdClass&object{level: int|null} $config */
@@ -119,7 +120,7 @@ public function loadConfiguration(): void
119120
->setAutowired($class->name)
120121
->addTag(LazyRegistry::RULE_TAG);
121122

122-
$this->processConstructorParameters($class->name, $definition, $constructorParameters);
123+
self::processConstructorParameters($builder, $class->name, $definition, $constructorParameters);
123124
}
124125

125126
foreach (Attributes::findTargetClasses(RegisteredCollector::class) as $class) {
@@ -133,17 +134,16 @@ public function loadConfiguration(): void
133134
->setAutowired($class->name)
134135
->addTag(RegistryFactory::COLLECTOR_TAG);
135136

136-
$this->processConstructorParameters($class->name, $definition, $constructorParameters);
137+
self::processConstructorParameters($builder, $class->name, $definition, $constructorParameters);
137138
}
138139
}
139140

140141
/**
141142
* @param class-string $className
142143
* @param array<lowercase-string, non-empty-list<TargetMethodParameter<AutowiredParameter>>> $constructorParameters
143144
*/
144-
private function processConstructorParameters(string $className, ServiceDefinition $definition, array $constructorParameters): void
145+
public static function processConstructorParameters(ContainerBuilder $builder, string $className, ServiceDefinition $definition, array $constructorParameters): void
145146
{
146-
$builder = $this->getContainerBuilder();
147147
foreach ($constructorParameters[strtolower($className)] ?? [] as $autowiredParameter) {
148148
$ref = $autowiredParameter->attribute->ref;
149149
if ($ref === null) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\DependencyInjection;
4+
5+
use Nette\DI\CompilerExtension;
6+
use olvlvl\ComposerAttributeCollector\Attributes;
7+
use Override;
8+
use PHPStan\PhpDoc\StubValidator;
9+
use function strcasecmp;
10+
use function strtolower;
11+
12+
final class StubValidatorRuleServicesExtension extends CompilerExtension
13+
{
14+
15+
#[Override]
16+
public function loadConfiguration(): void
17+
{
18+
require_once __DIR__ . '/../../vendor/attributes.php';
19+
$builder = $this->getContainerBuilder();
20+
21+
$autowiredParameters = Attributes::findTargetMethodParameters(AutowiredParameter::class);
22+
$constructorParameters = [];
23+
foreach ($autowiredParameters as $parameter) {
24+
if (strcasecmp($parameter->method, '__construct') !== 0) {
25+
continue;
26+
}
27+
$lowerClass = strtolower($parameter->class);
28+
$constructorParameters[$lowerClass] ??= [];
29+
$constructorParameters[$lowerClass][] = $parameter;
30+
}
31+
32+
foreach (Attributes::findTargetClasses(ValidatesStubFiles::class) as $class) {
33+
$definition = $builder->addDefinition(null)
34+
->setFactory($class->name)
35+
->setAutowired(false)
36+
->addTag(StubValidator::SERVICE_RULE_TAG);
37+
38+
AutowiredAttributeServicesExtension::processConstructorParameters($builder, $class->name, $definition, $constructorParameters);
39+
}
40+
}
41+
42+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\DependencyInjection;
4+
5+
use Attribute;
6+
7+
/**
8+
* Registers a rule in the PHPStan\PhpDoc\StubValidator
9+
*
10+
* See https://phpstan.org/user-guide/stub-files
11+
*
12+
* Works thanks to https://github.com/ondrejmirtes/composer-attribute-collector
13+
* and StubValidatorRuleServicesExtension (similar to AutowiredAttributeServicesExtension).
14+
*/
15+
#[Attribute(flags: Attribute::TARGET_CLASS)]
16+
final class ValidatesStubFiles
17+
{
18+
19+
}

src/PhpDoc/StubValidator.php

Lines changed: 4 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -8,97 +8,10 @@
88
use PHPStan\Analyser\NodeScopeResolver;
99
use PHPStan\Collectors\Registry as CollectorRegistry;
1010
use PHPStan\DependencyInjection\AutowiredService;
11-
use PHPStan\DependencyInjection\Container;
1211
use PHPStan\DependencyInjection\DerivativeContainerFactory;
13-
use PHPStan\Php\PhpVersion;
14-
use PHPStan\PhpDocParser\Lexer\Lexer;
15-
use PHPStan\PhpDocParser\Parser\PhpDocParser;
16-
use PHPStan\Reflection\Php\PhpClassReflectionExtension;
1712
use PHPStan\Reflection\PhpVersionStaticAccessor;
18-
use PHPStan\Reflection\ReflectionProvider;
1913
use PHPStan\Reflection\ReflectionProviderStaticAccessor;
20-
use PHPStan\Rules\Classes\DuplicateClassDeclarationRule;
21-
use PHPStan\Rules\Classes\DuplicateDeclarationHelper;
22-
use PHPStan\Rules\Classes\DuplicateDeclarationRule;
23-
use PHPStan\Rules\Classes\ExistingClassesInClassImplementsRule;
24-
use PHPStan\Rules\Classes\ExistingClassesInInterfaceExtendsRule;
25-
use PHPStan\Rules\Classes\ExistingClassInClassExtendsRule;
26-
use PHPStan\Rules\Classes\ExistingClassInTraitUseRule;
27-
use PHPStan\Rules\Classes\LocalTypeAliasesCheck;
28-
use PHPStan\Rules\Classes\LocalTypeAliasesRule;
29-
use PHPStan\Rules\Classes\LocalTypeTraitAliasesRule;
30-
use PHPStan\Rules\Classes\LocalTypeTraitUseAliasesRule;
31-
use PHPStan\Rules\Classes\MethodTagCheck;
32-
use PHPStan\Rules\Classes\MethodTagRule;
33-
use PHPStan\Rules\Classes\MethodTagTraitRule;
34-
use PHPStan\Rules\Classes\MethodTagTraitUseRule;
35-
use PHPStan\Rules\Classes\MixinCheck;
36-
use PHPStan\Rules\Classes\MixinRule;
37-
use PHPStan\Rules\Classes\MixinTraitRule;
38-
use PHPStan\Rules\Classes\MixinTraitUseRule;
39-
use PHPStan\Rules\Classes\PropertyTagCheck;
40-
use PHPStan\Rules\Classes\PropertyTagRule;
41-
use PHPStan\Rules\Classes\PropertyTagTraitRule;
42-
use PHPStan\Rules\Classes\PropertyTagTraitUseRule;
43-
use PHPStan\Rules\ClassNameCheck;
4414
use PHPStan\Rules\DirectRegistry as DirectRuleRegistry;
45-
use PHPStan\Rules\FunctionDefinitionCheck;
46-
use PHPStan\Rules\Functions\DuplicateFunctionDeclarationRule;
47-
use PHPStan\Rules\Functions\MissingFunctionParameterTypehintRule;
48-
use PHPStan\Rules\Functions\MissingFunctionReturnTypehintRule;
49-
use PHPStan\Rules\Generics\ClassAncestorsRule;
50-
use PHPStan\Rules\Generics\ClassTemplateTypeRule;
51-
use PHPStan\Rules\Generics\CrossCheckInterfacesHelper;
52-
use PHPStan\Rules\Generics\EnumAncestorsRule;
53-
use PHPStan\Rules\Generics\EnumTemplateTypeRule;
54-
use PHPStan\Rules\Generics\FunctionSignatureVarianceRule;
55-
use PHPStan\Rules\Generics\FunctionTemplateTypeRule;
56-
use PHPStan\Rules\Generics\GenericAncestorsCheck;
57-
use PHPStan\Rules\Generics\GenericObjectTypeCheck;
58-
use PHPStan\Rules\Generics\InterfaceAncestorsRule;
59-
use PHPStan\Rules\Generics\InterfaceTemplateTypeRule;
60-
use PHPStan\Rules\Generics\MethodSignatureVarianceRule;
61-
use PHPStan\Rules\Generics\MethodTagTemplateTypeCheck;
62-
use PHPStan\Rules\Generics\MethodTagTemplateTypeRule;
63-
use PHPStan\Rules\Generics\MethodTagTemplateTypeTraitRule;
64-
use PHPStan\Rules\Generics\MethodTemplateTypeRule;
65-
use PHPStan\Rules\Generics\PropertyVarianceRule;
66-
use PHPStan\Rules\Generics\TemplateTypeCheck;
67-
use PHPStan\Rules\Generics\TraitTemplateTypeRule;
68-
use PHPStan\Rules\Generics\UsedTraitsRule;
69-
use PHPStan\Rules\Generics\VarianceCheck;
70-
use PHPStan\Rules\Methods\ExistingClassesInTypehintsRule;
71-
use PHPStan\Rules\Methods\MethodParameterComparisonHelper;
72-
use PHPStan\Rules\Methods\MethodPrototypeFinder;
73-
use PHPStan\Rules\Methods\MethodSignatureRule;
74-
use PHPStan\Rules\Methods\MethodVisibilityComparisonHelper;
75-
use PHPStan\Rules\Methods\MissingMethodParameterTypehintRule;
76-
use PHPStan\Rules\Methods\MissingMethodReturnTypehintRule;
77-
use PHPStan\Rules\Methods\MissingMethodSelfOutTypeRule;
78-
use PHPStan\Rules\Methods\OverridingMethodRule;
79-
use PHPStan\Rules\Methods\ParentMethodHelper;
80-
use PHPStan\Rules\MissingTypehintCheck;
81-
use PHPStan\Rules\PhpDoc\AssertRuleHelper;
82-
use PHPStan\Rules\PhpDoc\ConditionalReturnTypeRuleHelper;
83-
use PHPStan\Rules\PhpDoc\FunctionAssertRule;
84-
use PHPStan\Rules\PhpDoc\FunctionConditionalReturnTypeRule;
85-
use PHPStan\Rules\PhpDoc\GenericCallableRuleHelper;
86-
use PHPStan\Rules\PhpDoc\IncompatibleClassConstantPhpDocTypeRule;
87-
use PHPStan\Rules\PhpDoc\IncompatibleParamImmediatelyInvokedCallableRule;
88-
use PHPStan\Rules\PhpDoc\IncompatiblePhpDocTypeCheck;
89-
use PHPStan\Rules\PhpDoc\IncompatiblePhpDocTypeRule;
90-
use PHPStan\Rules\PhpDoc\IncompatiblePropertyPhpDocTypeRule;
91-
use PHPStan\Rules\PhpDoc\IncompatibleSelfOutTypeRule;
92-
use PHPStan\Rules\PhpDoc\InvalidPhpDocTagValueRule;
93-
use PHPStan\Rules\PhpDoc\InvalidPHPStanDocTagRule;
94-
use PHPStan\Rules\PhpDoc\InvalidThrowsPhpDocValueRule;
95-
use PHPStan\Rules\PhpDoc\MethodAssertRule;
96-
use PHPStan\Rules\PhpDoc\MethodConditionalReturnTypeRule;
97-
use PHPStan\Rules\PhpDoc\UnresolvableTypeHelper;
98-
use PHPStan\Rules\Properties\ExistingClassesInPropertiesRule;
99-
use PHPStan\Rules\Properties\MissingPropertyTypehintRule;
100-
use PHPStan\Rules\Registry as RuleRegistry;
101-
use PHPStan\Type\FileTypeMapper;
10215
use PHPStan\Type\ObjectType;
10316
use Throwable;
10417
use function array_fill_keys;
@@ -109,6 +22,8 @@
10922
final class StubValidator
11023
{
11124

25+
public const SERVICE_RULE_TAG = 'phpstan.stubValidator.rule';
26+
11227
public function __construct(
11328
private DerivativeContainerFactory $derivativeContainerFactory,
11429
)
@@ -133,9 +48,6 @@ public function validate(array $stubFiles, bool $debug): array
13348
__DIR__ . '/../../conf/config.stubValidator.neon',
13449
]);
13550

136-
$ruleRegistry = $this->getRuleRegistry($container);
137-
$collectorRegistry = $this->getCollectorRegistry();
138-
13951
$fileAnalyser = $container->getByType(FileAnalyser::class);
14052

14153
$nodeScopeResolver = $container->getByType(NodeScopeResolver::class);
@@ -152,8 +64,8 @@ public function validate(array $stubFiles, bool $debug): array
15264
$tmpErrors = $fileAnalyser->analyseFile(
15365
$stubFile,
15466
$analysedFiles,
155-
$ruleRegistry,
156-
$collectorRegistry,
67+
new DirectRuleRegistry($container->getServicesByTag(self::SERVICE_RULE_TAG)),
68+
new CollectorRegistry([]),
15769
static function (): void {
15870
},
15971
)->getErrors();
@@ -183,120 +95,4 @@ static function (): void {
18395
return $errors;
18496
}
18597

186-
private function getRuleRegistry(Container $container): RuleRegistry
187-
{
188-
$fileTypeMapper = $container->getByType(FileTypeMapper::class);
189-
$genericObjectTypeCheck = $container->getByType(GenericObjectTypeCheck::class);
190-
$genericAncestorsCheck = $container->getByType(GenericAncestorsCheck::class);
191-
$templateTypeCheck = $container->getByType(TemplateTypeCheck::class);
192-
$varianceCheck = $container->getByType(VarianceCheck::class);
193-
$reflectionProvider = $container->getByType(ReflectionProvider::class);
194-
$classNameCheck = $container->getByType(ClassNameCheck::class);
195-
$functionDefinitionCheck = $container->getByType(FunctionDefinitionCheck::class);
196-
$missingTypehintCheck = $container->getByType(MissingTypehintCheck::class);
197-
$unresolvableTypeHelper = $container->getByType(UnresolvableTypeHelper::class);
198-
$crossCheckInterfacesHelper = $container->getByType(CrossCheckInterfacesHelper::class);
199-
$phpVersion = $container->getByType(PhpVersion::class);
200-
$localTypeAliasesCheck = $container->getByType(LocalTypeAliasesCheck::class);
201-
$phpClassReflectionExtension = $container->getByType(PhpClassReflectionExtension::class);
202-
$genericCallableRuleHelper = $container->getByType(GenericCallableRuleHelper::class);
203-
$methodTagTemplateTypeCheck = $container->getByType(MethodTagTemplateTypeCheck::class);
204-
$mixinCheck = $container->getByType(MixinCheck::class);
205-
$discoveringSymbolsTip = $container->getParameter('tips')['discoveringSymbols'];
206-
$methodTagCheck = new MethodTagCheck($reflectionProvider, $classNameCheck, $genericObjectTypeCheck, $missingTypehintCheck, $unresolvableTypeHelper, checkClassCaseSensitivity: true, checkMissingTypehints: true, discoveringSymbolsTip: $discoveringSymbolsTip);
207-
$propertyTagCheck = new PropertyTagCheck($reflectionProvider, $classNameCheck, $genericObjectTypeCheck, $missingTypehintCheck, $unresolvableTypeHelper, checkClassCaseSensitivity: true, checkMissingTypehints: true, discoveringSymbolsTip: $discoveringSymbolsTip);
208-
$reflector = $container->getService('stubReflector');
209-
$relativePathHelper = $container->getService('simpleRelativePathHelper');
210-
$assertRuleHelper = $container->getByType(AssertRuleHelper::class);
211-
$conditionalReturnTypeRuleHelper = $container->getByType(ConditionalReturnTypeRuleHelper::class);
212-
$parentMethodHelper = $container->getByType(ParentMethodHelper::class);
213-
214-
$rules = [
215-
// level 0
216-
new ExistingClassesInClassImplementsRule($classNameCheck, $reflectionProvider, $discoveringSymbolsTip),
217-
new ExistingClassesInInterfaceExtendsRule($classNameCheck, $reflectionProvider, $discoveringSymbolsTip),
218-
new ExistingClassInClassExtendsRule($classNameCheck, $reflectionProvider, $discoveringSymbolsTip),
219-
new ExistingClassInTraitUseRule($classNameCheck, $reflectionProvider, $discoveringSymbolsTip),
220-
new ExistingClassesInTypehintsRule($functionDefinitionCheck),
221-
new \PHPStan\Rules\Functions\ExistingClassesInTypehintsRule($functionDefinitionCheck),
222-
new ExistingClassesInPropertiesRule($reflectionProvider, $classNameCheck, $unresolvableTypeHelper, $phpVersion, checkClassCaseSensitivity: true, checkThisOnly: false, discoveringSymbolsTip: $discoveringSymbolsTip),
223-
new OverridingMethodRule(
224-
$phpVersion,
225-
new MethodSignatureRule($parentMethodHelper, reportMaybes: true, reportStatic: true),
226-
true,
227-
new MethodParameterComparisonHelper($phpVersion),
228-
new MethodVisibilityComparisonHelper(),
229-
new MethodPrototypeFinder($phpVersion, $phpClassReflectionExtension),
230-
$container->getParameter('checkMissingOverrideMethodAttribute'),
231-
),
232-
new DuplicateDeclarationRule(new DuplicateDeclarationHelper()),
233-
new LocalTypeAliasesRule($localTypeAliasesCheck),
234-
new LocalTypeTraitAliasesRule($localTypeAliasesCheck, $reflectionProvider),
235-
new LocalTypeTraitUseAliasesRule($localTypeAliasesCheck),
236-
237-
// level 2
238-
new ClassAncestorsRule($genericAncestorsCheck, $crossCheckInterfacesHelper),
239-
new ClassTemplateTypeRule($templateTypeCheck),
240-
new FunctionTemplateTypeRule($fileTypeMapper, $templateTypeCheck),
241-
new FunctionSignatureVarianceRule($varianceCheck),
242-
new InterfaceAncestorsRule($genericAncestorsCheck, $crossCheckInterfacesHelper),
243-
new InterfaceTemplateTypeRule($templateTypeCheck),
244-
new MethodTemplateTypeRule($fileTypeMapper, $templateTypeCheck),
245-
new MethodTagTemplateTypeRule($methodTagTemplateTypeCheck),
246-
new MethodSignatureVarianceRule($varianceCheck),
247-
new TraitTemplateTypeRule($fileTypeMapper, $templateTypeCheck),
248-
new IncompatiblePhpDocTypeRule($fileTypeMapper, new IncompatiblePhpDocTypeCheck($genericObjectTypeCheck, $unresolvableTypeHelper, $genericCallableRuleHelper)),
249-
new IncompatiblePropertyPhpDocTypeRule($genericObjectTypeCheck, $unresolvableTypeHelper, $genericCallableRuleHelper),
250-
new InvalidPhpDocTagValueRule(
251-
$container->getByType(Lexer::class),
252-
$container->getByType(PhpDocParser::class),
253-
),
254-
new IncompatibleParamImmediatelyInvokedCallableRule($fileTypeMapper),
255-
new IncompatibleSelfOutTypeRule($unresolvableTypeHelper, $genericObjectTypeCheck),
256-
new IncompatibleClassConstantPhpDocTypeRule($genericObjectTypeCheck, $unresolvableTypeHelper),
257-
new InvalidPHPStanDocTagRule(
258-
$container->getByType(Lexer::class),
259-
$container->getByType(PhpDocParser::class),
260-
),
261-
new InvalidThrowsPhpDocValueRule($fileTypeMapper),
262-
new MixinTraitRule($mixinCheck, $reflectionProvider),
263-
new MixinRule($mixinCheck),
264-
new MixinTraitUseRule($mixinCheck),
265-
new MethodTagRule($methodTagCheck),
266-
new MethodTagTraitRule($methodTagCheck, $reflectionProvider),
267-
new MethodTagTraitUseRule($methodTagCheck),
268-
new MethodTagTemplateTypeTraitRule($methodTagTemplateTypeCheck, $reflectionProvider),
269-
new PropertyTagRule($propertyTagCheck),
270-
new PropertyTagTraitRule($propertyTagCheck, $reflectionProvider),
271-
new PropertyTagTraitUseRule($propertyTagCheck),
272-
new EnumAncestorsRule($genericAncestorsCheck, $crossCheckInterfacesHelper),
273-
new EnumTemplateTypeRule(),
274-
new PropertyVarianceRule($varianceCheck),
275-
new UsedTraitsRule($fileTypeMapper, $genericAncestorsCheck),
276-
new FunctionAssertRule($assertRuleHelper),
277-
new MethodAssertRule($assertRuleHelper),
278-
new FunctionConditionalReturnTypeRule($conditionalReturnTypeRuleHelper),
279-
new MethodConditionalReturnTypeRule($conditionalReturnTypeRuleHelper),
280-
281-
// level 6
282-
new MissingFunctionParameterTypehintRule($missingTypehintCheck),
283-
new MissingFunctionReturnTypehintRule($missingTypehintCheck),
284-
new MissingMethodParameterTypehintRule($missingTypehintCheck),
285-
new MissingMethodReturnTypehintRule($missingTypehintCheck),
286-
new MissingPropertyTypehintRule($missingTypehintCheck),
287-
new MissingMethodSelfOutTypeRule($missingTypehintCheck),
288-
289-
// duplicate stubs
290-
new DuplicateClassDeclarationRule($reflector, $relativePathHelper),
291-
new DuplicateFunctionDeclarationRule($reflector, $relativePathHelper),
292-
];
293-
294-
return new DirectRuleRegistry($rules);
295-
}
296-
297-
private function getCollectorRegistry(): CollectorRegistry
298-
{
299-
return new CollectorRegistry([]);
300-
}
301-
30298
}

0 commit comments

Comments
 (0)