Skip to content

Commit ca3a193

Browse files
committed
Fix tests with FNSR
1 parent 6642e34 commit ca3a193

7 files changed

Lines changed: 86 additions & 25 deletions

File tree

src/Analyser/DirectInternalScopeFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function create(
5959
array $currentlyAllowedUndefinedExpressions = [],
6060
array $inFunctionCallsStack = [],
6161
bool $afterExtractCall = false,
62-
?Scope $parentScope = null,
62+
?MutatingScope $parentScope = null,
6363
bool $nativeTypesPromoted = false,
6464
): MutatingScope
6565
{

src/Analyser/Fiber/FiberScope.php

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,20 @@
66
use PhpParser\Node\Expr;
77
use PHPStan\Analyser\MutatingScope;
88
use PHPStan\Analyser\Scope;
9+
use PHPStan\Reflection\FunctionReflection;
10+
use PHPStan\Reflection\MethodReflection;
11+
use PHPStan\Reflection\ParameterReflection;
912
use PHPStan\Type\Type;
1013

1114
final class FiberScope extends MutatingScope
1215
{
1316

17+
/** @var Expr[] */
18+
private array $truthyValueExprs = [];
19+
20+
/** @var Expr[] */
21+
private array $falseyValueExprs = [];
22+
1423
public function toFiberScope(): self
1524
{
1625
return $this;
@@ -46,10 +55,7 @@ public function getType(Expr $node): Type
4655
new BeforeScopeForExprRequest($node, $this),
4756
);
4857

49-
$scope = $beforeScope->toMutatingScope();
50-
if ($this->nativeTypesPromoted) {
51-
$scope = $scope->doNotTreatPhpDocTypesAsCertain();
52-
}
58+
$scope = $this->preprocessScope($beforeScope->toMutatingScope());
5359

5460
return $scope->getType($node);
5561
}
@@ -72,10 +78,7 @@ public function getNativeType(Expr $expr): Type
7278
new BeforeScopeForExprRequest($expr, $this),
7379
);
7480

75-
$scope = $beforeScope->toMutatingScope();
76-
if ($this->nativeTypesPromoted) {
77-
$scope = $scope->doNotTreatPhpDocTypesAsCertain();
78-
}
81+
$scope = $this->preprocessScope($beforeScope->toMutatingScope());
7982

8083
return $scope->getNativeType($expr);
8184
}
@@ -87,12 +90,70 @@ public function getKeepVoidType(Expr $node): Type
8790
new BeforeScopeForExprRequest($node, $this),
8891
);
8992

90-
$scope = $beforeScope->toMutatingScope();
93+
$scope = $this->preprocessScope($beforeScope->toMutatingScope());
94+
95+
return $scope->getKeepVoidType($node);
96+
}
97+
98+
public function filterByTruthyValue(Expr $expr): self
99+
{
100+
/** @var self $scope */
101+
$scope = parent::filterByTruthyValue($expr);
102+
$scope->truthyValueExprs = $this->truthyValueExprs;
103+
$scope->truthyValueExprs[] = $expr;
104+
105+
return $scope;
106+
}
107+
108+
public function filterByFalseyValue(Expr $expr): self
109+
{
110+
/** @var self $scope */
111+
$scope = parent::filterByTruthyValue($expr);
112+
$scope->falseyValueExprs = $this->falseyValueExprs;
113+
$scope->falseyValueExprs[] = $expr;
114+
115+
return $scope;
116+
}
117+
118+
private function preprocessScope(Scope $scope): Scope
119+
{
91120
if ($this->nativeTypesPromoted) {
92121
$scope = $scope->doNotTreatPhpDocTypesAsCertain();
93122
}
94123

95-
return $scope->getKeepVoidType($node);
124+
foreach ($this->truthyValueExprs as $expr) {
125+
$scope = $scope->filterByTruthyValue($expr);
126+
}
127+
foreach ($this->falseyValueExprs as $expr) {
128+
$scope = $scope->filterByFalseyValue($expr);
129+
}
130+
131+
return $scope;
132+
}
133+
134+
/**
135+
* @param MethodReflection|FunctionReflection|null $reflection
136+
*/
137+
public function pushInFunctionCall($reflection, ?ParameterReflection $parameter, bool $rememberTypes): self
138+
{
139+
// no need to track this in rules, the type will be correct anyway
140+
return $this;
141+
}
142+
143+
public function popInFunctionCall(): self
144+
{
145+
// no need to track this in rules, the type will be correct anyway
146+
return $this;
147+
}
148+
149+
public function getParentScope(): ?MutatingScope
150+
{
151+
$parent = parent::getParentScope();
152+
if ($parent === null) {
153+
return null;
154+
}
155+
156+
return $parent->toFiberScope();
96157
}
97158

98159
}

src/Analyser/InternalScopeFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function create(
3535
array $currentlyAllowedUndefinedExpressions = [],
3636
array $inFunctionCallsStack = [],
3737
bool $afterExtractCall = false,
38-
?Scope $parentScope = null,
38+
?MutatingScope $parentScope = null,
3939
bool $nativeTypesPromoted = false,
4040
): MutatingScope;
4141

