Skip to content

Commit 2c4c0cd

Browse files
committed
A few more MutatingScope method parameters made required
1 parent a2854d1 commit 2c4c0cd

File tree

9 files changed

+68
-63
lines changed

9 files changed

+68
-63
lines changed

src/Analyser/MutatingScope.php

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3614,7 +3614,7 @@ private function enterArrowFunctionWithoutReflection(Expr\ArrowFunction $arrowFu
36143614
if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) {
36153615
throw new ShouldNotHappenException();
36163616
}
3617-
$arrowFunctionScope = $arrowFunctionScope->assignVariable($parameter->var->name, $parameterType, $parameterType);
3617+
$arrowFunctionScope = $arrowFunctionScope->assignVariable($parameter->var->name, $parameterType, $parameterType, TrinaryLogic::createYes());
36183618
}
36193619

36203620
if ($arrowFunction->static) {
@@ -3733,6 +3733,7 @@ public function enterForeach(self $originalScope, Expr $iteratee, string $valueN
37333733
$valueName,
37343734
$originalScope->getIterableValueType($iterateeType),
37353735
$originalScope->getIterableValueType($nativeIterateeType),
3736+
TrinaryLogic::createYes(),
37363737
);
37373738
if ($keyName !== null) {
37383739
$scope = $scope->enterForeachKey($originalScope, $iteratee, $keyName);
@@ -3749,6 +3750,7 @@ public function enterForeachKey(self $originalScope, Expr $iteratee, string $key
37493750
$keyName,
37503751
$originalScope->getIterableKeyType($iterateeType),
37513752
$originalScope->getIterableKeyType($nativeIterateeType),
3753+
TrinaryLogic::createYes(),
37523754
);
37533755

37543756
if ($iterateeType->isArray()->yes()) {
@@ -3783,6 +3785,7 @@ public function enterCatchType(Type $catchType, ?string $variableName): self
37833785
$variableName,
37843786
TypeCombinator::intersect($catchType, new ObjectType(Throwable::class)),
37853787
TypeCombinator::intersect($catchType, new ObjectType(Throwable::class)),
3788+
TrinaryLogic::createYes(),
37863789
);
37873790
}
37883791

@@ -3928,18 +3931,16 @@ public function isUndefinedExpressionAllowed(Expr $expr): bool
39283931
return array_key_exists($exprString, $this->currentlyAllowedUndefinedExpressions);
39293932
}
39303933

3931-
public function assignVariable(string $variableName, Type $type, Type $nativeType, ?TrinaryLogic $certainty = null): self
3934+
public function assignVariable(string $variableName, Type $type, Type $nativeType, TrinaryLogic $certainty): self
39323935
{
39333936
$node = new Variable($variableName);
39343937
$scope = $this->assignExpression($node, $type, $nativeType);
3935-
if ($certainty !== null) {
3936-
if ($certainty->no()) {
3937-
throw new ShouldNotHappenException();
3938-
} elseif (!$certainty->yes()) {
3939-
$exprString = '$' . $variableName;
3940-
$scope->expressionTypes[$exprString] = new ExpressionTypeHolder($node, $type, $certainty);
3941-
$scope->nativeExpressionTypes[$exprString] = new ExpressionTypeHolder($node, $nativeType, $certainty);
3942-
}
3938+
if ($certainty->no()) {
3939+
throw new ShouldNotHappenException();
3940+
} elseif (!$certainty->yes()) {
3941+
$exprString = '$' . $variableName;
3942+
$scope->expressionTypes[$exprString] = new ExpressionTypeHolder($node, $type, $certainty);
3943+
$scope->nativeExpressionTypes[$exprString] = new ExpressionTypeHolder($node, $nativeType, $certainty);
39433944
}
39443945

39453946
$parameterOriginalValueExprString = $this->getNodeKey(new ParameterVariableOriginalValueExpr($variableName));
@@ -3987,7 +3988,7 @@ public function unsetExpression(Expr $expr): self
39873988
return $scope->invalidateExpression($expr);
39883989
}
39893990

3990-
public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType, ?TrinaryLogic $certainty = null): self
3991+
public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType, TrinaryLogic $certainty): self
39913992
{
39923993
if ($expr instanceof ConstFetch) {
39933994
$loweredConstName = strtolower($expr->name->toString());
@@ -4035,9 +4036,7 @@ public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType,
40354036
}
40364037
}
40374038

