Skip to content

Commit e10c993

Browse files
committed
fix empty token parse in capturing group
1 parent 55946c3 commit e10c993

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

7171
$this->updateAlternationAstRemoveVerticalBarsAndAddEmptyToken($ast);
72+
$this->updateCapturingAstAddEmptyToken($ast);
7273

7374
$captureOnlyNamed = false;
7475
$modifiers = $this->regexExpressionHelper->getPatternModifiers($regex) ?? '';
@@ -121,6 +122,21 @@ private function updateAlternationAstRemoveVerticalBarsAndAddEmptyToken(TreeNode
121122
$ast->setChildren(array_values($children));
122123
}
123124

125+
private function updateCapturingAstAddEmptyToken(TreeNode $ast): void
126+
{
127+
foreach ($ast->getChildren() as $child) {
128+
$this->updateCapturingAstAddEmptyToken($child);
129+
}
130+
131+
if ($ast->getId() !== '#capturing' || $ast->getChildren() !== []) {
132+
return;
133+
}
134+
135+
$emptyAlternationAst = new TreeNode('#alternation', null, [], $ast);
136+
$emptyAlternationAst->setChildren([$this->createEmptyTokenTreeNode($emptyAlternationAst)]);
137+
$ast->setChildren([$emptyAlternationAst]);
138+
}
139+
124140
private function walkRegexAst(
125141
TreeNode $ast,
126142
?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)