oficinasuport-wp-theme/vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesAsInvokedFunc...

189 lines
5.7 KiB
PHP

<?php
/**
* PHPCompatibility, an external standard for PHP_CodeSniffer.
*
* @package PHPCompatibility
* @copyright 2012-2019 PHPCompatibility Contributors
* @license https://opensource.org/licenses/LGPL-3.0 LGPL3
* @link https://github.com/PHPCompatibility/PHPCompatibility
*/
namespace PHPCompatibility\Sniffs\Keywords;
use PHPCompatibility\Sniff;
use PHP_CodeSniffer_File as File;
use PHP_CodeSniffer_Tokens as Tokens;
/**
* Prohibits the use of reserved keywords invoked as functions.
*
* PHP version All
*
* @link https://www.php.net/manual/en/reserved.keywords.php
*
* @since 5.5
*/
class ForbiddenNamesAsInvokedFunctionsSniff extends Sniff
{
/**
* List of tokens to register.
*
* @since 5.5
*
* @var array
*/
protected $targetedTokens = array(
\T_ABSTRACT => '5.0',
\T_CALLABLE => '5.4',
\T_CATCH => '5.0',
\T_FINAL => '5.0',
\T_FINALLY => '5.5',
\T_GOTO => '5.3',
\T_IMPLEMENTS => '5.0',
\T_INTERFACE => '5.0',
\T_INSTANCEOF => '5.0',
\T_INSTEADOF => '5.4',
\T_NAMESPACE => '5.3',
\T_PRIVATE => '5.0',
\T_PROTECTED => '5.0',
\T_PUBLIC => '5.0',
\T_TRAIT => '5.4',
\T_TRY => '5.0',
);
/**
* T_STRING keywords to recognize as targetted tokens.
*
* Compatibility for PHP versions where the keyword is not yet recognized
* as its own token and for PHPCS versions which change the token to
* T_STRING when used in a method call.
*
* @since 5.5
*
* @var array
*/
protected $targetedStringTokens = array(
'abstract' => '5.0',
'callable' => '5.4',
'catch' => '5.0',
'final' => '5.0',
'finally' => '5.5',
'goto' => '5.3',
'implements' => '5.0',
'interface' => '5.0',
'instanceof' => '5.0',
'insteadof' => '5.4',
'namespace' => '5.3',
'private' => '5.0',
'protected' => '5.0',
'public' => '5.0',
'trait' => '5.4',
'try' => '5.0',
);
/**
* Returns an array of tokens this test wants to listen for.
*
* @since 5.5
*
* @return array
*/
public function register()
{
$tokens = array_keys($this->targetedTokens);
$tokens[] = \T_STRING;
return $tokens;
}
/**
* Processes this test, when one of its tokens is encountered.
*
* @since 5.5
*
* @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the current token in the
* stack passed in $tokens.
*
* @return void
*/
public function process(File $phpcsFile, $stackPtr)
{
$tokens = $phpcsFile->getTokens();
$tokenCode = $tokens[$stackPtr]['code'];
$tokenContentLc = strtolower($tokens[$stackPtr]['content']);
$isString = false;
/*
* For string tokens we only care if the string is a reserved word used
* as a function. This only happens in older versions of PHP where the
* token doesn't exist yet for that keyword or in later versions when the
* token is used in a method invocation.
*/
if ($tokenCode === \T_STRING
&& (isset($this->targetedStringTokens[$tokenContentLc]) === false)
) {
return;
}
if ($tokenCode === \T_STRING) {
$isString = true;
}
// Make sure this is a function call.
$next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
if ($next === false || $tokens[$next]['code'] !== \T_OPEN_PARENTHESIS) {
// Not a function call.
return;
}
// This sniff isn't concerned about function declarations.
$prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
if ($prev !== false && $tokens[$prev]['code'] === \T_FUNCTION) {
return;
}
/*
* Deal with PHP 7 relaxing the rules.
* "As of PHP 7.0.0 these keywords are allowed as property, constant, and method names
* of classes, interfaces and traits...", i.e. they can be invoked as a method call.
*
* Only needed for those keywords which we sniff out via T_STRING.
*/
if (($tokens[$prev]['code'] === \T_OBJECT_OPERATOR || $tokens[$prev]['code'] === \T_DOUBLE_COLON)
&& $this->supportsBelow('5.6') === false
) {
return;
}
// For the word catch, it is valid to have an open parenthesis
// after it, but only if it is preceded by a right curly brace.
if ($tokenCode === \T_CATCH) {
if ($prev !== false && $tokens[$prev]['code'] === \T_CLOSE_CURLY_BRACKET) {
// Ok, it's fine.
return;
}
}
if ($isString === true) {
$version = $this->targetedStringTokens[$tokenContentLc];
} else {
$version = $this->targetedTokens[$tokenCode];
}
if ($this->supportsAbove($version)) {
$error = "'%s' is a reserved keyword introduced in PHP version %s and cannot be invoked as a function (%s)";
$errorCode = $this->stringToErrorCode($tokenContentLc) . 'Found';
$data = array(
$tokenContentLc,
$version,
$tokens[$stackPtr]['type'],
);
$phpcsFile->addError($error, $stackPtr, $errorCode, $data);
}
}
}