src/Analyser/LazyInternalScopeFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public function create(
5555
array $currentlyAllowedUndefinedExpressions = [],
5656
array $inFunctionCallsStack = [],
5757
bool $afterExtractCall = false,
58-
?Scope $parentScope = null,
58+
?MutatingScope $parentScope = null,
5959
bool $nativeTypesPromoted = false,
6060
): MutatingScope
6161
{

src/Analyser/MutatingScope.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ public function __construct(
237237
protected array $currentlyAllowedUndefinedExpressions = [],
238238
protected array $inFunctionCallsStack = [],
239239
protected bool $afterExtractCall = false,
240-
private ?Scope $parentScope = null,
240+
private ?self $parentScope = null,
241241
protected bool $nativeTypesPromoted = false,
242242
)
243243
{
@@ -469,7 +469,7 @@ public function getNamespace(): ?string
469469
}
470470

471471
/** @api */
472-
public function getParentScope(): ?Scope
472+
public function getParentScope(): ?self
473473
{
474474
return $this->parentScope;
475475
}
@@ -4616,9 +4616,8 @@ public function removeTypeFromExpression(Expr $expr, Type $typeToRemove): self
46164616

46174617
/**
46184618
* @api
4619-
* @return MutatingScope
46204619
*/
4621-
public function filterByTruthyValue(Expr $expr): Scope
4620+
public function filterByTruthyValue(Expr $expr): self
46224621
{
46234622
$exprString = $this->getNodeKey($expr);
46244623
if (array_key_exists($exprString, $this->truthyScopes)) {
@@ -4634,9 +4633,8 @@ public function filterByTruthyValue(Expr $expr): Scope
46344633

46354634
/**
46364635
* @api
4637-
* @return MutatingScope
46384636
*/
4639-
public function filterByFalseyValue(Expr $expr): Scope
4637+
public function filterByFalseyValue(Expr $expr): self
46404638
{
46414639
$exprString = $this->getNodeKey($expr);
46424640
if (array_key_exists($exprString, $this->falseyScopes)) {

src/Reflection/ParametersAcceptorSelector.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Closure;
66
use PhpParser\Node;
77
use PHPStan\Analyser\ArgumentsNormalizer;
8+
use PHPStan\Analyser\Fiber\FiberScope;
89
use PHPStan\Analyser\MutatingScope;
910
use PHPStan\Analyser\Scope;
1011
use PHPStan\Node\Expr\ParameterVariableOriginalValueExpr;
@@ -499,14 +500,14 @@ public static function selectFromArgs(
499500
}
500501
}
501502

502-
if ($parameter !== null && $scope instanceof MutatingScope) {
503+
if ($parameter !== null && $scope instanceof MutatingScope && !$scope instanceof FiberScope) {
503504
$rememberTypes = !$originalArg->value instanceof Node\Expr\Closure && !$originalArg->value instanceof Node\Expr\ArrowFunction;
504505
$scope = $scope->pushInFunctionCall(null, $parameter, $rememberTypes);
505506
}
506507

507508
$type = $scope->getType($originalArg->value);
508509

509-
if ($parameter !== null && $scope instanceof MutatingScope) {
510+
if ($parameter !== null && $scope instanceof MutatingScope && !$scope instanceof FiberScope) {
510511
$scope = $scope->popInFunctionCall();
511512
}
512513

tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use PHPStan\Testing\RuleTestCase;
1212
use PHPUnit\Framework\Attributes\DataProvider;
1313
use PHPUnit\Framework\Attributes\RequiresPhp;
14+
use function getenv;
1415
use function sprintf;
1516
use const PHP_VERSION_ID;
1617

@@ -604,12 +605,12 @@ public function testArrayReduceCallback(): void
604605
5,
605606
],
606607
[
607-
'Parameter #2 $callback of function array_reduce expects callable(non-empty-string|null, 1|2|3): (non-empty-string|null), Closure(string, int): non-falsy-string given.',
608+
sprintf('Parameter #2 $callback of function array_reduce expects callable(%1$s|null, 1|2|3): (%1$s|null), Closure(string, int): non-falsy-string given.', getenv('PHPSTAN_FNSR') === '1' ? 'non-falsy-string' : 'non-empty-string'),
608609
13,
609610
'Type string of parameter #1 $foo of passed callable needs to be same or wider than parameter type string|null of accepting callable.',
610611
],
611612
[
612-
'Parameter #2 $callback of function array_reduce expects callable(non-empty-string|null, 1|2|3): (non-empty-string|null), Closure(string, int): non-falsy-string given.',
613+
sprintf('Parameter #2 $callback of function array_reduce expects callable(%1$s|null, 1|2|3): (%1$s|null), Closure(string, int): non-falsy-string given.', getenv('PHPSTAN_FNSR') === '1' ? 'non-falsy-string' : 'non-empty-string'),
613614
22,
614615
'Type string of parameter #1 $foo of passed callable needs to be same or wider than parameter type string|null of accepting callable.',
615616
],
@@ -624,12 +625,12 @@ public function testArrayReduceArrowFunctionCallback(): void
624625
5,
625626
],
626627
[
627-
'Parameter #2 $callback of function array_reduce expects callable(non-empty-string|null, 1|2|3): (non-empty-string|null), Closure(string, int): non-falsy-string given.',
628+
sprintf('Parameter #2 $callback of function array_reduce expects callable(%1$s|null, 1|2|3): (%1$s|null), Closure(string, int): non-falsy-string given.', getenv('PHPSTAN_FNSR') === '1' ? 'non-falsy-string' : 'non-empty-string'),
628629
11,
629630
'Type string of parameter #1 $foo of passed callable needs to be same or wider than parameter type string|null of accepting callable.',
630631
],
631632
[
632-
'Parameter #2 $callback of function array_reduce expects callable(non-empty-string|null, 1|2|3): (non-empty-string|null), Closure(string, int): non-falsy-string given.',
633+
sprintf('Parameter #2 $callback of function array_reduce expects callable(%1$s|null, 1|2|3): (%1$s|null), Closure(string, int): non-falsy-string given.', getenv('PHPSTAN_FNSR') === '1' ? 'non-falsy-string' : 'non-empty-string'),
633634
18,
634635
'Type string of parameter #1 $foo of passed callable needs to be same or wider than parameter type string|null of accepting callable.',
635636
],

0 commit comments

Comments
 (0)