Missing dependancies
This commit is contained in:
+152
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of PHP CS Fixer.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
* Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace PhpCsFixer\Fixer\Strict;
|
||||
|
||||
use PhpCsFixer\AbstractFixer;
|
||||
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
|
||||
/**
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*/
|
||||
final class DeclareStrictTypesFixer extends AbstractFixer implements WhitespacesAwareFixerInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition(): FixerDefinitionInterface
|
||||
{
|
||||
return new FixerDefinition(
|
||||
'Force strict types declaration in all files. Requires PHP >= 7.0.',
|
||||
[
|
||||
new CodeSample(
|
||||
"<?php\n"
|
||||
),
|
||||
],
|
||||
null,
|
||||
'Forcing strict types will stop non strict code from working.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Must run before BlankLineAfterOpeningTagFixer, DeclareEqualNormalizeFixer, HeaderCommentFixer.
|
||||
*/
|
||||
public function getPriority(): int
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens): bool
|
||||
{
|
||||
return isset($tokens[0]) && $tokens[0]->isGivenKind(T_OPEN_TAG);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isRisky(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
|
||||
{
|
||||
// check if the declaration is already done
|
||||
$searchIndex = $tokens->getNextMeaningfulToken(0);
|
||||
if (null === $searchIndex) {
|
||||
$this->insertSequence($tokens); // declaration not found, insert one
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$sequenceLocation = $tokens->findSequence([[T_DECLARE, 'declare'], '(', [T_STRING, 'strict_types'], '=', [T_LNUMBER], ')'], $searchIndex, null, false);
|
||||
if (null === $sequenceLocation) {
|
||||
$this->insertSequence($tokens); // declaration not found, insert one
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->fixStrictTypesCasingAndValue($tokens, $sequenceLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, Token> $sequence
|
||||
*/
|
||||
private function fixStrictTypesCasingAndValue(Tokens $tokens, array $sequence): void
|
||||
{
|
||||
/** @var int $index */
|
||||
/** @var Token $token */
|
||||
foreach ($sequence as $index => $token) {
|
||||
if ($token->isGivenKind(T_STRING)) {
|
||||
$tokens[$index] = new Token([T_STRING, strtolower($token->getContent())]);
|
||||
|
||||
continue;
|
||||
}
|
||||
if ($token->isGivenKind(T_LNUMBER)) {
|
||||
$tokens[$index] = new Token([T_LNUMBER, '1']);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function insertSequence(Tokens $tokens): void
|
||||
{
|
||||
$sequence = [
|
||||
new Token([T_DECLARE, 'declare']),
|
||||
new Token('('),
|
||||
new Token([T_STRING, 'strict_types']),
|
||||
new Token('='),
|
||||
new Token([T_LNUMBER, '1']),
|
||||
new Token(')'),
|
||||
new Token(';'),
|
||||
];
|
||||
$endIndex = \count($sequence);
|
||||
|
||||
$tokens->insertAt(1, $sequence);
|
||||
|
||||
// start index of the sequence is always 1 here, 0 is always open tag
|
||||
// transform "<?php\n" to "<?php " if needed
|
||||
if (str_contains($tokens[0]->getContent(), "\n")) {
|
||||
$tokens[0] = new Token([$tokens[0]->getId(), trim($tokens[0]->getContent()).' ']);
|
||||
}
|
||||
|
||||
if ($endIndex === \count($tokens) - 1) {
|
||||
return; // no more tokens after sequence, single_blank_line_at_eof might add a line
|
||||
}
|
||||
|
||||
$lineEnding = $this->whitespacesConfig->getLineEnding();
|
||||
if (!$tokens[1 + $endIndex]->isWhitespace()) {
|
||||
$tokens->insertAt(1 + $endIndex, new Token([T_WHITESPACE, $lineEnding]));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$content = $tokens[1 + $endIndex]->getContent();
|
||||
$tokens[1 + $endIndex] = new Token([T_WHITESPACE, $lineEnding.ltrim($content, " \t")]);
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of PHP CS Fixer.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
* Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace PhpCsFixer\Fixer\Strict;
|
||||
|
||||
use PhpCsFixer\AbstractFixer;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
|
||||
/**
|
||||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
*/
|
||||
final class StrictComparisonFixer extends AbstractFixer
|
||||
{
|
||||
public function getDefinition(): FixerDefinitionInterface
|
||||
{
|
||||
return new FixerDefinition(
|
||||
'Comparisons should be strict.',
|
||||
[new CodeSample("<?php\n\$a = 1== \$b;\n")],
|
||||
null,
|
||||
'Changing comparisons to strict might change code behavior.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Must run before BinaryOperatorSpacesFixer, ModernizeStrposFixer.
|
||||
*/
|
||||
public function getPriority(): int
|
||||
{
|
||||
return 38;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens): bool
|
||||
{
|
||||
return $tokens->isAnyTokenKindsFound([T_IS_EQUAL, T_IS_NOT_EQUAL]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isRisky(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
|
||||
{
|
||||
static $map = [
|
||||
T_IS_EQUAL => [
|
||||
'id' => T_IS_IDENTICAL,
|
||||
'content' => '===',
|
||||
],
|
||||
T_IS_NOT_EQUAL => [
|
||||
'id' => T_IS_NOT_IDENTICAL,
|
||||
'content' => '!==',
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($tokens as $index => $token) {
|
||||
$tokenId = $token->getId();
|
||||
|
||||
if (isset($map[$tokenId])) {
|
||||
$tokens[$index] = new Token([$map[$tokenId]['id'], $map[$tokenId]['content']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of PHP CS Fixer.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
* Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace PhpCsFixer\Fixer\Strict;
|
||||
|
||||
use PhpCsFixer\AbstractFixer;
|
||||
use PhpCsFixer\FixerDefinition\CodeSample;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinition;
|
||||
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
|
||||
use PhpCsFixer\Tokenizer\Analyzer\FunctionsAnalyzer;
|
||||
use PhpCsFixer\Tokenizer\CT;
|
||||
use PhpCsFixer\Tokenizer\Token;
|
||||
use PhpCsFixer\Tokenizer\Tokens;
|
||||
|
||||
/**
|
||||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
*/
|
||||
final class StrictParamFixer extends AbstractFixer
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDefinition(): FixerDefinitionInterface
|
||||
{
|
||||
return new FixerDefinition(
|
||||
'Functions should be used with `$strict` param set to `true`.',
|
||||
[new CodeSample("<?php\n\$a = array_keys(\$b);\n\$a = array_search(\$b, \$c);\n\$a = base64_decode(\$b);\n\$a = in_array(\$b, \$c);\n\$a = mb_detect_encoding(\$b, \$c);\n")],
|
||||
'The functions "array_keys", "array_search", "base64_decode", "in_array" and "mb_detect_encoding" should be used with $strict param.',
|
||||
'Risky when the fixed function is overridden or if the code relies on non-strict usage.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isCandidate(Tokens $tokens): bool
|
||||
{
|
||||
return $tokens->isTokenKindFound(T_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isRisky(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Must run before MethodArgumentSpaceFixer, NativeFunctionInvocationFixer.
|
||||
*/
|
||||
public function getPriority(): int
|
||||
{
|
||||
return 31;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
|
||||
{
|
||||
$functionsAnalyzer = new FunctionsAnalyzer();
|
||||
|
||||
static $map = null;
|
||||
|
||||
if (null === $map) {
|
||||
$trueToken = new Token([T_STRING, 'true']);
|
||||
|
||||
$map = [
|
||||
'array_keys' => [null, null, $trueToken],
|
||||
'array_search' => [null, null, $trueToken],
|
||||
'base64_decode' => [null, $trueToken],
|
||||
'in_array' => [null, null, $trueToken],
|
||||
'mb_detect_encoding' => [null, [new Token([T_STRING, 'mb_detect_order']), new Token('('), new Token(')')], $trueToken],
|
||||
];
|
||||
}
|
||||
|
||||
for ($index = $tokens->count() - 1; 0 <= $index; --$index) {
|
||||
$token = $tokens[$index];
|
||||
|
||||
$nextIndex = $tokens->getNextMeaningfulToken($index);
|
||||
if (null !== $nextIndex && !$tokens[$nextIndex]->equals('(')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lowercaseContent = strtolower($token->getContent());
|
||||
if (isset($map[$lowercaseContent]) && $functionsAnalyzer->isGlobalFunctionCall($tokens, $index)) {
|
||||
$this->fixFunction($tokens, $index, $map[$lowercaseContent]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function fixFunction(Tokens $tokens, int $functionIndex, array $functionParams): void
|
||||
{
|
||||
$startBraceIndex = $tokens->getNextTokenOfKind($functionIndex, ['(']);
|
||||
$endBraceIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startBraceIndex);
|
||||
$paramsQuantity = 0;
|
||||
$expectParam = true;
|
||||
|
||||
for ($index = $startBraceIndex + 1; $index < $endBraceIndex; ++$index) {
|
||||
$token = $tokens[$index];
|
||||
|
||||
if ($expectParam && !$token->isWhitespace() && !$token->isComment()) {
|
||||
++$paramsQuantity;
|
||||
$expectParam = false;
|
||||
}
|
||||
|
||||
if ($token->equals('(')) {
|
||||
$index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $index);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($token->isGivenKind(CT::T_ARRAY_SQUARE_BRACE_OPEN)) {
|
||||
$index = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $index);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($token->equals(',')) {
|
||||
$expectParam = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$functionParamsQuantity = \count($functionParams);
|
||||
|
||||
if ($paramsQuantity === $functionParamsQuantity) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tokensToInsert = [];
|
||||
|
||||
for ($i = $paramsQuantity; $i < $functionParamsQuantity; ++$i) {
|
||||
// function call do not have all params that are required to set useStrict flag, exit from method!
|
||||
if (!$functionParams[$i]) {
|
||||
return;
|
||||
}
|
||||
|
||||
$tokensToInsert[] = new Token(',');
|
||||
$tokensToInsert[] = new Token([T_WHITESPACE, ' ']);
|
||||
|
||||
if (!\is_array($functionParams[$i])) {
|
||||
$tokensToInsert[] = clone $functionParams[$i];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($functionParams[$i] as $param) {
|
||||
$tokensToInsert[] = clone $param;
|
||||
}
|
||||
}
|
||||
|
||||
$beforeEndBraceIndex = $tokens->getPrevMeaningfulToken($endBraceIndex);
|
||||
|
||||
if ($tokens[$beforeEndBraceIndex]->equals(',')) {
|
||||
array_shift($tokensToInsert);
|
||||
$tokensToInsert[] = new Token(',');
|
||||
}
|
||||
|
||||
$tokens->insertAt($beforeEndBraceIndex + 1, $tokensToInsert);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user