Merge branch 'feature/33-deprecated-handling' into feature/42-deprecated-constants

This commit is contained in:
Daniel Siepmann 2017-04-04 08:41:02 +02:00
commit b5e7e15683
4 changed files with 78 additions and 59 deletions

View file

@ -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 - Check for ``create`` on ``ObjectManager``, which is "stupid" just all ``create`` calls are marked
with a warning. 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? What does it look like?
======================= =======================
@ -194,3 +202,21 @@ Example:
.. code:: bash .. code:: bash
--runtime-set vendor YourVendor --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
<config name="removedFunctionConfigFiles" value="/Some/Absolute/Path/*.yaml"/>
Example:
.. code:: bash
--runtime-set removedFunctionConfigFiles "/Some/Absolute/Path/*.yaml"

View file

@ -67,7 +67,7 @@ class Typo3Update_Sniffs_Deprecated_AjaxRegistrationSniff implements PhpCsSniff
} }
$tokens = $phpcsFile->getTokens(); $tokens = $phpcsFile->getTokens();
if ($tokens[$stackPtr]['content'] !== "'AJAX'") { if (preg_match('/"AJAX"|\'AJAX\'/', $tokens[$stackPtr]['content']) !== 1) {
return; return;
} }
$equalSign = $phpcsFile->findNext(T_EQUAL, $stackPtr, null, false, null, true); $equalSign = $phpcsFile->findNext(T_EQUAL, $stackPtr, null, false, null, true);

View file

