Skip to content

Commit 356e0f8

Browse files
committed
remove uppercase-string from parse_url()
per convo w/ @VincentLanglet
1 parent b4395b2 commit 356e0f8

File tree

2 files changed

+23
-144
lines changed

2 files changed

+23
-144
lines changed

src/Type/Php/ParseUrlFunctionDynamicReturnTypeExtension.php

Lines changed: 23 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use PHPStan\Reflection\FunctionReflection;
88
use PHPStan\ShouldNotHappenException;
99
use PHPStan\Type\Accessory\AccessoryLowercaseStringType;
10-
use PHPStan\Type\Accessory\AccessoryUppercaseStringType;
1110
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
1211
use PHPStan\Type\Constant\ConstantBooleanType;
1312
use PHPStan\Type\Constant\ConstantIntegerType;
@@ -40,23 +39,15 @@ final class ParseUrlFunctionDynamicReturnTypeExtension implements DynamicFunctio
4039
/** @var array<string,Type>|null */
4140
private ?array $componentTypesPairedStrings = null;
4241

43-
private ?Type $allComponentsTogetherType = null;
44-
4542
/** @var array<int,Type>|null */
4643
private ?array $componentTypesPairedConstantsForLowercaseString = null;
4744

4845
/** @var array<string,Type>|null */
4946
private ?array $componentTypesPairedStringsForLowercaseString = null;
5047

51-
private ?Type $allComponentsTogetherTypeForLowercaseString = null;
52-
53-
/** @var array<int,Type>|null */
54-
private ?array $componentTypesPairedConstantsForUppercaseString = null;
55-
56-
/** @var array<string,Type>|null */
57-
private ?array $componentTypesPairedStringsForUppercaseString = null;
48+
private ?Type $allComponentsTogetherType = null;
5849

59-
private ?Type $allComponentsTogetherTypeForUppercaseString = null;
50+
private ?Type $allComponentsTogetherTypeForLowercaseString = null;
6051

6152
public function isFunctionSupported(FunctionReflection $functionReflection): bool
6253
{
@@ -76,18 +67,12 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
7667
$componentType = $scope->getType($functionCall->getArgs()[1]->value);
7768

7869
if (!$componentType->isConstantValue()->yes()) {
79-
return $this->createAllComponentsReturnType(
80-
$urlType->isLowercaseString()->yes(),
81-
$urlType->isUppercaseString()->yes(),
82-
);
70+
return $this->createAllComponentsReturnType($urlType->isLowercaseString()->yes());
8371
}
8472

8573
$componentType = $componentType->toInteger();
8674
if (!$componentType instanceof ConstantIntegerType) {
87-
return $this->createAllComponentsReturnType(
88-
$urlType->isLowercaseString()->yes(),
89-
$urlType->isUppercaseString()->yes(),
90-
);
75+
return $this->createAllComponentsReturnType($urlType->isLowercaseString()->yes());
9176
}
9277
} else {
9378
$componentType = new ConstantIntegerType(-1);
@@ -111,10 +96,7 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
11196

11297
if ($componentType->getValue() === -1) {
11398
return TypeCombinator::union(
114-
$this->createComponentsArray(
115-
$urlType->isLowercaseString()->yes(),
116-
$urlType->isUppercaseString()->yes(),
117-
),
99+
$this->createComponentsArray($urlType->isLowercaseString()->yes()),
118100
new ConstantBooleanType(false),
119101
);
120102
}
@@ -123,43 +105,19 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
123105
return $this->componentTypesPairedConstantsForLowercaseString[$componentType->getValue()] ?? new ConstantBooleanType(false);
124106
}
125107

126-
if ($urlType->isUppercaseString()->yes()) {
127-
return $this->componentTypesPairedConstantsForUppercaseString[$componentType->getValue()] ?? new ConstantBooleanType(false);
128-
}
129-
130108
return $this->componentTypesPairedConstants[$componentType->getValue()] ?? new ConstantBooleanType(false);
131109
}
132110