4038-
if ($certainty === null) {
4039-
$certainty = TrinaryLogic::createYes();
4040-
} elseif ($certainty->no()) {
4039+
if ($certainty->no()) {
40414040
throw new ShouldNotHappenException();
40424041
}
40434042

@@ -4073,11 +4072,8 @@ public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType,
40734072
return $scope;
40744073
}
40754074

4076-
public function assignExpression(Expr $expr, Type $type, ?Type $nativeType = null): self
4075+
public function assignExpression(Expr $expr, Type $type, Type $nativeType): self
40774076
{
4078-
if ($nativeType === null) {
4079-
$nativeType = new MixedType();
4080-
}
40814077
$scope = $this;
40824078
if ($expr instanceof PropertyFetch) {
40834079
$scope = $this->invalidateExpression($expr)
@@ -4088,7 +4084,7 @@ public function assignExpression(Expr $expr, Type $type, ?Type $nativeType = nul
40884084
$scope = $this->invalidateExpression($expr);
40894085
}
40904086

4091-
return $scope->specifyExpressionType($expr, $type, $nativeType);
4087+
return $scope->specifyExpressionType($expr, $type, $nativeType, TrinaryLogic::createYes());
40924088
}
40934089

40944090
public function assignInitializedProperty(Type $fetchedOnType, string $propertyName): self
@@ -4292,13 +4288,14 @@ public function addTypeToExpression(Expr $expr, Type $type): self
42924288

42934289
if ($originalExprType->equals($nativeType)) {
42944290
$newType = TypeCombinator::intersect($type, $originalExprType);
4295-
return $this->specifyExpressionType($expr, $newType, $newType);
4291+
return $this->specifyExpressionType($expr, $newType, $newType, TrinaryLogic::createYes());
42964292
}
42974293

42984294
return $this->specifyExpressionType(
42994295
$expr,
43004296
TypeCombinator::intersect($type, $originalExprType),
43014297
TypeCombinator::intersect($type, $nativeType),
4298+
TrinaryLogic::createYes(),
43024299
);
43034300
}
43044301

@@ -4315,6 +4312,7 @@ public function removeTypeFromExpression(Expr $expr, Type $typeToRemove): self
43154312
$expr,
43164313
TypeCombinator::remove($exprType, $typeToRemove),
43174314
TypeCombinator::remove($this->getNativeType($expr), $typeToRemove),
4315+
TrinaryLogic::createYes(),
43184316
);
43194317
}
43204318

src/Analyser/NodeScopeResolver.php

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,7 +1809,7 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void {
18091809
continue;
18101810
}
18111811

1812-
$scope = $scope->assignVariable($var->name, new MixedType(), new MixedType());
1812+
$scope = $scope->assignVariable($var->name, new MixedType(), new MixedType(), TrinaryLogic::createYes());
18131813
$vars[] = $var->name;
18141814
}
18151815
$scope = $this->processVarAnnotation($scope, $vars, $stmt);
@@ -1842,7 +1842,7 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void {
18421842
$impurePoints = array_merge($impurePoints, $varResult->getImpurePoints());
18431843
$scope = $scope->exitExpressionAssign($var->var);
18441844

1845-
$scope = $scope->assignVariable($var->var->name, new MixedType(), new MixedType());
1845+
$scope = $scope->assignVariable($var->var->name, new MixedType(), new MixedType(), TrinaryLogic::createYes());
18461846
$vars[] = $var->var->name;
18471847
}
18481848

@@ -2091,6 +2091,7 @@ private function ensureShallowNonNullability(MutatingScope $scope, Scope $origin
20912091
$exprToSpecify,
20922092
$exprTypeWithoutNull,
20932093
TypeCombinator::removeNull($nativeType),
2094+
TrinaryLogic::createYes(),
20942095
);
20952096

