<commit_before><?php

declare(strict_types=1);

namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;

use Nette\Utils\Strings;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\Tokenizer\Tokens;

final class SuperfluousReturnNameMalformWorker extends AbstractMalformWorker
{
    /**
     * @var string
     * @see https://regex101.com/r/26Wy7Y/1
     */
    private const RETURN_VARIABLE_NAME_REGEX = '#(@return)(?<type>\s+[|\\\\\w]+)?(\s+)(?<variableName>\$[\w]+)#';

    /**
     * @var string[]
     */
    private const ALLOWED_VARIABLE_NAMES = ['$this'];

    /**
     * @var string
     * @see https://regex101.com/r/IE9fA6/1
     */
    private const VARIABLE_NAME_REGEX = '#\$\w+#';

    public function work(string $docContent, Tokens $tokens, int $position): string
    {
        $docBlock = new DocBlock($docContent);

        $lines = $docBlock->getLines();
        foreach ($lines as $line) {
            $match = Strings::match($line->getContent(), self::RETURN_VARIABLE_NAME_REGEX);
            if ($this->shouldSkip($match, $line->getContent())) {
                continue;
            }

            $newLineContent = Strings::replace(
                $line->getContent(),
                self::RETURN_VARIABLE_NAME_REGEX,
                function (array $match) {
                    $replacement = $match[1];
                    if ($match['type'] !== []) {
                        $replacement .= $match['type'];
                    }

                    return $replacement;
                }
            );

            $line->setContent($newLineContent);
        }

        return $docBlock->getContent();
    }

    /**
     * @param mixed[]|null $match
     */
    private function shouldSkip(?array $match, string $content): bool
    {
        if ($match === null) {
            return true;
        }

        if (in_array($match['variableName'], self::ALLOWED_VARIABLE_NAMES, true)) {
            return true;
        }
        // has multiple return values? "@return array $one, $two"
        return count(Strings::matchAll($content, self::VARIABLE_NAME_REGEX)) >= 2;
    }
}<commit_msg>[Cleaning] Get rid of nullable parameters (#2977)<commit_after><?php

declare(strict_types=1);

namespace Symplify\CodingStandard\TokenRunner\DocBlock\MalformWorker;

use Nette\Utils\Strings;
use PhpCsFixer\DocBlock\DocBlock;
use PhpCsFixer\Tokenizer\Tokens;

final class SuperfluousReturnNameMalformWorker extends AbstractMalformWorker
{
    /**
     * @var string
     * @see https://regex101.com/r/26Wy7Y/1
     */
    private const RETURN_VARIABLE_NAME_REGEX = '#(@return)(?<type>\s+[|\\\\\w]+)?(\s+)(?<' . self::VARIABLE_NAME_PART . '>\$[\w]+)#';

    /**
     * @var string[]
     */
    private const ALLOWED_VARIABLE_NAMES = ['$this'];

    /**
     * @var string
     * @see https://regex101.com/r/IE9fA6/1
     */
    private const VARIABLE_NAME_REGEX = '#\$\w+#';

    /**
     * @var string
     */
    private const VARIABLE_NAME_PART = 'variableName';

    public function work(string $docContent, Tokens $tokens, int $position): string
    {
        $docBlock = new DocBlock($docContent);

        $lines = $docBlock->getLines();
        foreach ($lines as $line) {
            $match = Strings::match($line->getContent(), self::RETURN_VARIABLE_NAME_REGEX);
            if ($match === null) {
                continue;
            }

            if ($this->shouldSkip($match, $line->getContent())) {
                continue;
            }

            $newLineContent = Strings::replace(
                $line->getContent(),
                self::RETURN_VARIABLE_NAME_REGEX,
                function (array $match) {
                    $replacement = $match[1];
                    if ($match['type'] !== []) {
                        $replacement .= $match['type'];
                    }

                    return $replacement;
                }
            );

            $line->setContent($newLineContent);
        }

        return $docBlock->getContent();
    }

    /**
     * @param array<string, string> $match
     */
    private function shouldSkip(array $match, string $content): bool
    {
        if (in_array($match[self::VARIABLE_NAME_PART], self::ALLOWED_VARIABLE_NAMES, true)) {
            return true;
        }

        // has multiple return values? "@return array $one, $two"
        return count(Strings::matchAll($content, self::VARIABLE_NAME_REGEX)) >= 2;
    }
}
{'fraction_non_alphanumeric': 0.14793965323125421, 'fraction_numerical': 0.008106282368835848, 'mean_word_length': 2.0740484429065744, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 24, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1376166', 'n_tokens_mistral': 1397, 'n_tokens_neox': 1329, 'n_words': 240}