From f972533e04e3e5c65cb8ad5c054351bd358768c1 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Tue, 25 Apr 2017 09:22:50 +0200 Subject: [PATCH 01/11] WIP|FEATURE: Check for removed php classes. * Add feature to existing code base and logic, see #72 . * Add first removed classes for TYPO3 7.0 as example. * Adjust first test to make sure basic implementation works. Relates: #41 --- .../Configuration/Features/RemovedClass.yaml | 14 + .../Configuration/Removed/Classes/7.0.yaml | 11 + .../Feature/RemovedByYamlConfiguration.php | 294 ++++++++++++++++++ .../Feature/RemovedClassFeature.php | 56 ++++ src/Standards/Typo3Update/Options.php | 13 + .../PhpDocCommentSniff/Expected.diff | 3 +- .../PhpDocCommentSniff/Expected.json | 17 +- .../PhpDocCommentSniff/InputFileForIssues.php | 1 + 8 files changed, 404 insertions(+), 5 deletions(-) create mode 100644 src/Standards/Typo3Update/Configuration/Features/RemovedClass.yaml create mode 100644 src/Standards/Typo3Update/Configuration/Removed/Classes/7.0.yaml create mode 100644 src/Standards/Typo3Update/Feature/RemovedByYamlConfiguration.php create mode 100644 src/Standards/Typo3Update/Feature/RemovedClassFeature.php diff --git a/src/Standards/Typo3Update/Configuration/Features/RemovedClass.yaml b/src/Standards/Typo3Update/Configuration/Features/RemovedClass.yaml new file mode 100644 index 0000000..1b7974f --- /dev/null +++ b/src/Standards/Typo3Update/Configuration/Features/RemovedClass.yaml @@ -0,0 +1,14 @@ +Typo3Update\Feature\RemovedClassFeature: + - Typo3Update_Sniffs_Classname_InheritanceSniff + - Typo3Update_Sniffs_Classname_InlineCommentSniff + - Typo3Update_Sniffs_Classname_InstanceofSniff + - Typo3Update_Sniffs_Classname_InstantiationWithMakeInstanceSniff + - Typo3Update_Sniffs_Classname_InstantiationWithNewSniff + - Typo3Update_Sniffs_Classname_InstantiationWithObjectManagerSniff + - Typo3Update_Sniffs_Classname_IsACallSniff + - Typo3Update_Sniffs_Classname_MissingVendorForPluginsAndModulesSniff + - Typo3Update_Sniffs_Classname_PhpDocCommentSniff + - Typo3Update_Sniffs_Classname_StaticCallSniff + - Typo3Update_Sniffs_Classname_TypeHintCatchExceptionSniff + - Typo3Update_Sniffs_Classname_TypeHintSniff + - Typo3Update_Sniffs_Classname_UseSniff diff --git a/src/Standards/Typo3Update/Configuration/Removed/Classes/7.0.yaml b/src/Standards/Typo3Update/Configuration/Removed/Classes/7.0.yaml new file mode 100644 index 0000000..2341204 --- /dev/null +++ b/src/Standards/Typo3Update/Configuration/Removed/Classes/7.0.yaml @@ -0,0 +1,11 @@ +# Breaking changes in 7.0: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Index.html#breaking-changes +'7.0': + \TYPO3\CMS\Backend\Template\MediumDocumentTemplate: + replacement: 'Use \TYPO3\CMS\Backend\Template\DocumentTemplate instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61782-DeprecatedDocumentTemplateClassesRemoved.html' + \TYPO3\CMS\Backend\Template\SmallDocumentTemplate: + replacement: 'Use \TYPO3\CMS\Backend\Template\DocumentTemplate instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61782-DeprecatedDocumentTemplateClassesRemoved.html' + \TYPO3\CMS\Backend\Template\StandardDocumentTemplate: + replacement: 'Use \TYPO3\CMS\Backend\Template\DocumentTemplate instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61782-DeprecatedDocumentTemplateClassesRemoved.html' diff --git a/src/Standards/Typo3Update/Feature/RemovedByYamlConfiguration.php b/src/Standards/Typo3Update/Feature/RemovedByYamlConfiguration.php new file mode 100644 index 0000000..53f28a5 --- /dev/null +++ b/src/Standards/Typo3Update/Feature/RemovedByYamlConfiguration.php @@ -0,0 +1,294 @@ +<?php +namespace Typo3Update\Sniffs\Removed; + +/* + * Copyright (C) 2017 Daniel Siepmann <coding@daniel-siepmann.de> + * + * 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. + */ + +use PHP_CodeSniffer_File as PhpCsFile; +use PHP_CodeSniffer_Sniff as PhpCsSniff; +use PHP_CodeSniffer_Tokens as Tokens; +use Symfony\Component\Yaml\Yaml; +use Typo3Update\Options; + +/** + * Contains common functionality for removed code like constants or functions. + * + * Removed parts are configured using YAML-Files, for examples see + * src/Standards/Typo3Update/Configuration/Removed/Constants/7.0.yaml Also + * check out the configuration options in Readme.rst. + */ +abstract class AbstractGenericUsage implements PhpCsSniff +{ + use \Typo3Update\Sniffs\ExtendedPhpCsSupportTrait; + + /** + * Configuration to define removed code. + * + * @var array + */ + protected $configured = []; + + /** + * Constant for the current sniff instance. + * @var array + */ + protected $removed = []; + + public function __construct() + { + if ($this->configured === []) { + foreach ($this->getRemovedConfigFiles() as $file) { + $this->configured = array_merge( + $this->configured, + $this->prepareStructure(Yaml::parse(file_get_contents((string) $file))) + ); + } + } + } + + /** + * Return file names containing removed configurations. + * + * @return array<string> + */ + abstract protected function getRemovedConfigFiles(); + + /** + * Prepares structure from config for later usage. + * + * @param array $typo3Versions + * @return array + */ + protected function prepareStructure(array $typo3Versions) + { + $newStructure = []; + + foreach ($typo3Versions as $typo3Version => $removals) { + foreach ($removals as $removed => $config) { + // Split static methods and methods. + $split = preg_split('/::|->/', $removed); + + $newStructure[$removed] = $config; + + $newStructure[$removed]['static'] = strpos($removed, '::') !== false; + $newStructure[$removed]['fqcn'] = null; + $newStructure[$removed]['class'] = null; + $newStructure[$removed]['name'] = $split[0]; + $newStructure[$removed]['version_removed'] = $typo3Version; + + // If split contains two parts, it's a class + if (isset($split[1])) { + $newStructure[$removed]['fqcn'] = $split[0]; + $newStructure[$removed]['class'] = array_slice( + explode('\\', $newStructure[$removed]['fqcn']), + -1 + )[0]; + $newStructure[$removed]['name'] = $split[1]; + } + }; + } + + return $newStructure; + } + + /** + * Processes the tokens that this sniff is interested in. + * + * This is the default implementation, as most of the time next T_STRING is + * the class name. This way only the register method has to be registered + * in default cases. + * + * @param PhpCsFile $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(PhpCsFile $phpcsFile, $stackPtr) + { + if (!$this->isRemoved($phpcsFile, $stackPtr)) { + return; + } + + $this->addMessage($phpcsFile, $stackPtr); + } + + /** + * Check whether the current token is removed. + * + * @param PhpCsFile $phpcsFile + * @param int $stackPtr + * @return bool + */ + protected function isRemoved(PhpCsFile $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + $staticPosition = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true, null, true); + + $name = $tokens[$stackPtr]['content']; + $isStatic = false; + $class = false; + + if ($staticPosition !== false) { + $isStatic = $tokens[$staticPosition]['code'] === T_DOUBLE_COLON; + } + + if ($isStatic) { + $class = $phpcsFile->findPrevious(T_STRING, $staticPosition, null, false, null, true); + if ($class !== false) { + $class = $tokens[$class]['content']; + } + } + + $this->removed = $this->getMatchingRemoved($name, $class, $isStatic); + return $this->removed !== []; + } + + /** + * Returns all matching removed functions for given arguments. + * + * @param string $name + * @param string $className The last part of the class name, splitted by namespaces. + * @param bool $isStatic + * + * @return array + */ + protected function getMatchingRemoved($name, $className, $isStatic) + { + // We will not match any static calls, without the class name, at least for now. + if ($isStatic === true && $className === false) { + return []; + } + + return array_filter( + $this->configured, + function ($config) use ($name, $isStatic, $className) { + return $name === $config['name'] + && $isStatic === $config['static'] + && ( + $className === $config['class'] + || $className === false + ) + ; + } + ); + } + + /** + * Add message for the given token position. + * + * Default is a warning, non fixable. Just overwrite in concrete sniff, if + * something different suites better. + * + * @param PhpCsFile $phpcsFile + * @param int $tokenPosition + * + * @return void + */ + protected function addMessage(PhpCsFile $phpcsFile, $tokenPosition) + { + foreach ($this->removed as $constant) { + $phpcsFile->addWarning( + 'Legacy calls are not allowed; found %s. Removed in %s. %s. See: %s', + $tokenPosition, + $this->getIdentifier($constant), + [ + $this->getOldUsage($constant), + $this->getRemovedVersion($constant), + $this->getReplacement($constant), + $this->getDocsUrl($constant), + ] + ); + } + } + + /** + * Identifier for configuring this specific error / warning through PHPCS. + * + * @param array $config + * + * @return string + */ + protected function getIdentifier(array $config) + { + $name = $config['name']; + if ($config['class']) { + $name = $config['class'] . '.' . $name; + } + + return $name; + } + + /** + * The original call, to allow user to check matches. + * + * As we match the name, that can be provided by multiple classes, you + * should provide an example, so users can check that this is the legacy + * one. + * + * @param array $config + * + * @return string + */ + abstract protected function getOldUsage(array $config); + + /** + * Returns TYPO3 version when the breaking change happened. + * + * To let user decide whether this is important for him. + * + * @param array $config + * + * @return string + */ + protected function getRemovedVersion(array $config) + { + return $config['version_removed']; + } + + /** + * The new call, or information how to migrate. + * + * To provide feedback for user to ease migration. + * + * @param array $config + * + * @return string + */ + protected function getReplacement(array $config) + { + $newCall = $config['replacement']; + if ($newCall !== null) { + return $newCall; + } + return 'There is no replacement, just remove call'; + } + + /** + * Allow user to lookup the official docs related to this deprecation / breaking change. + * + * @param array $config The converted structure for a single constant. + * + * @return string + */ + protected function getDocsUrl(array $config) + { + return $config['docsUrl']; + } +} diff --git a/src/Standards/Typo3Update/Feature/RemovedClassFeature.php b/src/Standards/Typo3Update/Feature/RemovedClassFeature.php new file mode 100644 index 0000000..d81c34d --- /dev/null +++ b/src/Standards/Typo3Update/Feature/RemovedClassFeature.php @@ -0,0 +1,56 @@ +<?php +namespace Typo3Update\Feature; + +/* + * Copyright (C) 2017 Daniel Siepmann <coding@daniel-siepmann.de> + * + * 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. + */ + +use PHP_CodeSniffer as PhpCs; +use PHP_CodeSniffer_File as PhpCsFile; +use PHP_CodeSniffer_Sniff as PhpCsSniff; + +/** + * This feature will add fixable errors for old legacy classnames. + * + * Can be attached to sniffs returning classnames. + */ +class RemovedClassFeature implements FeatureInterface +{ + /** + * Process like a PHPCS Sniff. + * + * @param PhpCsFile $phpcsFile + * @param int $classnamePosition + * @param string $classname + * + * @return void + */ + public function process(PhpCsFile $phpcsFile, $classnamePosition, $classname) + { + if ($this->isClassnameRemoved($classname) === false) { + return; + } + + $phpcsFile->addError( + 'Removed classes are not allowed; found "%s", use "%s" instead', + $classnamePosition, + 'removedClassname', + [$classname] + ); + } +} diff --git a/src/Standards/Typo3Update/Options.php b/src/Standards/Typo3Update/Options.php index 1ce768c..935da03 100644 --- a/src/Standards/Typo3Update/Options.php +++ b/src/Standards/Typo3Update/Options.php @@ -95,6 +95,19 @@ class Options ); } + /** + * Returns an array of absolute file names containing removed class configurations. + * + * @return array<string> + */ + public static function getRemovedClassConfigFiles() + { + return static::getOptionFileNames( + 'removedClassConfigFiles', + __DIR__ . '/../Configuration/Removed/Classes/*.yaml' + ); + } + /** * Get the option by optionName, if not defined, use default. * diff --git a/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.diff b/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.diff index 807e03e..36a8cf7 100644 --- a/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.diff +++ b/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.diff @@ -1,6 +1,6 @@ --- tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/InputFileForIssues.php +++ PHP_CodeSniffer -@@ -22,19 +22,19 @@ +@@ -22,20 +22,20 @@ class InputFileForIssues { /** @@ -13,6 +13,7 @@ /** - * @param t3lib_div + * @param \TYPO3\CMS\Core\Utility\GeneralUtility + * @param \TYPO3\CMS\Backend\Template\MediumDocumentTemplate * - * @return Tx_Extbase_Configuration_Configurationmanager + * @return \TYPO3\CMS\Extbase\Configuration\ConfigurationManager diff --git a/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.json b/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.json index dc72038..c528d04 100644 --- a/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.json +++ b/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.json @@ -21,10 +21,19 @@ "source": "Typo3Update.Classname.PhpDocComment.legacyClassname", "type": "ERROR" }, + { + "column": 15, + "fixable": false, + "line": 32, + "message": "Legacy calls are not allowed; found \\TYPO3\\CMS\\Backend\\Template\\MediumDocumentTemplate. Removed in 7.0. Use \\TYPO3\\CMS\\Backend\\Template\\DocumentTemplate instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61782-DeprecatedDocumentTemplateClassesRemoved.html", + "severity": 5, + "source": "Typo3Update.LegacyClassnames.DocComment.TYPO3_CMS_Backend_Template_MediumDocumentTemplate", + "type": "WARNING" + }, { "column": 16, "fixable": true, - "line": 33, + "line": 34, "message": "Legacy classes are not allowed; found \"Tx_Extbase_Configuration_Configurationmanager\", use \"TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager\" instead", "severity": 5, "source": "Typo3Update.Classname.PhpDocComment.legacyClassname", @@ -33,19 +42,19 @@ { "column": 18, "fixable": true, - "line": 37, + "line": 38, "message": "Legacy classes are not allowed; found \"t3lib_div\", use \"TYPO3\\CMS\\Core\\Utility\\GeneralUtility\" instead", "severity": 5, "source": "Typo3Update.Classname.PhpDocComment.legacyClassname", "type": "ERROR" } ], - "warnings": 0 + "warnings": 1 } }, "totals": { "errors": 4, "fixable": 4, - "warnings": 0 + "warnings": 1 } } diff --git a/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/InputFileForIssues.php b/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/InputFileForIssues.php index 92acefb..7a2de67 100644 --- a/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/InputFileForIssues.php +++ b/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/InputFileForIssues.php @@ -29,6 +29,7 @@ class InputFileForIssues /** * @param t3lib_div + * @param \TYPO3\CMS\Backend\Template\MediumDocumentTemplate * * @return Tx_Extbase_Configuration_Configurationmanager */ -- GitLab From fad2a4e498e11026c99a78e17729e17e6a2f5ce2 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Thu, 27 Apr 2017 11:48:59 +0200 Subject: [PATCH 02/11] FEATURE: Allow empty feature yaml files * Handle empty yaml files for features in options class. --- src/Standards/Typo3Update/Options.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Standards/Typo3Update/Options.php b/src/Standards/Typo3Update/Options.php index 935da03..6db1bd2 100644 --- a/src/Standards/Typo3Update/Options.php +++ b/src/Standards/Typo3Update/Options.php @@ -140,10 +140,11 @@ class Options ); foreach ($fileNames as $file) { - $option = array_merge( - $option, - Yaml::parse(file_get_contents((string) $file)) - ); + $content = Yaml::parse(file_get_contents((string) $file)); + if ($content === null) { + $content = []; + } + $option = array_merge($option, $content); } return $option; -- GitLab From 2659066e2125c83ed0abe09d5d43716215b6c3eb Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Thu, 27 Apr 2017 12:50:10 +0200 Subject: [PATCH 03/11] WIP|TASK: Migrate Typo3Update_Sniffs_Removed_TypoScriptSniff * Refactor yaml based removed check architecture. * Migrate TypoScriptSniff to new architecture. Relates: #71 --- composer.json | 1 + .../Feature/RemovedByYamlConfiguration.php | 294 ------------------ .../RemovedByYamlConfiguration.php | 60 ++++ .../Sniffs/Removed/AbstractGenericUsage.php | 233 ++------------ .../Sniffs/Removed/TypoScriptSniff.php | 47 +-- 5 files changed, 94 insertions(+), 541 deletions(-) delete mode 100644 src/Standards/Typo3Update/Feature/RemovedByYamlConfiguration.php create mode 100644 src/Standards/Typo3Update/RemovedByYamlConfiguration.php diff --git a/composer.json b/composer.json index 6f9a5df..87aab93 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ ] }, "require": { + "php": "~7.1", "helmich/typo3-typoscript-parser": "1.1.*", "squizlabs/php_codesniffer": "2.8.*", "symfony/yaml": "3.2.*", diff --git a/src/Standards/Typo3Update/Feature/RemovedByYamlConfiguration.php b/src/Standards/Typo3Update/Feature/RemovedByYamlConfiguration.php deleted file mode 100644 index 53f28a5..0000000 --- a/src/Standards/Typo3Update/Feature/RemovedByYamlConfiguration.php +++ /dev/null @@ -1,294 +0,0 @@ -<?php -namespace Typo3Update\Sniffs\Removed; - -/* - * Copyright (C) 2017 Daniel Siepmann <coding@daniel-siepmann.de> - * - * 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. - */ - -use PHP_CodeSniffer_File as PhpCsFile; -use PHP_CodeSniffer_Sniff as PhpCsSniff; -use PHP_CodeSniffer_Tokens as Tokens; -use Symfony\Component\Yaml\Yaml; -use Typo3Update\Options; - -/** - * Contains common functionality for removed code like constants or functions. - * - * Removed parts are configured using YAML-Files, for examples see - * src/Standards/Typo3Update/Configuration/Removed/Constants/7.0.yaml Also - * check out the configuration options in Readme.rst. - */ -abstract class AbstractGenericUsage implements PhpCsSniff -{ - use \Typo3Update\Sniffs\ExtendedPhpCsSupportTrait; - - /** - * Configuration to define removed code. - * - * @var array - */ - protected $configured = []; - - /** - * Constant for the current sniff instance. - * @var array - */ - protected $removed = []; - - public function __construct() - { - if ($this->configured === []) { - foreach ($this->getRemovedConfigFiles() as $file) { - $this->configured = array_merge( - $this->configured, - $this->prepareStructure(Yaml::parse(file_get_contents((string) $file))) - ); - } - } - } - - /** - * Return file names containing removed configurations. - * - * @return array<string> - */ - abstract protected function getRemovedConfigFiles(); - - /** - * Prepares structure from config for later usage. - * - * @param array $typo3Versions - * @return array - */ - protected function prepareStructure(array $typo3Versions) - { - $newStructure = []; - - foreach ($typo3Versions as $typo3Version => $removals) { - foreach ($removals as $removed => $config) { - // Split static methods and methods. - $split = preg_split('/::|->/', $removed); - - $newStructure[$removed] = $config; - - $newStructure[$removed]['static'] = strpos($removed, '::') !== false; - $newStructure[$removed]['fqcn'] = null; - $newStructure[$removed]['class'] = null; - $newStructure[$removed]['name'] = $split[0]; - $newStructure[$removed]['version_removed'] = $typo3Version; - - // If split contains two parts, it's a class - if (isset($split[1])) { - $newStructure[$removed]['fqcn'] = $split[0]; - $newStructure[$removed]['class'] = array_slice( - explode('\\', $newStructure[$removed]['fqcn']), - -1 - )[0]; - $newStructure[$removed]['name'] = $split[1]; - } - }; - } - - return $newStructure; - } - - /** - * Processes the tokens that this sniff is interested in. - * - * This is the default implementation, as most of the time next T_STRING is - * the class name. This way only the register method has to be registered - * in default cases. - * - * @param PhpCsFile $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(PhpCsFile $phpcsFile, $stackPtr) - { - if (!$this->isRemoved($phpcsFile, $stackPtr)) { - return; - } - - $this->addMessage($phpcsFile, $stackPtr); - } - - /** - * Check whether the current token is removed. - * - * @param PhpCsFile $phpcsFile - * @param int $stackPtr - * @return bool - */ - protected function isRemoved(PhpCsFile $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - $staticPosition = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true, null, true); - - $name = $tokens[$stackPtr]['content']; - $isStatic = false; - $class = false; - - if ($staticPosition !== false) { - $isStatic = $tokens[$staticPosition]['code'] === T_DOUBLE_COLON; - } - - if ($isStatic) { - $class = $phpcsFile->findPrevious(T_STRING, $staticPosition, null, false, null, true); - if ($class !== false) { - $class = $tokens[$class]['content']; - } - } - - $this->removed = $this->getMatchingRemoved($name, $class, $isStatic); - return $this->removed !== []; - } - - /** - * Returns all matching removed functions for given arguments. - * - * @param string $name - * @param string $className The last part of the class name, splitted by namespaces. - * @param bool $isStatic - * - * @return array - */ - protected function getMatchingRemoved($name, $className, $isStatic) - { - // We will not match any static calls, without the class name, at least for now. - if ($isStatic === true && $className === false) { - return []; - } - - return array_filter( - $this->configured, - function ($config) use ($name, $isStatic, $className) { - return $name === $config['name'] - && $isStatic === $config['static'] - && ( - $className === $config['class'] - || $className === false - ) - ; - } - ); - } - - /** - * Add message for the given token position. - * - * Default is a warning, non fixable. Just overwrite in concrete sniff, if - * something different suites better. - * - * @param PhpCsFile $phpcsFile - * @param int $tokenPosition - * - * @return void - */ - protected function addMessage(PhpCsFile $phpcsFile, $tokenPosition) - { - foreach ($this->removed as $constant) { - $phpcsFile->addWarning( - 'Legacy calls are not allowed; found %s. Removed in %s. %s. See: %s', - $tokenPosition, - $this->getIdentifier($constant), - [ - $this->getOldUsage($constant), - $this->getRemovedVersion($constant), - $this->getReplacement($constant), - $this->getDocsUrl($constant), - ] - ); - } - } - - /** - * Identifier for configuring this specific error / warning through PHPCS. - * - * @param array $config - * - * @return string - */ - protected function getIdentifier(array $config) - { - $name = $config['name']; - if ($config['class']) { - $name = $config['class'] . '.' . $name; - } - - return $name; - } - - /** - * The original call, to allow user to check matches. - * - * As we match the name, that can be provided by multiple classes, you - * should provide an example, so users can check that this is the legacy - * one. - * - * @param array $config - * - * @return string - */ - abstract protected function getOldUsage(array $config); - - /** - * Returns TYPO3 version when the breaking change happened. - * - * To let user decide whether this is important for him. - * - * @param array $config - * - * @return string - */ - protected function getRemovedVersion(array $config) - { - return $config['version_removed']; - } - - /** - * The new call, or information how to migrate. - * - * To provide feedback for user to ease migration. - * - * @param array $config - * - * @return string - */ - protected function getReplacement(array $config) - { - $newCall = $config['replacement']; - if ($newCall !== null) { - return $newCall; - } - return 'There is no replacement, just remove call'; - } - - /** - * Allow user to lookup the official docs related to this deprecation / breaking change. - * - * @param array $config The converted structure for a single constant. - * - * @return string - */ - protected function getDocsUrl(array $config) - { - return $config['docsUrl']; - } -} diff --git a/src/Standards/Typo3Update/RemovedByYamlConfiguration.php b/src/Standards/Typo3Update/RemovedByYamlConfiguration.php new file mode 100644 index 0000000..f1ab402 --- /dev/null +++ b/src/Standards/Typo3Update/RemovedByYamlConfiguration.php @@ -0,0 +1,60 @@ +<?php +namespace Typo3Update; + +/* + * Copyright (C) 2017 Daniel Siepmann <coding@daniel-siepmann.de> + * + * 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. + */ + +use Symfony\Component\Yaml\Yaml; + +class RemovedByYamlConfiguration +{ + /** + * Configuration to define removed code. + * + * @var array + */ + protected $configured = []; + + public function __construct(array $configFiles, $prepareStructure) + { + foreach ($configFiles as $file) { + $this->configured = array_merge( + $this->configured, + $prepareStructure(Yaml::parse(file_get_contents((string) $file))) + ); + } + } + + public function isRemoved($identifier) + { + return isset($this->configured[$identifier]); + } + + public function getRemoved($identifier) + { + if (!$this->isRemoved($identifier)) { + throw new \Exception( + sprintf('Identifier "%s" is not configured to be removed.', $identifier), + 1493289133 + ); + } + + return $this->configured[$identifier]; + } +} diff --git a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php index 3cda85a..f8e8e0a 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php @@ -22,9 +22,7 @@ namespace Typo3Update\Sniffs\Removed; use PHP_CodeSniffer_File as PhpCsFile; use PHP_CodeSniffer_Sniff as PhpCsSniff; -use PHP_CodeSniffer_Tokens as Tokens; -use Symfony\Component\Yaml\Yaml; -use Typo3Update\Options; +use Typo3Update\RemovedByYamlConfiguration; /** * Contains common functionality for removed code like constants or functions. @@ -35,233 +33,60 @@ use Typo3Update\Options; */ abstract class AbstractGenericUsage implements PhpCsSniff { - use \Typo3Update\Sniffs\ExtendedPhpCsSupportTrait; - - /** - * Configuration to define removed code. - * - * @var array - */ - protected $configured = []; - - /** - * Entries removed in current sniff. - * @var array - */ - protected $removed = []; + protected $configured; public function __construct() { - if ($this->configured === []) { - foreach ($this->getRemovedConfigFiles() as $file) { - $this->configured = array_merge( - $this->configured, - $this->prepareStructure(Yaml::parse(file_get_contents((string) $file))) - ); - } - } + $this->configured = new RemovedByYamlConfiguration( + $this->getRemovedConfigFiles(), + \Closure::fromCallable([$this, 'prepareStructure']) + ); } - /** - * Return file names containing removed configurations. - * - * @return array<string> - */ - abstract protected function getRemovedConfigFiles(); - /** * Prepares structure from config for later usage. * * @param array $typo3Versions * @return array */ - protected function prepareStructure(array $typo3Versions) - { - $newStructure = []; - - foreach ($typo3Versions as $typo3Version => $removals) { - foreach ($removals as $removed => $config) { - // Split static methods and methods. - $split = preg_split('/::|->/', $removed); - - $newStructure[$removed] = $config; - - $newStructure[$removed]['static'] = strpos($removed, '::') !== false; - $newStructure[$removed]['fqcn'] = null; - $newStructure[$removed]['class'] = null; - $newStructure[$removed]['name'] = $split[0]; - $newStructure[$removed]['version_removed'] = $typo3Version; - - // If split contains two parts, it's a class - if (isset($split[1])) { - $newStructure[$removed]['fqcn'] = $split[0]; - $newStructure[$removed]['class'] = array_slice( - explode('\\', $newStructure[$removed]['fqcn']), - -1 - )[0]; - $newStructure[$removed]['name'] = $split[1]; - } - } - } - - return $newStructure; - } + abstract protected function prepareStructure(array $typo3Versions); /** - * Processes the tokens that this sniff is interested in. - * - * This is the default implementation, as most of the time next T_STRING is - * the class name. This way only the register method has to be registered - * in default cases. - * - * @param PhpCsFile $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(PhpCsFile $phpcsFile, $stackPtr) - { - if (!$this->isRemoved($phpcsFile, $stackPtr)) { - return; - } - - $this->addMessage($phpcsFile, $stackPtr); - } - - /** - * Check whether the current token is removed. + * Return file names containing removed configurations. * - * @param PhpCsFile $phpcsFile - * @param int $stackPtr - * @return bool + * @return array<string> */ - protected function isRemoved(PhpCsFile $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - $staticPosition = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true, null, true); - - $name = $tokens[$stackPtr]['content']; - $isStatic = false; - $class = false; - - if ($staticPosition !== false) { - $isStatic = $tokens[$staticPosition]['code'] === T_DOUBLE_COLON; - } - - if ($isStatic) { - $class = $phpcsFile->findPrevious(T_STRING, $staticPosition, null, false, null, true); - if ($class !== false) { - $class = $tokens[$class]['content']; - } - } + abstract protected function getRemovedConfigFiles(); - $this->removed = $this->getMatchingRemoved($name, $class, $isStatic); - return $this->removed !== []; - } + abstract protected function findRemoved(PhpCsFile $phpcsFile, $stackPtr); - /** - * Returns all matching removed functions for given arguments. - * - * @param string $name - * @param string $className The last part of the class name, splitted by namespaces. - * @param bool $isStatic - * - * @return array - */ - protected function getMatchingRemoved($name, $className, $isStatic) + public function process(PhpCsFile $phpcsFile, $stackPtr) { - // We will not match any static calls, without the class name, at least for now. - if ($isStatic === true && $className === false) { - return []; + $removed = $this->findRemoved($phpcsFile, $stackPtr); + if ($removed === []) { + return; } - return array_filter( - $this->configured, - function ($config) use ($name, $isStatic, $className) { - return $name === $config['name'] - && $isStatic === $config['static'] - && ( - $className === $config['class'] - || $className === false - ) - ; - } - ); + $this->addMessage($removed); } - /** - * Add message for the given token position. - * - * Default is a warning, non fixable. Just overwrite in concrete sniff, if - * something different suites better. - * - * @param PhpCsFile $phpcsFile - * @param int $tokenPosition - * - * @return void - */ - protected function addMessage(PhpCsFile $phpcsFile, $tokenPosition) + protected function addMessage(array $removed) { - foreach ($this->removed as $removed) { + foreach ($removed as $removed) { $phpcsFile->addWarning( - 'Legacy calls are not allowed; found %s. Removed in %s. %s. See: %s', + 'Calls to removed code are not allowed; found %s. Removed in %s. %s. See: %s', $tokenPosition, - $this->getIdentifier($removed), + $removed['identifier'], [ - $this->getOldUsage($removed), - $this->getRemovedVersion($removed), + $removed['oldUsage'], + $removed['versionRemoved'], $this->getReplacement($removed), - $this->getDocsUrl($removed), + $removed['docsUrl'], ] ); } } - /** - * Identifier for configuring this specific error / warning through PHPCS. - * - * @param array $config - * - * @return string - */ - protected function getIdentifier(array $config) - { - $name = $config['name']; - if ($config['class']) { - $name = $config['class'] . '.' . $name; - } - - return $name; - } - - /** - * The original call, to allow user to check matches. - * - * As we match the name, that can be provided by multiple classes, you - * should provide an example, so users can check that this is the legacy - * one. - * - * @param array $config - * - * @return string - */ - abstract protected function getOldUsage(array $config); - - /** - * Returns TYPO3 version when the breaking change happened. - * - * To let user decide whether this is important for him. - * - * @param array $config - * - * @return string - */ - protected function getRemovedVersion(array $config) - { - return $config['version_removed']; - } - /** * The new call, or information how to migrate. * @@ -279,16 +104,4 @@ abstract class AbstractGenericUsage implements PhpCsSniff } return 'There is no replacement, just remove call'; } - - /** - * Allow user to lookup the official docs related to this deprecation / breaking change. - * - * @param array $config - * - * @return string - */ - protected function getDocsUrl(array $config) - { - return $config['docsUrl']; - } } diff --git a/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php b/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php index 98c0cca..739f21a 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php @@ -59,7 +59,6 @@ class Typo3Update_Sniffs_Removed_TypoScriptSniff extends AbstractGenericUsage protected function prepareStructure(array $typo3Versions) { $newStructure = []; - foreach ($typo3Versions as $typo3Version => $removals) { foreach ($removals as $removed => $config) { $config['type'] = TokenInterface::TYPE_OBJECT_IDENTIFIER; @@ -70,7 +69,9 @@ class Typo3Update_Sniffs_Removed_TypoScriptSniff extends AbstractGenericUsage } $config['name'] = $removed; - $config['version_removed'] = $typo3Version; + $config['identifier'] = str_replace('.', '-', $removed); + $config['versionRemoved'] = $typo3Version; + $config['oldUsage'] = $removed; $newStructure[$removed] = $config; } @@ -86,48 +87,20 @@ class Typo3Update_Sniffs_Removed_TypoScriptSniff extends AbstractGenericUsage * @param int $stackPtr * @return bool */ - protected function isRemoved(PhpCsFile $phpcsFile, $stackPtr) + protected function findRemoved(PhpCsFile $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $token = $tokens[$stackPtr]; $objectIdentifier = $token['content']; - if (isset($this->configured[$objectIdentifier]) && $token['type'] === $this->configured[$objectIdentifier]['type']) { - $this->removed = [ - $this->configured[$objectIdentifier] - ]; - return true; + if (!$this->configured->isRemoved($objectIdentifier)) { + return []; } - return false; - } - - /** - * Identifier for configuring this specific error / warning through PHPCS. - * - * @param array $config - * - * @return string - */ - protected function getIdentifier(array $config) - { - return str_replace('.', '-', $config['name']); - } - - /** - * The original call, to allow user to check matches. - * - * As we match the name, that can be provided by multiple classes, you - * should provide an example, so users can check that this is the legacy - * one. - * - * @param array $config - * - * @return string - */ - protected function getOldUsage(array $config) - { - return $config['name']; + $removed = $this->configured->getRemoved($objectIdentifier); + if ($token['type'] === $removed['type']) { + return [$removed]; + } } /** -- GitLab From 5704351d22dd91aac9a57402bb1f9191f18ec9b6 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Thu, 27 Apr 2017 12:53:07 +0200 Subject: [PATCH 04/11] TASK: Adjust to PHP 7.1 * As PHP 7.1 is required, document and adjust tests in CI. Relates: #71 --- .gitlab-ci.yml | 10 +++------- Documentation/source/index.rst | 2 ++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 88d1918..202f4e0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,7 +27,7 @@ sync:github: - git push --mirror ${MIRROR_GIT_URL} lint:coding-guideline: &PHP-LINTING - image: php:7.0-alpine + image: php:7.1-alpine stage: test script: - ./vendor/bin/phpcs -s -n --report-full=result/phpcs-full.txt --report-diff=result/phpcs-diff.txt --report-summary=result/phpcs-summary.txt @@ -41,16 +41,12 @@ lint:php-mass-detection: script: - ./vendor/bin/phpmd src text phpmd.xml > result/phpmd.txt -test:5.6: &PHP-UNITTESTING - image: php:5.6-alpine +test:7.1: &PHP-UNITTESTING + image: php:7.1-alpine stage: test script: - ./vendor/bin/phpunit -test:7.0: - <<: *PHP-UNITTESTING - image: php:7.0-alpine - test:latest: <<: *PHP-UNITTESTING image: php:7-alpine diff --git a/Documentation/source/index.rst b/Documentation/source/index.rst index 93ec3be..709f4ec 100644 --- a/Documentation/source/index.rst +++ b/Documentation/source/index.rst @@ -19,6 +19,8 @@ Requirements To install the project you need ``composer`` to be installed and inside your ``$PATH``. Otherwise run ``make install-composer`` to install composer. +At least PHP 7.1 is required. + Installation ============ -- GitLab From 84dd380a3ce64547f80a71277229ea3a5294db41 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Thu, 27 Apr 2017 13:23:51 +0200 Subject: [PATCH 05/11] TASK: Migrate GenericFunctionCallSniff * Migrate GenericFunctionCallSniff to new architecture. * Provide new abstract class for php removed functions and constants. * Fix TypoScriptSniff not always returning array. * Adjust warnings in Expected.json Relates: #71 --- .../RemovedByYamlConfiguration.php | 5 + .../Removed/AbstractGenericPhpUsage.php | 141 ++++++++++++++++++ .../Sniffs/Removed/AbstractGenericUsage.php | 14 +- .../Removed/GenericFunctionCallSniff.php | 49 +----- .../Sniffs/Removed/TypoScriptSniff.php | 2 + .../GenericConstantUsageSniff/Expected.json | 10 +- .../GenericFunctionCallSniff/Expected.json | 10 +- .../Removed/TypoScriptSniff/Expected.json | 18 +-- 8 files changed, 176 insertions(+), 73 deletions(-) create mode 100644 src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php diff --git a/src/Standards/Typo3Update/RemovedByYamlConfiguration.php b/src/Standards/Typo3Update/RemovedByYamlConfiguration.php index f1ab402..a527e43 100644 --- a/src/Standards/Typo3Update/RemovedByYamlConfiguration.php +++ b/src/Standards/Typo3Update/RemovedByYamlConfiguration.php @@ -46,6 +46,11 @@ class RemovedByYamlConfiguration return isset($this->configured[$identifier]); } + public function getAllRemoved() + { + return $this->configured; + } + public function getRemoved($identifier) { if (!$this->isRemoved($identifier)) { diff --git a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php new file mode 100644 index 0000000..d93645f --- /dev/null +++ b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php @@ -0,0 +1,141 @@ +<?php +namespace Typo3Update\Sniffs\Removed; + +/* + * Copyright (C) 2017 Daniel Siepmann <coding@daniel-siepmann.de> + * + * 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. + */ + +use PHP_CodeSniffer_File as PhpCsFile; +use Typo3Update\Sniffs\ExtendedPhpCsSupportTrait; + +abstract class AbstractGenericPhpUsage extends AbstractGenericUsage +{ + use ExtendedPhpCsSupportTrait; + + protected function prepareStructure(array $typo3Versions) + { + $newStructure = []; + + foreach ($typo3Versions as $typo3Version => $removals) { + foreach ($removals as $removed => $config) { + $newStructure[$removed] = $config; + + $newStructure[$removed]['fqcn'] = null; + $newStructure[$removed]['class'] = null; + $newStructure[$removed]['versionRemoved'] = $typo3Version; + + $this->handleStatic($removed, $newStructure[$removed]); + + $newStructure[$removed]['oldUsage'] = $this->getOldUsage($newStructure[$removed]); + $newStructure[$removed]['identifier'] = $this->getIdentifier($newStructure[$removed]); + }; + } + + return $newStructure; + } + + protected function findRemoved(PhpCsFile $phpcsFile, $stackPtr) + { + if (!$this->isFunctionCall($phpcsFile, $stackPtr)) { + return []; + } + + $tokens = $phpcsFile->getTokens(); + $staticPosition = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true, null, true); + + $name = $tokens[$stackPtr]['content']; + $isStatic = false; + $class = false; + + if ($staticPosition !== false) { + $isStatic = $tokens[$staticPosition]['code'] === T_DOUBLE_COLON; + } + + if ($isStatic) { + $class = $phpcsFile->findPrevious(T_STRING, $staticPosition, null, false, null, true); + if ($class !== false) { + $class = $tokens[$class]['content']; + } + } + + return $this->getMatchingRemoved($name, $class, $isStatic); + } + + /** + * Returns all matching removed functions for given arguments. + * + * @param string $name + * @param string $className The last part of the class name, splitted by namespaces. + * @param bool $isStatic + * + * @return array + */ + protected function getMatchingRemoved($name, $className, $isStatic) + { + // We will not match any static calls, without the class name, at least for now. + if ($isStatic === true && $className === false) { + return []; + } + + return array_filter( + $this->configured->getAllRemoved(), + function ($config) use ($name, $isStatic, $className) { + return $name === $config['name'] + && $isStatic === $config['static'] + && ( + $className === $config['class'] + || $className === false + ) + ; + } + ); + } + + protected function handleStatic($identifier, array &$config) + { + $split = preg_split('/::|->/', $identifier); + + $config['name'] = $split[0]; + $config['static'] = strpos($identifier, '::') !== false; + + if (isset($split[1])) { + $config['fqcn'] = $split[0]; + $config['class'] = array_slice(explode('\\', $config['fqcn']), -1)[0]; + $config['name'] = $split[1]; + } + } + + protected function getOldUsage(array $config) + { + $concat = '->'; + if ($config['static']) { + $concat = '::'; + } + return $config['fqcn'] . $concat . $config['name']; + } + + protected function getIdentifier(array $config) + { + $name = $config['name']; + if ($config['class']) { + $name = $config['class'] . '.' . $name; + } + + return $name; + } +} diff --git a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php index f8e8e0a..ff67d4f 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php @@ -62,20 +62,10 @@ abstract class AbstractGenericUsage implements PhpCsSniff public function process(PhpCsFile $phpcsFile, $stackPtr) { - $removed = $this->findRemoved($phpcsFile, $stackPtr); - if ($removed === []) { - return; - } - - $this->addMessage($removed); - } - - protected function addMessage(array $removed) - { - foreach ($removed as $removed) { + foreach ($this->findRemoved($phpcsFile, $stackPtr) as $removed) { $phpcsFile->addWarning( 'Calls to removed code are not allowed; found %s. Removed in %s. %s. See: %s', - $tokenPosition, + $stackPtr, $removed['identifier'], [ $removed['oldUsage'], diff --git a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php index 4124eb2..7fa8a12 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php @@ -19,26 +19,15 @@ * 02110-1301, USA. */ -use PHP_CodeSniffer_File as PhpCsFile; use PHP_CodeSniffer_Tokens as Tokens; -use Typo3Update\Sniffs\Removed\AbstractGenericUsage; +use Typo3Update\Sniffs\Removed\AbstractGenericPhpUsage; use Typo3Update\Options; /** * Sniff that handles all calls to removed functions. */ -class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff extends AbstractGenericUsage +class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff extends AbstractGenericPhpUsage { - /** - * Return file names containing removed configurations. - * - * @return array<string> - */ - protected function getRemovedConfigFiles() - { - return Options::getRemovedFunctionConfigFiles(); - } - /** * Returns the token types that this sniff is interested in. * @@ -46,40 +35,16 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff extends AbstractGeneri */ public function register() { - return Tokens::$functionNameTokens; + return [T_STRING]; } /** - * Check whether function at given point is removed. - * - * @return bool - */ - protected function isRemoved(PhpCsFile $phpcsFile, $stackPtr) - { - if (!$this->isFunctionCall($phpcsFile, $stackPtr)) { - return false; - } - - return parent::isRemoved($phpcsFile, $stackPtr); - } - - /** - * The original function call, to allow user to check matches. - * - * As we match the function name, that can be provided by multiple classes, - * you should provide an example, so users can check that this is the - * legacy one. - * - * @param array $config The converted structure for a single function. + * Return file names containing removed configurations. * - * @return string + * @return array<string> */ - protected function getOldUsage(array $config) + protected function getRemovedConfigFiles() { - $concat = '->'; - if ($config['static']) { - $concat = '::'; - } - return $config['fqcn'] . $concat . $config['name']; + return Options::getRemovedFunctionConfigFiles(); } } diff --git a/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php b/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php index 739f21a..419b55a 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php @@ -101,6 +101,8 @@ class Typo3Update_Sniffs_Removed_TypoScriptSniff extends AbstractGenericUsage if ($token['type'] === $removed['type']) { return [$removed]; } + + return []; } /** diff --git a/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/GenericConstantUsageSniff/Expected.json b/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/GenericConstantUsageSniff/Expected.json index e3072f3..6d0f5d6 100644 --- a/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/GenericConstantUsageSniff/Expected.json +++ b/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/GenericConstantUsageSniff/Expected.json @@ -7,7 +7,7 @@ "column": 9, "fixable": false, "line": 22, - "message": "Legacy calls are not allowed; found constant PATH_tslib. Removed in 7.0. The folder and constant no longer exist. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61459-RemovalTslib.html", + "message": "Calls to removed code are not allowed; found constant PATH_tslib. Removed in 7.0. The folder and constant no longer exist. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61459-RemovalTslib.html", "severity": 5, "source": "Typo3Update.Removed.GenericConstantUsage.PATH_tslib", "type": "WARNING" @@ -16,7 +16,7 @@ "column": 11, "fixable": false, "line": 23, - "message": "Legacy calls are not allowed; found constant TYPO3_MOD_PATH. Removed in 7.4. It is required to route modules through typo3/mod.php from now on in case the module relies on the definition of those constants. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.4/Breaking-67987-RemovedEntryScriptHandling.html", + "message": "Calls to removed code are not allowed; found constant TYPO3_MOD_PATH. Removed in 7.4. It is required to route modules through typo3/mod.php from now on in case the module relies on the definition of those constants. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.4/Breaking-67987-RemovedEntryScriptHandling.html", "severity": 5, "source": "Typo3Update.Removed.GenericConstantUsage.TYPO3_MOD_PATH", "type": "WARNING" @@ -25,7 +25,7 @@ "column": 75, "fixable": false, "line": 24, - "message": "Legacy calls are not allowed; found constant \\TYPO3\\CMS\\IndexedSearch\\Controller\\SearchFormController::WILDCARD_LEFT. Removed in 7.6. Use \\TYPO3\\CMS\\IndexedSearch\\Utility\\LikeWildcard::LEFT instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.6/Breaking-69227-StringsForLikeAreNotProperlyEscaped.html", + "message": "Calls to removed code are not allowed; found constant \\TYPO3\\CMS\\IndexedSearch\\Controller\\SearchFormController::WILDCARD_LEFT. Removed in 7.6. Use \\TYPO3\\CMS\\IndexedSearch\\Utility\\LikeWildcard::LEFT instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.6/Breaking-69227-StringsForLikeAreNotProperlyEscaped.html", "severity": 5, "source": "Typo3Update.Removed.GenericConstantUsage.SearchFormController.WILDCARD_LEFT", "type": "WARNING" @@ -34,7 +34,7 @@ "column": 39, "fixable": false, "line": 27, - "message": "Legacy calls are not allowed; found constant \\TYPO3\\CMS\\IndexedSearch\\Controller\\SearchFormController::WILDCARD_LEFT. Removed in 7.6. Use \\TYPO3\\CMS\\IndexedSearch\\Utility\\LikeWildcard::LEFT instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.6/Breaking-69227-StringsForLikeAreNotProperlyEscaped.html", + "message": "Calls to removed code are not allowed; found constant \\TYPO3\\CMS\\IndexedSearch\\Controller\\SearchFormController::WILDCARD_LEFT. Removed in 7.6. Use \\TYPO3\\CMS\\IndexedSearch\\Utility\\LikeWildcard::LEFT instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.6/Breaking-69227-StringsForLikeAreNotProperlyEscaped.html", "severity": 5, "source": "Typo3Update.Removed.GenericConstantUsage.SearchFormController.WILDCARD_LEFT", "type": "WARNING" @@ -43,7 +43,7 @@ "column": 66, "fixable": false, "line": 29, - "message": "Legacy calls are not allowed; found constant \\TYPO3\\CMS\\IndexedSearch\\Controller\\SearchFormController::WILDCARD_LEFT. Removed in 7.6. Use \\TYPO3\\CMS\\IndexedSearch\\Utility\\LikeWildcard::LEFT instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.6/Breaking-69227-StringsForLikeAreNotProperlyEscaped.html", + "message": "Calls to removed code are not allowed; found constant \\TYPO3\\CMS\\IndexedSearch\\Controller\\SearchFormController::WILDCARD_LEFT. Removed in 7.6. Use \\TYPO3\\CMS\\IndexedSearch\\Utility\\LikeWildcard::LEFT instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.6/Breaking-69227-StringsForLikeAreNotProperlyEscaped.html", "severity": 5, "source": "Typo3Update.Removed.GenericConstantUsage.SearchFormController.WILDCARD_LEFT", "type": "WARNING" diff --git a/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff/Expected.json b/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff/Expected.json index f2e61ab..a818be1 100644 --- a/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff/Expected.json +++ b/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff/Expected.json @@ -7,7 +7,7 @@ "column": 41, "fixable": false, "line": 24, - "message": "Legacy calls are not allowed; found \\TYPO3\\CMS\\Core\\Utility\\GeneralUtility::loadTCA. Removed in 7.0. There is no replacement, just remove call. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61785-LoadTcaFunctionRemoved.html", + "message": "Calls to removed code are not allowed; found \\TYPO3\\CMS\\Core\\Utility\\GeneralUtility::loadTCA. Removed in 7.0. There is no replacement, just remove call. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61785-LoadTcaFunctionRemoved.html", "severity": 5, "source": "Typo3Update.Removed.GenericFunctionCall.GeneralUtility.loadTCA", "type": "WARNING" @@ -16,7 +16,7 @@ "column": 17, "fixable": false, "line": 26, - "message": "Legacy calls are not allowed; found \\TYPO3\\CMS\\Core\\Utility\\GeneralUtility::loadTCA. Removed in 7.0. There is no replacement, just remove call. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61785-LoadTcaFunctionRemoved.html", + "message": "Calls to removed code are not allowed; found \\TYPO3\\CMS\\Core\\Utility\\GeneralUtility::loadTCA. Removed in 7.0. There is no replacement, just remove call. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61785-LoadTcaFunctionRemoved.html", "severity": 5, "source": "Typo3Update.Removed.GenericFunctionCall.GeneralUtility.loadTCA", "type": "WARNING" @@ -25,7 +25,7 @@ "column": 44, "fixable": false, "line": 28, - "message": "Legacy calls are not allowed; found \\TYPO3\\CMS\\Core\\Utility\\GeneralUtility::loadTCA. Removed in 7.0. There is no replacement, just remove call. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61785-LoadTcaFunctionRemoved.html", + "message": "Calls to removed code are not allowed; found \\TYPO3\\CMS\\Core\\Utility\\GeneralUtility::loadTCA. Removed in 7.0. There is no replacement, just remove call. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61785-LoadTcaFunctionRemoved.html", "severity": 5, "source": "Typo3Update.Removed.GenericFunctionCall.GeneralUtility.loadTCA", "type": "WARNING" @@ -34,7 +34,7 @@ "column": 8, "fixable": false, "line": 31, - "message": "Legacy calls are not allowed; found \\TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController->includeTCA. Removed in 7.0. Full TCA is always loaded during bootstrap in FE, the method is obsolete. If an eid script calls this method to load TCA, use \\TYPO3\\CMS\\Frontend\\Utility\\EidUtility::initTCA() instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61785-FrontendTcaFunctionsRemoved.html", + "message": "Calls to removed code are not allowed; found \\TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController->includeTCA. Removed in 7.0. Full TCA is always loaded during bootstrap in FE, the method is obsolete. If an eid script calls this method to load TCA, use \\TYPO3\\CMS\\Frontend\\Utility\\EidUtility::initTCA() instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61785-FrontendTcaFunctionsRemoved.html", "severity": 5, "source": "Typo3Update.Removed.GenericFunctionCall.TypoScriptFrontendController.includeTCA", "type": "WARNING" @@ -43,7 +43,7 @@ "column": 17, "fixable": false, "line": 35, - "message": "Legacy calls are not allowed; found \\TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController->includeTCA. Removed in 7.0. Full TCA is always loaded during bootstrap in FE, the method is obsolete. If an eid script calls this method to load TCA, use \\TYPO3\\CMS\\Frontend\\Utility\\EidUtility::initTCA() instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61785-FrontendTcaFunctionsRemoved.html", + "message": "Calls to removed code are not allowed; found \\TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController->includeTCA. Removed in 7.0. Full TCA is always loaded during bootstrap in FE, the method is obsolete. If an eid script calls this method to load TCA, use \\TYPO3\\CMS\\Frontend\\Utility\\EidUtility::initTCA() instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61785-FrontendTcaFunctionsRemoved.html", "severity": 5, "source": "Typo3Update.Removed.GenericFunctionCall.TypoScriptFrontendController.includeTCA", "type": "WARNING" diff --git a/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff/Expected.json b/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff/Expected.json index ff6e6bd..e66a962 100644 --- a/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff/Expected.json +++ b/tests/Fixtures/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff/Expected.json @@ -7,7 +7,7 @@ "column": 10, "fixable": false, "line": 2, - "message": "Legacy calls are not allowed; found styles.insertContent. Removed in 7.0. Either remove usage of styles.insertContent or add a snippet at an early point in TypoScript for backwards compatibility. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-42543-DefaultTypoScriptRemoved.html", + "message": "Calls to removed code are not allowed; found styles.insertContent. Removed in 7.0. Either remove usage of styles.insertContent or add a snippet at an early point in TypoScript for backwards compatibility. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-42543-DefaultTypoScriptRemoved.html", "severity": 5, "source": "Typo3Update.Removed.TypoScript.styles-insertContent", "type": "WARNING" @@ -16,7 +16,7 @@ "column": 11, "fixable": false, "line": 3, - "message": "Legacy calls are not allowed; found styles.insertContent. Removed in 7.0. Either remove usage of styles.insertContent or add a snippet at an early point in TypoScript for backwards compatibility. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-42543-DefaultTypoScriptRemoved.html", + "message": "Calls to removed code are not allowed; found styles.insertContent. Removed in 7.0. Either remove usage of styles.insertContent or add a snippet at an early point in TypoScript for backwards compatibility. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-42543-DefaultTypoScriptRemoved.html", "severity": 5, "source": "Typo3Update.Removed.TypoScript.styles-insertContent", "type": "WARNING" @@ -25,7 +25,7 @@ "column": 1, "fixable": false, "line": 6, - "message": "Legacy calls are not allowed; found styles.insertContent. Removed in 7.0. Either remove usage of styles.insertContent or add a snippet at an early point in TypoScript for backwards compatibility. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-42543-DefaultTypoScriptRemoved.html", + "message": "Calls to removed code are not allowed; found styles.insertContent. Removed in 7.0. Either remove usage of styles.insertContent or add a snippet at an early point in TypoScript for backwards compatibility. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-42543-DefaultTypoScriptRemoved.html", "severity": 5, "source": "Typo3Update.Removed.TypoScript.styles-insertContent", "type": "WARNING" @@ -34,7 +34,7 @@ "column": 1, "fixable": false, "line": 13, - "message": "Legacy calls are not allowed; found mod.web_list.alternateBgColors. Removed in 7.0. Removed without substitution. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-53658-RemoveAlternateBgColorsOption.html", + "message": "Calls to removed code are not allowed; found mod.web_list.alternateBgColors. Removed in 7.0. Removed without substitution. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-53658-RemoveAlternateBgColorsOption.html", "severity": 5, "source": "Typo3Update.Removed.TypoScript.mod-web_list-alternateBgColors", "type": "WARNING" @@ -43,7 +43,7 @@ "column": 10, "fixable": false, "line": 26, - "message": "Legacy calls are not allowed; found CLEARGIF. Removed in 7.1. Any installation should migrate to alternatives such as FLUIDTEMPLATE to customize the output of the content. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.1/Breaking-64639-RemovedContentObjects.html", + "message": "Calls to removed code are not allowed; found CLEARGIF. Removed in 7.1. Any installation should migrate to alternatives such as FLUIDTEMPLATE to customize the output of the content. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.1/Breaking-64639-RemovedContentObjects.html", "severity": 5, "source": "Typo3Update.Removed.TypoScript.CLEARGIF", "type": "WARNING" @@ -52,7 +52,7 @@ "column": 10, "fixable": false, "line": 27, - "message": "Legacy calls are not allowed; found COLUMNS. Removed in 7.1. Any installation should migrate to alternatives such as FLUIDTEMPLATE to customize the output of the content. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.1/Breaking-64639-RemovedContentObjects.html", + "message": "Calls to removed code are not allowed; found COLUMNS. Removed in 7.1. Any installation should migrate to alternatives such as FLUIDTEMPLATE to customize the output of the content. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.1/Breaking-64639-RemovedContentObjects.html", "severity": 5, "source": "Typo3Update.Removed.TypoScript.COLUMNS", "type": "WARNING" @@ -61,7 +61,7 @@ "column": 10, "fixable": false, "line": 28, - "message": "Legacy calls are not allowed; found CTABLE. Removed in 7.1. Any installation should migrate to alternatives such as FLUIDTEMPLATE to customize the output of the content. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.1/Breaking-64639-RemovedContentObjects.html", + "message": "Calls to removed code are not allowed; found CTABLE. Removed in 7.1. Any installation should migrate to alternatives such as FLUIDTEMPLATE to customize the output of the content. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.1/Breaking-64639-RemovedContentObjects.html", "severity": 5, "source": "Typo3Update.Removed.TypoScript.CTABLE", "type": "WARNING" @@ -70,7 +70,7 @@ "column": 10, "fixable": false, "line": 29, - "message": "Legacy calls are not allowed; found OTABLE. Removed in 7.1. Any installation should migrate to alternatives such as FLUIDTEMPLATE to customize the output of the content. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.1/Breaking-64639-RemovedContentObjects.html", + "message": "Calls to removed code are not allowed; found OTABLE. Removed in 7.1. Any installation should migrate to alternatives such as FLUIDTEMPLATE to customize the output of the content. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.1/Breaking-64639-RemovedContentObjects.html", "severity": 5, "source": "Typo3Update.Removed.TypoScript.OTABLE", "type": "WARNING" @@ -79,7 +79,7 @@ "column": 10, "fixable": false, "line": 30, - "message": "Legacy calls are not allowed; found HRULER. Removed in 7.1. Any installation should migrate to alternatives such as FLUIDTEMPLATE to customize the output of the content. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.1/Breaking-64639-RemovedContentObjects.html", + "message": "Calls to removed code are not allowed; found HRULER. Removed in 7.1. Any installation should migrate to alternatives such as FLUIDTEMPLATE to customize the output of the content. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.1/Breaking-64639-RemovedContentObjects.html", "severity": 5, "source": "Typo3Update.Removed.TypoScript.HRULER", "type": "WARNING" -- GitLab From bcbd1f96bc5740bdf19150ed813d31ff03390316 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Thu, 27 Apr 2017 13:33:28 +0200 Subject: [PATCH 06/11] TASK: Migrate GenericConstantUsageSniff * Migrate GenericConstantUsageSniff to new architecture. * Move non common functionality from AbstractGenericPhpUsage to concrete classes. Relates: #71 --- .../Removed/AbstractGenericPhpUsage.php | 21 +++------- .../Removed/GenericConstantUsageSniff.php | 40 ++++--------------- .../Removed/GenericFunctionCallSniff.php | 38 ++++++++++-------- 3 files changed, 35 insertions(+), 64 deletions(-) diff --git a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php index d93645f..c426721 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php @@ -21,11 +21,13 @@ namespace Typo3Update\Sniffs\Removed; */ use PHP_CodeSniffer_File as PhpCsFile; -use Typo3Update\Sniffs\ExtendedPhpCsSupportTrait; abstract class AbstractGenericPhpUsage extends AbstractGenericUsage { - use ExtendedPhpCsSupportTrait; + public function register() + { + return [T_STRING]; + } protected function prepareStructure(array $typo3Versions) { @@ -51,10 +53,6 @@ abstract class AbstractGenericPhpUsage extends AbstractGenericUsage protected function findRemoved(PhpCsFile $phpcsFile, $stackPtr) { - if (!$this->isFunctionCall($phpcsFile, $stackPtr)) { - return []; - } - $tokens = $phpcsFile->getTokens(); $staticPosition = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true, null, true); @@ -120,15 +118,6 @@ abstract class AbstractGenericPhpUsage extends AbstractGenericUsage } } - protected function getOldUsage(array $config) - { - $concat = '->'; - if ($config['static']) { - $concat = '::'; - } - return $config['fqcn'] . $concat . $config['name']; - } - protected function getIdentifier(array $config) { $name = $config['name']; @@ -138,4 +127,6 @@ abstract class AbstractGenericPhpUsage extends AbstractGenericUsage return $name; } + + abstract protected function getOldUsage(array $config); } diff --git a/src/Standards/Typo3Update/Sniffs/Removed/GenericConstantUsageSniff.php b/src/Standards/Typo3Update/Sniffs/Removed/GenericConstantUsageSniff.php index 1ee46b1..e42a07d 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/GenericConstantUsageSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/GenericConstantUsageSniff.php @@ -19,42 +19,11 @@ * 02110-1301, USA. */ -use PHP_CodeSniffer_File as PhpCsFile; -use Typo3Update\Sniffs\Removed\AbstractGenericUsage; +use Typo3Update\Sniffs\Removed\AbstractGenericPhpUsage; use Typo3Update\Options; -/** - * Sniff that handles all calls to removed constants. - */ -class Typo3Update_Sniffs_Removed_GenericConstantUsageSniff extends AbstractGenericUsage +class Typo3Update_Sniffs_Removed_GenericConstantUsageSniff extends AbstractGenericPhpUsage { - /** - * Return file names containing removed configurations. - * - * @return array<string> - */ - protected function getRemovedConfigFiles() - { - return Options::getRemovedConstantConfigFiles(); - } - - /** - * Returns the token types that this sniff is interested in. - * - * @return array<int> - */ - public function register() - { - return [T_STRING]; - } - - /** - * The original constant call, to allow user to check matches. - * - * @param array $config - * - * @return string - */ protected function getOldUsage(array $config) { $old = $config['name']; @@ -64,4 +33,9 @@ class Typo3Update_Sniffs_Removed_GenericConstantUsageSniff extends AbstractGener return 'constant ' . $old; } + + protected function getRemovedConfigFiles() + { + return Options::getRemovedConstantConfigFiles(); + } } diff --git a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php index 7fa8a12..4d1784b 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php @@ -19,32 +19,38 @@ * 02110-1301, USA. */ -use PHP_CodeSniffer_Tokens as Tokens; -use Typo3Update\Sniffs\Removed\AbstractGenericPhpUsage; +use PHP_CodeSniffer_File as PhpCsFile; use Typo3Update\Options; +use Typo3Update\Sniffs\ExtendedPhpCsSupportTrait; +use Typo3Update\Sniffs\Removed\AbstractGenericPhpUsage; /** * Sniff that handles all calls to removed functions. */ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff extends AbstractGenericPhpUsage { - /** - * Returns the token types that this sniff is interested in. - * - * @return array<int> - */ - public function register() - { - return [T_STRING]; - } + use ExtendedPhpCsSupportTrait; - /** - * Return file names containing removed configurations. - * - * @return array<string> - */ protected function getRemovedConfigFiles() { return Options::getRemovedFunctionConfigFiles(); } + + protected function findRemoved(PhpCsFile $phpcsFile, $stackPtr) + { + if (!$this->isFunctionCall($phpcsFile, $stackPtr)) { + return []; + } + + return parent::findRemoved($phpcsFile, $stackPtr); + } + + protected function getOldUsage(array $config) + { + $concat = '->'; + if ($config['static']) { + $concat = '::'; + } + return $config['fqcn'] . $concat . $config['name']; + } } -- GitLab From b9bdd5dd3b89b4661994f4123622db14c88e2fb0 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Thu, 27 Apr 2017 14:05:05 +0200 Subject: [PATCH 07/11] TASK: Migrate RemovedClassFeature * Also migrate RemovedClassFeature to new structure with AbstractYamlRemovedUsage Relates: #71 --- .../Feature/AbstractYamlRemovedUsage.php | 103 ++++++++++++++++++ .../Typo3Update/Feature/FeatureInterface.php | 6 + .../Feature/RemovedClassFeature.php | 51 +++++---- src/Standards/Typo3Update/Options.php | 2 +- .../PhpDocCommentSniff/Expected.json | 4 +- 5 files changed, 140 insertions(+), 26 deletions(-) create mode 100644 src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php diff --git a/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php b/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php new file mode 100644 index 0000000..9395d44 --- /dev/null +++ b/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php @@ -0,0 +1,103 @@ +<?php +namespace Typo3Update\Feature; + +/* + * Copyright (C) 2017 Daniel Siepmann <coding@daniel-siepmann.de> + * + * 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. + */ + +use PHP_CodeSniffer as PhpCs; +use PHP_CodeSniffer_File as PhpCsFile; +use PHP_CodeSniffer_Sniff as PhpCsSniff; +use Typo3Update\RemovedByYamlConfiguration; + +/** + * Contains common functionality for removed code like constants or functions. + * + * Removed parts are configured using YAML-Files, for examples see + * src/Standards/Typo3Update/Configuration/Removed/Constants/7.0.yaml Also + * check out the configuration options in Readme.rst. + */ +abstract class AbstractYamlRemovedUsage implements FeatureInterface +{ + /** + * @var array + */ + protected $configured; + + /** + * @var PhpCsSniff + */ + protected $sniff; + + public function __construct(PhpCsSniff $sniff) + { + $this->sniff = $sniff; + $this->configured = new RemovedByYamlConfiguration( + $this->getRemovedConfigFiles(), + \Closure::fromCallable([$this, 'prepareStructure']) + ); + } + + /** + * Prepares structure from config for later usage. + * + * @param array $typo3Versions + * @return array + */ + abstract protected function prepareStructure(array $typo3Versions); + + /** + * Return file names containing removed configurations. + * + * @return array<string> + */ + abstract protected function getRemovedConfigFiles(); + + protected function addWarning(PhpCsFile $phpcsFile, $stackPtr, array $removed) + { + $phpcsFile->addWarning( + 'Calls to removed code are not allowed; found %s. Removed in %s. %s. See: %s', + $stackPtr, + $removed['identifier'], + [ + $removed['oldUsage'], + $removed['versionRemoved'], + $this->getReplacement($removed), + $removed['docsUrl'], + ] + ); + } + + /** + * The new call, or information how to migrate. + * + * To provide feedback for user to ease migration. + * + * @param array $config + * + * @return string + */ + protected function getReplacement(array $config) + { + $newCall = $config['replacement']; + if ($newCall !== null) { + return $newCall; + } + return 'There is no replacement, just remove call'; + } +} diff --git a/src/Standards/Typo3Update/Feature/FeatureInterface.php b/src/Standards/Typo3Update/Feature/FeatureInterface.php index 39de10c..ac8b7a9 100644 --- a/src/Standards/Typo3Update/Feature/FeatureInterface.php +++ b/src/Standards/Typo3Update/Feature/FeatureInterface.php @@ -21,12 +21,18 @@ namespace Typo3Update\Feature; */ use PHP_CodeSniffer_File as PhpCsFile; +use PHP_CodeSniffer_Sniff as PhpCsSniff; /** * See "Features" in documentation. */ interface FeatureInterface { + /** + * @var PhpCsSniff $sniff + */ + public function __construct(PhpCsSniff $sniff); + /** * Process like a PHPCS Sniff. * diff --git a/src/Standards/Typo3Update/Feature/RemovedClassFeature.php b/src/Standards/Typo3Update/Feature/RemovedClassFeature.php index d81c34d..ffc61df 100644 --- a/src/Standards/Typo3Update/Feature/RemovedClassFeature.php +++ b/src/Standards/Typo3Update/Feature/RemovedClassFeature.php @@ -20,37 +20,42 @@ namespace Typo3Update\Feature; * 02110-1301, USA. */ -use PHP_CodeSniffer as PhpCs; use PHP_CodeSniffer_File as PhpCsFile; -use PHP_CodeSniffer_Sniff as PhpCsSniff; +use Typo3Update\Options; -/** - * This feature will add fixable errors for old legacy classnames. - * - * Can be attached to sniffs returning classnames. - */ -class RemovedClassFeature implements FeatureInterface +class RemovedClassFeature extends AbstractYamlRemovedUsage { - /** - * Process like a PHPCS Sniff. - * - * @param PhpCsFile $phpcsFile - * @param int $classnamePosition - * @param string $classname - * - * @return void - */ public function process(PhpCsFile $phpcsFile, $classnamePosition, $classname) { - if ($this->isClassnameRemoved($classname) === false) { + if (! $this->configured->isRemoved($classname)) { return; } - - $phpcsFile->addError( - 'Removed classes are not allowed; found "%s", use "%s" instead', + $this->addWarning( + $phpcsFile, $classnamePosition, - 'removedClassname', - [$classname] + $this->configured->getRemoved($classname) ); } + + protected function prepareStructure(array $typo3Versions) + { + $newStructure = []; + foreach ($typo3Versions as $typo3Version => $removals) { + foreach ($removals as $removed => $config) { + $config['name'] = $removed; + $config['identifier'] = 'RemovedClass.' . str_replace('\\', '_', ltrim($removed, '\\')); + $config['versionRemoved'] = $typo3Version; + $config['oldUsage'] = $removed; + + $newStructure[$removed] = $config; + } + } + + return $newStructure; + } + + protected function getRemovedConfigFiles() + { + return Options::getRemovedClassConfigFiles(); + } } diff --git a/src/Standards/Typo3Update/Options.php b/src/Standards/Typo3Update/Options.php index 6db1bd2..62b8a78 100644 --- a/src/Standards/Typo3Update/Options.php +++ b/src/Standards/Typo3Update/Options.php @@ -104,7 +104,7 @@ class Options { return static::getOptionFileNames( 'removedClassConfigFiles', - __DIR__ . '/../Configuration/Removed/Classes/*.yaml' + __DIR__ . '/Configuration/Removed/Classes/*.yaml' ); } diff --git a/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.json b/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.json index c528d04..89158c7 100644 --- a/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.json +++ b/tests/Fixtures/Standards/Typo3Update/Sniffs/Classname/PhpDocCommentSniff/Expected.json @@ -25,9 +25,9 @@ "column": 15, "fixable": false, "line": 32, - "message": "Legacy calls are not allowed; found \\TYPO3\\CMS\\Backend\\Template\\MediumDocumentTemplate. Removed in 7.0. Use \\TYPO3\\CMS\\Backend\\Template\\DocumentTemplate instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61782-DeprecatedDocumentTemplateClassesRemoved.html", + "message": "Calls to removed code are not allowed; found \\TYPO3\\CMS\\Backend\\Template\\MediumDocumentTemplate. Removed in 7.0. Use \\TYPO3\\CMS\\Backend\\Template\\DocumentTemplate instead. See: https://docs.typo3.org/typo3cms/extensions/core/7.6/Changelog/7.0/Breaking-61782-DeprecatedDocumentTemplateClassesRemoved.html", "severity": 5, - "source": "Typo3Update.LegacyClassnames.DocComment.TYPO3_CMS_Backend_Template_MediumDocumentTemplate", + "source": "Typo3Update.Classname.PhpDocComment.RemovedClass.TYPO3_CMS_Backend_Template_MediumDocumentTemplate", "type": "WARNING" }, { -- GitLab From 510774a3cc47bf6dabd498815e597a18b2d752c5 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Thu, 27 Apr 2017 14:16:22 +0200 Subject: [PATCH 08/11] TASK: Support at least PHP 5.6 * Adjust CI , composer and docs. * Migrate modern code to 5.6 supported code. Relates: #71 --- .gitlab-ci.yml | 12 ++++++++++-- Documentation/source/index.rst | 3 ++- composer.json | 2 +- .../Typo3Update/Feature/AbstractYamlRemovedUsage.php | 9 ++++++++- .../Sniffs/Removed/AbstractGenericUsage.php | 9 ++++++++- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 202f4e0..af289ad 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -41,12 +41,20 @@ lint:php-mass-detection: script: - ./vendor/bin/phpmd src text phpmd.xml > result/phpmd.txt -test:7.1: &PHP-UNITTESTING - image: php:7.1-alpine +test:5.6: &PHP-UNITTESTING + image: php:5.6-alpine stage: test script: - ./vendor/bin/phpunit +test:7.0: + <<: *PHP-UNITTESTING + image: php:7.0-alpine + +test:7.1: + <<: *PHP-UNITTESTING + image: php:7.1-alpine + test:latest: <<: *PHP-UNITTESTING image: php:7-alpine diff --git a/Documentation/source/index.rst b/Documentation/source/index.rst index 709f4ec..1dd04c3 100644 --- a/Documentation/source/index.rst +++ b/Documentation/source/index.rst @@ -19,7 +19,8 @@ Requirements To install the project you need ``composer`` to be installed and inside your ``$PATH``. Otherwise run ``make install-composer`` to install composer. -At least PHP 7.1 is required. +We recommend to use at least PHP 5.6, we do not test with lower versions as 5.6 is latest maintained +version. Installation ============ diff --git a/composer.json b/composer.json index 87aab93..623bfde 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ ] }, "require": { - "php": "~7.1", + "php": ">=5.6", "helmich/typo3-typoscript-parser": "1.1.*", "squizlabs/php_codesniffer": "2.8.*", "symfony/yaml": "3.2.*", diff --git a/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php b/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php index 9395d44..d5463d6 100644 --- a/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php +++ b/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php @@ -49,10 +49,17 @@ abstract class AbstractYamlRemovedUsage implements FeatureInterface $this->sniff = $sniff; $this->configured = new RemovedByYamlConfiguration( $this->getRemovedConfigFiles(), - \Closure::fromCallable([$this, 'prepareStructure']) + $this->getPrepateStructure() ); } + protected function getPrepateStructure() + { + return function (array $typo3Versions) { + return call_user_func_array([$this, 'prepareStructure'], [$typo3Versions]); + }; + } + /** * Prepares structure from config for later usage. * diff --git a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php index ff67d4f..ba2ba40 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php @@ -39,10 +39,17 @@ abstract class AbstractGenericUsage implements PhpCsSniff { $this->configured = new RemovedByYamlConfiguration( $this->getRemovedConfigFiles(), - \Closure::fromCallable([$this, 'prepareStructure']) + $this->getPrepateStructure() ); } + protected function getPrepateStructure() + { + return function (array $typo3Versions) { + return call_user_func_array([$this, 'prepareStructure'], [$typo3Versions]); + }; + } + /** * Prepares structure from config for later usage. * -- GitLab From 003609342edb40beb14d176aa9e09fd724112742 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Thu, 27 Apr 2017 14:37:24 +0200 Subject: [PATCH 09/11] TASK: Refactor DRY * Don't duplicate code and logic. * Move common code to parent class. Relates: #71 --- .../Typo3Update/AbstractYamlRemovedUsage.php | 72 ++++++++++++++++ .../Feature/AbstractYamlRemovedUsage.php | 84 +------------------ .../Sniffs/Removed/AbstractGenericUsage.php | 73 +--------------- 3 files changed, 78 insertions(+), 151 deletions(-) create mode 100644 src/Standards/Typo3Update/AbstractYamlRemovedUsage.php diff --git a/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php b/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php new file mode 100644 index 0000000..84aee44 --- /dev/null +++ b/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php @@ -0,0 +1,72 @@ +<?php +namespace Typo3Update; + +/* + * Copyright (C) 2017 Daniel Siepmann <coding@daniel-siepmann.de> + * + * 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. + */ + +use PHP_CodeSniffer_File as PhpCsFile; +use Typo3Update\RemovedByYamlConfiguration; + +abstract class AbstractYamlRemovedUsage +{ + protected $configured; + + public function __construct() + { + $this->configured = new RemovedByYamlConfiguration( + $this->getRemovedConfigFiles(), + $this->getPrepareStructureCallback() + ); + } + + protected function getPrepareStructureCallback() + { + return function (array $typo3Versions) { + return call_user_func_array([$this, 'prepareStructure'], [$typo3Versions]); + }; + } + + abstract protected function prepareStructure(array $typo3Versions); + + abstract protected function getRemovedConfigFiles(); + + protected function addWarning(PhpCsFile $phpcsFile, $stackPtr, array $removed) + { + $phpcsFile->addWarning( + 'Calls to removed code are not allowed; found %s. Removed in %s. %s. See: %s', + $stackPtr, + $removed['identifier'], + [ + $removed['oldUsage'], + $removed['versionRemoved'], + $this->getReplacement($removed), + $removed['docsUrl'], + ] + ); + } + + protected function getReplacement(array $config) + { + $newCall = $config['replacement']; + if ($newCall !== null) { + return $newCall; + } + return 'There is no replacement, just remove call'; + } +} diff --git a/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php b/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php index d5463d6..2a1fb9f 100644 --- a/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php +++ b/src/Standards/Typo3Update/Feature/AbstractYamlRemovedUsage.php @@ -20,91 +20,13 @@ namespace Typo3Update\Feature; * 02110-1301, USA. */ -use PHP_CodeSniffer as PhpCs; -use PHP_CodeSniffer_File as PhpCsFile; use PHP_CodeSniffer_Sniff as PhpCsSniff; -use Typo3Update\RemovedByYamlConfiguration; +use Typo3Update\AbstractYamlRemovedUsage as BaseAbstractYamlRemovedUsage; -/** - * Contains common functionality for removed code like constants or functions. - * - * Removed parts are configured using YAML-Files, for examples see - * src/Standards/Typo3Update/Configuration/Removed/Constants/7.0.yaml Also - * check out the configuration options in Readme.rst. - */ -abstract class AbstractYamlRemovedUsage implements FeatureInterface +abstract class AbstractYamlRemovedUsage extends BaseAbstractYamlRemovedUsage implements FeatureInterface { - /** - * @var array - */ - protected $configured; - - /** - * @var PhpCsSniff - */ - protected $sniff; - public function __construct(PhpCsSniff $sniff) { - $this->sniff = $sniff; - $this->configured = new RemovedByYamlConfiguration( - $this->getRemovedConfigFiles(), - $this->getPrepateStructure() - ); - } - - protected function getPrepateStructure() - { - return function (array $typo3Versions) { - return call_user_func_array([$this, 'prepareStructure'], [$typo3Versions]); - }; - } - - /** - * Prepares structure from config for later usage. - * - * @param array $typo3Versions - * @return array - */ - abstract protected function prepareStructure(array $typo3Versions); - - /** - * Return file names containing removed configurations. - * - * @return array<string> - */ - abstract protected function getRemovedConfigFiles(); - - protected function addWarning(PhpCsFile $phpcsFile, $stackPtr, array $removed) - { - $phpcsFile->addWarning( - 'Calls to removed code are not allowed; found %s. Removed in %s. %s. See: %s', - $stackPtr, - $removed['identifier'], - [ - $removed['oldUsage'], - $removed['versionRemoved'], - $this->getReplacement($removed), - $removed['docsUrl'], - ] - ); - } - - /** - * The new call, or information how to migrate. - * - * To provide feedback for user to ease migration. - * - * @param array $config - * - * @return string - */ - protected function getReplacement(array $config) - { - $newCall = $config['replacement']; - if ($newCall !== null) { - return $newCall; - } - return 'There is no replacement, just remove call'; + parent::__construct(); } } diff --git a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php index ba2ba40..b7ab259 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php @@ -22,83 +22,16 @@ namespace Typo3Update\Sniffs\Removed; use PHP_CodeSniffer_File as PhpCsFile; use PHP_CodeSniffer_Sniff as PhpCsSniff; -use Typo3Update\RemovedByYamlConfiguration; +use Typo3Update\AbstractYamlRemovedUsage as BaseAbstractYamlRemovedUsage; -/** - * Contains common functionality for removed code like constants or functions. - * - * Removed parts are configured using YAML-Files, for examples see - * src/Standards/Typo3Update/Configuration/Removed/Constants/7.0.yaml Also - * check out the configuration options in Readme.rst. - */ -abstract class AbstractGenericUsage implements PhpCsSniff +abstract class AbstractGenericUsage extends BaseAbstractYamlRemovedUsage implements PhpCsSniff { - protected $configured; - - public function __construct() - { - $this->configured = new RemovedByYamlConfiguration( - $this->getRemovedConfigFiles(), - $this->getPrepateStructure() - ); - } - - protected function getPrepateStructure() - { - return function (array $typo3Versions) { - return call_user_func_array([$this, 'prepareStructure'], [$typo3Versions]); - }; - } - - /** - * Prepares structure from config for later usage. - * - * @param array $typo3Versions - * @return array - */ - abstract protected function prepareStructure(array $typo3Versions); - - /** - * Return file names containing removed configurations. - * - * @return array<string> - */ - abstract protected function getRemovedConfigFiles(); - abstract protected function findRemoved(PhpCsFile $phpcsFile, $stackPtr); public function process(PhpCsFile $phpcsFile, $stackPtr) { foreach ($this->findRemoved($phpcsFile, $stackPtr) as $removed) { - $phpcsFile->addWarning( - 'Calls to removed code are not allowed; found %s. Removed in %s. %s. See: %s', - $stackPtr, - $removed['identifier'], - [ - $removed['oldUsage'], - $removed['versionRemoved'], - $this->getReplacement($removed), - $removed['docsUrl'], - ] - ); - } - } - - /** - * The new call, or information how to migrate. - * - * To provide feedback for user to ease migration. - * - * @param array $config - * - * @return string - */ - protected function getReplacement(array $config) - { - $newCall = $config['replacement']; - if ($newCall !== null) { - return $newCall; + $this->addWarning($phpcsFile, $stackPtr, $removed); } - return 'There is no replacement, just remove call'; } } -- GitLab From 11db09a3038861154bd4bad524deb0b083208d1c Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Thu, 27 Apr 2017 15:40:02 +0200 Subject: [PATCH 10/11] TASK: Update phpdocs * Remove unnecessary docs. * Add necessary docs. --- .../Typo3Update/AbstractYamlRemovedUsage.php | 25 ++++++++++++++++++ .../RemovedByYamlConfiguration.php | 14 ++++++++++ .../Removed/AbstractGenericPhpUsage.php | 24 +++++++++++++++++ .../Sniffs/Removed/AbstractGenericUsage.php | 9 +++++++ .../Removed/GenericFunctionCallSniff.php | 3 --- .../Sniffs/Removed/TypoScriptSniff.php | 26 ------------------- 6 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php b/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php index 84aee44..37d1c4e 100644 --- a/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php +++ b/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php @@ -23,8 +23,14 @@ namespace Typo3Update; use PHP_CodeSniffer_File as PhpCsFile; use Typo3Update\RemovedByYamlConfiguration; +/** + * Base class for all classes working with removed configuration through yaml files. + */ abstract class AbstractYamlRemovedUsage { + /** + * @var array + */ protected $configured; public function __construct() @@ -35,6 +41,9 @@ abstract class AbstractYamlRemovedUsage ); } + /** + * @return \Callable + */ protected function getPrepareStructureCallback() { return function (array $typo3Versions) { @@ -42,10 +51,22 @@ abstract class AbstractYamlRemovedUsage }; } + /** + * @param array $typo3Versions + * @return array + */ abstract protected function prepareStructure(array $typo3Versions); + /** + * @return array + */ abstract protected function getRemovedConfigFiles(); + /** + * @param PhpCsFile $phpcsFile + * @param int $stackPtr + * @param array $removed + */ protected function addWarning(PhpCsFile $phpcsFile, $stackPtr, array $removed) { $phpcsFile->addWarning( @@ -61,6 +82,10 @@ abstract class AbstractYamlRemovedUsage ); } + /** + * @param array $config + * @return string + */ protected function getReplacement(array $config) { $newCall = $config['replacement']; diff --git a/src/Standards/Typo3Update/RemovedByYamlConfiguration.php b/src/Standards/Typo3Update/RemovedByYamlConfiguration.php index a527e43..f1596a9 100644 --- a/src/Standards/Typo3Update/RemovedByYamlConfiguration.php +++ b/src/Standards/Typo3Update/RemovedByYamlConfiguration.php @@ -31,6 +31,10 @@ class RemovedByYamlConfiguration */ protected $configured = []; + /** + * @param array $configFiles + * @param Callable $prepareStructure + */ public function __construct(array $configFiles, $prepareStructure) { foreach ($configFiles as $file) { @@ -41,16 +45,26 @@ class RemovedByYamlConfiguration } } + /** + * @param string $identifier + * @return bool + */ public function isRemoved($identifier) { return isset($this->configured[$identifier]); } + /** + * @return array + */ public function getAllRemoved() { return $this->configured; } + /** + * @return array + */ public function getRemoved($identifier) { if (!$this->isRemoved($identifier)) { diff --git a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php index c426721..99c81d1 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericPhpUsage.php @@ -24,11 +24,18 @@ use PHP_CodeSniffer_File as PhpCsFile; abstract class AbstractGenericPhpUsage extends AbstractGenericUsage { + /** + * @return int[] + */ public function register() { return [T_STRING]; } + /** + * @param array $typo3Versions + * @return array + */ protected function prepareStructure(array $typo3Versions) { $newStructure = []; @@ -51,6 +58,11 @@ abstract class AbstractGenericPhpUsage extends AbstractGenericUsage return $newStructure; } + /** + * @param PhpCsFile $phpcsFile + * @param int $stackPtr + * @return array + */ protected function findRemoved(PhpCsFile $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); @@ -104,6 +116,10 @@ abstract class AbstractGenericPhpUsage extends AbstractGenericUsage ); } + /** + * @param string $identifier + * @param array &$config + */ protected function handleStatic($identifier, array &$config) { $split = preg_split('/::|->/', $identifier); @@ -118,6 +134,10 @@ abstract class AbstractGenericPhpUsage extends AbstractGenericUsage } } + /** + * @param array $config + * @return string + */ protected function getIdentifier(array $config) { $name = $config['name']; @@ -128,5 +148,9 @@ abstract class AbstractGenericPhpUsage extends AbstractGenericUsage return $name; } + /** + * @param array $config + * @return string + */ abstract protected function getOldUsage(array $config); } diff --git a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php index b7ab259..557dcb5 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/AbstractGenericUsage.php @@ -26,8 +26,17 @@ use Typo3Update\AbstractYamlRemovedUsage as BaseAbstractYamlRemovedUsage; abstract class AbstractGenericUsage extends BaseAbstractYamlRemovedUsage implements PhpCsSniff { + /** + * @param PhpCsFile $phpcsFile + * @param int $stackPtr + * @return array + */ abstract protected function findRemoved(PhpCsFile $phpcsFile, $stackPtr); + /** + * @param PhpCsFile $phpcsFile + * @param int $stackPtr + */ public function process(PhpCsFile $phpcsFile, $stackPtr) { foreach ($this->findRemoved($phpcsFile, $stackPtr) as $removed) { diff --git a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php index 4d1784b..2915a87 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php @@ -24,9 +24,6 @@ use Typo3Update\Options; use Typo3Update\Sniffs\ExtendedPhpCsSupportTrait; use Typo3Update\Sniffs\Removed\AbstractGenericPhpUsage; -/** - * Sniff that handles all calls to removed functions. - */ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff extends AbstractGenericPhpUsage { use ExtendedPhpCsSupportTrait; diff --git a/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php b/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php index 419b55a..6638b34 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/TypoScriptSniff.php @@ -24,9 +24,6 @@ use PHP_CodeSniffer_File as PhpCsFile; use Typo3Update\Options; use Typo3Update\Sniffs\Removed\AbstractGenericUsage; -/** - * Check usage of removed or breaking changed TypoScript. - */ class Typo3Update_Sniffs_Removed_TypoScriptSniff extends AbstractGenericUsage { /** @@ -37,11 +34,6 @@ class Typo3Update_Sniffs_Removed_TypoScriptSniff extends AbstractGenericUsage 'TYPOSCRIPT', ]; - /** - * Returns the token types that this sniff is interested in. - * - * @return array<int> - */ public function register() { return [ @@ -50,12 +42,6 @@ class Typo3Update_Sniffs_Removed_TypoScriptSniff extends AbstractGenericUsage ]; } - /** - * Prepares structure from config for later usage. - * - * @param array $typo3Versions - * @return array - */ protected function prepareStructure(array $typo3Versions) { $newStructure = []; @@ -80,13 +66,6 @@ class Typo3Update_Sniffs_Removed_TypoScriptSniff extends AbstractGenericUsage return $newStructure; } - /** - * Check whether the current token is removed. - * - * @param PhpCsFile $phpcsFile - * @param int $stackPtr - * @return bool - */ protected function findRemoved(PhpCsFile $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); @@ -105,11 +84,6 @@ class Typo3Update_Sniffs_Removed_TypoScriptSniff extends AbstractGenericUsage return []; } - /** - * Return file names containing removed configurations. - * - * @return array<string> - */ protected function getRemovedConfigFiles() { return Options::getRemovedTypoScriptConfigFiles(); -- GitLab From 9e3f7ac1e507713d021c39967428dabb58c2dc59 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <coding@daniel-siepmann.de> Date: Tue, 2 May 2017 08:09:10 +0200 Subject: [PATCH 11/11] TASK: Fix MR issues * Remove construct from interface. * Fix wrong type hints. * Keep naming of variable in sync. * Also keep conditions format in sync. Relates: #71 --- .../Typo3Update/AbstractYamlRemovedUsage.php | 16 ++++++++-------- .../Typo3Update/Feature/FeatureInterface.php | 5 ----- .../Typo3Update/Feature/RemovedClassFeature.php | 2 +- .../Typo3Update/RemovedByYamlConfiguration.php | 2 +- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php b/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php index 37d1c4e..e753605 100644 --- a/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php +++ b/src/Standards/Typo3Update/AbstractYamlRemovedUsage.php @@ -29,7 +29,7 @@ use Typo3Update\RemovedByYamlConfiguration; abstract class AbstractYamlRemovedUsage { /** - * @var array + * @var RemovedByYamlConfiguration */ protected $configured; @@ -65,19 +65,19 @@ abstract class AbstractYamlRemovedUsage /** * @param PhpCsFile $phpcsFile * @param int $stackPtr - * @param array $removed + * @param array $config */ - protected function addWarning(PhpCsFile $phpcsFile, $stackPtr, array $removed) + protected function addWarning(PhpCsFile $phpcsFile, $stackPtr, array $config) { $phpcsFile->addWarning( 'Calls to removed code are not allowed; found %s. Removed in %s. %s. See: %s', $stackPtr, - $removed['identifier'], + $config['identifier'], [ - $removed['oldUsage'], - $removed['versionRemoved'], - $this->getReplacement($removed), - $removed['docsUrl'], + $config['oldUsage'], + $config['versionRemoved'], + $this->getReplacement($config), + $config['docsUrl'], ] ); } diff --git a/src/Standards/Typo3Update/Feature/FeatureInterface.php b/src/Standards/Typo3Update/Feature/FeatureInterface.php index ac8b7a9..8ab83a7 100644 --- a/src/Standards/Typo3Update/Feature/FeatureInterface.php +++ b/src/Standards/Typo3Update/Feature/FeatureInterface.php @@ -28,11 +28,6 @@ use PHP_CodeSniffer_Sniff as PhpCsSniff; */ interface FeatureInterface { - /** - * @var PhpCsSniff $sniff - */ - public function __construct(PhpCsSniff $sniff); - /** * Process like a PHPCS Sniff. * diff --git a/src/Standards/Typo3Update/Feature/RemovedClassFeature.php b/src/Standards/Typo3Update/Feature/RemovedClassFeature.php index ffc61df..5584dfc 100644 --- a/src/Standards/Typo3Update/Feature/RemovedClassFeature.php +++ b/src/Standards/Typo3Update/Feature/RemovedClassFeature.php @@ -27,7 +27,7 @@ class RemovedClassFeature extends AbstractYamlRemovedUsage { public function process(PhpCsFile $phpcsFile, $classnamePosition, $classname) { - if (! $this->configured->isRemoved($classname)) { + if ($this->configured->isRemoved($classname) === false) { return; } $this->addWarning( diff --git a/src/Standards/Typo3Update/RemovedByYamlConfiguration.php b/src/Standards/Typo3Update/RemovedByYamlConfiguration.php index f1596a9..046c180 100644 --- a/src/Standards/Typo3Update/RemovedByYamlConfiguration.php +++ b/src/Standards/Typo3Update/RemovedByYamlConfiguration.php @@ -33,7 +33,7 @@ class RemovedByYamlConfiguration /** * @param array $configFiles - * @param Callable $prepareStructure + * @param \Callable $prepareStructure */ public function __construct(array $configFiles, $prepareStructure) { -- GitLab