|
13 | 13 | use PhpParser\Node\Name;
|
14 | 14 | use PHPStan\Analyser\Scope;
|
15 | 15 | use PHPStan\Php\PhpVersion;
|
| 16 | +use PHPStan\Reflection\InitializerExprTypeResolver; |
16 | 17 | use PHPStan\ShouldNotHappenException;
|
17 | 18 | use PHPStan\TrinaryLogic;
|
18 | 19 | use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
|
@@ -55,6 +56,7 @@ final class RegexArrayShapeMatcher
|
55 | 56 |
|
56 | 57 | public function __construct(
|
57 | 58 | private PhpVersion $phpVersion,
|
| 59 | + private InitializerExprTypeResolver $initializerExprTypeResolver, |
58 | 60 | )
|
59 | 61 | {
|
60 | 62 | }
|
@@ -725,38 +727,42 @@ private function getPatternType(Expr $patternExpr, Scope $scope): Type
|
725 | 727 | */
|
726 | 728 | private function resolvePatternConcat(Expr\BinaryOp\Concat $concat, Scope $scope): Type
|
727 | 729 | {
|
728 |
| - if ( |
729 |
| - $concat->left instanceof Expr\FuncCall |
730 |
| - && $concat->left->name instanceof Name |
731 |
| - && $concat->left->name->toLowerString() === 'preg_quote' |
732 |
| - ) { |
733 |
| - $left = new ConstantStringType(''); |
734 |
| - } elseif ($concat->left instanceof Expr\BinaryOp\Concat) { |
735 |
| - $left = $this->resolvePatternConcat($concat->left, $scope); |
736 |
| - } else { |
737 |
| - $left = $scope->getType($concat->left); |
738 |
| - } |
| 730 | + $resolver = new class($scope) { |
739 | 731 |
|
740 |
| - if ( |
741 |
| - $concat->right instanceof Expr\FuncCall |
742 |
| - && $concat->right->name instanceof Name |
743 |
| - && $concat->right->name->toLowerString() === 'preg_quote' |
744 |
| - ) { |
745 |
| - $right = new ConstantStringType(''); |
746 |
| - } elseif ($concat->right instanceof Expr\BinaryOp\Concat) { |
747 |
| - $right = $this->resolvePatternConcat($concat->right, $scope); |
748 |
| - } else { |
749 |
| - $right = $scope->getType($concat->right); |
750 |
| - } |
| 732 | + public function __construct(private Scope $scope) |
| 733 | + { |
| 734 | + } |
| 735 | + |
| 736 | + public function resolve(Expr $expr): Type |
| 737 | + { |
| 738 | + if ( |
| 739 | + $expr instanceof Expr\FuncCall |
| 740 | + && $expr->name instanceof Name |
| 741 | + && $expr->name->toLowerString() === 'preg_quote' |
| 742 | + ) { |
| 743 | + return new ConstantStringType(''); |
| 744 | + } |
| 745 | + |
| 746 | + if ($expr instanceof Expr\BinaryOp\Concat) { |
| 747 | + $left = $this->resolve($expr->left); |
| 748 | + $right = $this->resolve($expr->right); |
| 749 | + |
| 750 | + $strings = []; |
| 751 | + foreach ($left->toString()->getConstantStrings() as $leftString) { |
| 752 | + foreach ($right->toString()->getConstantStrings() as $rightString) { |
| 753 | + $strings[] = new ConstantStringType($leftString->getValue() . $rightString->getValue()); |
| 754 | + } |
| 755 | + } |
751 | 756 |
|
752 |
| - $strings = []; |
753 |
| - foreach ($left->getConstantStrings() as $leftString) { |
754 |
| - foreach ($right->getConstantStrings() as $rightString) { |
755 |
| - $strings[] = new ConstantStringType($leftString->getValue() . $rightString->getValue()); |
| 757 | + return TypeCombinator::union(...$strings); |
| 758 | + } |
| 759 | + |
| 760 | + return $this->scope->getType($expr); |
756 | 761 | }
|
757 |
| - } |
758 | 762 |
|
759 |
| - return TypeCombinator::union(...$strings); |
| 763 | + }; |
| 764 | + |
| 765 | + return $this->initializerExprTypeResolver->getConcatType($concat->left, $concat->right, static fn (Expr $expr): Type => $resolver->resolve($expr)); |
760 | 766 | }
|
761 | 767 |
|
762 | 768 | }
|
0 commit comments