Updated Rector to commit a8f322ad7e93f7902fca0a057e8d604482f71080

a8f322ad7e [Core] Remove BetterStandardPrinter::pStmt_Class() (#3072)
This commit is contained in:
Tomas Votruba 2022-11-17 10:44:46 +00:00
parent ad35b62266
commit 8360fa1a7a
21 changed files with 333 additions and 75 deletions

View File

@ -4,6 +4,7 @@ declare (strict_types=1);
namespace Rector\CodeQuality\Rector\Empty_;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\Empty_;
@ -44,7 +45,7 @@ final class SimplifyEmptyCheckOnEmptyArrayRector extends AbstractScopeAwareRecto
}
return new Identical($node->expr, new Array_());
}
private function isAllowedExpr(Node\Expr $expr) : bool
private function isAllowedExpr(Expr $expr) : bool
{
if ($expr instanceof Variable) {
return \true;
@ -52,9 +53,6 @@ final class SimplifyEmptyCheckOnEmptyArrayRector extends AbstractScopeAwareRecto
if ($expr instanceof PropertyFetch) {
return \true;
}
if ($expr instanceof StaticPropertyFetch) {
return \true;
}
return \false;
return $expr instanceof StaticPropertyFetch;
}
}

View File

@ -8,7 +8,6 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Trait_;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use RectorPrefix202211\Webmozart\Assert\Assert;
@ -17,10 +16,6 @@ use RectorPrefix202211\Webmozart\Assert\Assert;
*/
final class RemoveTraitUseRector extends AbstractRector implements ConfigurableRectorInterface
{
/**
* @var bool
*/
private $classHasChanged = \false;
/**
* @var string[]
*/
@ -52,19 +47,17 @@ CODE_SAMPLE
*/
public function refactor(Node $node) : ?Node
{
$this->classHasChanged = \false;
$classHasChanged = \false;
foreach ($node->getTraitUses() as $traitUse) {
foreach ($traitUse->traits as $trait) {
if (!$this->isNames($trait, $this->traitsToRemove)) {
continue;
}
$this->removeNode($traitUse);
$this->classHasChanged = \true;
$classHasChanged = \true;
}
}
// invoke re-print
if ($this->classHasChanged) {
$node->setAttribute(AttributeKey::ORIGINAL_NODE, null);
if ($classHasChanged) {
return $node;
}
return null;

View File

@ -17,12 +17,12 @@ final class VersionResolver
* @api
* @var string
*/
public const PACKAGE_VERSION = '8ac960d30cd26f5e071cda5835e4df5c26d30314';
public const PACKAGE_VERSION = 'a8f322ad7e93f7902fca0a057e8d604482f71080';
/**
* @api
* @var string
*/
public const RELEASE_DATE = '2022-11-16 22:12:09';
public const RELEASE_DATE = '2022-11-17 11:40:00';
/**
* @var int
*/

View File

@ -24,7 +24,6 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Declare_;
use PhpParser\Node\Stmt\Nop;
use PhpParser\Node\Stmt\TraitUse;
use PhpParser\Node\Stmt\Use_;
use PhpParser\PrettyPrinter\Standard;
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
@ -302,24 +301,6 @@ final class BetterStandardPrinter extends Standard implements NodePrinterInterfa
// this approach is chosen, to keep changes in parent pStmt_ClassMethod() updated
return Strings::replace($content, self::REPLACE_COLON_WITH_SPACE_REGEX, '$1: ');
}
/**
* Clean class and trait from empty "use x;" for traits causing invalid code
*/
protected function pStmt_Class(Class_ $class) : string
{
$shouldReindex = \false;
foreach ($class->stmts as $key => $stmt) {
// remove empty ones
if ($stmt instanceof TraitUse && $stmt->traits === []) {
unset($class->stmts[$key]);
$shouldReindex = \true;
}
}
if ($shouldReindex) {
$class->stmts = \array_values($class->stmts);
}
return parent::pStmt_Class($class);
}
/**
* It remove all spaces extra to parent
*/

2
vendor/autoload.php vendored
View File

@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInitcf51f0b01cfda16e7ca58972956089b5::getLoader();
return ComposerAutoloaderInitf3d946c54bdbd2e959f0f6c3f35bf397::getLoader();

View File

@ -342,13 +342,16 @@ return array(
'RectorPrefix202211\\Clue\\React\\NDJson\\Decoder' => $vendorDir . '/clue/ndjson-react/src/Decoder.php',
'RectorPrefix202211\\Clue\\React\\NDJson\\Encoder' => $vendorDir . '/clue/ndjson-react/src/Encoder.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchAllResult' => $vendorDir . '/composer/pcre/src/MatchAllResult.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchAllStrictGroupsResult' => $vendorDir . '/composer/pcre/src/MatchAllStrictGroupsResult.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchAllWithOffsetsResult' => $vendorDir . '/composer/pcre/src/MatchAllWithOffsetsResult.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchResult' => $vendorDir . '/composer/pcre/src/MatchResult.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchStrictGroupsResult' => $vendorDir . '/composer/pcre/src/MatchStrictGroupsResult.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchWithOffsetsResult' => $vendorDir . '/composer/pcre/src/MatchWithOffsetsResult.php',
'RectorPrefix202211\\Composer\\Pcre\\PcreException' => $vendorDir . '/composer/pcre/src/PcreException.php',
'RectorPrefix202211\\Composer\\Pcre\\Preg' => $vendorDir . '/composer/pcre/src/Preg.php',
'RectorPrefix202211\\Composer\\Pcre\\Regex' => $vendorDir . '/composer/pcre/src/Regex.php',
'RectorPrefix202211\\Composer\\Pcre\\ReplaceResult' => $vendorDir . '/composer/pcre/src/ReplaceResult.php',
'RectorPrefix202211\\Composer\\Pcre\\UnexpectedNullMatchException' => $vendorDir . '/composer/pcre/src/UnexpectedNullMatchException.php',
'RectorPrefix202211\\Composer\\Semver\\Comparator' => $vendorDir . '/composer/semver/src/Comparator.php',
'RectorPrefix202211\\Composer\\Semver\\CompilingMatcher' => $vendorDir . '/composer/semver/src/CompilingMatcher.php',
'RectorPrefix202211\\Composer\\Semver\\Constraint\\Bound' => $vendorDir . '/composer/semver/src/Constraint/Bound.php',

View File

@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitcf51f0b01cfda16e7ca58972956089b5
class ComposerAutoloaderInitf3d946c54bdbd2e959f0f6c3f35bf397
{
private static $loader;
@ -22,19 +22,19 @@ class ComposerAutoloaderInitcf51f0b01cfda16e7ca58972956089b5
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitcf51f0b01cfda16e7ca58972956089b5', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInitf3d946c54bdbd2e959f0f6c3f35bf397', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
spl_autoload_unregister(array('ComposerAutoloaderInitcf51f0b01cfda16e7ca58972956089b5', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInitf3d946c54bdbd2e959f0f6c3f35bf397', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInitcf51f0b01cfda16e7ca58972956089b5::getInitializer($loader));
call_user_func(\Composer\Autoload\ComposerStaticInitf3d946c54bdbd2e959f0f6c3f35bf397::getInitializer($loader));
$loader->setClassMapAuthoritative(true);
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInitcf51f0b01cfda16e7ca58972956089b5::$files;
$includeFiles = \Composer\Autoload\ComposerStaticInitf3d946c54bdbd2e959f0f6c3f35bf397::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequirecf51f0b01cfda16e7ca58972956089b5($fileIdentifier, $file);
composerRequiref3d946c54bdbd2e959f0f6c3f35bf397($fileIdentifier, $file);
}
return $loader;
@ -46,7 +46,7 @@ class ComposerAutoloaderInitcf51f0b01cfda16e7ca58972956089b5
* @param string $file
* @return void
*/
function composerRequirecf51f0b01cfda16e7ca58972956089b5($fileIdentifier, $file)
function composerRequiref3d946c54bdbd2e959f0f6c3f35bf397($fileIdentifier, $file)
{
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

View File

@ -4,7 +4,7 @@
namespace Composer\Autoload;
class ComposerStaticInitcf51f0b01cfda16e7ca58972956089b5
class ComposerStaticInitf3d946c54bdbd2e959f0f6c3f35bf397
{
public static $files = array (
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
@ -587,13 +587,16 @@ class ComposerStaticInitcf51f0b01cfda16e7ca58972956089b5
'RectorPrefix202211\\Clue\\React\\NDJson\\Decoder' => __DIR__ . '/..' . '/clue/ndjson-react/src/Decoder.php',
'RectorPrefix202211\\Clue\\React\\NDJson\\Encoder' => __DIR__ . '/..' . '/clue/ndjson-react/src/Encoder.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchAllResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchAllResult.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchAllStrictGroupsResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchAllStrictGroupsResult.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchAllWithOffsetsResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchAllWithOffsetsResult.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchResult.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchStrictGroupsResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchStrictGroupsResult.php',
'RectorPrefix202211\\Composer\\Pcre\\MatchWithOffsetsResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchWithOffsetsResult.php',
'RectorPrefix202211\\Composer\\Pcre\\PcreException' => __DIR__ . '/..' . '/composer/pcre/src/PcreException.php',
'RectorPrefix202211\\Composer\\Pcre\\Preg' => __DIR__ . '/..' . '/composer/pcre/src/Preg.php',
'RectorPrefix202211\\Composer\\Pcre\\Regex' => __DIR__ . '/..' . '/composer/pcre/src/Regex.php',
'RectorPrefix202211\\Composer\\Pcre\\ReplaceResult' => __DIR__ . '/..' . '/composer/pcre/src/ReplaceResult.php',
'RectorPrefix202211\\Composer\\Pcre\\UnexpectedNullMatchException' => __DIR__ . '/..' . '/composer/pcre/src/UnexpectedNullMatchException.php',
'RectorPrefix202211\\Composer\\Semver\\Comparator' => __DIR__ . '/..' . '/composer/semver/src/Comparator.php',
'RectorPrefix202211\\Composer\\Semver\\CompilingMatcher' => __DIR__ . '/..' . '/composer/semver/src/CompilingMatcher.php',
'RectorPrefix202211\\Composer\\Semver\\Constraint\\Bound' => __DIR__ . '/..' . '/composer/semver/src/Constraint/Bound.php',
@ -3033,9 +3036,9 @@ class ComposerStaticInitcf51f0b01cfda16e7ca58972956089b5
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->prefixLengthsPsr4 = ComposerStaticInitcf51f0b01cfda16e7ca58972956089b5::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitcf51f0b01cfda16e7ca58972956089b5::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitcf51f0b01cfda16e7ca58972956089b5::$classMap;
$loader->prefixLengthsPsr4 = ComposerStaticInitf3d946c54bdbd2e959f0f6c3f35bf397::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitf3d946c54bdbd2e959f0f6c3f35bf397::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitf3d946c54bdbd2e959f0f6c3f35bf397::$classMap;
}, null, ClassLoader::class);
}

View File

@ -69,17 +69,17 @@
},
{
"name": "composer\/pcre",
"version": "3.0.2",
"version_normalized": "3.0.2.0",
"version": "3.1.0",
"version_normalized": "3.1.0.0",
"source": {
"type": "git",
"url": "https:\/\/github.com\/composer\/pcre.git",
"reference": "4482b6409ca6bfc2af043a5711cd21ac3e7a8dfb"
"reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2"
},
"dist": {
"type": "zip",
"url": "https:\/\/api.github.com\/repos\/composer\/pcre\/zipball\/4482b6409ca6bfc2af043a5711cd21ac3e7a8dfb",
"reference": "4482b6409ca6bfc2af043a5711cd21ac3e7a8dfb",
"url": "https:\/\/api.github.com\/repos\/composer\/pcre\/zipball\/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
"reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
"shasum": ""
},
"require": {
@ -90,7 +90,7 @@
"phpstan\/phpstan-strict-rules": "^1.1",
"symfony\/phpunit-bridge": "^5"
},
"time": "2022-11-03T20:24:16+00:00",
"time": "2022-11-17T09:50:14+00:00",
"type": "library",
"extra": {
"branch-alias": {
@ -123,7 +123,7 @@
],
"support": {
"issues": "https:\/\/github.com\/composer\/pcre\/issues",
"source": "https:\/\/github.com\/composer\/pcre\/tree\/3.0.2"
"source": "https:\/\/github.com\/composer\/pcre\/tree\/3.1.0"
},
"funding": [
{

File diff suppressed because one or more lines are too long

View File

@ -84,6 +84,23 @@ if (Preg::isMatch('{fo+}', $string, $matches)) // bool
if (Preg::isMatchAll('{fo+}', $string, $matches)) // bool
```
Finally the `Preg` class provides a few `*StrictGroups` method variants that ensure match groups
are always present and thus non-nullable, making it easier to write type-safe code:
```php
use Composer\Pcre\Preg;
// $matches is guaranteed to be an array of strings, if a subpattern does not match and produces a null it will throw
if (Preg::matchStrictGroups('{fo+}', $string, $matches))
if (Preg::matchAllStrictGroups('{fo+}', $string, $matches))
```
**Note:** This is generally safe to use as long as you do not have optional subpatterns (i.e. `(something)?`
or `(something)*` or branches with a `|` that result in some groups not being matched at all).
A subpattern that can match an empty string like `(.*)` is **not** optional, it will be present as an
empty string in the matches. A non-matching subpattern, even if optional like `(?:foo)?` will anyway not be present in
matches so it is also not a problem to use these with `*StrictGroups` methods.
If you would prefer a slightly more verbose usage, replacing by-ref arguments by result objects, you can use the `Regex` class:
```php

View File

@ -31,9 +31,9 @@ final class MatchAllResult
public $matched;
/**
* @param 0|positive-int $count
* @param array<array<string|null>> $matches
* @param array<int|string, array<string|null>> $matches
*/
public function __construct($count, array $matches)
public function __construct(int $count, array $matches)
{
$this->matches = $matches;
$this->matched = (bool) $count;

View File

@ -0,0 +1,42 @@
<?php
/*
* This file is part of composer/pcre.
*
* (c) Composer <https://github.com/composer>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace RectorPrefix202211\Composer\Pcre;
final class MatchAllStrictGroupsResult
{
/**
* An array of match group => list of matched strings
*
* @readonly
* @var array<int|string, list<string>>
*/
public $matches;
/**
* @readonly
* @var 0|positive-int
*/
public $count;
/**
* @readonly
* @var bool
*/
public $matched;
/**
* @param 0|positive-int $count
* @param array<array<string>> $matches
*/
public function __construct(int $count, array $matches)
{
$this->matches = $matches;
$this->matched = (bool) $count;
$this->count = $count;
}
}

View File

@ -35,7 +35,7 @@ final class MatchAllWithOffsetsResult
* @param array<int|string, list<array{string|null, int}>> $matches
* @phpstan-param array<int|string, list<array{string|null, int<-1, max>}>> $matches
*/
public function __construct($count, array $matches)
public function __construct(int $count, array $matches)
{
$this->matches = $matches;
$this->matched = (bool) $count;

View File

@ -28,7 +28,7 @@ final class MatchResult
* @param 0|positive-int $count
* @param array<string|null> $matches
*/
public function __construct($count, array $matches)
public function __construct(int $count, array $matches)
{
$this->matches = $matches;
$this->matched = (bool) $count;

View File

@ -0,0 +1,36 @@
<?php
/*
* This file is part of composer/pcre.
*
* (c) Composer <https://github.com/composer>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace RectorPrefix202211\Composer\Pcre;
final class MatchStrictGroupsResult
{
/**
* An array of match group => string matched
*
* @readonly
* @var array<int|string, string>
*/
public $matches;
/**
* @readonly
* @var bool
*/
public $matched;
/**
* @param 0|positive-int $count
* @param array<string> $matches
*/
public function __construct(int $count, array $matches)
{
$this->matches = $matches;
$this->matched = (bool) $count;
}
}

View File

@ -30,7 +30,7 @@ final class MatchWithOffsetsResult
* @param array<array{string|null, int}> $matches
* @phpstan-param array<int|string, array{string|null, int<-1, max>}> $matches
*/
public function __construct($count, array $matches)
public function __construct(int $count, array $matches)
{
$this->matches = $matches;
$this->matched = (bool) $count;

View File

@ -33,6 +33,23 @@ class Preg
}
return $result;
}
/**
* Variant of `match()` which outputs non-null matches (or throws)
*
* @param non-empty-string $pattern
* @param array<string> $matches Set by method
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
* @return 0|1
* @throws UnexpectedNullMatchException
*
* @param-out array<int|string, string> $matches
*/
public static function matchStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : int
{
$result = self::match($pattern, $subject, $matchesInternal, $flags, $offset);
$matches = self::enforceNonNullMatches($pattern, $matchesInternal, 'match');
return $result;
}
/**
* Runs preg_match with PREG_OFFSET_CAPTURE
*
@ -54,7 +71,7 @@ class Preg
/**
* @param non-empty-string $pattern
* @param array<int|string, list<string|null>> $matches Set by method
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_SET_ORDER> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
* @return 0|positive-int
*
* @param-out array<int|string, list<string|null>> $matches
@ -62,9 +79,7 @@ class Preg
public static function matchAll(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : int
{
self::checkOffsetCapture($flags, 'matchAllWithOffsets');
if (($flags & \PREG_SET_ORDER) !== 0) {
throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the type of $matches');
}
self::checkSetOrder($flags);
$result = \preg_match_all($pattern, $subject, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset);
if (!\is_int($result)) {
// PHP < 8 may return null, 8+ returns int|false
@ -72,6 +87,23 @@ class Preg
}
return $result;
}
/**
* Variant of `match()` which outputs non-null matches (or throws)
*
* @param non-empty-string $pattern
* @param array<int|string, list<string|null>> $matches Set by method
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
* @return 0|positive-int
* @throws UnexpectedNullMatchException
*
* @param-out array<int|string, list<string>> $matches
*/
public static function matchAllStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : int
{
$result = self::matchAll($pattern, $subject, $matchesInternal, $flags, $offset);
$matches = self::enforceNonNullMatchAll($pattern, $matchesInternal, 'matchAll');
return $result;
}
/**
* Runs preg_match_all with PREG_OFFSET_CAPTURE
*
@ -84,6 +116,7 @@ class Preg
*/
public static function matchAllWithOffsets(string $pattern, string $subject, ?array &$matches, int $flags = 0, int $offset = 0) : int
{
self::checkSetOrder($flags);
$result = \preg_match_all($pattern, $subject, $matches, $flags | \PREG_UNMATCHED_AS_NULL | \PREG_OFFSET_CAPTURE, $offset);
if (!\is_int($result)) {
// PHP < 8 may return null, 8+ returns int|false
@ -136,6 +169,23 @@ class Preg
}
return $result;
}
/**
* Variant of `replaceCallback()` which outputs non-null matches (or throws)
*
* @param string $pattern
* @param callable(array<int|string, string>): string $replacement
* @param string $subject
* @param int $count Set by method
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE or PREG_UNMATCHED_AS_NULL, only available on PHP 7.4+
*
* @param-out int<0, max> $count
*/
public static function replaceCallbackStrictGroups(string $pattern, callable $replacement, $subject, int $limit = -1, int &$count = null, int $flags = 0) : string
{
return self::replaceCallback($pattern, function (array $matches) use($pattern, $replacement) {
return $replacement(self::enforceNonNullMatches($pattern, $matches, 'replaceCallback'));
}, $subject, $limit, $count, $flags);
}
/**
* @param array<string, callable(array<int|string, string|null>): string> $pattern
* @param string $subject
@ -203,6 +253,8 @@ class Preg
return $result;
}
/**
* Variant of match() which returns a bool instead of int
*
* @param non-empty-string $pattern
* @param array<string|null> $matches Set by method
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
@ -214,6 +266,22 @@ class Preg
return (bool) static::match($pattern, $subject, $matches, $flags, $offset);
}
/**
* Variant of `isMatch()` which outputs non-null matches (or throws)
*
* @param non-empty-string $pattern
* @param array<string> $matches Set by method
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
* @throws UnexpectedNullMatchException
*
* @param-out array<int|string, string> $matches
*/
public static function isMatchStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : bool
{
return (bool) self::matchStrictGroups($pattern, $subject, $matches, $flags, $offset);
}
/**
* Variant of matchAll() which returns a bool instead of int
*
* @param non-empty-string $pattern
* @param array<int|string, list<string|null>> $matches Set by method
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
@ -225,6 +293,21 @@ class Preg
return (bool) static::matchAll($pattern, $subject, $matches, $flags, $offset);
}
/**
* Variant of `isMatchAll()` which outputs non-null matches (or throws)
*
* @param non-empty-string $pattern
* @param array<int|string, list<string>> $matches Set by method
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
*
* @param-out array<int|string, list<string>> $matches
*/
public static function isMatchAllStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : bool
{
return (bool) self::matchAllStrictGroups($pattern, $subject, $matches, $flags, $offset);
}
/**
* Variant of matchWithOffsets() which returns a bool instead of int
*
* Runs preg_match with PREG_OFFSET_CAPTURE
*
* @param non-empty-string $pattern
@ -238,6 +321,8 @@ class Preg
return (bool) static::matchWithOffsets($pattern, $subject, $matches, $flags, $offset);
}
/**
* Variant of matchAllWithOffsets() which returns a bool instead of int
*
* Runs preg_match_all with PREG_OFFSET_CAPTURE
*
* @param non-empty-string $pattern
@ -256,4 +341,42 @@ class Preg
throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the type of $matches, use ' . $useFunctionName . '() instead');
}
}
private static function checkSetOrder(int $flags) : void
{
if (($flags & \PREG_SET_ORDER) !== 0) {
throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the type of $matches');
}
}
/**
* @param array<int|string, string|null> $matches
* @return array<int|string, string>
* @throws UnexpectedNullMatchException
*/
private static function enforceNonNullMatches(string $pattern, array $matches, string $variantMethod)
{
foreach ($matches as $group => $match) {
if (null === $match) {
throw new UnexpectedNullMatchException('Pattern "' . $pattern . '" had an unexpected unmatched group "' . $group . '", make sure the pattern always matches or use ' . $variantMethod . '() instead.');
}
}
/** @var array<string> */
return $matches;
}
/**
* @param array<int|string, list<string|null>> $matches
* @return array<int|string, list<string>>
* @throws UnexpectedNullMatchException
*/
private static function enforceNonNullMatchAll(string $pattern, array $matches, string $variantMethod)
{
foreach ($matches as $group => $groupMatches) {
foreach ($groupMatches as $match) {
if (null === $match) {
throw new UnexpectedNullMatchException('Pattern "' . $pattern . '" had an unexpected unmatched group "' . $group . '", make sure the pattern always matches or use ' . $variantMethod . '() instead.');
}
}
}
/** @var array<int|string, list<string>> */
return $matches;
}
}

View File

@ -25,10 +25,22 @@ class Regex
*/
public static function match(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchResult
{
self::checkOffsetCapture($flags);
self::checkOffsetCapture($flags, 'matchWithOffsets');
$count = Preg::match($pattern, $subject, $matches, $flags, $offset);
return new MatchResult($count, $matches);
}
/**
* Variant of `match()` which returns non-null matches (or throws)
*
* @param non-empty-string $pattern
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
* @throws UnexpectedNullMatchException
*/
public static function matchStrictGroups(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchStrictGroupsResult
{
$count = Preg::matchStrictGroups($pattern, $subject, $matches, $flags, $offset);
return new MatchStrictGroupsResult($count, $matches);
}
/**
* Runs preg_match with PREG_OFFSET_CAPTURE
*
@ -42,17 +54,29 @@ class Regex
}
/**
* @param non-empty-string $pattern
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_SET_ORDER> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
*/
public static function matchAll(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchAllResult
{
self::checkOffsetCapture($flags);
if (($flags & \PREG_SET_ORDER) !== 0) {
throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the return type');
}
self::checkOffsetCapture($flags, 'matchAllWithOffsets');
self::checkSetOrder($flags);
$count = Preg::matchAll($pattern, $subject, $matches, $flags, $offset);
return new MatchAllResult($count, $matches);
}
/**
* Variant of `matchAll()` which returns non-null matches (or throws)
*
* @param non-empty-string $pattern
* @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
* @throws UnexpectedNullMatchException
*/
public static function matchAllStrictGroups(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchAllStrictGroupsResult
{
self::checkOffsetCapture($flags, 'matchAllWithOffsets');
self::checkSetOrder($flags);
$count = Preg::matchAllStrictGroups($pattern, $subject, $matches, $flags, $offset);
return new MatchAllStrictGroupsResult($count, $matches);
}
/**
* Runs preg_match_all with PREG_OFFSET_CAPTURE
*
@ -61,6 +85,7 @@ class Regex
*/
public static function matchAllWithOffsets(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchAllWithOffsetsResult
{
self::checkSetOrder($flags);
$count = Preg::matchAllWithOffsets($pattern, $subject, $matches, $flags, $offset);
return new MatchAllWithOffsetsResult($count, $matches);
}
@ -85,6 +110,19 @@ class Regex
$result = Preg::replaceCallback($pattern, $replacement, $subject, $limit, $count, $flags);
return new ReplaceResult($count, $result);
}
/**
* Variant of `replaceCallback()` which outputs non-null matches (or throws)
*
* @param string $pattern
* @param callable(array<int|string, string>): string $replacement
* @param string $subject
* @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE or PREG_UNMATCHED_AS_NULL, only available on PHP 7.4+
*/
public static function replaceCallbackStrictGroups($pattern, callable $replacement, $subject, int $limit = -1, int $flags = 0) : ReplaceResult
{
$result = Preg::replaceCallbackStrictGroups($pattern, $replacement, $subject, $limit, $count, $flags);
return new ReplaceResult($count, $result);
}
/**
* @param array<string, callable(array<int|string, string|null>): string> $pattern
* @param string $subject
@ -95,10 +133,16 @@ class Regex
$result = Preg::replaceCallbackArray($pattern, $subject, $limit, $count, $flags);
return new ReplaceResult($count, $result);
}
private static function checkOffsetCapture(int $flags) : void
private static function checkOffsetCapture(int $flags, string $useFunctionName) : void
{
if (($flags & \PREG_OFFSET_CAPTURE) !== 0) {
throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the return type, use matchWithOffsets() instead');
throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the return type, use ' . $useFunctionName . '() instead');
}
}
private static function checkSetOrder(int $flags) : void
{
if (($flags & \PREG_SET_ORDER) !== 0) {
throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the return type');
}
}
}

View File

@ -29,9 +29,8 @@ final class ReplaceResult
public $matched;
/**
* @param 0|positive-int $count
* @param string $result
*/
public function __construct($count, $result)
public function __construct(int $count, string $result)
{
$this->count = $count;
$this->matched = (bool) $count;

View File

@ -0,0 +1,19 @@
<?php
/*
* This file is part of composer/pcre.
*
* (c) Composer <https://github.com/composer>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace RectorPrefix202211\Composer\Pcre;
class UnexpectedNullMatchException extends PcreException
{
public static function fromFunction($function, $pattern)
{
throw new \LogicException('fromFunction should not be called on ' . self::class . ', use ' . PcreException::class);
}
}