diff --git a/README.md b/README.md
index c31ce2c7..02bd31cb 100644
--- a/README.md
+++ b/README.md
@@ -127,10 +127,12 @@ Each chain method call must be on own line
## ParamReturnAndVarTagMalformsFixer
-Fixes @param, @return, `@var` and inline `@var` annotations broken formats
+Fixes `@param`, `@return`, `@var` and inline `@var` annotations broken formats. This single rule covers a wide range of docblock malforms:
- class: [`Symplify\CodingStandard\Fixer\Commenting\ParamReturnAndVarTagMalformsFixer`](../src/Fixer/Commenting/ParamReturnAndVarTagMalformsFixer.php)
+**Add a missing `@param` variable name**
+
```diff
/**
- * @param string
@@ -141,6 +143,97 @@ Fixes @param, @return, `@var` and inline `@var` annotations broken formats
}
```
+**Reorder switched type and variable name**
+
+```diff
+ /**
+- * @param $a string
+- * @param $b string|null
++ * @param string $a
++ * @param string|null $b
+ */
+ function test($a, string $b = null): string
+ {
+ }
+```
+
+**Remove a dead `@param` line that has only a name and no type**
+
+```diff
+ /**
+ * @param string $name
+- * @param $age
+ */
+ function withDeadParam(string $name, $age)
+ {
+ }
+```
+
+**Fix a typo in the `@param` variable name to match the real argument**
+
+```diff
+ /**
+ * @param string $one
+- * @param string $twoTypo
++ * @param string $two
+ */
+ function anotherFunction(string $one, string $two)
+ {
+ }
+```
+
+**Remove the reference `&` from a `@param` name**
+
+```diff
+ /**
+- * @param string &$name
++ * @param string $name
+ */
+ function paramReference($name)
+ {
+ }
+```
+
+**Remove a superfluous variable name from `@return`**
+
+```diff
+ /**
+- * @return int $value
++ * @return int
+ */
+ function function1(): int
+ {
+ }
+```
+
+**Remove a superfluous variable name from a property `@var`**
+
+```diff
+ /**
+- * @var string $property
++ * @var string
+ */
+ private $property;
+```
+
+**Add a missing variable name to an inline `@var`**
+
+```diff
+-/** @var int */
++/** @var int $value */
+ $value = 1000;
+```
+
+**Normalize a malformed inline `@var` (single asterisk, switched name/type)**
+
+```diff
+-/* @var $variable int */
++/** @var int $variable */
+ $variable = 5;
+```
+
+It also handles the `@phpstan-` and `@psalm-` prefixed variants of these tags.
+
## RemovePropertyVariableNameDescriptionFixer
diff --git a/composer.json b/composer.json
index 07544ea6..b3b65d07 100644
--- a/composer.json
+++ b/composer.json
@@ -4,7 +4,6 @@
"license": "MIT",
"require": {
"php": ">=8.4",
- "nette/utils": "^4.1",
"friendsofphp/php-cs-fixer": "^3.95.4"
},
"require-dev": {
diff --git a/src/DocBlock/UselessDocBlockCleaner.php b/src/DocBlock/UselessDocBlockCleaner.php
index a7ceb77b..36265866 100644
--- a/src/DocBlock/UselessDocBlockCleaner.php
+++ b/src/DocBlock/UselessDocBlockCleaner.php
@@ -4,8 +4,8 @@
namespace Symplify\CodingStandard\DocBlock;
-use Nette\Utils\Strings;
use PhpCsFixer\Tokenizer\Token;
+use Symplify\CodingStandard\Utils\Regex;
final class UselessDocBlockCleaner
{
@@ -72,7 +72,7 @@ public function clearDocTokenContent(Token $currentToken, ?string $classLikeName
}
foreach (self::CLEANING_REGEXES as $cleaningRegex) {
- $commentLine = Strings::replace($commentLine, $cleaningRegex);
+ $commentLine = Regex::replace($commentLine, $cleaningRegex);
}
$cleanedCommentLines[$key] = $commentLine;
@@ -90,7 +90,7 @@ public function clearDocTokenContent(Token $currentToken, ?string $classLikeName
$commentText = implode("\n", $cleanedCommentLines);
// run multilines regex on final result
- return Strings::replace($commentText, self::DOCTRINE_GENERATED_COMMENT_REGEX);
+ return Regex::replace($commentText, self::DOCTRINE_GENERATED_COMMENT_REGEX);
}
/**
diff --git a/src/Fixer/Annotation/RemoveMethodNameDuplicateDescriptionFixer.php b/src/Fixer/Annotation/RemoveMethodNameDuplicateDescriptionFixer.php
index 065fd2a2..3fcc29e0 100644
--- a/src/Fixer/Annotation/RemoveMethodNameDuplicateDescriptionFixer.php
+++ b/src/Fixer/Annotation/RemoveMethodNameDuplicateDescriptionFixer.php
@@ -4,7 +4,6 @@
namespace Symplify\CodingStandard\Fixer\Annotation;
-use Nette\Utils\Strings;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\Token;
@@ -13,6 +12,7 @@
use Symplify\CodingStandard\Fixer\AbstractSymplifyFixer;
use Symplify\CodingStandard\Fixer\Naming\MethodNameResolver;
use Symplify\CodingStandard\TokenRunner\Traverser\TokenReverser;
+use Symplify\CodingStandard\Utils\Regex;
/**
* @see \Symplify\CodingStandard\Tests\Fixer\Annotation\RemoveMethodNameDuplicateDescriptionFixer\RemoveMethodNameDuplicateDescriptionFixerTest
@@ -70,7 +70,7 @@ public function fix(SplFileInfo $fileInfo, Tokens $tokens): void
$docblockLines = explode("\n", $originalDocContent);
foreach ($docblockLines as $key => $docblockLine) {
- $spacelessDocblockLine = Strings::replace($docblockLine, '#[\s\n]+#', '');
+ $spacelessDocblockLine = Regex::replace($docblockLine, '#[\s\n]+#', '');
if (strtolower($spacelessDocblockLine) !== strtolower('*' . $methodName)) {
continue;
}
diff --git a/src/Fixer/Annotation/RemovePHPStormAnnotationFixer.php b/src/Fixer/Annotation/RemovePHPStormAnnotationFixer.php
index 83bafa4c..905415da 100644
--- a/src/Fixer/Annotation/RemovePHPStormAnnotationFixer.php
+++ b/src/Fixer/Annotation/RemovePHPStormAnnotationFixer.php
@@ -4,7 +4,6 @@
namespace Symplify\CodingStandard\Fixer\Annotation;
-use Nette\Utils\Strings;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\Token;
@@ -12,6 +11,7 @@
use SplFileInfo;
use Symplify\CodingStandard\Fixer\AbstractSymplifyFixer;
use Symplify\CodingStandard\TokenRunner\Traverser\TokenReverser;
+use Symplify\CodingStandard\Utils\Regex;
/**
* @see \Symplify\CodingStandard\Tests\Fixer\Annotation\RemovePHPStormAnnotationFixer\RemovePHPStormAnnotationFixerTest
@@ -56,7 +56,7 @@ public function fix(SplFileInfo $fileInfo, Tokens $tokens): void
}
$originalDocContent = $token->getContent();
- $cleanedDocContent = Strings::replace($originalDocContent, self::CREATED_BY_PHPSTORM_DOC_REGEX, '');
+ $cleanedDocContent = Regex::replace($originalDocContent, self::CREATED_BY_PHPSTORM_DOC_REGEX, '');
if ($cleanedDocContent !== '') {
continue;
}
diff --git a/src/Fixer/Annotation/RemovePropertyVariableNameDescriptionFixer.php b/src/Fixer/Annotation/RemovePropertyVariableNameDescriptionFixer.php
index 49844f78..024ed7f5 100644
--- a/src/Fixer/Annotation/RemovePropertyVariableNameDescriptionFixer.php
+++ b/src/Fixer/Annotation/RemovePropertyVariableNameDescriptionFixer.php
@@ -4,7 +4,6 @@
namespace Symplify\CodingStandard\Fixer\Annotation;
-use Nette\Utils\Strings;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\Token;
@@ -90,7 +89,7 @@ public function fix(SplFileInfo $fileInfo, Tokens $tokens): void
}
// remove last x characters
- $docblockLine = Strings::substring($docblockLine, 0, -strlen(' ' . $propertyName));
+ $docblockLine = mb_substr($docblockLine, 0, -strlen(' ' . $propertyName));
$hasChanged = true;
$docblockLines[$key] = rtrim($docblockLine);
diff --git a/src/Fixer/Commenting/ParamReturnAndVarTagMalformsFixer.php b/src/Fixer/Commenting/ParamReturnAndVarTagMalformsFixer.php
index b8ce0148..fd11ef7c 100644
--- a/src/Fixer/Commenting/ParamReturnAndVarTagMalformsFixer.php
+++ b/src/Fixer/Commenting/ParamReturnAndVarTagMalformsFixer.php
@@ -4,7 +4,6 @@
namespace Symplify\CodingStandard\Fixer\Commenting;
-use Nette\Utils\Strings;
use Override;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
@@ -24,6 +23,7 @@
use Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker\SuperfluousVarNameMalformWorker;
use Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker\SwitchedTypeAndNameMalformWorker;
use Symplify\CodingStandard\TokenRunner\Traverser\TokenReverser;
+use Symplify\CodingStandard\Utils\Regex;
/**
* @see \Symplify\CodingStandard\Tests\Fixer\Commenting\ParamReturnAndVarTagMalformsFixer\ParamReturnAndVarTagMalformsFixerTest
@@ -113,7 +113,7 @@ public function fix(SplFileInfo $fileInfo, Tokens $tokens): void
}
$docContent = $token->getContent();
- if (! Strings::match($docContent, self::TYPE_ANNOTATION_REGEX)) {
+ if (! Regex::match($docContent, self::TYPE_ANNOTATION_REGEX)) {
continue;
}
@@ -154,6 +154,6 @@ public function getPriority(): int
private function isEmptyDocBlock(string $docContent): bool
{
- return Strings::replace($docContent, '#/\*\*|\*/|\*|\s#', '') === '';
+ return Regex::replace($docContent, '#/\*\*|\*/|\*|\s#', '') === '';
}
}
diff --git a/src/TokenRunner/DocBlock/MalformWorker/DeadParamMalformWorker.php b/src/TokenRunner/DocBlock/MalformWorker/DeadParamMalformWorker.php
index 57c65286..f3d872ab 100644
--- a/src/TokenRunner/DocBlock/MalformWorker/DeadParamMalformWorker.php
+++ b/src/TokenRunner/DocBlock/MalformWorker/DeadParamMalformWorker.php
@@ -4,11 +4,11 @@
namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;
-use Nette\Utils\Strings;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symplify\CodingStandard\TokenRunner\Contract\DocBlock\MalformWorkerInterface;
+use Symplify\CodingStandard\Utils\Regex;
/**
* Removes dead param annotation lines that only contain a variable name and no type,
@@ -29,7 +29,7 @@ public function work(string $docContent, Tokens $tokens, int $position): string
$docBlock = new DocBlock($docContent);
foreach ($docBlock->getLines() as $line) {
- if (! Strings::match($line->getContent(), self::PARAM_WITHOUT_TYPE_REGEX)) {
+ if (! Regex::match($line->getContent(), self::PARAM_WITHOUT_TYPE_REGEX)) {
continue;
}
diff --git a/src/TokenRunner/DocBlock/MalformWorker/InlineVarMalformWorker.php b/src/TokenRunner/DocBlock/MalformWorker/InlineVarMalformWorker.php
index cd3ec362..29019015 100644
--- a/src/TokenRunner/DocBlock/MalformWorker/InlineVarMalformWorker.php
+++ b/src/TokenRunner/DocBlock/MalformWorker/InlineVarMalformWorker.php
@@ -4,10 +4,10 @@
namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;
-use Nette\Utils\Strings;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symplify\CodingStandard\TokenRunner\Contract\DocBlock\MalformWorkerInterface;
+use Symplify\CodingStandard\Utils\Regex;
final class InlineVarMalformWorker implements MalformWorkerInterface
{
@@ -28,6 +28,6 @@ public function work(string $docContent, Tokens $tokens, int $position): string
return $docContent;
}
- return Strings::replace($docContent, self::SINGLE_ASTERISK_START_REGEX, '/**$1');
+ return Regex::replace($docContent, self::SINGLE_ASTERISK_START_REGEX, '/**$1');
}
}
diff --git a/src/TokenRunner/DocBlock/MalformWorker/InlineVariableDocBlockMalformWorker.php b/src/TokenRunner/DocBlock/MalformWorker/InlineVariableDocBlockMalformWorker.php
index af822b39..294bef0e 100644
--- a/src/TokenRunner/DocBlock/MalformWorker/InlineVariableDocBlockMalformWorker.php
+++ b/src/TokenRunner/DocBlock/MalformWorker/InlineVariableDocBlockMalformWorker.php
@@ -4,10 +4,10 @@
namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;
-use Nette\Utils\Strings;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symplify\CodingStandard\TokenRunner\Contract\DocBlock\MalformWorkerInterface;
+use Symplify\CodingStandard\Utils\Regex;
final class InlineVariableDocBlockMalformWorker implements MalformWorkerInterface
{
@@ -41,13 +41,13 @@ public function work(string $docContent, Tokens $tokens, int $position): string
}
// asterisk start
- $docContent = Strings::replace($docContent, self::SINGLE_ASTERISK_START_REGEX, '/**$1');
+ $docContent = Regex::replace($docContent, self::SINGLE_ASTERISK_START_REGEX, '/**$1');
// inline
- $docContent = Strings::replace($docContent, self::SPACE_REGEX, ' ');
+ $docContent = Regex::replace($docContent, self::SPACE_REGEX, ' ');
// remove asterisk leftover
- return Strings::replace($docContent, self::ASTERISK_LEFTOVERS_REGEX, '$1');
+ return Regex::replace($docContent, self::ASTERISK_LEFTOVERS_REGEX, '$1');
}
/**
diff --git a/src/TokenRunner/DocBlock/MalformWorker/MissingParamNameMalformWorker.php b/src/TokenRunner/DocBlock/MalformWorker/MissingParamNameMalformWorker.php
index 208ed8ac..446bb2cf 100644
--- a/src/TokenRunner/DocBlock/MalformWorker/MissingParamNameMalformWorker.php
+++ b/src/TokenRunner/DocBlock/MalformWorker/MissingParamNameMalformWorker.php
@@ -4,13 +4,13 @@
namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;
-use Nette\Utils\Strings;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\DocBlock\Line;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symplify\CodingStandard\TokenAnalyzer\DocblockRelatedParamNamesResolver;
use Symplify\CodingStandard\TokenRunner\Contract\DocBlock\MalformWorkerInterface;
+use Symplify\CodingStandard\Utils\Regex;
final readonly class MissingParamNameMalformWorker implements MalformWorkerInterface
{
@@ -64,7 +64,7 @@ private function filterOutExistingParamNames(string $docContent, array $function
{
foreach ($functionArgumentNames as $key => $functionArgumentName) {
$pattern = '# ' . preg_quote($functionArgumentName, '#') . '\b#';
- if (Strings::match($docContent, $pattern)) {
+ if (Regex::match($docContent, $pattern)) {
unset($functionArgumentNames[$key]);
}
}
@@ -116,11 +116,11 @@ private function shouldSkipLine(Line $line): bool
}
// already has a param name
- if (Strings::match($line->getContent(), self::PARAM_WITH_NAME_REGEX)) {
+ if (Regex::match($line->getContent(), self::PARAM_WITH_NAME_REGEX)) {
return true;
}
- $match = Strings::match($line->getContent(), self::PARAM_WITHOUT_NAME_REGEX);
+ $match = Regex::match($line->getContent(), self::PARAM_WITHOUT_NAME_REGEX);
return $match === null;
}
@@ -130,12 +130,12 @@ private function createNewLineContent(string $newArgumentName, Line $line): stri
$missingDollarSignPattern = '#(@param\s+([\w\|\[\]\\\\]+\s)?)(' . ltrim($newArgumentName, '$') . ')#';
// missing \$ case - possibly own worker
- if (Strings::match($line->getContent(), $missingDollarSignPattern)) {
- return Strings::replace($line->getContent(), $missingDollarSignPattern, '$1$$3');
+ if (Regex::match($line->getContent(), $missingDollarSignPattern)) {
+ return Regex::replace($line->getContent(), $missingDollarSignPattern, '$1$$3');
}
$replacement = '@param $1 ' . $newArgumentName . '$2' . "\n";
- return Strings::replace($line->getContent(), self::PARAM_WITHOUT_NAME_REGEX, $replacement);
+ return Regex::replace($line->getContent(), self::PARAM_WITHOUT_NAME_REGEX, $replacement);
}
}
diff --git a/src/TokenRunner/DocBlock/MalformWorker/MissingVarNameMalformWorker.php b/src/TokenRunner/DocBlock/MalformWorker/MissingVarNameMalformWorker.php
index 72ab2115..49e2d480 100644
--- a/src/TokenRunner/DocBlock/MalformWorker/MissingVarNameMalformWorker.php
+++ b/src/TokenRunner/DocBlock/MalformWorker/MissingVarNameMalformWorker.php
@@ -4,10 +4,10 @@
namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;
-use Nette\Utils\Strings;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symplify\CodingStandard\TokenRunner\Contract\DocBlock\MalformWorkerInterface;
+use Symplify\CodingStandard\Utils\Regex;
final class MissingVarNameMalformWorker implements MalformWorkerInterface
{
@@ -21,7 +21,7 @@ final class MissingVarNameMalformWorker implements MalformWorkerInterface
*/
public function work(string $docContent, Tokens $tokens, int $position): string
{
- if (! Strings::match($docContent, self::VAR_WITHOUT_NAME_REGEX)) {
+ if (! Regex::match($docContent, self::VAR_WITHOUT_NAME_REGEX)) {
return $docContent;
}
@@ -30,7 +30,7 @@ public function work(string $docContent, Tokens $tokens, int $position): string
return $docContent;
}
- return Strings::replace(
+ return Regex::replace(
$docContent,
self::VAR_WITHOUT_NAME_REGEX,
static fn (array $match): string => $match['open'] . $match['type'] . ' ' . $nextVariableToken->getContent() . $match['close']
diff --git a/src/TokenRunner/DocBlock/MalformWorker/ParamNameReferenceMalformWorker.php b/src/TokenRunner/DocBlock/MalformWorker/ParamNameReferenceMalformWorker.php
index 650ad112..26c66909 100644
--- a/src/TokenRunner/DocBlock/MalformWorker/ParamNameReferenceMalformWorker.php
+++ b/src/TokenRunner/DocBlock/MalformWorker/ParamNameReferenceMalformWorker.php
@@ -4,10 +4,10 @@
namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;
-use Nette\Utils\Strings;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symplify\CodingStandard\TokenRunner\Contract\DocBlock\MalformWorkerInterface;
+use Symplify\CodingStandard\Utils\Regex;
final class ParamNameReferenceMalformWorker implements MalformWorkerInterface
{
@@ -21,7 +21,7 @@ final class ParamNameReferenceMalformWorker implements MalformWorkerInterface
*/
public function work(string $docContent, Tokens $tokens, int $position): string
{
- return Strings::replace(
+ return Regex::replace(
$docContent,
self::PARAM_NAME_REGEX,
static fn ($match): string => $match['param'] . $match['paramName']
diff --git a/src/TokenRunner/DocBlock/MalformWorker/ParamNameTypoMalformWorker.php b/src/TokenRunner/DocBlock/MalformWorker/ParamNameTypoMalformWorker.php
index 29470043..b17f8fb5 100644
--- a/src/TokenRunner/DocBlock/MalformWorker/ParamNameTypoMalformWorker.php
+++ b/src/TokenRunner/DocBlock/MalformWorker/ParamNameTypoMalformWorker.php
@@ -4,13 +4,13 @@
namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;
-use Nette\Utils\Strings;
use PhpCsFixer\DocBlock\Annotation;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symplify\CodingStandard\TokenAnalyzer\DocblockRelatedParamNamesResolver;
use Symplify\CodingStandard\TokenRunner\Contract\DocBlock\MalformWorkerInterface;
+use Symplify\CodingStandard\Utils\Regex;
final readonly class ParamNameTypoMalformWorker implements MalformWorkerInterface
{
@@ -68,7 +68,7 @@ private function getParamNames(string $docContent): array
$paramNames = [];
foreach ($paramAnnotations as $paramAnnotation) {
- $match = Strings::match($paramAnnotation->getContent(), self::PARAM_NAME_REGEX);
+ $match = Regex::match($paramAnnotation->getContent(), self::PARAM_NAME_REGEX);
if (isset($match['paramName'])) {
// skip callables, as they contain nested params
if (isset($match['callable']) && $match['callable'] === 'callable') {
@@ -111,7 +111,7 @@ private function fixTypos(array $argumentNames, array $missArgumentNames, array
$typoName = $paramNames[$key];
$replacePattern = '#@param(.*?)(' . preg_quote($typoName, '#') . '\b)#';
- $docContent = Strings::replace($docContent, $replacePattern, static function (array $matched) use ($argumentName, &$replacedParams) {
+ $docContent = Regex::replace($docContent, $replacePattern, static function (array $matched) use ($argumentName, &$replacedParams) {
$paramName = $matched[2];
// 2. If the PHPDoc $paramName is one of the existing $argumentNames and has not already been replaced, it will be deferred
diff --git a/src/TokenRunner/DocBlock/MalformWorker/SuperfluousReturnNameMalformWorker.php b/src/TokenRunner/DocBlock/MalformWorker/SuperfluousReturnNameMalformWorker.php
index 716bebbb..386099ef 100644
--- a/src/TokenRunner/DocBlock/MalformWorker/SuperfluousReturnNameMalformWorker.php
+++ b/src/TokenRunner/DocBlock/MalformWorker/SuperfluousReturnNameMalformWorker.php
@@ -4,11 +4,11 @@
namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;
-use Nette\Utils\Strings;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symplify\CodingStandard\TokenRunner\Contract\DocBlock\MalformWorkerInterface;
+use Symplify\CodingStandard\Utils\Regex;
final class SuperfluousReturnNameMalformWorker implements MalformWorkerInterface
{
@@ -38,7 +38,7 @@ public function work(string $docContent, Tokens $tokens, int $position): string
$lines = $docBlock->getLines();
foreach ($lines as $line) {
- $match = Strings::match($line->getContent(), self::RETURN_VARIABLE_NAME_REGEX);
+ $match = Regex::match($line->getContent(), self::RETURN_VARIABLE_NAME_REGEX);
if ($match === null) {
continue;
}
@@ -47,7 +47,7 @@ public function work(string $docContent, Tokens $tokens, int $position): string
continue;
}
- $newLineContent = Strings::replace(
+ $newLineContent = Regex::replace(
$line->getContent(),
self::RETURN_VARIABLE_NAME_REGEX,
static function (array $match) {
@@ -76,6 +76,6 @@ private function shouldSkip(array $match, string $content): bool
}
// has multiple return values? "@return array $one, $two"
- return count(Strings::matchAll($content, self::VARIABLE_NAME_REGEX)) >= 2;
+ return count(Regex::matchAll($content, self::VARIABLE_NAME_REGEX)) >= 2;
}
}
diff --git a/src/TokenRunner/DocBlock/MalformWorker/SuperfluousVarNameMalformWorker.php b/src/TokenRunner/DocBlock/MalformWorker/SuperfluousVarNameMalformWorker.php
index 78b05289..e26b7cb4 100644
--- a/src/TokenRunner/DocBlock/MalformWorker/SuperfluousVarNameMalformWorker.php
+++ b/src/TokenRunner/DocBlock/MalformWorker/SuperfluousVarNameMalformWorker.php
@@ -4,11 +4,11 @@
namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;
-use Nette\Utils\Strings;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symplify\CodingStandard\TokenRunner\Contract\DocBlock\MalformWorkerInterface;
+use Symplify\CodingStandard\Utils\Regex;
final class SuperfluousVarNameMalformWorker implements MalformWorkerInterface
{
@@ -35,12 +35,12 @@ public function work(string $docContent, Tokens $tokens, int $position): string
$lines = $docBlock->getLines();
foreach ($lines as $line) {
- $match = Strings::match($line->getContent(), self::VAR_VARIABLE_NAME_REGEX);
+ $match = Regex::match($line->getContent(), self::VAR_VARIABLE_NAME_REGEX);
if ($match === null) {
continue;
}
- $newLineContent = Strings::replace(
+ $newLineContent = Regex::replace(
$line->getContent(),
self::VAR_VARIABLE_NAME_REGEX,
static function (array $match): string {
@@ -49,7 +49,7 @@ static function (array $match): string {
$replacement .= $match['type'];
}
- if (Strings::match($match['propertyName'], self::THIS_VARIABLE_REGEX)) {
+ if (Regex::match($match['propertyName'], self::THIS_VARIABLE_REGEX)) {
return $match['tag'] . ' self';
}
diff --git a/src/TokenRunner/DocBlock/MalformWorker/SwitchedTypeAndNameMalformWorker.php b/src/TokenRunner/DocBlock/MalformWorker/SwitchedTypeAndNameMalformWorker.php
index 9e36caf8..ac6d9db7 100644
--- a/src/TokenRunner/DocBlock/MalformWorker/SwitchedTypeAndNameMalformWorker.php
+++ b/src/TokenRunner/DocBlock/MalformWorker/SwitchedTypeAndNameMalformWorker.php
@@ -4,11 +4,11 @@
namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;
-use Nette\Utils\Strings;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Symplify\CodingStandard\TokenRunner\Contract\DocBlock\MalformWorkerInterface;
+use Symplify\CodingStandard\Utils\Regex;
final class SwitchedTypeAndNameMalformWorker implements MalformWorkerInterface
{
@@ -27,7 +27,7 @@ public function work(string $docContent, Tokens $tokens, int $position): string
$lines = $docBlock->getLines();
foreach ($lines as $line) {
// $value is first, instead of type is first
- $match = Strings::match($line->getContent(), self::NAME_THEN_TYPE_REGEX);
+ $match = Regex::match($line->getContent(), self::NAME_THEN_TYPE_REGEX);
if ($match === null) {
continue;
}
@@ -45,7 +45,7 @@ public function work(string $docContent, Tokens $tokens, int $position): string
continue;
}
- $newLine = Strings::replace($line->getContent(), self::NAME_THEN_TYPE_REGEX, '@$1$2$5$4$3');
+ $newLine = Regex::replace($line->getContent(), self::NAME_THEN_TYPE_REGEX, '@$1$2$5$4$3');
$line->setContent($newLine);
}
diff --git a/src/Utils/Regex.php b/src/Utils/Regex.php
new file mode 100644
index 00000000..30577e4f
--- /dev/null
+++ b/src/Utils/Regex.php
@@ -0,0 +1,44 @@
+|null
+ */
+ public static function match(string $subject, string $pattern): ?array
+ {
+ $matches = [];
+ if (preg_match($pattern, $subject, $matches) === 1) {
+ return $matches;
+ }
+
+ return null;
+ }
+
+ /**
+ * @return array>
+ */
+ public static function matchAll(string $subject, string $pattern): array
+ {
+ $matches = [];
+ preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);
+
+ return $matches;
+ }
+
+ public static function replace(string $subject, string $pattern, string|callable $replacement = ''): string
+ {
+ if (is_callable($replacement)) {
+ return (string) preg_replace_callback($pattern, $replacement, $subject);
+ }
+
+ return (string) preg_replace($pattern, $replacement, $subject);
+ }
+}
diff --git a/tests/Utils/RegexTest.php b/tests/Utils/RegexTest.php
new file mode 100644
index 00000000..eb971947
--- /dev/null
+++ b/tests/Utils/RegexTest.php
@@ -0,0 +1,51 @@
+\w+)\s+\$(?\w+)#');
+
+ $this->assertNotNull($match);
+ $this->assertSame('string', $match['type']);
+ $this->assertSame('value', $match['name']);
+ }
+
+ public function testMatchReturnsNullOnNoMatch(): void
+ {
+ $this->assertNull(Regex::match('nothing here', '#@param#'));
+ }
+
+ public function testMatchAllReturnsSetOrder(): void
+ {
+ $matches = Regex::matchAll('$a $b $c', '#\$(?\w)#');
+
+ $this->assertCount(3, $matches);
+ $this->assertSame('a', $matches[0]['name']);
+ $this->assertSame('c', $matches[2]['name']);
+ }
+
+ public function testReplaceWithString(): void
+ {
+ $this->assertSame('x-x', Regex::replace('1-2', '#\d#', 'x'));
+ }
+
+ public function testReplaceWithDefaultRemovesMatch(): void
+ {
+ $this->assertSame('abc', Regex::replace('a1b2c3', '#\d#'));
+ }
+
+ public function testReplaceWithCallable(): void
+ {
+ $result = Regex::replace('a1b', '#\d#', static fn (array $match): string => '[' . $match[0] . ']');
+
+ $this->assertSame('a[1]b', $result);
+ }
+}