From 56d692bac7ed2a60706c0d09837ac0dce75cc7fa Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Thu, 30 Mar 2017 13:18:18 +0200 Subject: [PATCH 1/5] TASK: Add missing docs * Add docs for new feature. Relates: #33 --- Readme.rst | 26 +++++++++++++++++++ .../Typo3Update/Sniffs/OptionsAccessTrait.php | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Readme.rst b/Readme.rst index a7a1243..e87a3a8 100644 --- a/Readme.rst +++ b/Readme.rst @@ -100,6 +100,14 @@ Also we check for the following deprecated calls: - Check for ``create`` on ``ObjectManager``, which is "stupid" just all ``create`` calls are marked with a warning. +Beside the features above which are covered by ``phpcs`` and phpcbf``, the following linting is also +available to generate a report of possible issues and during coding through ``phpcs``: + +- Check for usage of removed functions. + The functions are configured via yaml files. The location of them is configurable, default is + inside the standard itself, and we try to deliver all information. + For configuration options see ``removedFunctionConfigFiles``. + What does it look like? ======================= @@ -194,3 +202,21 @@ Example: .. code:: bash --runtime-set vendor YourVendor + +``removedFunctionConfigFiles`` + Configure your vendor through ``ruleset.xml`` or using ``--runtime-set``. Default is + ``Configuration/Removed/Functions/*.yaml`` inside the standard itself. + Globing is used, so placeholders like ``*`` are possible, see + https://secure.php.net/manual/en/function.glob.php + + Example: + +.. code:: xml + + + +Example: + +.. code:: bash + + --runtime-set removedFunctionConfigFiles "/Some/Absolute/Path/*.yaml" diff --git a/src/Standards/Typo3Update/Sniffs/OptionsAccessTrait.php b/src/Standards/Typo3Update/Sniffs/OptionsAccessTrait.php index 9db7ee7..9920467 100644 --- a/src/Standards/Typo3Update/Sniffs/OptionsAccessTrait.php +++ b/src/Standards/Typo3Update/Sniffs/OptionsAccessTrait.php @@ -62,7 +62,7 @@ trait OptionsAccessTrait */ public function getRemovedFunctionConfigFiles() { - $configFiles = PhpCs::getConfigData('removedfunctionConfigFiles'); + $configFiles = PhpCs::getConfigData('removedFunctionConfigFiles'); if (!$configFiles) { $configFiles = __DIR__ . '/../Configuration/Removed/Functions/*.yaml'; } From aa8ffab3fa76030c41c464f0e66756536fd87acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Hu=CC=88rtgen?= Date: Thu, 30 Mar 2017 16:58:34 +0200 Subject: [PATCH 2/5] TASK: Rename removed function method --- .../Sniffs/Removed/GenericFunctionCallSniff.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php index 7420a63..8b97280 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php @@ -163,26 +163,26 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff } } - return $this->getRemovedFunction($functionName, $class, $isStatic) !== []; + $this->detectRemovedFunctions($functionName, $class, $isStatic) + + return $this->removedFunction !== []; } /** - * Returns all matching removed functions for given arguments. - * - * Also prepares functions for later usages in $this->removedFunction. + * Detect removed functions for given arguments. * * @param string $functionName * @param string $className The last part of the class name, splitted by namespaces. * @param bool $isStatic * - * @return array + * @return void */ - protected function getRemovedFunction($functionName, $className, $isStatic) + protected function detectRemovedFunctions($functionName, $className, $isStatic) { // We will not match any static method, without the class name, at least for now. // Otherwise we could handle them the same way as instance methods. if ($isStatic === true && $className === false) { - return []; + return; } $this->removedFunction = array_filter( @@ -197,8 +197,6 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff ; } ); - - return $this->removedFunction; } /** From 9c6085642e6d8233c25adad06ae27c9c7584656a Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 4 Apr 2017 08:12:14 +0200 Subject: [PATCH 3/5] BUGFIX: Respect double quotes for ajax deprecation Relates: #33 --- .../Typo3Update/Sniffs/Deprecated/AjaxRegistrationSniff.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Standards/Typo3Update/Sniffs/Deprecated/AjaxRegistrationSniff.php b/src/Standards/Typo3Update/Sniffs/Deprecated/AjaxRegistrationSniff.php index 355e408..14574ac 100644 --- a/src/Standards/Typo3Update/Sniffs/Deprecated/AjaxRegistrationSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Deprecated/AjaxRegistrationSniff.php @@ -67,7 +67,7 @@ class Typo3Update_Sniffs_Deprecated_AjaxRegistrationSniff implements PhpCsSniff } $tokens = $phpcsFile->getTokens(); - if ($tokens[$stackPtr]['content'] !== "'AJAX'") { + if (preg_match('/"AJAX"|\'AJAX\'/', $tokens[$stackPtr]['content']) !== 1) { return; } $equalSign = $phpcsFile->findNext(T_EQUAL, $stackPtr, null, false, null, true); From 830584fa8788915e6330941c1f7f27f316ec8b8b Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 4 Apr 2017 08:31:36 +0200 Subject: [PATCH 4/5] TASK: Improve docs --- .../Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php index 8b97280..706d892 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php @@ -27,7 +27,8 @@ use Symfony\Component\Yaml\Yaml; /** * Sniff that handles all calls to removed functions. * - * A single array defines the deprecations, see $removedFunctions. + * Removed functions are configured using YAML-Files, for examples see src/Standards/Typo3Update/Configuration/Removed/Functions/7.0.yaml + * Also check out the configuration options in Readme.rst. */ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff { From 034ab57a34af371ee3325c7c92637d8b8833f7df Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Tue, 4 Apr 2017 08:31:54 +0200 Subject: [PATCH 5/5] TASK: Skip unnecessary function call --- .../Removed/GenericFunctionCallSniff.php | 100 ++++++++---------- 1 file changed, 47 insertions(+), 53 deletions(-) diff --git a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php index 706d892..b81ff7d 100644 --- a/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Removed/GenericFunctionCallSniff.php @@ -40,13 +40,13 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff * * @var array */ - protected static $removedFunctions = []; + protected static $configuredFunctions = []; /** * Function for the current sniff instance. * @var array */ - private $removedFunction = []; + private $removedFunctions = []; /** * TODO: Multiple files allowed, using glob ... @@ -54,10 +54,10 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff */ public function __construct() { - if (static::$removedFunctions === []) { + if (static::$configuredFunctions === []) { foreach ($this->getRemovedFunctionConfigFiles() as $file) { - static::$removedFunctions = array_merge( - static::$removedFunctions, + static::$configuredFunctions = array_merge( + static::$configuredFunctions, $this->prepareStructure(Yaml::parse(file_get_contents((string) $file))) ); } @@ -67,16 +67,15 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff /** * Prepares structure from config for later usage. * - * @param array $oldStructure + * @param array $typo3Versions * @return array */ - protected function prepareStructure(array $oldStructure) + protected function prepareStructure(array $typo3Versions) { - $typo3Versions = array_keys($oldStructure); $newStructure = []; - foreach ($typo3Versions as $typo3Version) { - foreach ($oldStructure[$typo3Version] as $function => $config) { + foreach ($typo3Versions as $typo3Version => $functions) { + foreach ($functions as $function => $config) { // Split static methods and methods. $split = preg_split('/::|->/', $function); @@ -164,13 +163,12 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff } } - $this->detectRemovedFunctions($functionName, $class, $isStatic) - - return $this->removedFunction !== []; + $this->removedFunctions = $this->getMatchingRemovedFunctions($functionName, $class, $isStatic); + return $this->removedFunctions !== []; } /** - * Detect removed functions for given arguments. + * Returns all matching removed functions for given arguments. * * @param string $functionName * @param string $className The last part of the class name, splitted by namespaces. @@ -178,7 +176,7 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff * * @return void */ - protected function detectRemovedFunctions($functionName, $className, $isStatic) + protected function getMatchingRemovedFunctions($functionName, $className, $isStatic) { // We will not match any static method, without the class name, at least for now. // Otherwise we could handle them the same way as instance methods. @@ -186,8 +184,8 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff return; } - $this->removedFunction = array_filter( - static::$removedFunctions, + return array_filter( + static::$configuredFunctions, function ($config) use ($functionName, $isStatic, $className) { return $functionName === $config['function'] && $isStatic === $config['static'] @@ -195,25 +193,11 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff $className === $config['class'] || $className === false ) - ; + ; } ); } - /** - * Returns configuration for currently checked function. - * - * @return array - */ - protected function getCurrentRemovedFunction() - { - $config = current($this->removedFunction); - - // TODO: Add exception if something went wrong? - - return $config; - } - /** * Add warning for the given token position. * @@ -224,27 +208,30 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff */ protected function addWarning(PhpCsFile $phpcsFile, $tokenPosition) { - $phpcsFile->addWarning( - 'Legacy function calls are not allowed; found %s. Removed in %s. %s. See: %s', - $tokenPosition, - $this->getFunctionIdentifier(), - [ - $this->getOldfunctionCall(), - $this->getRemovedVersion(), - $this->getNewFunctionCall(), - $this->getDocsUrl(), - ] - ); + foreach ($this->removedFunctions as $function) { + $phpcsFile->addWarning( + 'Legacy function calls are not allowed; found %s. Removed in %s. %s. See: %s', + $tokenPosition, + $this->getFunctionIdentifier($function), + [ + $this->getOldfunctionCall($function), + $this->getRemovedVersion($function), + $this->getNewFunctionCall($function), + $this->getDocsUrl($function), + ] + ); + } } /** * Identifier for configuring this specific error / warning through PHPCS. * + * @param array $config The converted structure for a single function. + * * @return string */ - protected function getFunctionIdentifier() + protected function getFunctionIdentifier(array $config) { - $config = $this->getCurrentRemovedFunction(); return $config['class'] . '.' . $config['function']; } @@ -255,11 +242,12 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff * 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 string */ - protected function getOldFunctionCall() + protected function getOldFunctionCall(array $config) { - $config = $this->getCurrentRemovedFunction(); $concat = '->'; if ($config['static']) { $concat = '::'; @@ -272,11 +260,13 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff * * To let user decide whether this is important for him. * + * @param array $config The converted structure for a single function. + * * @return string */ - protected function getRemovedVersion() + protected function getRemovedVersion(array $config) { - return $this->getCurrentRemovedFunction()['version_removed']; + return $config['version_removed']; } /** @@ -284,11 +274,13 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff * * To provide feedback for user to ease migration. * + * @param array $config The converted structure for a single function. + * * @return string */ - protected function getNewFunctionCall() + protected function getNewFunctionCall(array $config) { - $newCall = $this->getCurrentRemovedFunction()['newFunctionCall']; + $newCall = $config['newFunctionCall']; if ($newCall !== null) { return $newCall; } @@ -298,10 +290,12 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff /** * Allow user to lookup the official docs related to this deprecation / breaking change. * + * @param array $config The converted structure for a single function. + * * @return string */ - protected function getDocsUrl() + protected function getDocsUrl(array $config) { - return $this->getCurrentRemovedFunction()['docsUrl']; + return $config['docsUrl']; } }