Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding the PHP 7.2 support for PREG_UNMATCHED_AS_NULL #3226

Merged
merged 2 commits into from
Jul 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions src/Type/Php/RegexArrayShapeMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
final class RegexArrayShapeMatcher
{

/**
* Pass this into $flagsType as well if the library supports emulating PREG_UNMATCHED_AS_NULL on PHP 7.2 and 7.3
*/
public const PREG_UNMATCHED_AS_NULL_ON_72_73 = 2048;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The highest in use currently is 256, so I chose 2048 to leave 512/1024 as gaps if PHP should add new constants there.


private static ?Parser $parser = null;

public function __construct(
Expand All @@ -53,14 +58,17 @@ public function matchType(Type $patternType, ?Type $flagsType, TrinaryLogic $was

$flags = null;
if ($flagsType !== null) {
if (
!$flagsType instanceof ConstantIntegerType
|| !in_array($flagsType->getValue(), [PREG_OFFSET_CAPTURE, PREG_UNMATCHED_AS_NULL, PREG_OFFSET_CAPTURE | PREG_UNMATCHED_AS_NULL], true)
) {
if (!$flagsType instanceof ConstantIntegerType) {
return null;
}

$flags = $flagsType->getValue();
/** @var int-mask<PREG_OFFSET_CAPTURE | PREG_UNMATCHED_AS_NULL | self::PREG_UNMATCHED_AS_NULL_ON_72_73> $flags */
$flags = $flagsType->getValue() & (PREG_OFFSET_CAPTURE | PREG_UNMATCHED_AS_NULL | self::PREG_UNMATCHED_AS_NULL_ON_72_73);
Comment on lines +65 to +66
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow phpstan thinks it's an int<0, 2816> as that's the value on the right. Could be nice if it was smarter here but I guess bitwise use is rare enough that it's not worth that much time spent optimizing for them.

The var annotation fixed it though.


// some other unsupported/unexpected flag was passed in
if ($flags !== $flagsType->getValue()) {
return null;
}
}

$matchedTypes = [];
Expand All @@ -81,7 +89,7 @@ public function matchType(Type $patternType, ?Type $flagsType, TrinaryLogic $was
}

/**
* @param int-mask<PREG_OFFSET_CAPTURE|PREG_UNMATCHED_AS_NULL>|null $flags
* @param int-mask<PREG_OFFSET_CAPTURE|PREG_UNMATCHED_AS_NULL|self::PREG_UNMATCHED_AS_NULL_ON_72_73>|null $flags
*/
private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched): ?Type
{
Expand Down Expand Up @@ -292,7 +300,7 @@ private function buildArrayType(

private function containsUnmatchedAsNull(int $flags): bool
{
return ($flags & PREG_UNMATCHED_AS_NULL) !== 0 && $this->phpVersion->supportsPregUnmatchedAsNull();
return ($flags & PREG_UNMATCHED_AS_NULL) !== 0 && (($flags & self::PREG_UNMATCHED_AS_NULL_ON_72_73) !== 0 || $this->phpVersion->supportsPregUnmatchedAsNull());
}

private function getKeyType(int|string $key): Type
Expand Down
Loading