|
9 | 9 | use PHPStan\ShouldNotHappenException;
|
10 | 10 | use PHPStan\TrinaryLogic;
|
11 | 11 | use PHPStan\Type\Accessory\AccessoryArrayListType;
|
| 12 | +use PHPStan\Type\Accessory\AccessoryLowercaseStringType; |
| 13 | +use PHPStan\Type\Accessory\AccessoryNonEmptyStringType; |
| 14 | +use PHPStan\Type\Accessory\AccessoryUppercaseStringType; |
12 | 15 | use PHPStan\Type\Accessory\NonEmptyArrayType;
|
13 | 16 | use PHPStan\Type\ArrayType;
|
14 | 17 | use PHPStan\Type\Constant\ConstantArrayType;
|
@@ -80,32 +83,43 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
|
80 | 83 | }
|
81 | 84 | }
|
82 | 85 |
|
83 |
| - if (!isset($splitLength)) { |
84 |
| - return null; |
85 |
| - } |
86 |
| - |
87 | 86 | $stringType = $scope->getType($functionCall->getArgs()[0]->value);
|
88 |
| - |
89 |
| - $constantStrings = $stringType->getConstantStrings(); |
90 |
| - if (count($constantStrings) > 0) { |
91 |
| - $results = []; |
92 |
| - foreach ($constantStrings as $constantString) { |
93 |
| - $items = $encoding === null |
94 |
| - ? str_split($constantString->getValue(), $splitLength) |
95 |
| - : @mb_str_split($constantString->getValue(), $splitLength, $encoding); |
96 |
| - if ($items === false) { |
97 |
| - throw new ShouldNotHappenException(); |
| 87 | + if (isset($splitLength)) { |
| 88 | + $constantStrings = $stringType->getConstantStrings(); |
| 89 | + if (count($constantStrings) > 0) { |
| 90 | + $results = []; |
| 91 | + foreach ($constantStrings as $constantString) { |
| 92 | + $items = $encoding === null |
| 93 | + ? str_split($constantString->getValue(), $splitLength) |
| 94 | + : @mb_str_split($constantString->getValue(), $splitLength, $encoding); |
| 95 | + if ($items === false) { |
| 96 | + throw new ShouldNotHappenException(); |
| 97 | + } |
| 98 | + |
| 99 | + $results[] = self::createConstantArrayFrom($items, $scope); |
98 | 100 | }
|
99 | 101 |
|
100 |
| - $results[] = self::createConstantArrayFrom($items, $scope); |
| 102 | + return TypeCombinator::union(...$results); |
101 | 103 | }
|
| 104 | + } |
| 105 | + |
| 106 | + $isInputNonEmptyString = $stringType->isNonEmptyString()->yes(); |
102 | 107 |
|
103 |
| - return TypeCombinator::union(...$results); |
| 108 | + $valueTypes = [new StringType()]; |
| 109 | + if ($isInputNonEmptyString || $this->phpVersion->strSplitReturnsEmptyArray()) { |
| 110 | + $valueTypes[] = new AccessoryNonEmptyStringType(); |
| 111 | + } |
| 112 | + if ($stringType->isLowercaseString()->yes()) { |
| 113 | + $valueTypes[] = new AccessoryLowercaseStringType(); |
| 114 | + } |
| 115 | + if ($stringType->isUppercaseString()->yes()) { |
| 116 | + $valueTypes[] = new AccessoryUppercaseStringType(); |
104 | 117 | }
|
| 118 | + $returnValueType = TypeCombinator::intersect(new StringType(), ...$valueTypes); |
105 | 119 |
|
106 |
| - $returnType = AccessoryArrayListType::intersectWith(new ArrayType(new IntegerType(), new StringType())); |
| 120 | + $returnType = AccessoryArrayListType::intersectWith(TypeCombinator::intersect(new ArrayType(new IntegerType(), $returnValueType))); |
107 | 121 |
|
108 |
| - return $encoding === null && !$this->phpVersion->strSplitReturnsEmptyArray() |
| 122 | + return $isInputNonEmptyString || ($encoding === null && !$this->phpVersion->strSplitReturnsEmptyArray()) |
109 | 123 | ? TypeCombinator::intersect($returnType, new NonEmptyArrayType())
|
110 | 124 | : $returnType;
|
111 | 125 | }
|
|
0 commit comments