@ -62,7 +62,7 @@ trait OptionsAccessTrait
*/ */
public function getRemovedFunctionConfigFiles() public function getRemovedFunctionConfigFiles()
{ {
$configFiles = PhpCs::getConfigData('removedfunctionConfigFiles'); $configFiles = PhpCs::getConfigData('removedFunctionConfigFiles');
if (!$configFiles) { if (!$configFiles) {
$configFiles = __DIR__ . '/../Configuration/Removed/Functions/*.yaml'; $configFiles = __DIR__ . '/../Configuration/Removed/Functions/*.yaml';
} }

View file

@ -27,7 +27,8 @@ use Symfony\Component\Yaml\Yaml;
/** /**
* Sniff that handles all calls to removed functions. * 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 class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
{ {
@ -39,13 +40,13 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
* *
* @var array * @var array
*/ */
protected static $removedFunctions = []; protected static $configuredFunctions = [];
/** /**
* Function for the current sniff instance. * Function for the current sniff instance.
* @var array * @var array
*/ */
private $removedFunction = []; private $removedFunctions = [];
/** /**
* TODO: Multiple files allowed, using glob ... * TODO: Multiple files allowed, using glob ...
@ -53,10 +54,10 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
*/ */
public function __construct() public function __construct()
{ {
if (static::$removedFunctions === []) { if (static::$configuredFunctions === []) {
foreach ($this->getRemovedFunctionConfigFiles() as $file) { foreach ($this->getRemovedFunctionConfigFiles() as $file) {
static::$removedFunctions = array_merge( static::$configuredFunctions = array_merge(
static::$removedFunctions, static::$configuredFunctions,
$this->prepareStructure(Yaml::parse(file_get_contents((string) $file))) $this->prepareStructure(Yaml::parse(file_get_contents((string) $file)))
); );
} }
@ -66,16 +67,15 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
/** /**
* Prepares structure from config for later usage. * Prepares structure from config for later usage.
* *
* @param array $oldStructure * @param array $typo3Versions
* @return array * @return array
*/ */
protected function prepareStructure(array $oldStructure) protected function prepareStructure(array $typo3Versions)
{ {
$typo3Versions = array_keys($oldStructure);
$newStructure = []; $newStructure = [];
foreach ($typo3Versions as $typo3Version) { foreach ($typo3Versions as $typo3Version => $functions) {
foreach ($oldStructure[$typo3Version] as $function => $config) { foreach ($functions as $function => $config) {
// Split static methods and methods. // Split static methods and methods.
$split = preg_split('/::|->/', $function); $split = preg_split('/::|->/', $function);
@ -163,30 +163,29 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
} }
} }
return $this->getRemovedFunction($functionName, $class, $isStatic) !== []; $this->removedFunctions = $this->getMatchingRemovedFunctions($functionName, $class, $isStatic);
return $this->removedFunctions !== [];
} }
/** /**
* Returns all matching removed functions for given arguments. * Returns all matching removed functions for given arguments.
* *
* Also prepares functions for later usages in $this->removedFunction.
*
* @param string $functionName * @param string $functionName
* @param string $className The last part of the class name, splitted by namespaces. * @param string $className The last part of the class name, splitted by namespaces.
* @param bool $isStatic * @param bool $isStatic
* *
* @return array * @return void
*/ */
protected function getRemovedFunction($functionName, $className, $isStatic) protected function getMatchingRemovedFunctions($functionName, $className, $isStatic)
{ {
// We will not match any static method, without the class name, at least for now. // 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. // Otherwise we could handle them the same way as instance methods.
if ($isStatic === true && $className === false) { if ($isStatic === true && $className === false) {
return []; return;
} }
$this->removedFunction = array_filter( return array_filter(
static::$removedFunctions, static::$configuredFunctions,
function ($config) use ($functionName, $isStatic, $className) { function ($config) use ($functionName, $isStatic, $className) {
return $functionName === $config['function'] return $functionName === $config['function']
&& $isStatic === $config['static'] && $isStatic === $config['static']
@ -197,22 +196,6 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
; ;
} }
); );
return $this->removedFunction;
}
/**
* Returns configuration for currently checked function.
*
* @return array
*/
protected function getCurrentRemovedFunction()
{
$config = current($this->removedFunction);
// TODO: Add exception if something went wrong?
return $config;
} }
/** /**
@ -225,27 +208,30 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
*/ */
protected function addWarning(PhpCsFile $phpcsFile, $tokenPosition) protected function addWarning(PhpCsFile $phpcsFile, $tokenPosition)
{ {
foreach ($this->removedFunctions as $function) {
$phpcsFile->addWarning( $phpcsFile->addWarning(
'Legacy function calls are not allowed; found %s. Removed in %s. %s. See: %s', 'Legacy function calls are not allowed; found %s. Removed in %s. %s. See: %s',
$tokenPosition, $tokenPosition,
$this->getFunctionIdentifier(), $this->getFunctionIdentifier($function),
[ [
$this->getOldfunctionCall(), $this->getOldfunctionCall($function),
$this->getRemovedVersion(), $this->getRemovedVersion($function),
$this->getNewFunctionCall(), $this->getNewFunctionCall($function),
$this->getDocsUrl(), $this->getDocsUrl($function),
] ]
); );
} }
}
/** /**
* Identifier for configuring this specific error / warning through PHPCS. * Identifier for configuring this specific error / warning through PHPCS.
* *
* @param array $config The converted structure for a single function.
*
* @return string * @return string
*/ */
protected function getFunctionIdentifier() protected function getFunctionIdentifier(array $config)
{ {
$config = $this->getCurrentRemovedFunction();
return $config['class'] . '.' . $config['function']; return $config['class'] . '.' . $config['function'];
} }
@ -256,11 +242,12 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
* you should provide an example, so users can check that this is the * you should provide an example, so users can check that this is the
* legacy one. * legacy one.
* *
* @param array $config The converted structure for a single function.
*
* @return string * @return string
*/ */
protected function getOldFunctionCall() protected function getOldFunctionCall(array $config)
{ {
$config = $this->getCurrentRemovedFunction();
$concat = '->'; $concat = '->';
if ($config['static']) { if ($config['static']) {
$concat = '::'; $concat = '::';
@ -273,11 +260,13 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
* *
* To let user decide whether this is important for him. * To let user decide whether this is important for him.
* *
* @param array $config The converted structure for a single function.
*
* @return string * @return string
*/ */
protected function getRemovedVersion() protected function getRemovedVersion(array $config)
{ {
return $this->getCurrentRemovedFunction()['version_removed']; return $config['version_removed'];
} }
/** /**
@ -285,11 +274,13 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
* *
* To provide feedback for user to ease migration. * To provide feedback for user to ease migration.
* *
* @param array $config The converted structure for a single function.
*
* @return string * @return string
*/ */
protected function getNewFunctionCall() protected function getNewFunctionCall(array $config)
{ {
$newCall = $this->getCurrentRemovedFunction()['newFunctionCall']; $newCall = $config['newFunctionCall'];
if ($newCall !== null) { if ($newCall !== null) {
return $newCall; return $newCall;
} }
@ -299,10 +290,12 @@ class Typo3Update_Sniffs_Removed_GenericFunctionCallSniff implements PhpCsSniff
/** /**
* Allow user to lookup the official docs related to this deprecation / breaking change. * 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 * @return string
*/ */
protected function getDocsUrl() protected function getDocsUrl(array $config)
{ {
return $this->getCurrentRemovedFunction()['docsUrl']; return $config['docsUrl'];
} }
} }