20962097
return new EnsuredNonNullabilityResult(
@@ -2457,7 +2458,7 @@ static function (): void {
24572458
$functionReflection !== null
24582459
&& in_array($functionReflection->getName(), ['fopen', 'file_get_contents'], true)
24592460
) {
2460-
$scope = $scope->assignVariable('http_response_header', AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new StringType())), new ArrayType(new IntegerType(), new StringType()));
2461+
$scope = $scope->assignVariable('http_response_header', AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new StringType())), new ArrayType(new IntegerType(), new StringType()), TrinaryLogic::createYes());
24612462
}
24622463

24632464
if (
@@ -4217,7 +4218,7 @@ private function processClosureNode(
42174218
$variableNativeType = TypeCombinator::union($scope->getVariableType($inAssignRightSideVariableName), $inAssignRightSideNativeType);
42184219
}
42194220
}
4220-
$scope = $scope->assignVariable($inAssignRightSideVariableName, $variableType, $variableNativeType);
4221+
$scope = $scope->assignVariable($inAssignRightSideVariableName, $variableType, $variableNativeType, TrinaryLogic::createYes());
42214222
}
42224223
}
42234224
$this->processExprNode($stmt, $use->var, $useScope, $nodeCallback, $context);
@@ -4625,7 +4626,7 @@ private function processArgs(
46254626
&& !$arg->value->static
46264627
) {
46274628
$restoreThisScope = $scopeToPass;
4628-
$scopeToPass = $scopeToPass->assignVariable('this', $parameter->getClosureThisType(), new ObjectWithoutClassType());
4629+
$scopeToPass = $scopeToPass->assignVariable('this', $parameter->getClosureThisType(), new ObjectWithoutClassType(), TrinaryLogic::createYes());
46294630
}
46304631

