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

Improve preg_split() function ReturnType #3757

Open
wants to merge 18 commits into
base: 2.0.x
Choose a base branch
from

Conversation

malsuke
Copy link

@malsuke malsuke commented Dec 26, 2024

I developed further extended the extension for the preg_split() function.

The preg_split() function can specify ReturnType with the following cases:

  • When the regular expression passed as the $pattern argument is invalid.
  • When the $pattern and $subject arguments are constants.
  • When the string passed as the $subject argument is non-empty-string.
  • When the $flag argument is set to one or more of the following: PREG_SPLIT_OFFSET_CAPTURE, PREG_SPLIT_NO_EMPTY, or PREG_SPLIT_DELIM_CAPTURE.

The detailed cases are specified in the test cases.

Additionally, the current default return type is set to list<string>|false. However, depending on the flags, it also return list<array{string, int<0, max>}>. To account for this, I have added support for this possibility and applied a benevolent union to cover all three types. So, I set __benevolent<list<string>|list<array{string, int<0, max>}>|false> to the basic return type.

@malsuke malsuke marked this pull request as draft December 26, 2024 07:53
@malsuke malsuke marked this pull request as ready for review December 26, 2024 08:13
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

} else {
$flagType = $scope->getType($flagArg->value);
$flags = $flagType->getConstantScalarValues();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

By replacing it as follows, type checking within multiple Constant loops will no longer be necessary.

$flags = [];
$flagType = $scope->getType($flagArg->value);
foreach ($flagType->getConstantScalarValues() as $flag) {
    if (!is_int()) {
        return new ErrorType();
    }

    $flags[] = $flag;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

resolved 8cb3030

@@ -9081,7 +9081,7 @@
'preg_replace' => ['string|array|null', 'regex'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
'preg_replace_callback' => ['string|array|null', 'regex'=>'string|array', 'callback'=>'callable(array<int|string, string>):string', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
'preg_replace_callback_array' => ['string|array|null', 'pattern'=>'array<string,callable>', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
'preg_split' => ['list<string>|false', 'pattern'=>'string', 'subject'=>'string', 'limit='=>'?int', 'flags='=>'int'],
'preg_split' => ['__benevolent<list<string>|list<array{string, int<0, max>}>|false>', 'pattern'=>'string', 'subject'=>'string', 'limit='=>'?int', 'flags='=>'int'],
Copy link
Contributor

Choose a reason for hiding this comment

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

The other preg_ method are not using benevolent union, so I would think more consistent to not use a benevolent union here too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants