Skip to content

Commit

Permalink
RegexArrayShapeMatcher - Fix PREG_UNMATCHED_AS_NULL with top level al…
Browse files Browse the repository at this point in the history
…ternation
  • Loading branch information
staabm authored and ondrejmirtes committed Jul 15, 2024
1 parent 7d3be58 commit b116e71
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/Type/Php/RegexArrayShapeMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
$beforeCurrentCombo = false;
} elseif ($beforeCurrentCombo && !$group->resetsGroupCounter()) {
$group->forceNonOptional();
} elseif ($group->getAlternationId() === $onlyTopLevelAlternationId) {
} elseif ($group->getAlternationId() === $onlyTopLevelAlternationId && !$this->containsUnmatchedAsNull($flags ?? 0)) {
unset($comboList[$groupId]);
}
}
Expand All @@ -191,7 +191,7 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
}
}

if ($isOptionalAlternation) {
if ($isOptionalAlternation && !$this->containsUnmatchedAsNull($flags ?? 0)) {
$combiTypes[] = new ConstantArrayType([new ConstantIntegerType(0)], [new StringType()], [0], [], true);
}

Expand Down
14 changes: 14 additions & 0 deletions tests/PHPStan/Analyser/nsrt/bug-11311.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,17 @@ function bug11331c(string $url):void {
assertType('array{string, string|null, string|null, string, string}', $matches);
}
}

class UnmatchedAsNullWithTopLevelAlternation {
function doFoo(string $s): void {
if (preg_match('/Price: (?:(£)|(€))\d+/', $s, $matches, PREG_UNMATCHED_AS_NULL)) {
assertType('array{string, string|null, string|null}', $matches); // could be array{0: string, 1: null, 2: string}|array{0: string, 1: string, 2: null}
}
}

function doBar(string $s): void {
if (preg_match('/Price: (?:(£)|(€))?\d+/', $s, $matches, PREG_UNMATCHED_AS_NULL)) {
assertType('array{string, string|null, string|null}', $matches);
}
}
}

0 comments on commit b116e71

Please sign in to comment.