Skip to content

Commit 4c1a2b9

Browse files
committed
Detect named arguments whose parameters are renamed in subtypes
1 parent d7cd9c7 commit 4c1a2b9

30 files changed

+334
-29
lines changed

src/Analyser/MutatingScope.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,10 @@ class MutatingScope implements Scope, NodeCallbackInvoker, CollectedDataEmitter
146146
/** @var Type[] */
147147
private array $resolvedTypes = [];
148148

149-
/** @var array<string, self> */
149+
/** @var array<string, static> */
150150
private array $truthyScopes = [];
151151

152-
/** @var array<string, self> */
152+
/** @var array<string, static> */
153153
private array $falseyScopes = [];
154154

155155
private ?self $fiberScope = null;
@@ -3115,6 +3115,9 @@ public function filterByFalseyValue(Expr $expr): self
31153115
return $scope;
31163116
}
31173117

3118+
/**
3119+
* @return static
3120+
*/
31183121
public function filterBySpecifiedTypes(SpecifiedTypes $specifiedTypes): self
31193122
{
31203123
$typeSpecifications = [];
@@ -3224,6 +3227,7 @@ public function filterBySpecifiedTypes(SpecifiedTypes $specifiedTypes): self
32243227
}
32253228
}
32263229

3230+
/** @var static */
32273231
return $scope->scopeFactory->create(
32283232
$scope->context,
32293233
$scope->isDeclareStrictTypes(),

src/Analyser/Scope.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@ public function isUndefinedExpressionAllowed(Expr $expr): bool;
307307
* if-branch of `if ($x instanceof Foo)`.
308308
*
309309
* Uses the TypeSpecifier internally to determine type narrowing.
310+
*
311+
* @return static
310312
*/
311313
public function filterByTruthyValue(Expr $expr): self;
312314

@@ -316,6 +318,8 @@ public function filterByTruthyValue(Expr $expr): self;
316318
* The opposite of filterByTruthyValue(). Given `$x instanceof Foo`, returns
317319
* a scope where $x is known NOT to be of type Foo. This is the scope used
318320
* in the else-branch of `if ($x instanceof Foo)`.
321+
*
322+
* @return static
319323
*/
320324
public function filterByFalseyValue(Expr $expr): self;
321325

src/Rules/AttributesCheck.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use Attribute;
66
use PhpParser\Node\AttributeGroup;
77
use PhpParser\Node\Expr\New_;
8+
use PHPStan\Analyser\CollectedDataEmitter;
9+
use PHPStan\Analyser\NodeCallbackInvoker;
810
use PHPStan\Analyser\Scope;
911
use PHPStan\DependencyInjection\AutowiredParameter;
1012
use PHPStan\DependencyInjection\AutowiredService;
@@ -36,7 +38,7 @@ public function __construct(
3638
* @return list<IdentifierRuleError>
3739
*/
3840
public function check(
39-
Scope $scope,
41+
Scope&NodeCallbackInvoker&CollectedDataEmitter $scope,
4042
array $attrGroups,
4143
int $requiredTarget,
4244
string $targetName,
@@ -160,6 +162,7 @@ public function check(
160162
'Constant %s is not allowed for %s of attribute class ' . $attributeClassName . ' constructor.',
161163
'Constants %s cannot be combined for %s of attribute class ' . $attributeClassName . ' constructor.',
162164
'Combining constants with | is not allowed for %s of attribute class ' . $attributeClassName . ' constructor.',
165+
null,
163166
);
164167

165168
foreach ($parameterErrors as $error) {

src/Rules/Classes/ClassAttributesRule.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Attribute;
66
use PhpParser\Node;
7+
use PHPStan\Analyser\CollectedDataEmitter;
8+
use PHPStan\Analyser\NodeCallbackInvoker;
79
use PHPStan\Analyser\Scope;
810
use PHPStan\DependencyInjection\RegisteredRule;
911
use PHPStan\Node\InClassNode;
@@ -30,7 +32,7 @@ public function getNodeType(): string
3032
return InClassNode::class;
3133
}
3234

33-
public function processNode(Node $node, Scope $scope): array
35+
public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
3436
{
3537
$classReflection = $node->getClassReflection();
3638

src/Rules/Classes/ClassConstantAttributesRule.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Attribute;
66
use PhpParser\Node;
7+
use PHPStan\Analyser\CollectedDataEmitter;
8+
use PHPStan\Analyser\NodeCallbackInvoker;
79
use PHPStan\Analyser\Scope;
810
use PHPStan\DependencyInjection\RegisteredRule;
911
use PHPStan\Rules\AttributesCheck;
@@ -25,7 +27,7 @@ public function getNodeType(): string
2527
return Node\Stmt\ClassConst::class;
2628
}
2729

28-
public function processNode(Node $node, Scope $scope): array
30+
public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
2931
{
3032
return $this->attributesCheck->check(
3133
$scope,

src/Rules/Classes/InstantiationRule.php

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

55
use PhpParser\Node;
66
use PhpParser\Node\Expr\New_;
7+
use PHPStan\Analyser\CollectedDataEmitter;
8+
use PHPStan\Analyser\NodeCallbackInvoker;
79
use PHPStan\Analyser\Scope;
810
use PHPStan\DependencyInjection\AutowiredParameter;
911
use PHPStan\DependencyInjection\Container;
@@ -58,7 +60,7 @@ public function getNodeType(): string
5860
return New_::class;
5961
}
6062

61-
public function processNode(Node $node, Scope $scope): array
63+
public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
6264
{
6365
$errors = [];
6466
foreach ($this->getClassNames($node, $scope) as [$class, $isName]) {
@@ -71,7 +73,7 @@ public function processNode(Node $node, Scope $scope): array
7173
* @param Node\Expr\New_ $node
7274
* @return list<IdentifierRuleError>
7375
*/
74-
private function checkClassName(string $class, bool $isName, Node $node, Scope $scope): array
76+
private function checkClassName(string $class, bool $isName, Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
7577
{
7678
$lowercasedClass = strtolower($class);
7779
$messages = [];
@@ -272,6 +274,7 @@ private function checkClassName(string $class, bool $isName, Node $node, Scope $
272274
'Constant %s is not allowed for %s of class ' . $classDisplayName . ' constructor.',
273275
'Constants %s cannot be combined for %s of class ' . $classDisplayName . ' constructor.',
274276
'Combining constants with | is not allowed for %s of class ' . $classDisplayName . ' constructor.',
277+
null,
275278
));
276279
}
277280

src/Rules/Constants/ConstantAttributesRule.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Attribute;
66
use PhpParser\Node;
7+
use PHPStan\Analyser\CollectedDataEmitter;
8+
use PHPStan\Analyser\NodeCallbackInvoker;
79
use PHPStan\Analyser\Scope;
810
use PHPStan\DependencyInjection\RegisteredRule;
911
use PHPStan\Php\PhpVersion;
@@ -31,7 +33,7 @@ public function getNodeType(): string
3133
return Node\Stmt\Const_::class;
3234
}
3335

34-
public function processNode(Node $node, Scope $scope): array
36+
public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
3537
{
3638
if ($node->attrGroups === []) {
3739
return [];

src/Rules/EnumCases/EnumCaseAttributesRule.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Attribute;
66
use PhpParser\Node;
7+
use PHPStan\Analyser\CollectedDataEmitter;
8+
use PHPStan\Analyser\NodeCallbackInvoker;
79
use PHPStan\Analyser\Scope;
810
use PHPStan\DependencyInjection\RegisteredRule;
911
use PHPStan\Rules\AttributesCheck;
@@ -25,7 +27,7 @@ public function getNodeType(): string
2527
return Node\Stmt\EnumCase::class;
2628
}
2729

28-
public function processNode(Node $node, Scope $scope): array
30+
public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
2931
{
3032
return $this->attributesCheck->check(
3133
$scope,

src/Rules/FunctionCallParametersCheck.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
use PhpParser\Node;
66
use PhpParser\Node\Expr;
7+
use PHPStan\Analyser\CollectedDataEmitter;
78
use PHPStan\Analyser\MutatingScope;
9+
use PHPStan\Analyser\NodeCallbackInvoker;
810
use PHPStan\Analyser\Scope;
911
use PHPStan\DependencyInjection\AutowiredParameter;
1012
use PHPStan\DependencyInjection\AutowiredService;
@@ -14,6 +16,7 @@
1416
use PHPStan\Reflection\ParametersAcceptor;
1517
use PHPStan\Reflection\ReflectionProvider;
1618
use PHPStan\Reflection\ResolvedFunctionVariant;
19+
use PHPStan\Rules\Methods\NamedArgumentParameterMethodCallsCollector;
1720
use PHPStan\Rules\PhpDoc\UnresolvableTypeHelper;
1821
use PHPStan\Rules\Properties\PropertyReflectionFinder;
1922
use PHPStan\ShouldNotHappenException;
@@ -32,6 +35,7 @@
3235
use function array_fill;
3336
use function array_key_exists;
3437
use function array_last;
38+
use function array_merge;
3539
use function count;
3640
use function implode;
3741
use function in_array;
@@ -65,11 +69,12 @@ public function __construct(
6569

6670
/**
6771
* @param 'attribute'|'callable'|'method'|'staticMethod'|'function'|'new' $nodeType
72+
* @param array{class-string, string}|null $renamedNamedArgumentParameterData
6873
* @return list<IdentifierRuleError>
6974
*/
7075
public function check(
7176
ParametersAcceptor $parametersAcceptor,
72-
Scope $scope,
77+
Scope&NodeCallbackInvoker&CollectedDataEmitter $scope,
7378
bool $isBuiltin,
7479
Node\Expr\FuncCall|Node\Expr\MethodCall|Node\Expr\StaticCall|Node\Expr\New_ $funcCall,
7580
string $nodeType,
@@ -92,6 +97,7 @@ public function check(
9297
string $invalidConstantMessage,
9398
string $exclusiveConstantsMessage,
9499
string $bitmaskNotAllowedMessage,
100+
?array $renamedNamedArgumentParameterData,
95101
): array
96102
{
97103
if ($funcCall instanceof Node\Expr\MethodCall || $funcCall instanceof Node\Expr\StaticCall || $funcCall instanceof Node\Expr\FuncCall) {
@@ -359,6 +365,11 @@ public function check(
359365
->build();
360366
}
361367
}
368+
} elseif ($argumentName !== null && $renamedNamedArgumentParameterData !== null) {
369+
$scope->emitCollectedData(NamedArgumentParameterMethodCallsCollector::class, array_merge(
370+
$renamedNamedArgumentParameterData,
371+
[$parameter->getName(), $argumentLine],
372+
));
362373
}
363374

364375
if ($this->checkArgumentTypes) {

src/Rules/Functions/ArrowFunctionAttributesRule.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Attribute;
66
use PhpParser\Node;
7+
use PHPStan\Analyser\CollectedDataEmitter;
8+
use PHPStan\Analyser\NodeCallbackInvoker;
79
use PHPStan\Analyser\Scope;
810
use PHPStan\DependencyInjection\RegisteredRule;
911
use PHPStan\Node\InArrowFunctionNode;
@@ -26,7 +28,7 @@ public function getNodeType(): string
2628
return InArrowFunctionNode::class;
2729
}
2830

29-
public function processNode(Node $node, Scope $scope): array
31+
public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
3032
{
3133
return $this->attributesCheck->check(
3234
$scope,

0 commit comments

Comments
 (0)