133-
private function createAllComponentsReturnType(bool $urlIsLowercase, bool $urlIsUppercase): Type
111+
private function createAllComponentsReturnType(bool $urlIsLowercase): Type
134112
{
135-
if ($urlIsLowercase && $urlIsUppercase) {
136-
if (
137-
$this->allComponentsTogetherTypeForLowercaseString === null
138-
&& $this->allComponentsTogetherTypeForUppercaseString === null
139-
) {
140-
$returnTypes = [
141-
new ConstantBooleanType(false),
142-
new NullType(),
143-
IntegerRangeType::fromInterval(0, 65535),
144-
new IntersectionType([new StringType(), new AccessoryLowercaseStringType(), new AccessoryUppercaseStringType()]),
145-
$this->createComponentsArray(true, true),
146-
];
147-
148-
$union = TypeCombinator::union(...$returnTypes);
149-
$this->allComponentsTogetherTypeForLowercaseString = $union;
150-
$this->allComponentsTogetherTypeForUppercaseString = $union;
151-
return $union;
152-
}
153-
}
154-
155113
if ($urlIsLowercase) {
156114
if ($this->allComponentsTogetherTypeForLowercaseString === null) {
157115
$returnTypes = [
158116
new ConstantBooleanType(false),
159117
new NullType(),
160118
IntegerRangeType::fromInterval(0, 65535),
161119
new IntersectionType([new StringType(), new AccessoryLowercaseStringType()]),
162-
$this->createComponentsArray(true, false),
120+
$this->createComponentsArray(true),
163121
];
164122

165123
$this->allComponentsTogetherTypeForLowercaseString = TypeCombinator::union(...$returnTypes);
@@ -168,29 +126,13 @@ private function createAllComponentsReturnType(bool $urlIsLowercase, bool $urlIs
168126
return $this->allComponentsTogetherTypeForLowercaseString;
169127
}
170128

171-
if ($urlIsUppercase) {
172-
if ($this->allComponentsTogetherTypeForUppercaseString === null) {
173-
$returnTypes = [
174-
new ConstantBooleanType(false),
175-
new NullType(),
176-
IntegerRangeType::fromInterval(0, 65535),
177-
new IntersectionType([new StringType(), new AccessoryUppercaseStringType()]),
178-
$this->createComponentsArray(false, true),
179-
];
180-
181-
$this->allComponentsTogetherTypeForUppercaseString = TypeCombinator::union(...$returnTypes);
182-
}
183-
184-
return $this->allComponentsTogetherTypeForUppercaseString;
185-
}
186-
187129
if ($this->allComponentsTogetherType === null) {
188130
$returnTypes = [
189131
new ConstantBooleanType(false),
190132
new NullType(),
191133
IntegerRangeType::fromInterval(0, 65535),
192134
new StringType(),
193-
$this->createComponentsArray(false, false),
135+
$this->createComponentsArray(false),
194136
];
195137

196138
$this->allComponentsTogetherType = TypeCombinator::union(...$returnTypes);
@@ -199,7 +141,7 @@ private function createAllComponentsReturnType(bool $urlIsLowercase, bool $urlIs
199141
return $this->allComponentsTogetherType;
200142
}
201143

202-
private function createComponentsArray(bool $urlIsLowercase, bool $urlIsUppercase): Type
144+
private function createComponentsArray(bool $urlIsLowercase): Type
203145
{
204146
$builder = ConstantArrayTypeBuilder::createEmpty();
205147

@@ -211,19 +153,7 @@ private function createComponentsArray(bool $urlIsLowercase, bool $urlIsUppercas
211153
foreach ($this->componentTypesPairedStringsForLowercaseString as $componentName => $componentValueType) {
212154
$builder->setOffsetValueType(new ConstantStringType($componentName), $componentValueType, true);
213155
}
214-
}
215-
216-
if ($urlIsUppercase) {
217-
if ($this->componentTypesPairedStringsForUppercaseString === null) {
218-
throw new ShouldNotHappenException();
219-
}
220-
221-
foreach ($this->componentTypesPairedStringsForUppercaseString as $componentName => $componentValueType) {
222-
$builder->setOffsetValueType(new ConstantStringType($componentName), $componentValueType, true);
223-
}
224-
}
225-
226-
if (! $urlIsLowercase && ! $urlIsUppercase) {
156+
} else {
227157
if ($this->componentTypesPairedStrings === null) {
228158
throw new ShouldNotHappenException();
229159
}
@@ -243,10 +173,13 @@ private function cacheReturnTypes(): void
243173
}
244174

245175
$string = new StringType();
176+
$lowercaseString = new IntersectionType([new StringType(), new AccessoryLowercaseStringType()]);
246177
$port = IntegerRangeType::fromInterval(0, 65535);
247178
$false = new ConstantBooleanType(false);
248179
$null = new NullType();
180+
249181
$stringOrFalseOrNull = TypeCombinator::union($string, $false, $null);
182+
$lowercaseStringOrFalseOrNull = TypeCombinator::union($lowercaseString, $false, $null);
250183
$portOrFalseOrNull = TypeCombinator::union($port, $false, $null);
251184

252185
$this->componentTypesPairedConstants = [
@@ -259,6 +192,16 @@ private function cacheReturnTypes(): void
259192
PHP_URL_QUERY => $stringOrFalseOrNull,
260193
PHP_URL_FRAGMENT => $stringOrFalseOrNull,
261194
];
195+
$this->componentTypesPairedConstantsForLowercaseString = [
196+
PHP_URL_SCHEME => $lowercaseStringOrFalseOrNull,
197+
PHP_URL_HOST => $lowercaseStringOrFalseOrNull,
198+
PHP_URL_PORT => $portOrFalseOrNull,
199+
PHP_URL_USER => $lowercaseStringOrFalseOrNull,
200+
PHP_URL_PASS => $lowercaseStringOrFalseOrNull,
201+
PHP_URL_PATH => $lowercaseStringOrFalseOrNull,
202+
PHP_URL_QUERY => $lowercaseStringOrFalseOrNull,
203+
PHP_URL_FRAGMENT => $lowercaseStringOrFalseOrNull,
204+
];
262205

263206
$this->componentTypesPairedStrings = [
264207
'scheme' => $string,
@@ -270,20 +213,6 @@ private function cacheReturnTypes(): void
270213
'query' => $string,
271214
'fragment' => $string,
272215
];
273-
274-
$lowercaseString = new IntersectionType([new StringType(), new AccessoryLowercaseStringType()]);
275-
$lowercaseStringOrFalseOrNull = TypeCombinator::union($lowercaseString, $false, $null);
276-
277-
$this->componentTypesPairedConstantsForLowercaseString = [
278-
PHP_URL_SCHEME => $lowercaseStringOrFalseOrNull,
279-
PHP_URL_HOST => $lowercaseStringOrFalseOrNull,
280-
PHP_URL_PORT => $portOrFalseOrNull,
281-
PHP_URL_USER => $lowercaseStringOrFalseOrNull,
282-
PHP_URL_PASS => $lowercaseStringOrFalseOrNull,
283-
PHP_URL_PATH => $lowercaseStringOrFalseOrNull,
284-
PHP_URL_QUERY => $lowercaseStringOrFalseOrNull,
285-
PHP_URL_FRAGMENT => $lowercaseStringOrFalseOrNull,
286-
];
287216
$this->componentTypesPairedStringsForLowercaseString = [
288217
'scheme' => $lowercaseString,
289218
'host' => $lowercaseString,
@@ -294,30 +223,6 @@ private function cacheReturnTypes(): void
294223
'query' => $lowercaseString,
295224
'fragment' => $lowercaseString,
296225
];
297-
298-
$uppercaseString = new IntersectionType([new StringType(), new AccessoryUppercaseStringType()]);
299-
$uppercaseStringOrFalseOrNull = TypeCombinator::union($uppercaseString, $false, $null);
300-
301-
$this->componentTypesPairedConstantsForUppercaseString = [
302-
PHP_URL_SCHEME => $uppercaseStringOrFalseOrNull,
303-
PHP_URL_HOST => $uppercaseStringOrFalseOrNull,
304-
PHP_URL_PORT => $portOrFalseOrNull,
305-
PHP_URL_USER => $uppercaseStringOrFalseOrNull,
306-
PHP_URL_PASS => $uppercaseStringOrFalseOrNull,
307-
PHP_URL_PATH => $uppercaseStringOrFalseOrNull,
308-
PHP_URL_QUERY => $uppercaseStringOrFalseOrNull,
309-
PHP_URL_FRAGMENT => $uppercaseStringOrFalseOrNull,
310-
];
311-
$this->componentTypesPairedStringsForUppercaseString = [
312-
'scheme' => $uppercaseString,
313-
'host' => $uppercaseString,
314-
'port' => $port,
315-
'user' => $uppercaseString,
316-
'pass' => $uppercaseString,
317-
'path' => $uppercaseString,
318-
'query' => $uppercaseString,
319-
'fragment' => $uppercaseString,
320-
];
321226
}
322227

323228
}

tests/PHPStan/Analyser/nsrt/uppercase-string-parse-url.php

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)