Skip to content

Commit 002d366

Browse files
committed
fix empty token parse in capturing group
1 parent 873fd62 commit 002d366

File tree

2 files changed

+18
-2
lines changed

2 files changed

+18
-2
lines changed

src/Type/Regex/RegexGroupParser.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public function parseGroups(string $regex): ?array
8080
}
8181

8282
$this->updateAlternationAstRemoveVerticalBarsAndAddEmptyToken($ast);
83+
$this->updateCapturingAstAddEmptyToken($ast);
8384

8485
$captureOnlyNamed = false;
8586
if ($this->phpVersion->supportsPregCaptureOnlyNamedGroups()) {
@@ -131,6 +132,21 @@ private function updateAlternationAstRemoveVerticalBarsAndAddEmptyToken(TreeNode
131132
$ast->setChildren(array_values($children));
132133
}
133134

135+
private function updateCapturingAstAddEmptyToken(TreeNode $ast): void
136+
{
137+
foreach ($ast->getChildren() as $child) {
138+
$this->updateCapturingAstAddEmptyToken($child);
139+
}
140+
141+
if ($ast->getId() !== '#capturing' || $ast->getChildren() !== []) {
142+
return;
143+
}
144+
145+
$emptyAlternationAst = new TreeNode('#alternation', null, [], $ast);
146+
$emptyAlternationAst->setChildren([$this->createEmptyTokenTreeNode($emptyAlternationAst)]);
147+
$ast->setChildren([$emptyAlternationAst]);
148+
}
149+
134150
private function walkRegexAst(
135151
TreeNode $ast,
136152
?RegexAlternation $alternation,

tests/PHPStan/Analyser/nsrt/preg_match_shapes.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ function bugEmptySubexpression (string $string): void {
907907
}
908908

909909
if (preg_match('/()/', $string, $matches)) {
910-
assertType("array{string, string}", $matches); // could be array{'', ''}
910+
assertType("array{string, ''}", $matches); // could be array{'', ''}
911911
}
912912

913913
if (preg_match('/|/', $string, $matches)) {
@@ -939,7 +939,7 @@ function bugEmptySubexpression (string $string): void {
939939
}
940940

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

0 commit comments

Comments
 (0)