155 lines
3.9 KiB
PHP
155 lines
3.9 KiB
PHP
<?php declare(strict_types = 1);
|
|
|
|
namespace SlevomatCodingStandard\Sniffs\Strings;
|
|
|
|
use PHP_CodeSniffer\Files\File;
|
|
use PHP_CodeSniffer\Sniffs\Sniff;
|
|
use UnexpectedValueException;
|
|
use function count;
|
|
use function in_array;
|
|
use function is_array;
|
|
use function sprintf;
|
|
use function strpos;
|
|
use function token_get_all;
|
|
use const T_DOUBLE_QUOTED_STRING;
|
|
use const T_HEREDOC;
|
|
use const T_VARIABLE;
|
|
|
|
class DisallowVariableParsingSniff implements Sniff
|
|
{
|
|
|
|
public const CODE_DISALLOWED_DOLLAR_CURLY_SYNTAX = 'DisallowedDollarCurlySyntax';
|
|
|
|
public const CODE_DISALLOWED_CURLY_DOLLAR_SYNTAX = 'DisallowedCurlyDollarSyntax';
|
|
|
|
public const CODE_DISALLOWED_SIMPLE_SYNTAX = 'DisallowedSimpleSyntax';
|
|
|
|
/** @var bool */
|
|
public $disallowDollarCurlySyntax = true;
|
|
|
|
/** @var bool */
|
|
public $disallowCurlyDollarSyntax = false;
|
|
|
|
/** @var bool */
|
|
public $disallowSimpleSyntax = false;
|
|
|
|
/**
|
|
* @return array<int, (int|string)>
|
|
*/
|
|
public function register(): array
|
|
{
|
|
return [
|
|
T_DOUBLE_QUOTED_STRING,
|
|
T_HEREDOC,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
|
|
* @param int $stringPointer
|
|
*/
|
|
public function process(File $phpcsFile, $stringPointer): void
|
|
{
|
|
if (!$this->disallowDollarCurlySyntax && !$this->disallowCurlyDollarSyntax && !$this->disallowSimpleSyntax) {
|
|
throw new UnexpectedValueException('No option is set.');
|
|
}
|
|
|
|
$tokens = $phpcsFile->getTokens();
|
|
$tokenContent = $tokens[$stringPointer]['content'];
|
|
|
|
if (strpos($tokenContent, '$') === false) {
|
|
return;
|
|
}
|
|
|
|
$stringTokens = $tokens[$stringPointer]['code'] === T_HEREDOC
|
|
? token_get_all('<?php "' . $tokenContent . '"')
|
|
: token_get_all('<?php ' . $tokenContent);
|
|
|
|
for ($i = 0; $i < count($stringTokens); $i++) {
|
|
$stringToken = $stringTokens[$i];
|
|
|
|
if (!is_array($stringToken)) {
|
|
continue;
|
|
}
|
|
|
|
if ($this->disallowDollarCurlySyntax && $this->getTokenContent($stringToken) === '${') {
|
|
$usedVariable = $stringToken[1];
|
|
|
|
for ($j = $i + 1; $j < count($stringTokens); $j++) {
|
|
$usedVariable .= $this->getTokenContent($stringTokens[$j]);
|
|
|
|
if ($this->getTokenContent($stringTokens[$j]) === '}') {
|
|
$phpcsFile->addError(
|
|
sprintf(
|
|
'Using variable syntax "${...}" inside string is disallowed as syntax "${...}" is deprecated as of PHP 8.2, found "%s".',
|
|
$usedVariable
|
|
),
|
|
$stringPointer,
|
|
self::CODE_DISALLOWED_DOLLAR_CURLY_SYNTAX
|
|
);
|
|
|
|
break;
|
|
}
|
|
}
|
|
} elseif ($stringToken[0] === T_VARIABLE) {
|
|
if ($this->disallowCurlyDollarSyntax && $this->getTokenContent($stringTokens[$i - 1]) === '{') {
|
|
$usedVariable = $stringToken[1];
|
|
|
|
for ($j = $i + 1; $j < count($stringTokens); $j++) {
|
|
$stringTokenContent = $this->getTokenContent($stringTokens[$j]);
|
|
if ($stringTokenContent === '}') {
|
|
break;
|
|
}
|
|
|
|
$usedVariable .= $stringTokenContent;
|
|
}
|
|
|
|
$phpcsFile->addError(
|
|
sprintf(
|
|
'Using variable syntax "{$...}" inside string is disallowed, found "{%s}".',
|
|
$usedVariable
|
|
),
|
|
$stringPointer,
|
|
self::CODE_DISALLOWED_CURLY_DOLLAR_SYNTAX
|
|
);
|
|
} elseif ($this->disallowSimpleSyntax) {
|
|
$error = true;
|
|
|
|
for ($j = $i - 1; $j >= 0; $j--) {
|
|
$stringTokenContent = $this->getTokenContent($stringTokens[$j]);
|
|
|
|
if (in_array($stringTokenContent, ['{', '${'], true)) {
|
|
$error = false;
|
|
break;
|
|
}
|
|
|
|
if ($stringTokenContent === '}') {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($error) {
|
|
$phpcsFile->addError(
|
|
sprintf(
|
|
'Using variable syntax "$..." inside string is disallowed, found "%s".',
|
|
$this->getTokenContent($stringToken)
|
|
),
|
|
$stringPointer,
|
|
self::CODE_DISALLOWED_SIMPLE_SYNTAX
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array{0: int, 1: string}|string $token
|
|
*/
|
|
private function getTokenContent($token): string
|
|
{
|
|
return is_array($token) ? $token[1] : $token;
|
|
}
|
|
|
|
}
|