46314632
if ($parameter !== null) {
@@ -4677,7 +4678,7 @@ private function processArgs(
46774678
&& $parameter->getClosureThisType() !== null
46784679
&& !$arg->value->static
46794680
) {
4680-
$scopeToPass = $scopeToPass->assignVariable('this', $parameter->getClosureThisType(), new ObjectWithoutClassType());
4681+
$scopeToPass = $scopeToPass->assignVariable('this', $parameter->getClosureThisType(), new ObjectWithoutClassType(), TrinaryLogic::createYes());
46814682
}
46824683

46834684
if ($parameter !== null) {
@@ -4983,7 +4984,7 @@ private function processAssignVar(
49834984
$conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($scope, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType);
49844985

49854986
$nodeCallback(new VariableAssignNode($var, $assignedExpr, $isAssignOp), $result->getScope());
4986-
$scope = $scope->assignVariable($var->name, $type, $scope->getNativeType($assignedExpr));
4987+
$scope = $scope->assignVariable($var->name, $type, $scope->getNativeType($assignedExpr), TrinaryLogic::createYes());
49874988
foreach ($conditionalExpressions as $exprString => $holders) {
49884989
$scope = $scope->addConditionalExpressions($exprString, $holders);
49894990
}
@@ -5142,7 +5143,7 @@ private function processAssignVar(
51425143
if ($varType->isArray()->yes() || !(new ObjectType(ArrayAccess::class))->isSuperTypeOf($varType)->yes()) {
51435144
if ($var instanceof Variable && is_string($var->name)) {
51445145
$nodeCallback(new VariableAssignNode($var, $assignedPropertyExpr, $isAssignOp), $scope);
5145-
$scope = $scope->assignVariable($var->name, $valueToWrite, $nativeValueToWrite);
5146+
$scope = $scope->assignVariable($var->name, $valueToWrite, $nativeValueToWrite, TrinaryLogic::createYes());
51465147
} else {
51475148
if ($var instanceof PropertyFetch || $var instanceof StaticPropertyFetch) {
51485149
$nodeCallback(new PropertyAssignNode($var, $assignedPropertyExpr, $isAssignOp), $scope);
@@ -5394,7 +5395,7 @@ static function (): void {
53945395

53955396
if ($var instanceof Variable && is_string($var->name)) {
53965397
$nodeCallback(new VariableAssignNode($var, $assignedPropertyExpr, $isAssignOp), $scope);
5397-
$scope = $scope->assignVariable($var->name, $valueToWrite, $nativeValueToWrite);
5398+
$scope = $scope->assignVariable($var->name, $valueToWrite, $nativeValueToWrite, TrinaryLogic::createYes());
53985399
} else {
53995400
if ($var instanceof PropertyFetch || $var instanceof StaticPropertyFetch) {
54005401
$nodeCallback(new PropertyAssignNode($var, $assignedPropertyExpr, $isAssignOp), $scope);
@@ -5603,13 +5604,13 @@ private function processVarAnnotation(MutatingScope $scope, array $variableNames
56035604

56045605
$variableType = $varTags[$variableName]->getType();
56055606
$changed = true;
5606-
$scope = $scope->assignVariable($variableName, $variableType, new MixedType());
5607+
$scope = $scope->assignVariable($variableName, $variableType, new MixedType(), TrinaryLogic::createYes());
56075608
}
56085609

56095610
if (count($variableNames) === 1 && count($varTags) === 1 && isset($varTags[0])) {
56105611
$variableType = $varTags[0]->getType();
56115612
$changed = true;
5612-
$scope = $scope->assignVariable($variableNames[0], $variableType, new MixedType());
5613+
$scope = $scope->assignVariable($variableNames[0], $variableType, new MixedType(), TrinaryLogic::createYes());
56135614
}
56145615

56155616
return $scope;

src/Rules/Operators/InvalidBinaryOperationRule.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PHPStan\Rules\RuleErrorBuilder;
1111
use PHPStan\Rules\RuleLevelHelper;
1212
use PHPStan\ShouldNotHappenException;
13+
use PHPStan\TrinaryLogic;
1314
use PHPStan\Type\ErrorType;
1415
use PHPStan\Type\Type;
1516
use PHPStan\Type\VerbosityLevel;
@@ -104,8 +105,8 @@ public function processNode(Node $node, Scope $scope): array
104105
}
105106

106107
$scope = $scope
107-
->assignVariable($leftName, $leftType, $leftType)
108-
->assignVariable($rightName, $rightType, $rightType);
108+
->assignVariable($leftName, $leftType, $leftType, TrinaryLogic::createYes())
109+
->assignVariable($rightName, $rightType, $rightType, TrinaryLogic::createYes());
109110

110111
if (!$scope->getType($newNode) instanceof ErrorType) {
111112
return [];

src/Rules/Operators/InvalidUnaryOperationRule.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPStan\Rules\RuleErrorBuilder;
1010
use PHPStan\Rules\RuleLevelHelper;
1111
use PHPStan\ShouldNotHappenException;
12+
use PHPStan\TrinaryLogic;
1213
use PHPStan\Type\ErrorType;
1314
use PHPStan\Type\Type;
1415
use PHPStan\Type\VerbosityLevel;
@@ -69,7 +70,7 @@ public function processNode(Node $node, Scope $scope): array
6970
throw new ShouldNotHappenException();
7071
}
7172

72-
$scope = $scope->assignVariable($varName, $exprType, $exprType);
73+
$scope = $scope->assignVariable($varName, $exprType, $exprType, TrinaryLogic::createYes());
7374
if (!$scope->getType($newNode) instanceof ErrorType) {
7475
return [];
7576
}

src/Type/Php/ArrayFilterFunctionReturnTypeExtension.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use PHPStan\Reflection\FunctionReflection;
1919
use PHPStan\Reflection\ReflectionProvider;
2020
use PHPStan\ShouldNotHappenException;
21+
use PHPStan\TrinaryLogic;
2122
use PHPStan\Type\ArrayType;
2223
use PHPStan\Type\BenevolentUnionType;
2324
use PHPStan\Type\Constant\ConstantArrayType;
@@ -244,7 +245,7 @@ private function processKeyAndItemType(MutatingScope $scope, Type $keyType, Type
244245
throw new ShouldNotHappenException();
245246
}
246247
$itemVarName = $itemVar->name;
247-
$scope = $scope->assignVariable($itemVarName, $itemType, new MixedType());
248+
$scope = $scope->assignVariable($itemVarName, $itemType, new MixedType(), TrinaryLogic::createYes());
248249
}
249250

250251
$keyVarName = null;
@@ -253,7 +254,7 @@ private function processKeyAndItemType(MutatingScope $scope, Type $keyType, Type
253254
throw new ShouldNotHappenException();
254255
}
255256
$keyVarName = $keyVar->name;
256-
$scope = $scope->assignVariable($keyVarName, $keyType, new MixedType());
257+
$scope = $scope->assignVariable($keyVarName, $keyType, new MixedType(), TrinaryLogic::createYes());
257258
}
258259

259260
$booleanResult = $scope->getType($expr)->toBoolean();

tests/PHPStan/Analyser/ScopeTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PhpParser\Node\Expr\ConstFetch;
66
use PhpParser\Node\Name\FullyQualified;
77
use PHPStan\Testing\PHPStanTestCase;
8+
use PHPStan\TrinaryLogic;
89
use PHPStan\Type\Constant\ConstantArrayType;
910
use PHPStan\Type\Constant\ConstantBooleanType;
1011
use PHPStan\Type\Constant\ConstantIntegerType;
@@ -232,8 +233,8 @@ public function testGeneralize(Type $a, Type $b, string $expectedTypeDescription
232233
{
233234
/** @var ScopeFactory $scopeFactory */
234235
$scopeFactory = self::getContainer()->getByType(ScopeFactory::class);
235-
$scopeA = $scopeFactory->create(ScopeContext::create('file.php'))->assignVariable('a', $a, $a);
236-
$scopeB = $scopeFactory->create(ScopeContext::create('file.php'))->assignVariable('a', $b, $b);
236+
$scopeA = $scopeFactory->create(ScopeContext::create('file.php'))->assignVariable('a', $a, $a, TrinaryLogic::createYes());
237+
$scopeB = $scopeFactory->create(ScopeContext::create('file.php'))->assignVariable('a', $b, $b, TrinaryLogic::createYes());
237238
$resultScope = $scopeA->generalizeWith($scopeB);
238239
$this->assertSame($expectedTypeDescription, $resultScope->getVariableType('a')->describe(VerbosityLevel::precise()));
239240
}

tests/PHPStan/Analyser/StatementResultTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PhpParser\Node\Stmt;
66
use PHPStan\Parser\Parser;
77
use PHPStan\Testing\PHPStanTestCase;
8+
use PHPStan\TrinaryLogic;
89
use PHPStan\Type\ArrayType;
910
use PHPStan\Type\IntegerType;
1011
use PHPStan\Type\MixedType;
@@ -395,10 +396,10 @@ public function testIsAlwaysTerminating(
395396
/** @var ScopeFactory $scopeFactory */
396397
$scopeFactory = self::getContainer()->getByType(ScopeFactory::class);
397398
$scope = $scopeFactory->create(ScopeContext::create('test.php'))
398-
->assignVariable('string', new StringType(), new StringType())
399-
->assignVariable('x', new IntegerType(), new IntegerType())
400-
->assignVariable('cond', new MixedType(), new MixedType())
401-
->assignVariable('arr', new ArrayType(new MixedType(), new MixedType()), new ArrayType(new MixedType(), new MixedType()));
399+
->assignVariable('string', new StringType(), new StringType(), TrinaryLogic::createYes())
400+
->assignVariable('x', new IntegerType(), new IntegerType(), TrinaryLogic::createYes())
401+
->assignVariable('cond', new MixedType(), new MixedType(), TrinaryLogic::createYes())
402+
->assignVariable('arr', new ArrayType(new MixedType(), new MixedType()), new ArrayType(new MixedType(), new MixedType()), TrinaryLogic::createYes());
402403
$result = $nodeScopeResolver->processStmtNodes(
403404
new Stmt\Namespace_(null, $stmts),
404405
$stmts,

0 commit comments

Comments
 (0)