Skip to content

Commit 640282d

Browse files
committed
Refactor TypeSpecifier::specifyTypesInCondition() for better readability
1 parent c586014 commit 640282d

File tree

1 file changed

+118
-45
lines changed

1 file changed

+118
-45
lines changed

src/Analyser/TypeSpecifier.php

Lines changed: 118 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ public function specifyTypesInCondition(
131131
return new SpecifiedTypes([], [], false, [], $rootExpr);
132132
}
133133

134+
// $expr instanceof $class
134135
if ($expr instanceof Instanceof_) {
135136
$exprNode = $expr->expr;
136137
if ($expr->class instanceof Name) {
@@ -189,56 +190,85 @@ public function specifyTypesInCondition(
189190
if ($context->true()) {
190191
return $this->create($exprNode, new ObjectWithoutClassType(), $context, false, $scope, $rootExpr);
191192
}
192-
} elseif ($expr instanceof Node\Expr\BinaryOp\Identical) {
193+
194+
return new SpecifiedTypes([], [], false, [], $rootExpr);
195+
}
196+
197+
// $left === $right
198+
if ($expr instanceof Node\Expr\BinaryOp\Identical) {
193199
return $this->resolveIdentical($expr, $scope, $context, $rootExpr);
200+
}
194201

195-
} elseif ($expr instanceof Node\Expr\BinaryOp\NotIdentical) {
202+
// $left !== $right
203+
if ($expr instanceof Node\Expr\BinaryOp\NotIdentical) {
196204
return $this->specifyTypesInCondition(
197205
$scope,
198206
new Node\Expr\BooleanNot(new Node\Expr\BinaryOp\Identical($expr->left, $expr->right)),
199207
$context,
200208
$rootExpr,
201209
);
202-
} elseif ($expr instanceof Expr\Cast\Bool_) {
210+
}
211+
212+
// (bool) $expr
213+
if ($expr instanceof Expr\Cast\Bool_) {
203214
return $this->specifyTypesInCondition(
204215
$scope,
205216
new Node\Expr\BinaryOp\Equal($expr->expr, new ConstFetch(new Name\FullyQualified('true'))),
206217
$context,
207218
$rootExpr,
208219
);
209-
} elseif ($expr instanceof Expr\Cast\String_) {
220+
}
221+
222+
// (string) $expr
223+
if ($expr instanceof Expr\Cast\String_) {
210224
return $this->specifyTypesInCondition(
211225
$scope,
212226
new Node\Expr\BinaryOp\NotEqual($expr->expr, new Node\Scalar\String_('')),
213227
$context,
214228
$rootExpr,
215229
);
216-
} elseif ($expr instanceof Expr\Cast\Int_) {
230+
}
231+
232+
// (int) $expr
233+
if ($expr instanceof Expr\Cast\Int_) {
217234
return $this->specifyTypesInCondition(
218235
$scope,
219236
new Node\Expr\BinaryOp\NotEqual($expr->expr, new Node\Scalar\LNumber(0)),
220237
$context,
221238
$rootExpr,
222239
);
223-
} elseif ($expr instanceof Expr\Cast\Double) {
240+
}
241+
242+
// (float) $expr
243+
if ($expr instanceof Expr\Cast\Double) {
224244
return $this->specifyTypesInCondition(
225245
$scope,
226246
new Node\Expr\BinaryOp\NotEqual($expr->expr, new Node\Scalar\DNumber(0.0)),
227247
$context,
228248
$rootExpr,
229249
);
230-
} elseif ($expr instanceof Node\Expr\BinaryOp\Equal) {
250+
}
251+
252+
// $left == $right
253+
if ($expr instanceof Node\Expr\BinaryOp\Equal) {
231254
return $this->resolveEqual($expr, $scope, $context, $rootExpr);
232-
} elseif ($expr instanceof Node\Expr\BinaryOp\NotEqual) {
255+
}
256+
257+
// $left != $right
258+
if ($expr instanceof Node\Expr\BinaryOp\NotEqual) {
233259
return $this->specifyTypesInCondition(
234260
$scope,
235261
new Node\Expr\BooleanNot(new Node\Expr\BinaryOp\Equal($expr->left, $expr->right)),
236262
$context,
237263
$rootExpr,
238264
);
265+
}
239266

240-
} elseif ($expr instanceof Node\Expr\BinaryOp\Smaller || $expr instanceof Node\Expr\BinaryOp\SmallerOrEqual) {
241-
267+
// $left < $right
268+
// $left <= $right
269+
if ($expr instanceof Node\Expr\BinaryOp\Smaller
270+
|| $expr instanceof Node\Expr\BinaryOp\SmallerOrEqual
271+
) {
242272
if (
243273
$expr->left instanceof FuncCall
244274
&& count($expr->left->getArgs()) >= 1
@@ -482,14 +512,20 @@ public function specifyTypesInCondition(
482512
}
483513

484514
return $result;
515+
}
485516

486-
} elseif ($expr instanceof Node\Expr\BinaryOp\Greater) {
517+
// $left > $right
518+
if ($expr instanceof Node\Expr\BinaryOp\Greater) {
487519
return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\Smaller($expr->right, $expr->left), $context, $rootExpr);
520+
}
488521

489-
} elseif ($expr instanceof Node\Expr\BinaryOp\GreaterOrEqual) {
522+
// $left >= $right
523+
if ($expr instanceof Node\Expr\BinaryOp\GreaterOrEqual) {
490524
return $this->specifyTypesInCondition($scope, new Expr\BinaryOp\SmallerOrEqual($expr->right, $expr->left), $context, $rootExpr);
525+
}
491526

492-
} elseif ($expr instanceof FuncCall && $expr->name instanceof Name) {
527+
// name(...)
528+
if ($expr instanceof FuncCall && $expr->name instanceof Name) {
493529
if ($this->reflectionProvider->hasFunction($expr->name, $scope)) {
494530
$functionReflection = $this->reflectionProvider->getFunction($expr->name, $scope);
495531
foreach ($this->getFunctionTypeSpecifyingExtensions() as $extension) {
@@ -529,7 +565,10 @@ public function specifyTypesInCondition(
529565
}
530566

531567
return $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope);
532-
} elseif ($expr instanceof MethodCall && $expr->name instanceof Node\Identifier) {
568+
}
569+
570+
// $var->name(...)
571+
if ($expr instanceof MethodCall && $expr->name instanceof Node\Identifier) {
533572
$methodCalledOnType = $scope->getType($expr->var);
534573
$methodReflection = $scope->getMethodReflection($methodCalledOnType, $expr->name->name);
535574
if ($methodReflection !== null) {
@@ -577,7 +616,10 @@ public function specifyTypesInCondition(
577616
}
578617

579618
return $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope);
580-
} elseif ($expr instanceof StaticCall && $expr->name instanceof Node\Identifier) {
619+
}
620+
621+
// $class::name(...)
622+
if ($expr instanceof StaticCall && $expr->name instanceof Node\Identifier) {
581623
if ($expr->class instanceof Name) {
582624
$calleeType = $scope->resolveTypeByName($expr->class);
583625
} else {
@@ -630,7 +672,14 @@ public function specifyTypesInCondition(
630672
}
631673

632674
return $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope);
633-
} elseif ($expr instanceof BooleanAnd || $expr instanceof LogicalAnd) {
675+
}
676+
677+
// $left && $right
678+
// $left and $right
679+
if (
680+
$expr instanceof BooleanAnd
681+
|| $expr instanceof LogicalAnd
682+
) {
634683
if (!$scope instanceof MutatingScope) {
635684
throw new ShouldNotHappenException();
636685
}
@@ -654,7 +703,14 @@ public function specifyTypesInCondition(
654703
}
655704

656705
return $types;
657-
} elseif ($expr instanceof BooleanOr || $expr instanceof LogicalOr) {
706+
}
707+
708+
// $left || $right
709+
// $left or $right
710+
if (
711+
$expr instanceof BooleanOr
712+
|| $expr instanceof LogicalOr
713+
) {
658714
if (!$scope instanceof MutatingScope) {
659715
throw new ShouldNotHappenException();
660716
}
@@ -678,9 +734,15 @@ public function specifyTypesInCondition(
678734
}
679735

680736
return $types;
681-
} elseif ($expr instanceof Node\Expr\BooleanNot && !$context->null()) {
737+
}
738+
739+
// !$expr
740+
if ($expr instanceof Node\Expr\BooleanNot && !$context->null()) {
682741
return $this->specifyTypesInCondition($scope, $expr->expr, $context->negate(), $rootExpr);
683-
} elseif ($expr instanceof Node\Expr\Assign) {
742+
}
743+
744+
// $var = $expr
745+
if ($expr instanceof Node\Expr\Assign) {
684746
if (!$scope instanceof MutatingScope) {
685747
throw new ShouldNotHappenException();
686748
}
@@ -689,11 +751,10 @@ public function specifyTypesInCondition(
689751
}
690752

691753
return $this->specifyTypesInCondition($scope->exitFirstLevelStatements(), $expr->var, $context, $rootExpr);
692-
} elseif (
693-
$expr instanceof Expr\Isset_
694-
&& count($expr->vars) > 0
695-
&& !$context->null()
696-
) {
754+
}
755+
756+
// isset(...$vars)
757+
if ($expr instanceof Expr\Isset_ && count($expr->vars) > 0 && !$context->null()) {
697758
// rewrite multi param isset() to and-chained single param isset()
698759
if (count($expr->vars) > 1) {
699760
$issets = [];
@@ -883,10 +944,10 @@ public function specifyTypesInCondition(
883944
}
884945

885946
return $types;
886-
} elseif (
887-
$expr instanceof Expr\BinaryOp\Coalesce
888-
&& !$context->null()
889-
) {
947+
}
948+
949+
// $a ?? $b
950+
if ($expr instanceof Expr\BinaryOp\Coalesce && !$context->null()) {
890951
if (!$context->true()) {
891952
if (!$scope instanceof MutatingScope) {
892953
throw new ShouldNotHappenException();
@@ -919,9 +980,11 @@ public function specifyTypesInCondition(
919980
);
920981
}
921982

922-
} elseif (
923-
$expr instanceof Expr\Empty_
924-
) {
983+
return new SpecifiedTypes([], [], false, [], $rootExpr);
984+
}
985+
986+
// empty($expr)
987+
if ($expr instanceof Expr\Empty_) {
925988
if (!$scope instanceof MutatingScope) {
926989
throw new ShouldNotHappenException();
927990
}
@@ -935,21 +998,25 @@ public function specifyTypesInCondition(
935998
new Expr\BooleanNot(new Expr\Isset_([$expr->expr])),
936999
new Expr\BooleanNot($expr->expr),
9371000
), $context, $rootExpr);
938-
} elseif ($expr instanceof Expr\ErrorSuppress) {
1001+
}
1002+
1003+
// @$a
1004+
if ($expr instanceof Expr\ErrorSuppress) {
9391005
return $this->specifyTypesInCondition($scope, $expr->expr, $context, $rootExpr);
940-
} elseif (
941-
$expr instanceof Expr\Ternary
942-
&& !$context->null()
943-
&& $scope->getType($expr->else)->isFalse()->yes()
944-
) {
1006+
}
1007+
1008+
// $cond ? $if : $else
1009+
if ($expr instanceof Expr\Ternary && !$context->null() && $scope->getType($expr->else)->isFalse()->yes()) {
9451010
$conditionExpr = $expr->cond;
9461011
if ($expr->if !== null) {
9471012
$conditionExpr = new BooleanAnd($conditionExpr, $expr->if);
9481013
}
9491014

9501015
return $this->specifyTypesInCondition($scope, $conditionExpr, $context, $rootExpr);
1016+
}
9511017

952-
} elseif ($expr instanceof Expr\NullsafePropertyFetch && !$context->null()) {
1018+
// $var?->name(...)
1019+
if ($expr instanceof Expr\NullsafePropertyFetch && !$context->null()) {
9531020
$types = $this->specifyTypesInCondition(
9541021
$scope,
9551022
new BooleanAnd(
@@ -962,7 +1029,10 @@ public function specifyTypesInCondition(
9621029

9631030
$nullSafeTypes = $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope);
9641031
return $context->true() ? $types->unionWith($nullSafeTypes) : $types->normalize($scope)->intersectWith($nullSafeTypes->normalize($scope));
965-
} elseif ($expr instanceof Expr\NullsafeMethodCall && !$context->null()) {
1032+
}
1033+
1034+
// $var?->name(...)
1035+
if ($expr instanceof Expr\NullsafeMethodCall && !$context->null()) {
9661036
$types = $this->specifyTypesInCondition(
9671037
$scope,
9681038
new BooleanAnd(
@@ -975,11 +1045,10 @@ public function specifyTypesInCondition(
9751045

9761046
$nullSafeTypes = $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope);
9771047
return $context->true() ? $types->unionWith($nullSafeTypes) : $types->normalize($scope)->intersectWith($nullSafeTypes->normalize($scope));
978-
} elseif (
979-
$expr instanceof Expr\New_
980-
&& $expr->class instanceof Name
981-
&& $this->reflectionProvider->hasClass($expr->class->toString())
982-
) {
1048+
}
1049+
1050+
// new $class(...)
1051+
if ($expr instanceof Expr\New_ && $expr->class instanceof Name && $this->reflectionProvider->hasClass($expr->class->toString())) {
9831052
$classReflection = $this->reflectionProvider->getClass($expr->class->toString());
9841053

9851054
if ($classReflection->hasConstructor()) {
@@ -1003,7 +1072,11 @@ public function specifyTypesInCondition(
10031072
}
10041073
}
10051074
}
1006-
} elseif (!$context->null()) {
1075+
1076+
return new SpecifiedTypes([], [], false, [], $rootExpr);
1077+
}
1078+
1079+
if (!$context->null()) {
10071080
return $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope);
10081081
}
10091082

0 commit comments

Comments
 (0)