Skip to content

Commit fcbc002

Browse files
committed
enforce list when non-named
1 parent 34bf19a commit fcbc002

File tree

5 files changed

+21
-14
lines changed

5 files changed

+21
-14
lines changed

src/Type/Php/RegexArrayShapeMatcher.php

+7
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ private function buildArrayType(
243243
bool $matchesAll,
244244
): Type
245245
{
246+
$forceList = count($markVerbs) === 0;
246247
$builder = ConstantArrayTypeBuilder::createEmpty();
247248

248249
// first item in matches contains the overall match.
@@ -261,6 +262,8 @@ private function buildArrayType(
261262
$optional = $this->isGroupOptional($captureGroup, $wasMatched, $flags, $isTrailingOptional, $matchesAll);
262263

263264
if ($captureGroup->isNamed()) {
265+
$forceList = false;
266+
264267
$builder->setOffsetValueType(
265268
$this->getKeyType($captureGroup->getName()),
266269
$groupValueType,
@@ -300,6 +303,10 @@ private function buildArrayType(
300303
return $arrayType;
301304
}
302305

306+
if ($forceList) {
307+
return TypeCombinator::intersect($builder->getArray(), new AccessoryArrayListType());
308+
}
309+
303310
return $builder->getArray();
304311
}
305312

tests/PHPStan/Analyser/nsrt/bug-11311.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,12 @@ function (string $s): void {
191191

192192
function (string $s): void {
193193
preg_match('/%a(\d*)/', $s, $matches, PREG_UNMATCHED_AS_NULL);
194-
assertType("array{0?: string, 1?: ''|numeric-string|null}", $matches); // could be array{0?: string, 1?: ''|numeric-string}
194+
assertType("list{0?: string, 1?: ''|numeric-string|null}", $matches); // could be array{0?: string, 1?: ''|numeric-string}
195195
};
196196

197197
function (string $s): void {
198198
preg_match('/%a(\d*)?/', $s, $matches, PREG_UNMATCHED_AS_NULL);
199-
assertType("array{0?: string, 1?: ''|numeric-string|null}", $matches); // could be array{0?: string, 1?: ''|numeric-string}
199+
assertType("list{0?: string, 1?: ''|numeric-string|null}", $matches); // could be array{0?: string, 1?: ''|numeric-string}
200200
};
201201

202202
function (string $s): void {
@@ -222,5 +222,5 @@ function (string $s): void {
222222

223223
function (string $s): void {
224224
preg_match('~a|(\d)|(\s)~', $s, $matches, PREG_UNMATCHED_AS_NULL);
225-
assertType("array{0?: string, 1?: numeric-string|null, 2?: non-empty-string|null}", $matches);
225+
assertType("list{0?: string, 1?: numeric-string|null, 2?: non-empty-string|null}", $matches);
226226
};

tests/PHPStan/Analyser/nsrt/bug-11580.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function bad2(string $in): void
2626
public function bad3(string $in): void
2727
{
2828
$result = preg_match('~^/xxx/([\w\-]+)/?([\w\-]+)?/?$~', $in, $matches);
29-
assertType('array{0?: string, 1?: non-empty-string, 2?: non-empty-string}', $matches);
29+
assertType('list{0?: string, 1?: non-empty-string, 2?: non-empty-string}', $matches);
3030
if ($result) {
3131
assertType('array{0: non-falsy-string, 1: non-empty-string, 2?: non-empty-string}', $matches);
3232
}

tests/PHPStan/Analyser/nsrt/preg_match_shapes.php

+9-9
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ function (string $size): void {
300300
if (preg_match('~^a\.(b)?(c)?d~', $size, $matches) !== 1) {
301301
throw new InvalidArgumentException(sprintf('Invalid size "%s"', $size));
302302
}
303-
assertType("array{0: non-falsy-string, 1?: ''|'b', 2?: 'c'}", $matches);
303+
assertType("list{0: non-falsy-string, 1?: ''|'b', 2?: 'c'}", $matches);
304304
};
305305

306306
function (string $size): void {
@@ -525,15 +525,15 @@ function bug11323(string $s): void {
525525

526526
function (string $s): void {
527527
preg_match('/%a(\d*)/', $s, $matches);
528-
assertType("array{0?: string, 1?: ''|numeric-string}", $matches);
528+
assertType("list{0?: string, 1?: ''|numeric-string}", $matches);
529529
};
530530

531531
class Bug11376
532532
{
533533
public function test(string $str): void
534534
{
535535
preg_match('~^(?:(\w+)::)?(\w+)$~', $str, $matches);
536-
assertType('array{0?: string, 1?: string, 2?: non-empty-string}', $matches);
536+
assertType('list{0?: string, 1?: string, 2?: non-empty-string}', $matches);
537537
}
538538

539539
public function test2(string $str): void
@@ -564,7 +564,7 @@ function (string $s): void {
564564
}
565565

566566
if (preg_match($p, $s, $matches)) {
567-
assertType("array{0: non-falsy-string, 1: 'x'|'£'|numeric-string, 2?: ''|numeric-string, 3?: 'x'}", $matches);
567+
assertType("list{0: non-falsy-string, 1: 'x'|'£'|numeric-string, 2?: ''|numeric-string, 3?: 'x'}", $matches);
568568
}
569569
};
570570

@@ -730,7 +730,7 @@ function (string $s): void {
730730

731731
function (string $s): void {
732732
preg_match('~a|(\d)|(\s)~', $s, $matches);
733-
assertType("array{0?: string, 1?: '', 2?: non-empty-string}|array{0?: string, 1?: numeric-string}", $matches);
733+
assertType("list{0?: string, 1?: '', 2?: non-empty-string}|list{0?: string, 1?: numeric-string}", $matches);
734734
};
735735

736736
function bug11490 (string $expression): void {
@@ -762,13 +762,13 @@ function bug11604 (string $string): void {
762762
return;
763763
}
764764

765-
assertType("array{0: non-empty-string, 1?: ''|'XX', 2?: 'YY'}", $matches);
765+
assertType("list{0: non-empty-string, 1?: ''|'XX', 2?: 'YY'}", $matches);
766766
// could be array{string, '', 'YY'}|array{string, 'XX'}|array{string}
767767
}
768768

769769
function bug11604b (string $string): void {
770770
if (preg_match('/(XX)|(YY)?(ZZ)/', $string, $matches)) {
771-
assertType("array{0: non-empty-string, 1?: ''|'XX', 2?: ''|'YY', 3?: 'ZZ'}", $matches);
771+
assertType("list{0: non-empty-string, 1?: ''|'XX', 2?: ''|'YY', 3?: 'ZZ'}", $matches);
772772
}
773773
}
774774

@@ -935,11 +935,11 @@ function bugEmptySubexpression (string $string): void {
935935
}
936936

937937
if (preg_match('~((a)||(b))~', $string, $matches)) {
938-
assertType("array{0: string, 1: ''|'a'|'b', 2?: ''|'a', 3?: 'b'}", $matches);
938+
assertType("list{0: string, 1: ''|'a'|'b', 2?: ''|'a', 3?: 'b'}", $matches);
939939
}
940940

941941
if (preg_match('~((a)|()|(b))~', $string, $matches)) {
942-
assertType("array{0: string, 1: ''|'a'|'b', 2?: ''|'a', 3?: '', 4?: 'b'}", $matches);
942+
assertType("list{0: string, 1: ''|'a'|'b', 2?: ''|'a', 3?: '', 4?: 'b'}", $matches);
943943
}
944944
}
945945

tests/PHPStan/Analyser/nsrt/preg_replace_callback_shapes.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function (string $s): void {
2222
preg_replace_callback(
2323
'/(foo)?(bar)?(baz)?/',
2424
function ($matches) {
25-
assertType("array{0: array{string, int<-1, max>}, 1?: array{''|'foo', int<-1, max>}, 2?: array{''|'bar', int<-1, max>}, 3?: array{'baz', int<-1, max>}}", $matches);
25+
assertType("list{0: array{string, int<-1, max>}, 1?: array{''|'foo', int<-1, max>}, 2?: array{''|'bar', int<-1, max>}, 3?: array{'baz', int<-1, max>}}", $matches);
2626
return '';
2727
},
2828
$s,

0 commit comments

Comments
 (0)