Skip to content

Commit 83d466e

Browse files
committed
fix numeric string handling
1 parent 8c01032 commit 83d466e

File tree

5 files changed

+22
-15
lines changed

5 files changed

+22
-15
lines changed

src/Type/Regex/RegexGroupParser.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,20 @@ public function parseGroups(string $regex): ?RegexAstWalkResult
109109
$modifiers,
110110
RegexGroupWalkResult::createEmpty(),
111111
);
112-
if ($subjectAsGroupResult->isNonFalsy()->yes() || $subjectAsGroupResult->isNumeric()->yes()) {
113-
$astWalkResult = $astWalkResult->withSubjectBaseType(
114-
TypeCombinator::intersect(new StringType(), new AccessoryNonFalsyStringType()),
115-
);
112+
113+
// we could handle numeric-string, in case we know the regex is delimited by ^ and $
114+
$accessories = [];
115+
if ($subjectAsGroupResult->isNonFalsy()->yes()) {
116+
$accessories[] = new AccessoryNonFalsyStringType();
116117
} elseif ($subjectAsGroupResult->isNonEmpty()->yes()) {
118+
$accessories[] = new AccessoryNonEmptyStringType();
119+
}
120+
121+
if ($accessories !== []) {
122+
$accessories[] = new StringType();
123+
117124
$astWalkResult = $astWalkResult->withSubjectBaseType(
118-
TypeCombinator::intersect(new StringType(), new AccessoryNonEmptyStringType()),
125+
TypeCombinator::intersect(...$accessories),
119126
);
120127
}
121128

tests/PHPStan/Analyser/nsrt/bug11384.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class HelloWorld
1414
public function sayHello(string $s): void
1515
{
1616
if (preg_match('{(' . Bar::VAL . ')}', $s, $m)) {
17-
assertType("array{non-falsy-string, '3'}", $m);
17+
assertType("array{non-empty-string, '3'}", $m);
1818
}
1919
}
2020
}

tests/PHPStan/Analyser/nsrt/preg_match_shapes.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -477,13 +477,13 @@ function bug11323(string $s): void {
477477
assertType('array{non-falsy-string, non-falsy-string}', $matches);
478478
}
479479
if (preg_match('{([[:digit:]])}', $s, $matches)) {
480-
assertType('array{non-falsy-string, numeric-string}', $matches);
480+
assertType('array{non-empty-string, numeric-string}', $matches);
481481
}
482482
if (preg_match('{([\d])(\d)}', $s, $matches)) {
483483
assertType('array{non-falsy-string, numeric-string, numeric-string}', $matches);
484484
}
485485
if (preg_match('{([0-9])}', $s, $matches)) {
486-
assertType('array{non-falsy-string, numeric-string}', $matches);
486+
assertType('array{non-empty-string, numeric-string}', $matches);
487487
}
488488
if (preg_match('{(\p{L})(\p{P})(\p{Po})}', $s, $matches)) {
489489
assertType('array{non-falsy-string, non-empty-string, non-empty-string, non-empty-string}', $matches);
@@ -654,7 +654,7 @@ function (string $s): void {
654654

655655
function (string $s): void {
656656
if (preg_match('/( \d+ )/x', $s, $matches)) {
657-
assertType('array{non-falsy-string, numeric-string}', $matches);
657+
assertType('array{non-empty-string, numeric-string}', $matches);
658658
}
659659
};
660660

@@ -792,7 +792,7 @@ function testUnescapeBackslash (string $string): void {
792792
if (preg_match(<<<'EOD'
793793
~(\d)~
794794
EOD, $string, $matches)) {
795-
assertType("array{non-falsy-string, numeric-string}", $matches);
795+
assertType("array{non-empty-string, numeric-string}", $matches);
796796
}
797797

798798
if (preg_match(<<<'EOD'
@@ -1000,7 +1000,7 @@ function bug12749e(string $str): void
10001000
{
10011001
// no ^ $ delims, therefore can be anything which contains a number
10021002
if (preg_match('/[0-9]/', $str, $match)) {
1003-
assertType('array{non-falsy-string}', $match);
1003+
assertType('array{non-empty-string}', $match);
10041004
}
10051005
}
10061006

tests/PHPStan/Analyser/nsrt/preg_match_shapes_php80.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function doOffsetCaptureWithUnmatchedNull(string $s): void {
1515
function doNonAutoCapturingModifier(string $s): void {
1616
if (preg_match('/(?n)(\d+)/', $s, $matches)) {
1717
// should be assertType('array{string}', $matches);
18-
assertType('array{non-falsy-string, numeric-string}', $matches);
18+
assertType('array{non-empty-string, numeric-string}', $matches);
1919
}
20-
assertType('array{}|array{non-falsy-string, numeric-string}', $matches);
20+
assertType('array{}|array{non-empty-string, numeric-string}', $matches);
2121
}

tests/PHPStan/Analyser/nsrt/preg_match_shapes_php82.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// https://php.watch/versions/8.2/preg-n-no-capture-modifier
99
function doNonAutoCapturingFlag(string $s): void {
1010
if (preg_match('/(\d+)/n', $s, $matches)) {
11-
assertType('array{non-falsy-string}', $matches);
11+
assertType('array{non-empty-string}', $matches);
1212
}
13-
assertType('array{}|array{non-falsy-string}', $matches);
13+
assertType('array{}|array{non-empty-string}', $matches);
1414

1515
if (preg_match('/(\d+)(?P<num>\d+)/n', $s, $matches)) {
1616
assertType('array{0: non-falsy-string, num: numeric-string, 1: numeric-string}', $matches);

0 commit comments

Comments
 (0)