nodeTransformer = $nodeTransformer; } public function getRuleDefinition() : RuleDefinition { return new RuleDefinition('Turns array return to yield return in specific type and method', [new ConfiguredCodeSample(<<<'CODE_SAMPLE' use PHPUnit\Framework\TestCase; final class SomeTest implements TestCase { public static function provideData() { return [ ['some text'] ]; } } CODE_SAMPLE , <<<'CODE_SAMPLE' use PHPUnit\Framework\TestCase; final class SomeTest implements TestCase { public static function provideData() { yield ['some text']; } } CODE_SAMPLE , [new ReturnArrayClassMethodToYield('PHPUnit\\Framework\\TestCase', '*provide*')])]); } /** * @return array> */ public function getNodeTypes() : array { return [ClassMethod::class]; } /** * @param ClassMethod $node */ public function refactor(Node $node) : ?Node { if ($node->stmts === null) { return null; } $hasChanged = \false; foreach ($this->methodsToYields as $methodToYield) { if (!$this->isName($node, $methodToYield->getMethod())) { continue; } if (!$this->isObjectType($node, $methodToYield->getObjectType())) { continue; } $arrayNode = $this->collectReturnArrayNodesFromClassMethod($node); if (!$arrayNode instanceof Array_) { continue; } // keep comments of 1st array item $firstComment = $node->stmts[0]->getAttribute(AttributeKey::COMMENTS); $this->transformArrayToYieldsOnMethodNode($node, $arrayNode); if (\is_array($firstComment)) { $node->stmts[0]->setAttribute(AttributeKey::COMMENTS, \array_merge($firstComment, (array) $node->stmts[0]->getAttribute(AttributeKey::COMMENTS))); } $hasChanged = \true; } if (!$hasChanged) { return null; } return $node; } /** * @param mixed[] $configuration */ public function configure(array $configuration) : void { Assert::allIsAOf($configuration, ReturnArrayClassMethodToYield::class); $this->methodsToYields = $configuration; } private function collectReturnArrayNodesFromClassMethod(ClassMethod $classMethod) : ?Array_ { if ($classMethod->stmts === null) { return null; } foreach ($classMethod->stmts as $statement) { if ($statement instanceof Return_) { $returnedExpr = $statement->expr; if (!$returnedExpr instanceof Array_) { continue; } return $returnedExpr; } } return null; } private function transformArrayToYieldsOnMethodNode(ClassMethod $classMethod, Array_ $array) : void { $yields = $this->nodeTransformer->transformArrayToYields($array); $this->removeReturnTag($classMethod); // change return typehint $classMethod->returnType = new FullyQualified('Iterator'); foreach ((array) $classMethod->stmts as $key => $classMethodStmt) { if (!$classMethodStmt instanceof Return_) { continue; } unset($classMethod->stmts[$key]); } $classMethod->stmts = \array_merge((array) $classMethod->stmts, $yields); } private function removeReturnTag(ClassMethod $classMethod) : void { $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod); $phpDocInfo->removeByType(ReturnTagValueNode::class); } }