From d4e3724d2b120a1c6cf7928897ede4c9340b55ad Mon Sep 17 00:00:00 2001 From: umpirsky Date: Sat, 21 Nov 2015 11:28:01 +0100 Subject: [PATCH 1/6] Added get request fixer --- README.md | 1 + src/Symfony/Upgrade/Fixer/AbstractFixer.php | 14 ++ src/Symfony/Upgrade/Fixer/FormTypeFixer.php | 11 +- src/Symfony/Upgrade/Fixer/GetRequestFixer.php | 208 ++++++++++++++++++ .../Fixer/get-request/case1-input.php | 14 ++ .../Fixer/get-request/case1-output.php | 14 ++ .../Fixer/get-request/case2-input.php | 19 ++ .../Fixer/get-request/case2-output.php | 19 ++ .../Test/Fixer/GetRequestFixerTest.php | 22 ++ 9 files changed, 312 insertions(+), 10 deletions(-) create mode 100644 src/Symfony/Upgrade/Fixer/GetRequestFixer.php create mode 100644 tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case1-input.php create mode 100644 tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case1-output.php create mode 100644 tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case2-input.php create mode 100644 tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case2-output.php create mode 100644 tests/Symfony/Upgrade/Test/Fixer/GetRequestFixerTest.php diff --git a/README.md b/README.md index 4728dcb..1a21261 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ $ symfony-upgrade-fixer fix /path/to/code --dry-run | form_option_names | Options precision and virtual was renamed to scale and inherit_data. | | form_parent_type | Returning type instances from FormTypeInterface::getParent() is deprecated, return the fully-qualified class name of the parent type class instead. | | form_type_names | Instead of referencing types by name, you should reference them by their fully-qualified class name (FQCN) instead. | +| get_request | The getRequest method of the base controller class was removed, request object is injected in the action method instead. | | inherit_data_aware_iterator | The class VirtualFormAwareIterator was renamed to InheritDataAwareIterator. | | progress_bar | ProgressHelper has been removed in favor of ProgressBar. | | property_access | Renamed PropertyAccess::getPropertyAccessor to PropertyAccess::createPropertyAccessor. | diff --git a/src/Symfony/Upgrade/Fixer/AbstractFixer.php b/src/Symfony/Upgrade/Fixer/AbstractFixer.php index bbbdca5..4431949 100644 --- a/src/Symfony/Upgrade/Fixer/AbstractFixer.php +++ b/src/Symfony/Upgrade/Fixer/AbstractFixer.php @@ -77,4 +77,18 @@ protected function addUseStatement(Tokens $tokens, array $fqcn) ) ); } + + protected function extendsClass(Tokens $tokens, array $fqcn) + { + if (!$this->hasUseStatements($tokens, $fqcn)) { + return false; + } + + return null !== $tokens->findSequence([ + [T_CLASS], + [T_STRING], + [T_EXTENDS], + [T_STRING, array_pop($fqcn)], + ]); + } } diff --git a/src/Symfony/Upgrade/Fixer/FormTypeFixer.php b/src/Symfony/Upgrade/Fixer/FormTypeFixer.php index f396cc6..f8bf41b 100644 --- a/src/Symfony/Upgrade/Fixer/FormTypeFixer.php +++ b/src/Symfony/Upgrade/Fixer/FormTypeFixer.php @@ -41,16 +41,7 @@ abstract class FormTypeFixer extends AbstractFixer protected function isFormType(Tokens $tokens) { - if (!$this->hasUseStatements($tokens, ['Symfony', 'Component', 'Form', 'AbstractType'])) { - return false; - } - - return null !== $tokens->findSequence([ - [T_CLASS], - [T_STRING], - [T_EXTENDS], - [T_STRING, 'AbstractType'], - ]); + return $this->extendsClass($tokens, ['Symfony', 'Component', 'Form', 'AbstractType']); } protected function addTypeUse(Tokens $tokens, $name) diff --git a/src/Symfony/Upgrade/Fixer/GetRequestFixer.php b/src/Symfony/Upgrade/Fixer/GetRequestFixer.php new file mode 100644 index 0000000..08f56bb --- /dev/null +++ b/src/Symfony/Upgrade/Fixer/GetRequestFixer.php @@ -0,0 +1,208 @@ +isController($tokens)) { + $this->fixGetRequests($tokens); + } + + return $tokens->generateCode(); + } + + public function getDescription() + { + return 'The getRequest method of the base controller class was removed, request object is injected in the action method instead.'; + } + + private function isController(Tokens $tokens) + { + return $this->extendsClass($tokens, ['Symfony', 'Bundle', 'FrameworkBundle', 'Controller', 'Controller']); + } + + private function fixGetRequests(Tokens $tokens) + { + $todo = []; + + foreach ($this->getClassyElementsIndexed($tokens) as $i => $element) { + if ('method' === $element['type']) { + if ($this->fixActionParameters($tokens, $element['index'])) { + $todo[] = $i; + } + } + } + + foreach ($this->getClassyElementsIndexed($tokens) as $i => $element) { + if (in_array($i, $todo)) { + $this->fixActionBody($tokens, $element['index']); + } + } + } + + private function getClassyElementsIndexed(Tokens $tokens) + { + $elements = []; + + foreach ($tokens->getClassyElements() as $index => $element) { + $element['index'] = $index; + $elements[] = $element; + } + + return $elements; + } + + private function fixActionParameters(Tokens $tokens, $index) + { + if (!$this->isAction($tokens, $index)) { + return; + } + + $parenthesisIndexes = $this->getActionParenthesisIndexes($tokens, $index); + if ($this->hasRequestParameterSequence($tokens, $parenthesisIndexes[0], $parenthesisIndexes[1])) { + return; + } + + $curlyBraceIndexes = $this->getActionCurlyBraceIndexes($tokens, $index); + if (!$this->hasGetRequestSequence($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1])) { + return; + } + + if (null === $requestVariableName = $this->getRequestVariableName($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1])) { + return; + } + + $insertAt = $tokens->getNextMeaningfulToken($parenthesisIndexes[0]); + + $tokens->insertAt( + $insertAt, + array_merge( + [ + new Token([T_STRING, 'Request']), + new Token([T_WHITESPACE, ' ']), + new Token([T_VARIABLE, $requestVariableName]), + ], + $parenthesisIndexes[1] - $parenthesisIndexes[0] > 1 ? [new Token(','), new Token([T_WHITESPACE, ' '])] : [] + ) + ); + + $this->addUseStatement( + $tokens, + ['Symfony', 'Component', 'HttpFoundation', 'Request'] + ); + + return true; + } + + private function fixActionBody(Tokens $tokens, $index) + { + $curlyBraceIndexes = $this->getActionCurlyBraceIndexes($tokens, $index); + if (!$this->hasGetRequestSequence($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1])) { + return; + } + + $clearFrom = $tmp = $this->getRequestVariableTokenIndex($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1]); + $keys = array_keys($this->getGetRequestSequence($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1])); + $clearTo = array_pop($keys); + $clearTo = $tokens->getNextMeaningfulToken($clearTo); + if (!$tokens[$clearTo]->equals(';')) { + return; + } + + $tokens->clearRange($clearFrom, $clearTo); + $tokens->removeTrailingWhitespace($clearTo); + } + + private function isAction(Tokens $tokens, $index) + { + $actionNameToken = $tokens[$tokens->getNextMeaningfulToken($index)]; + + if (!$actionNameToken->isGivenKind(T_STRING)) { + return false; + } + if (substr($actionNameToken->getContent(), -6) !== 'Action') { + return false; + } + + return true; + } + + private function getActionParenthesisIndexes(Tokens $tokens, $index) + { + $openIndex = $tokens->getNextMeaningfulToken($tokens->getNextMeaningfulToken($index)); + $closeIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openIndex); + + return [$openIndex, $closeIndex]; + } + + private function getActionCurlyBraceIndexes(Tokens $tokens, $index) + { + $openIndex = $tokens->getNextMeaningfulToken( + $this->getActionParenthesisIndexes($tokens, $index)[1] + ); + $closeIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $openIndex); + + return [$openIndex, $closeIndex]; + } + + private function hasRequestParameterSequence(Tokens $tokens, $start, $end) + { + return null !== $tokens->findSequence([ + [T_STRING, 'Request'], + [T_VARIABLE], + ], $start, $end); + } + + private function hasGetRequestSequence(Tokens $tokens, $start, $end) + { + return null !== $this->getGetRequestSequence($tokens, $start, $end); + } + + private function getGetRequestSequence(Tokens $tokens, $start, $end) + { + return $tokens->findSequence([ + [T_VARIABLE, '$this'], + [T_OBJECT_OPERATOR], + [T_STRING, 'getRequest'], + '(', + ')', + ], $start, $end); + } + + private function getRequestVariableName(Tokens $tokens, $start, $end) + { + $requestVariableTokenIndex = $this->getRequestVariableTokenIndex($tokens, $start, $end); + $requestVariableToken = $tokens[$requestVariableTokenIndex]; + if (!$requestVariableToken->isGivenKind(T_VARIABLE)) { + return; + } + + return $requestVariableToken->getContent(); + } + + private function getRequestSequenceStartTokenIndex(Tokens $tokens, $start, $end) + { + $getRequestSequence = $this->getGetRequestSequence($tokens, $start, $end); + + return array_keys($getRequestSequence)[0]; + } + + private function getRequestVariableTokenIndex(Tokens $tokens, $start, $end) + { + $getRequestSequenceStartIndex = $this->getRequestSequenceStartTokenIndex($tokens, $start, $end); + + $assignTokenIndex = $tokens->getPrevMeaningfulToken($getRequestSequenceStartIndex); + if ('=' !== $tokens[$assignTokenIndex]->getContent()) { + return; + } + + return $tokens->getPrevMeaningfulToken($assignTokenIndex); + } +} diff --git a/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case1-input.php b/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case1-input.php new file mode 100644 index 0000000..38da588 --- /dev/null +++ b/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case1-input.php @@ -0,0 +1,14 @@ +getRequest(); + // ... + } +} diff --git a/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case1-output.php b/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case1-output.php new file mode 100644 index 0000000..3f62438 --- /dev/null +++ b/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case1-output.php @@ -0,0 +1,14 @@ +getRequest(); + // ... + } + + private function helperMethod() + { + // ... + } +} diff --git a/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case2-output.php b/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case2-output.php new file mode 100644 index 0000000..707ee88 --- /dev/null +++ b/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case2-output.php @@ -0,0 +1,19 @@ +makeTest($expected, $input, $file); + } + + public function provideExamples() + { + return [ + $this->prepareTestCase('case1-output.php', 'case1-input.php'), + $this->prepareTestCase('case2-output.php', 'case2-input.php'), + ]; + } +} From e21c7a3c6725c2e73e47213e6cdf3c1492825ea0 Mon Sep 17 00:00:00 2001 From: umpirsky Date: Sun, 22 Nov 2015 10:55:09 +0100 Subject: [PATCH 2/6] Add new failing test case --- .../Fixtures/Fixer/get-request/case3-input.php | 14 ++++++++++++++ .../Fixtures/Fixer/get-request/case3-output.php | 15 +++++++++++++++ .../Upgrade/Test/Fixer/GetRequestFixerTest.php | 1 + 3 files changed, 30 insertions(+) create mode 100644 tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case3-input.php create mode 100644 tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case3-output.php diff --git a/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case3-input.php b/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case3-input.php new file mode 100644 index 0000000..bb751a2 --- /dev/null +++ b/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case3-input.php @@ -0,0 +1,14 @@ +getRequest()->request->get('username'); + // ... + } +} diff --git a/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case3-output.php b/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case3-output.php new file mode 100644 index 0000000..fb5f123 --- /dev/null +++ b/tests/Symfony/Upgrade/Fixtures/Fixer/get-request/case3-output.php @@ -0,0 +1,15 @@ +request->get('username'); + // ... + } +} diff --git a/tests/Symfony/Upgrade/Test/Fixer/GetRequestFixerTest.php b/tests/Symfony/Upgrade/Test/Fixer/GetRequestFixerTest.php index 1b67cb6..05ea02f 100644 --- a/tests/Symfony/Upgrade/Test/Fixer/GetRequestFixerTest.php +++ b/tests/Symfony/Upgrade/Test/Fixer/GetRequestFixerTest.php @@ -17,6 +17,7 @@ public function provideExamples() return [ $this->prepareTestCase('case1-output.php', 'case1-input.php'), $this->prepareTestCase('case2-output.php', 'case2-input.php'), + $this->prepareTestCase('case3-output.php', 'case3-input.php'), ]; } } From b9b46498f598871afb4e7391f6975fb137c16b80 Mon Sep 17 00:00:00 2001 From: umpirsky Date: Sat, 28 Nov 2015 19:23:01 +0100 Subject: [PATCH 3/6] Fix test cases --- src/Symfony/Upgrade/Fixer/GetRequestFixer.php | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/Symfony/Upgrade/Fixer/GetRequestFixer.php b/src/Symfony/Upgrade/Fixer/GetRequestFixer.php index 08f56bb..ba5dd77 100644 --- a/src/Symfony/Upgrade/Fixer/GetRequestFixer.php +++ b/src/Symfony/Upgrade/Fixer/GetRequestFixer.php @@ -7,6 +7,8 @@ class GetRequestFixer extends AbstractFixer { + private $requestVariableName = '$request'; + public function fix(\SplFileInfo $file, $content) { $tokens = Tokens::fromCode($content); @@ -76,7 +78,7 @@ private function fixActionParameters(Tokens $tokens, $index) } if (null === $requestVariableName = $this->getRequestVariableName($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1])) { - return; + $requestVariableName = $this->requestVariableName; } $insertAt = $tokens->getNextMeaningfulToken($parenthesisIndexes[0]); @@ -109,15 +111,28 @@ private function fixActionBody(Tokens $tokens, $index) } $clearFrom = $tmp = $this->getRequestVariableTokenIndex($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1]); - $keys = array_keys($this->getGetRequestSequence($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1])); + $getRequestSequenceTokens = $this->getGetRequestSequence($tokens, $curlyBraceIndexes[0], $curlyBraceIndexes[1]); + $keys = array_keys($getRequestSequenceTokens); $clearTo = array_pop($keys); $clearTo = $tokens->getNextMeaningfulToken($clearTo); - if (!$tokens[$clearTo]->equals(';')) { + if ($tokens[$clearTo]->equals(';')) { + $tokens->clearRange($clearFrom, $clearTo); + $tokens->removeTrailingWhitespace($clearTo); + return; } - $tokens->clearRange($clearFrom, $clearTo); - $tokens->removeTrailingWhitespace($clearTo); + $replace = true; + foreach ($getRequestSequenceTokens as $key => $getRequestSequenceToken) { + if ($replace) { + $getRequestSequenceToken->override([T_VARIABLE, $this->requestVariableName]); + + $replace = false; + continue; + } + + $tokens[$key]->clear(); + } } private function isAction(Tokens $tokens, $index) @@ -179,6 +194,10 @@ private function getGetRequestSequence(Tokens $tokens, $start, $end) private function getRequestVariableName(Tokens $tokens, $start, $end) { $requestVariableTokenIndex = $this->getRequestVariableTokenIndex($tokens, $start, $end); + if (null === $requestVariableTokenIndex) { + return; + } + $requestVariableToken = $tokens[$requestVariableTokenIndex]; if (!$requestVariableToken->isGivenKind(T_VARIABLE)) { return; @@ -187,16 +206,16 @@ private function getRequestVariableName(Tokens $tokens, $start, $end) return $requestVariableToken->getContent(); } - private function getRequestSequenceStartTokenIndex(Tokens $tokens, $start, $end) + private function getRequestVariableTokenIndex(Tokens $tokens, $start, $end) { $getRequestSequence = $this->getGetRequestSequence($tokens, $start, $end); - return array_keys($getRequestSequence)[0]; - } + $getRequestSequenceKeys = array_keys($getRequestSequence); + $getRequestSequenceStartIndex = $getRequestSequenceKeys[0]; - private function getRequestVariableTokenIndex(Tokens $tokens, $start, $end) - { - $getRequestSequenceStartIndex = $this->getRequestSequenceStartTokenIndex($tokens, $start, $end); + if (';' !== $tokens[$tokens->getNextMeaningfulToken(array_pop($getRequestSequenceKeys))]->getContent()) { + return; + } $assignTokenIndex = $tokens->getPrevMeaningfulToken($getRequestSequenceStartIndex); if ('=' !== $tokens[$assignTokenIndex]->getContent()) { From 9e1a2b01dc4ea26e776947583589f6d560341f81 Mon Sep 17 00:00:00 2001 From: umpirsky Date: Sat, 28 Nov 2015 19:27:24 +0100 Subject: [PATCH 4/6] No failures allowed --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index a8c6670..b47425e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,3 @@ before_script: script: - phpunit - -matrix: - allow_failures: - - php: 7.0 From 097eef3704a735b65a1eadfafa47a0d212de3b45 Mon Sep 17 00:00:00 2001 From: umpirsky Date: Sat, 28 Nov 2015 19:28:53 +0100 Subject: [PATCH 5/6] Removed uused use statements --- src/Symfony/Upgrade/Fixer/FormConfigureOptionsFixer.php | 1 - src/Symfony/Upgrade/Fixer/FormTypeFixer.php | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Symfony/Upgrade/Fixer/FormConfigureOptionsFixer.php b/src/Symfony/Upgrade/Fixer/FormConfigureOptionsFixer.php index d015051..dfbac25 100644 --- a/src/Symfony/Upgrade/Fixer/FormConfigureOptionsFixer.php +++ b/src/Symfony/Upgrade/Fixer/FormConfigureOptionsFixer.php @@ -2,7 +2,6 @@ namespace Symfony\Upgrade\Fixer; -use Symfony\CS\Tokenizer\Token; use Symfony\CS\Tokenizer\Tokens; class FormConfigureOptionsFixer extends FormTypeFixer diff --git a/src/Symfony/Upgrade/Fixer/FormTypeFixer.php b/src/Symfony/Upgrade/Fixer/FormTypeFixer.php index f8bf41b..1635aa3 100644 --- a/src/Symfony/Upgrade/Fixer/FormTypeFixer.php +++ b/src/Symfony/Upgrade/Fixer/FormTypeFixer.php @@ -2,7 +2,6 @@ namespace Symfony\Upgrade\Fixer; -use Symfony\CS\Tokenizer\Token; use Symfony\CS\Tokenizer\Tokens; abstract class FormTypeFixer extends AbstractFixer From 707ae3f0bc8a55b12c243bcf36bd9cabfc00f940 Mon Sep 17 00:00:00 2001 From: umpirsky Date: Sun, 29 Nov 2015 13:52:16 +0100 Subject: [PATCH 6/6] Version 0.1.2 --- README.md | 2 +- src/Symfony/Upgrade/Fixer.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1a21261..0bf9cfc 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ You can run these commands to easily access ``symfony-upgrade-fixer`` from anywh your system: ```bash -$ sudo wget https://github.com/umpirsky/Symfony-Upgrade-Fixer/releases/download/v0.1.1/symfony-upgrade-fixer.phar -O /usr/local/bin/symfony-upgrade-fixer +$ sudo wget https://github.com/umpirsky/Symfony-Upgrade-Fixer/releases/download/v0.1.2/symfony-upgrade-fixer.phar -O /usr/local/bin/symfony-upgrade-fixer $ sudo chmod a+x /usr/local/bin/symfony-upgrade-fixer ``` Then, just run ``symfony-upgrade-fixer``. diff --git a/src/Symfony/Upgrade/Fixer.php b/src/Symfony/Upgrade/Fixer.php index 95c25eb..8acbf71 100644 --- a/src/Symfony/Upgrade/Fixer.php +++ b/src/Symfony/Upgrade/Fixer.php @@ -12,7 +12,7 @@ class Fixer { - const VERSION = '0.1.1'; + const VERSION = '0.1.2'; private $fixers = []; private $finder;