diff --git a/build/subtree-split-master-and-last-tag.sh b/build/subtree-split-master-and-last-tag.sh new file mode 100755 index 000000000000..c36c2d672164 --- /dev/null +++ b/build/subtree-split-master-and-last-tag.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +git subsplit init git@github.com:rectorphp/rector.git + +LAST_TAG=$(git tag -l --sort=committerdate | tail -n1); + +git subsplit publish --heads="master" --tags=$LAST_TAG packages/NodeTypeResolver:git@github.com:rectorphp/node-type-resolver.git + +rm -rf .subsplit/ + +# inspired by laravel: https://github.com/laravel/framework/blob/5.4/build/illuminate-split-full.sh +# they use SensioLabs now though: https://github.com/laravel/framework/pull/17048#issuecomment-269915319 diff --git a/packages/NodeTraverserQueue/src/BetterNodeFinder.php b/packages/NodeTraverserQueue/src/BetterNodeFinder.php index 6cb7792be196..bb9af7845a43 100644 --- a/packages/NodeTraverserQueue/src/BetterNodeFinder.php +++ b/packages/NodeTraverserQueue/src/BetterNodeFinder.php @@ -51,6 +51,19 @@ public function findFirstInstanceOf($nodes, string $type): ?Node return $this->nodeFinder->findFirstInstanceOf($nodes, $type); } + /** + * @param Node|Node[] $nodes + */ + public function findLastInstanceOf($nodes, string $type): ?Node + { + $foundInstances = $this->nodeFinder->findInstanceOf($nodes, $type); + if (! $foundInstances) { + return null; + } + + return array_pop($foundInstances); + } + /** * @param Node|Node[] $nodes * @return Node[] diff --git a/packages/NodeTypeResolver/src/Contract/PerNodeCallerTypeResolver/PerNodeCallerTypeResolverInterface.php b/packages/NodeTypeResolver/src/Contract/PerNodeCallerTypeResolver/PerNodeCallerTypeResolverInterface.php deleted file mode 100644 index 90d3d3ebd3ed..000000000000 --- a/packages/NodeTypeResolver/src/Contract/PerNodeCallerTypeResolver/PerNodeCallerTypeResolverInterface.php +++ /dev/null @@ -1,18 +0,0 @@ -fixedSerializer->getDocComment($docBlock); - return $this->clearUnnededPreslashes($docComment); + $docComment = $this->clearUnnededPreslashes($docComment); + + return $this->clearUnnededSpaces($docComment); } /** @@ -34,4 +37,15 @@ private function clearUnnededPreslashes(string $content): string return str_replace('@param \\', '@param ', $content); } + + /** + * phpDocumentor adds extra spaces before Doctrine-Annotation based annotations + * starting with uppercase and followed by (, e.g. @Route('value') + */ + private function clearUnnededSpaces(string $content): string + { + return Strings::replace($content, '#@[A-Z][a-z]+\s\(#', function (array $match) { + return str_replace(' ', '', $match[0]); + }); + } } diff --git a/phpstan.neon b/phpstan.neon index 2af0a193bcf8..5f38e17a26b5 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -36,6 +36,7 @@ parameters: - '#Property Rector\\NodeTypeResolver\\Tests\\PerNodeCallerTypeResolver\\MethodCallCallerTypeResolver\\NestedMethodCallTest::\$(formChainMethodCallNodes|nestedMethodCallNodes) \(array\) does not accept array#' - '#Cannot call method toString\(\) on string#' - '#Parameter \#1 \$node of method Rector\\NodeTypeResolver\\NodeTypeResolver::resolve\(\) expects PhpParser\\Node, PhpParser\\Node\\Expr|string given#' + - '#Cannot call method render\(\) on phpDocumentor\\Reflection\\DocBlock\\Tag\|string#' # known value of Name of MethodCall - '#Call to an undefined method PhpParser\\Node\\Expr\|PhpParser\\Node\\Name::toString\(\)#' diff --git a/src/Exception/Rector/InvalidRectorConfigurationException.php b/src/Exception/Rector/InvalidRectorConfigurationException.php new file mode 100644 index 000000000000..8ffe7142514f --- /dev/null +++ b/src/Exception/Rector/InvalidRectorConfigurationException.php @@ -0,0 +1,9 @@ +render('index.html.twig'); + * - } + */ +final class TemplateAnnotationRector extends AbstractRector +{ + /** + * @var DocBlockAnalyzer + */ + private $docBlockAnalyzer; + + /** + * @var MethodCallNodeFactory + */ + private $methodCallNodeFactory; + + /** + * @var NodeFactory + */ + private $nodeFactory; + + /** + * @var BetterNodeFinder + */ + private $betterNodeFinder; + + /** + * @var TemplateGuesser + */ + private $templateGuesser; + + /** + * @var int + */ + private $version; + + /** + * @param mixed[] $config + */ + public function __construct( + array $config, + DocBlockAnalyzer $docBlockAnalyzer, + MethodCallNodeFactory $methodCallNodeFactory, + NodeFactory $nodeFactory, + BetterNodeFinder $betterNodeFinder, + TemplateGuesser $templateGuesser + ) { + $this->setConfig($config); + $this->docBlockAnalyzer = $docBlockAnalyzer; + $this->methodCallNodeFactory = $methodCallNodeFactory; + $this->nodeFactory = $nodeFactory; + $this->betterNodeFinder = $betterNodeFinder; + $this->templateGuesser = $templateGuesser; + } + + public function isCandidate(Node $node): bool + { + if (! $node instanceof ClassMethod) { + return false; + } + + return $this->docBlockAnalyzer->hasAnnotation($node, 'Template'); + } + + /** + * @param ClassMethod $classMethodNode + */ + public function refactor(Node $classMethodNode): ?Node + { + /** @var Return_|null $returnNode */ + $returnNode = $this->betterNodeFinder->findLastInstanceOf((array) $classMethodNode->stmts, Return_::class); + + // create "$this->render('template.file.twig.html', ['key' => 'value']);" method call + $renderArguments = $this->resolveRenderArguments($classMethodNode, $returnNode); + $thisRenderMethodCall = $this->methodCallNodeFactory->createWithVariableNameMethodNameAndArguments( + 'this', + 'render', + $renderArguments + ); + + if (! $returnNode) { + // or add as last statement in the method + $classMethodNode->stmts[] = new Return_($thisRenderMethodCall); + } + + // replace Return_ node value if exists and is not already in correct format + if ($returnNode && ! $returnNode->expr instanceof MethodCall) { + $returnNode->expr = $thisRenderMethodCall; + } + + // remove annotation + $this->docBlockAnalyzer->removeAnnotationFromNode($classMethodNode, 'Template'); + + return $classMethodNode; + } + + /** + * @return Arg[] + */ + private function resolveRenderArguments(ClassMethod $classMethodNode, ?Return_ $returnNode): array + { + $arguments = [$this->resolveTemplateName($classMethodNode)]; + if (! $returnNode) { + return $this->nodeFactory->createArgs($arguments); + } + + if ($returnNode->expr instanceof Array_ && count($returnNode->expr->items)) { + $arguments[] = $returnNode->expr; + } + + $arguments = array_merge($arguments, $this->resolveArgumentsFromMethodCall($returnNode)); + + return $this->nodeFactory->createArgs($arguments); + } + + private function resolveTemplateName(ClassMethod $classMethodNode): string + { + $templateAnnotation = $this->docBlockAnalyzer->getTagsByName($classMethodNode, 'Template')[0]; + $content = $templateAnnotation->render(); + + // @todo consider using sth similar to offical parsing + $annotationContent = Strings::match($content, '#\("(?.*?)"\)#'); + + if (isset($annotationContent['filename'])) { + return $annotationContent['filename']; + } + + return $this->templateGuesser->resolveFromClassMethodNode($classMethodNode, $this->version); + } + + /** + * Already existing method call + * @return mixed[] + */ + private function resolveArgumentsFromMethodCall(Return_ $returnNode): array + { + $arguments = []; + if ($returnNode->expr instanceof MethodCall) { + foreach ($returnNode->expr->args as $arg) { + if ($arg->value instanceof Array_) { + $arguments[] = $arg->value; + } + } + } + + return $arguments; + } + + /** + * @param mixed[] $config + */ + private function setConfig(array $config): void + { + $this->ensureConfigHasVersion($config); + $this->version = $config['version']; + } + + /** + * @param mixed[] $config + */ + private function ensureConfigHasVersion(array $config): void + { + if (isset($config['version'])) { + return; + } + + throw new InvalidRectorConfigurationException(sprintf( + 'Rector "%s" is missing "%s" configuration. Add it as "%s" to config.yml under its key"', + self::class, + 'version', + 'version: ' + )); + } +} diff --git a/src/Rector/Contrib/Sensio/Helper/TemplateGuesser.php b/src/Rector/Contrib/Sensio/Helper/TemplateGuesser.php new file mode 100644 index 000000000000..9a59b75814e1 --- /dev/null +++ b/src/Rector/Contrib/Sensio/Helper/TemplateGuesser.php @@ -0,0 +1,78 @@ +getAttribute(Attribute::NAMESPACE_NAME); + $class = (string) $classMethodNode->getAttribute(Attribute::CLASS_NAME); + $method = $classMethodNode->name->toString(); + + if ($version === 3) { + return $this->resolveForVersion3($namespace, $class, $method); + } + + if ($version === 5) { + return $this->resolveForVersion5($namespace, $class, $method); + } + + throw new ShouldNotHappenException(sprintf( + 'Version "%d" is not supported in "%s". Add it.', + $version, + self::class + )); + } + + /** + * Mimics https://github.com/sensiolabs/SensioFrameworkExtraBundle/blob/v3.0.0/Templating/TemplateGuesser.php + */ + private function resolveForVersion3(string $namespace, string $class, string $method): string + { + // AppBundle\SomeNamespace\ => AppBundle + // App\OtherBundle\SomeNamespace\ => OtherBundle + $bundle = Strings::match($namespace, '/(?[A-Za-z]*Bundle)/')['bundle'] ?? ''; + + // SomeSuper\ControllerClass => ControllerClass + $controller = Strings::match($class, '/(?[A-Za-z0-9]*)Controller$/')['controller'] ?? ''; + + // indexAction => index + $action = Strings::match($method, '/(?[A-Za-z]*)Action$/')['method'] ?? ''; + + return sprintf('%s:%s:%s.html.twig', $bundle, $controller, $action); + } + + /** + * Mimics https://github.com/sensiolabs/SensioFrameworkExtraBundle/blob/v5.0.0/Templating/TemplateGuesser.php + */ + private function resolveForVersion5(string $namespace, string $class, string $method): string + { + $bundle = Strings::match($namespace, '/(?[A-Za-z]*Bundle)/')['bundle'] ?? ''; + $bundle = preg_replace('/Bundle$/', '', $bundle); + $bundle = $bundle ? '@' . $bundle . '/' : ''; + + $controller = $this->resolveControllerVersion5($class); + $action = preg_replace('/Action$/', '', $method); + + return sprintf('%s%s%s.html.twig', $bundle, $controller, $action); + } + + private function resolveControllerVersion5(string $class): string + { + if (! preg_match('/Controller\\\(.+)Controller$/', $class, $tempMatch)) { + return ''; + } + + $controller = str_replace('\\', '/', strtolower( + preg_replace('/([a-z\d])([A-Z])/', '\\1_\\2', $tempMatch[1]) + )); + + return $controller ? $controller . '/' : ''; + } +} diff --git a/src/config/level/sensio/framework-extra-bundle-30.yml b/src/config/level/sensio/framework-extra-bundle-30.yml new file mode 100644 index 000000000000..f64390908eb8 --- /dev/null +++ b/src/config/level/sensio/framework-extra-bundle-30.yml @@ -0,0 +1,3 @@ +rectors: + Rector\Rector\Contrib\Sensio\FrameworkExtraBundle\TemplateAnnotationRector: + version: 3 diff --git a/src/config/level/sensio/framework-extra-bundle-50.yml b/src/config/level/sensio/framework-extra-bundle-50.yml new file mode 100644 index 000000000000..73381919256f --- /dev/null +++ b/src/config/level/sensio/framework-extra-bundle-50.yml @@ -0,0 +1,3 @@ +rectors: + Rector\Rector\Contrib\Sensio\FrameworkExtraBundle\TemplateAnnotationRector: + version: 5 diff --git a/src/config/services.yml b/src/config/services.yml index 86b389892021..b723dc702333 100644 --- a/src/config/services.yml +++ b/src/config/services.yml @@ -5,7 +5,7 @@ services: Rector\: resource: '../' - exclude: '../{Node/Attribute.php,Rector/Contrib,Rector/Dynamic,Rector/MagicDisclosure,Testing}' + exclude: '../{Node/Attribute.php,Rector/Contrib/**/*Rector.php,Rector/Dynamic,Rector/MagicDisclosure,Testing}' Rector\Rector\Contrib\Symfony\Form\Helper\FormTypeStringToTypeProvider: ~ diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct.php.inc new file mode 100644 index 000000000000..d2845d88b442 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct.php.inc @@ -0,0 +1,13 @@ +render('AppBundle:ClassWithNamedService1:index.html.twig'); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct2.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct2.php.inc new file mode 100644 index 000000000000..ee1eb6fc951c --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct2.php.inc @@ -0,0 +1,13 @@ +render('AppBundle:ClassWithNamedService1:index.html.twig', ['someKey' => 'someValue']); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct3.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct3.php.inc new file mode 100644 index 000000000000..34a7d1a5f8df --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct3.php.inc @@ -0,0 +1,11 @@ +render('someFile.toBe.used'); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct4.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct4.php.inc new file mode 100644 index 000000000000..d2845d88b442 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct4.php.inc @@ -0,0 +1,13 @@ +render('AppBundle:ClassWithNamedService1:index.html.twig'); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct5.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct5.php.inc new file mode 100644 index 000000000000..100fee2b620a --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct5.php.inc @@ -0,0 +1,15 @@ +render('AppBundle:ClassWithNamedService1:index.html.twig', array( + 'form' => $form->createView() + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct6.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct6.php.inc new file mode 100644 index 000000000000..3cf6bce712a1 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct6.php.inc @@ -0,0 +1,19 @@ +redirectToRoute('rector_is_cool'); + } + + return $this->render('AppBundle:ClassWithNamedService1:index.html.twig', array( + 'form' => $form->createView() + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct7.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct7.php.inc new file mode 100644 index 000000000000..7ccfc9a79c90 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct7.php.inc @@ -0,0 +1,15 @@ +render('AppBundle:NameNotFollowingConvention:index.html.twig', array( + 'form' => $form->createView() + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct8.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct8.php.inc new file mode 100644 index 000000000000..8d1b0f95bf6b --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version3/correct8.php.inc @@ -0,0 +1,13 @@ +render('payment/new.html.twig', array( + 'form' => $form->createView(), + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct.php.inc new file mode 100644 index 000000000000..25ea1291bc6c --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct.php.inc @@ -0,0 +1,13 @@ +render('@App/class_with_named_service1/index.html.twig'); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct2.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct2.php.inc new file mode 100644 index 000000000000..ed9060dd621c --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct2.php.inc @@ -0,0 +1,13 @@ +render('@App/class_with_named_service1/index.html.twig', ['someKey' => 'someValue']); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct3.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct3.php.inc new file mode 100644 index 000000000000..34a7d1a5f8df --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct3.php.inc @@ -0,0 +1,11 @@ +render('someFile.toBe.used'); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct4.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct4.php.inc new file mode 100644 index 000000000000..d2845d88b442 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct4.php.inc @@ -0,0 +1,13 @@ +render('AppBundle:ClassWithNamedService1:index.html.twig'); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct5.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct5.php.inc new file mode 100644 index 000000000000..100fee2b620a --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct5.php.inc @@ -0,0 +1,15 @@ +render('AppBundle:ClassWithNamedService1:index.html.twig', array( + 'form' => $form->createView() + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct6.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct6.php.inc new file mode 100644 index 000000000000..d2eef7209b80 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct6.php.inc @@ -0,0 +1,19 @@ +redirectToRoute('rector_is_cool'); + } + + return $this->render('@App/class_with_named_service1/index.html.twig', array( + 'form' => $form->createView() + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct7.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct7.php.inc new file mode 100644 index 000000000000..7ccfc9a79c90 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct7.php.inc @@ -0,0 +1,15 @@ +render('AppBundle:NameNotFollowingConvention:index.html.twig', array( + 'form' => $form->createView() + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct8.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct8.php.inc new file mode 100644 index 000000000000..8d1b0f95bf6b --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct8.php.inc @@ -0,0 +1,13 @@ +render('payment/new.html.twig', array( + 'form' => $form->createView(), + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct9.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct9.php.inc new file mode 100644 index 000000000000..c03bdfbba14e --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Correct/Version5/correct9.php.inc @@ -0,0 +1,14 @@ +render('app/index.html.twig'); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Source/version3.yml b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Source/version3.yml new file mode 100644 index 000000000000..f64390908eb8 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Source/version3.yml @@ -0,0 +1,3 @@ +rectors: + Rector\Rector\Contrib\Sensio\FrameworkExtraBundle\TemplateAnnotationRector: + version: 3 diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Source/version5.yml b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Source/version5.yml new file mode 100644 index 000000000000..73381919256f --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Source/version5.yml @@ -0,0 +1,3 @@ +rectors: + Rector\Rector\Contrib\Sensio\FrameworkExtraBundle\TemplateAnnotationRector: + version: 5 diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/TemplateAnnotationVersion3RectorTest.php b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/TemplateAnnotationVersion3RectorTest.php new file mode 100644 index 000000000000..f8f7a50b45fc --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/TemplateAnnotationVersion3RectorTest.php @@ -0,0 +1,47 @@ +doTestFileMatchesExpectedContent($wrong, $fixed); + } + + /** + * @return string[][] + */ + public function provideWrongToFixedFiles(): array + { + return [ + [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/Version3/correct.php.inc'], + [__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/Version3/correct2.php.inc'], + [__DIR__ . '/Wrong/wrong3.php.inc', __DIR__ . '/Correct/Version3/correct3.php.inc'], + [__DIR__ . '/Wrong/wrong4.php.inc', __DIR__ . '/Correct/Version3/correct4.php.inc'], + [__DIR__ . '/Wrong/wrong5.php.inc', __DIR__ . '/Correct/Version3/correct5.php.inc'], + [__DIR__ . '/Wrong/wrong6.php.inc', __DIR__ . '/Correct/Version3/correct6.php.inc'], + [__DIR__ . '/Wrong/wrong7.php.inc', __DIR__ . '/Correct/Version3/correct7.php.inc'], + [__DIR__ . '/Wrong/wrong8.php.inc', __DIR__ . '/Correct/Version3/correct8.php.inc'], + ]; + } + + /** + * @return string[] + */ + protected function getRectorClasses(): array + { + return [TemplateAnnotationRector::class]; + } + + protected function provideConfig(): string + { + return __DIR__ . '/Source/version3.yml'; + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/TemplateAnnotationVersion5RectorTest.php b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/TemplateAnnotationVersion5RectorTest.php new file mode 100644 index 000000000000..6af7a6d800be --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/TemplateAnnotationVersion5RectorTest.php @@ -0,0 +1,48 @@ +doTestFileMatchesExpectedContent($wrong, $fixed); + } + + /** + * @return string[][] + */ + public function provideWrongToFixedFiles(): array + { + return [ + [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/Version5/correct.php.inc'], + [__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/Version5/correct2.php.inc'], + [__DIR__ . '/Wrong/wrong3.php.inc', __DIR__ . '/Correct/Version5/correct3.php.inc'], + [__DIR__ . '/Wrong/wrong4.php.inc', __DIR__ . '/Correct/Version5/correct4.php.inc'], + [__DIR__ . '/Wrong/wrong5.php.inc', __DIR__ . '/Correct/Version5/correct5.php.inc'], + [__DIR__ . '/Wrong/wrong6.php.inc', __DIR__ . '/Correct/Version5/correct6.php.inc'], + [__DIR__ . '/Wrong/wrong7.php.inc', __DIR__ . '/Correct/Version5/correct7.php.inc'], + [__DIR__ . '/Wrong/wrong8.php.inc', __DIR__ . '/Correct/Version5/correct8.php.inc'], + [__DIR__ . '/Wrong/wrong9.php.inc', __DIR__ . '/Correct/Version5/correct9.php.inc'], + ]; + } + + /** + * @return string[] + */ + protected function getRectorClasses(): array + { + return [TemplateAnnotationRector::class]; + } + + protected function provideConfig(): string + { + return __DIR__ . '/Source/version5.yml'; + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong.php.inc new file mode 100644 index 000000000000..a67d897776ec --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong.php.inc @@ -0,0 +1,14 @@ + 'someValue']; + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong3.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong3.php.inc new file mode 100644 index 000000000000..84816158d58b --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong3.php.inc @@ -0,0 +1,12 @@ +render('AppBundle:ClassWithNamedService1:index.html.twig'); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong5.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong5.php.inc new file mode 100644 index 000000000000..57cd1586c89b --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong5.php.inc @@ -0,0 +1,16 @@ +render('AppBundle:ClassWithNamedService1:index.html.twig', array( + 'form' => $form->createView() + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong6.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong6.php.inc new file mode 100644 index 000000000000..4ccac8ded4e5 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong6.php.inc @@ -0,0 +1,20 @@ +redirectToRoute('rector_is_cool'); + } + + return array( + 'form' => $form->createView() + ); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong7.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong7.php.inc new file mode 100644 index 000000000000..c455a6b221d3 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong7.php.inc @@ -0,0 +1,16 @@ +render('AppBundle:NameNotFollowingConvention:index.html.twig', array( + 'form' => $form->createView() + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong8.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong8.php.inc new file mode 100644 index 000000000000..4823e21edfbc --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong8.php.inc @@ -0,0 +1,14 @@ +render('payment/new.html.twig', array( + 'form' => $form->createView(), + )); + } +} diff --git a/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong9.php.inc b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong9.php.inc new file mode 100644 index 000000000000..25779ce05801 --- /dev/null +++ b/tests/Rector/Contrib/Sensio/FrameworkExtraBundle/TemplateAnnotationRector/Wrong/wrong9.php.inc @@ -0,0 +1,15 @@ +