From 9e0106c83fbeaa42b38a3ed1ed28405079d67e04 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 7 Mar 2017 14:53:31 +0100 Subject: [PATCH] FEATURE: Also migrate PHPDoc annotations * Migrate @param and @return statements. --- composer.json | 2 +- .../ClassnameChecker.php} | 96 ++++++++----------- .../LegacyClassnames/DocCommentSniff.php | 94 ++++++++++++++++++ .../LegacyClassnames/InheritanceSniff.php | 62 ++++++++++++ 4 files changed, 197 insertions(+), 57 deletions(-) rename src/Standards/Typo3Update/Sniffs/{Legacy/ClassnamesSniff.php => LegacyClassnames/ClassnameChecker.php} (50%) create mode 100644 src/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff.php create mode 100644 src/Standards/Typo3Update/Sniffs/LegacyClassnames/InheritanceSniff.php diff --git a/composer.json b/composer.json index 896e5ec..f72a287 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "project", "autoload": { "psr-4": { - "Typo3Update\\": "src/Classes/" + "Typo3Update\\": "src/Standards/Typo3Update/" } }, "require-dev": { diff --git a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php b/src/Standards/Typo3Update/Sniffs/LegacyClassnames/ClassnameChecker.php similarity index 50% rename from src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php rename to src/Standards/Typo3Update/Sniffs/LegacyClassnames/ClassnameChecker.php index d9993ae..d350347 100644 --- a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php +++ b/src/Standards/Typo3Update/Sniffs/LegacyClassnames/ClassnameChecker.php @@ -1,4 +1,5 @@ @@ -19,11 +20,12 @@ * 02110-1301, USA. */ +use PHP_CodeSniffer_File as PhpcsFile; + /** - * This sniff detects old, legacy class names like t3lib_div. - * Also it will make them fixable and migrate them to new ones. + * Provide common uses for all sniffs. */ -class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff +trait ClassnameChecker { /** * Contains mapping from old -> new class names. @@ -34,49 +36,45 @@ class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff /** * @param string $mappingFile File containing php array for mapping. */ - public function __construct($mappingFile = __DIR__ . '/../../../../../LegacyClassnames.php') + public function initialize($mappingFile = __DIR__ . '/../../../../../LegacyClassnames.php') { + if ($this->legacyClassnames !== []) { + return; + } + $legacyClassnames = require $mappingFile; $this->legacyClassnames = $legacyClassnames['aliasToClassNameMapping']; } /** - * Returns the token types that this sniff is interested in. - * - * @see http://php.net/manual/en/tokens.php - * - * @return array + * @param string $classname + * @return bool */ - public function register() + public function isLegacyClassname($classname) { - return [ - T_EXTENDS, - T_IMPLEMENTS, - // T_INSTANCEOF, - // T_NEW, - // T_STRING, - // T_USE, - ]; + $this->initialize(); + return isset($this->legacyClassnames[strtolower($classname)]); } /** - * Processes the tokens that this sniff is interested in. - * - * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. - * @param int $stackPtr The position in the stack where - * the token was found. - * - * @return void + * @param string $classname + * @return string */ - public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + public function getNewClassname($classname) { - $tokens = $phpcsFile->getTokens(); - $classnamePosition = $phpcsFile->findNext(T_STRING, $stackPtr); - if ($classnamePosition === false) { - return; - } - $classname = $tokens[$classnamePosition]['content']; + $this->initialize(); + return $this->legacyClassnames[strtolower($classname)]; + } + /** + * Add an fixable error if given $classname is legacy. + * + * @param PhpcsFile $phpcsFile + * @param int $classnamePosition + * @param string $classname + */ + public function addFixableError(PhpcsFile $phpcsFile, $classnamePosition, $classname) + { if ($this->isLegacyClassname($classname) === false) { return; } @@ -88,37 +86,23 @@ class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff [$classname] ); - if ($fix === false) { - return; - } - - switch ($tokens[$stackPtr]['code']) { - case T_EXTENDS: - case T_IMPLEMENTS: - $phpcsFile->fixer->replaceToken($classnamePosition, '\\' . $this->getNewClassname($classname)); - break; - - default: - throw new \RuntimeException('Could not fix type "' . $tokens[$stackPtr]['type'] . '"', 1488891438); - break; + if ($fix === true) { + $phpcsFile->fixer->replaceToken( + $classnamePosition, + $this->getTokenForReplacement('\\' . $this->getNewClassname($classname)) + ); } } /** - * @param string $classname - * @return bool - */ - protected function isLegacyClassname($classname) - { - return isset($this->legacyClassnames[strtolower($classname)]); - } - - /** + * String to use for replacing / fixing the token. + * Default is class name itself, can be overwritten in sniff for special behaviour. + * * @param string $classname * @return string */ - protected function getNewClassname($classname) + public function getTokenForReplacement($classname) { - return $this->legacyClassnames[strtolower($classname)]; + return $classname; } } diff --git a/src/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff.php b/src/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff.php new file mode 100644 index 0000000..4d38696 --- /dev/null +++ b/src/Standards/Typo3Update/Sniffs/LegacyClassnames/DocCommentSniff.php @@ -0,0 +1,94 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * Migrate PHP Doc comments. + * + * E.g. annotations like @param or @return, see $allowedTags. + */ +class Typo3Update_Sniffs_LegacyClassnames_DocCommentSniff implements PHP_CodeSniffer_Sniff +{ + use \Typo3Update\Sniffs\LegacyClassnames\ClassnameChecker; + + /** + * The configured tags will be processed. + * @var array + */ + protected $allowedTags = ['@param', '@return']; + + /** + * Original token for reuse accross methods. + * @var array + */ + protected $originalToken = []; + + /** + * Returns the token types that this sniff is interested in. + * + * @return array + */ + public function register() + { + return [ + T_DOC_COMMENT_TAG, + ]; + } + + /** + * Processes the tokens that this sniff is interested in. + * + * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. + * @param int $stackPtr The position in the stack where + * the token was found. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + if (!in_array($tokens[$stackPtr]['content'], $this->allowedTags)) { + return; + } + $classnamePosition = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $stackPtr); + if ($classnamePosition === false) { + return; + } + $classname = explode(' ', $tokens[$classnamePosition]['content'])[0]; + + $this->originalToken = $tokens[$classnamePosition]['content']; + $this->addFixableError($phpcsFile, $classnamePosition, $classname); + } + + /** + * As token contains more then just class name, we have to build new content ourself. + * + * + * @param string $classname + * @return string + */ + public function getTokenForReplacement($classname) + { + $token = explode(' ', $this->originalToken); + $token[0] = $classname; + + return implode(' ', $token); + } +} diff --git a/src/Standards/Typo3Update/Sniffs/LegacyClassnames/InheritanceSniff.php b/src/Standards/Typo3Update/Sniffs/LegacyClassnames/InheritanceSniff.php new file mode 100644 index 0000000..a7db60d --- /dev/null +++ b/src/Standards/Typo3Update/Sniffs/LegacyClassnames/InheritanceSniff.php @@ -0,0 +1,62 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * Detect and migrate extend and implement of old legacy classnames. + */ +class Typo3Update_Sniffs_LegacyClassnames_InheritanceSniff implements PHP_CodeSniffer_Sniff +{ + use \Typo3Update\Sniffs\LegacyClassnames\ClassnameChecker; + + /** + * Returns the token types that this sniff is interested in. + * + * @return array + */ + public function register() + { + return [ + T_EXTENDS, + T_IMPLEMENTS, + ]; + } + + /** + * Processes the tokens that this sniff is interested in. + * + * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. + * @param int $stackPtr The position in the stack where + * the token was found. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + $classnamePosition = $phpcsFile->findNext(T_STRING, $stackPtr); + if ($classnamePosition === false) { + return; + } + $classname = $tokens[$classnamePosition]['content']; + + $this->addFixableError($phpcsFile, $classnamePosition, $classname); + } +}