* Dariusz Rumiński * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ namespace PhpCsFixer\Fixer\PhpUnit; use PhpCsFixer\Fixer\AbstractPhpUnitFixer; use PhpCsFixer\FixerDefinition\CodeSample; use PhpCsFixer\FixerDefinition\FixerDefinition; use PhpCsFixer\FixerDefinition\FixerDefinitionInterface; use PhpCsFixer\Tokenizer\Analyzer\DataProviderAnalyzer; use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer; use PhpCsFixer\Tokenizer\CT; use PhpCsFixer\Tokenizer\Token; use PhpCsFixer\Tokenizer\Tokens; /** * @author Kuba Werłos */ final class PhpUnitDataProviderReturnTypeFixer extends AbstractPhpUnitFixer { public function getDefinition(): FixerDefinitionInterface { return new FixerDefinition( 'The return type of PHPUnit data provider must be `iterable`.', [ new CodeSample( 'getDataProviders($tokens, $startIndex, $endIndex)) as $dataProviderAnalysis) { $typeAnalysis = $functionsAnalyzer->getFunctionReturnType($tokens, $dataProviderAnalysis->getNameIndex()); if (null === $typeAnalysis) { $argumentsStart = $tokens->getNextTokenOfKind($dataProviderAnalysis->getNameIndex(), ['(']); $argumentsEnd = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $argumentsStart); $tokens->insertAt( $argumentsEnd + 1, [ new Token([CT::T_TYPE_COLON, ':']), new Token([T_WHITESPACE, ' ']), new Token([T_STRING, 'iterable']), ], ); continue; } if ('iterable' === $typeAnalysis->getName()) { continue; } $typeStartIndex = $tokens->getNextMeaningfulToken($typeAnalysis->getStartIndex() - 1); $typeEndIndex = $typeAnalysis->getEndIndex(); // @TODO: drop condition and it's body when PHP 8+ is required if ($tokens->generatePartialCode($typeStartIndex, $typeEndIndex) !== $typeAnalysis->getName()) { continue; } $tokens->overrideRange($typeStartIndex, $typeEndIndex, [new Token([T_STRING, 'iterable'])]); } } }