|
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