Skip to content

Commit 5281a8c

Browse files
committed
fix empty token parse in capturing group
1 parent 0c222fb commit 5281a8c

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
@@ -86,6 +86,7 @@ public function parseGroups(string $regex): ?array
8686
}
8787

8888
$this->updateAlternationAstRemoveVerticalBarsAndAddEmptyToken($ast);
89+
$this->updateCapturingAstAddEmptyToken($ast);
8990

9091
$captureOnlyNamed = false;
9192
if ($this->phpVersion->supportsPregCaptureOnlyNamedGroups()) {
@@ -137,6 +138,21 @@ private function updateAlternationAstRemoveVerticalBarsAndAddEmptyToken(TreeNode
137138
$ast->setChildren(array_values($children));
138139
}
139140

141+
private function updateCapturingAstAddEmptyToken(TreeNode $ast): void
142+
{
143+
foreach ($ast->getChildren() as $child) {
144+
$this->updateCapturingAstAddEmptyToken($child);
145+
}
146+
147+
if ($ast->getId() !== '#capturing' || $ast->getChildren() !== []) {
148+
return;
149+
}
150+
151+
$emptyAlternationAst = new TreeNode('#alternation', null, [], $ast);
152+
$emptyAlternationAst->setChildren([$this->createEmptyTokenTreeNode($emptyAlternationAst)]);
153+
$ast->setChildren([$emptyAlternationAst]);
154+
}
155+
140156
private function walkRegexAst(
141157
TreeNode $ast,
142158
?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)