Skip to content

Commit

Permalink
Merge branch 'master' into get-class-to-class-keyword
Browse files Browse the repository at this point in the history
  • Loading branch information
keradus committed Oct 5, 2021
2 parents c5a3dc0 + 72ebcfb commit c91a4dd
Show file tree
Hide file tree
Showing 32 changed files with 766 additions and 57 deletions.
10 changes: 10 additions & 0 deletions doc/list.rst
Expand Up @@ -2728,6 +2728,16 @@ List of Available Rules
Part of rule set `@PhpCsFixer:risky <./ruleSets/PhpCsFixerRisky.rst>`_

`Source PhpCsFixer\\Fixer\\Strict\\StrictParamFixer <./../src/Fixer/Strict/StrictParamFixer.php>`_
- `string_length_to_empty <./rules/string_notation/string_length_to_empty.rst>`_

String tests for empty must be done against ``''``, not with ``strlen``.

*warning risky* Risky when ``strlen`` is overridden, when called using a ``stringable``
object, also no longer triggers warning when called using non-string(able).

Part of rule sets `@PhpCsFixer:risky <./ruleSets/PhpCsFixerRisky.rst>`_ `@Symfony:risky <./ruleSets/SymfonyRisky.rst>`_

`Source PhpCsFixer\\Fixer\\StringNotation\\StringLengthToEmptyFixer <./../src/Fixer/StringNotation/StringLengthToEmptyFixer.php>`_
- `string_line_ending <./rules/string_notation/string_line_ending.rst>`_

All multi-line strings must use correct line ending.
Expand Down
1 change: 1 addition & 0 deletions doc/ruleSets/SymfonyRisky.rst
Expand Up @@ -42,5 +42,6 @@ Rules
- `psr_autoloading <./../rules/basic/psr_autoloading.rst>`_
- `self_accessor <./../rules/class_notation/self_accessor.rst>`_
- `set_type_to_cast <./../rules/alias/set_type_to_cast.rst>`_
- `string_length_to_empty <./../rules/string_notation/string_length_to_empty.rst>`_
- `string_line_ending <./../rules/string_notation/string_line_ending.rst>`_
- `ternary_to_elvis_operator <./../rules/operator/ternary_to_elvis_operator.rst>`_
3 changes: 3 additions & 0 deletions doc/rules/index.rst
Expand Up @@ -776,6 +776,9 @@ String Notation
- `single_quote <./string_notation/single_quote.rst>`_

Convert double quotes to single quotes for simple strings.
- `string_length_to_empty <./string_notation/string_length_to_empty.rst>`_ *(risky)*

String tests for empty must be done against ``''``, not with ``strlen``.
- `string_line_ending <./string_notation/string_line_ending.rst>`_ *(risky)*

All multi-line strings must use correct line ending.
Expand Down
34 changes: 34 additions & 0 deletions doc/rules/string_notation/string_length_to_empty.rst
@@ -0,0 +1,34 @@
===============================
Rule ``string_length_to_empty``
===============================

String tests for empty must be done against ``''``, not with ``strlen``.

.. warning:: Using this rule is risky.

Risky when ``strlen`` is overridden, when called using a ``stringable``
object, also no longer triggers warning when called using non-string(able).

Examples
--------

Example #1
~~~~~~~~~~

.. code-block:: diff
--- Original
+++ New
-<?php $a = 0 === strlen($b) || \STRLEN($c) < 1;
+<?php $a = '' === $b || $c === '';
Rule sets
---------

The rule is part of the following rule sets:

@PhpCsFixer:risky
Using the `@PhpCsFixer:risky <./../../ruleSets/PhpCsFixerRisky.rst>`_ rule set will enable the ``string_length_to_empty`` rule.

@Symfony:risky
Using the `@Symfony:risky <./../../ruleSets/SymfonyRisky.rst>`_ rule set will enable the ``string_length_to_empty`` rule.
21 changes: 18 additions & 3 deletions src/AbstractFunctionReferenceFixer.php
Expand Up @@ -24,6 +24,19 @@
*/
abstract class AbstractFunctionReferenceFixer extends AbstractFixer
{
/**
* @var null|FunctionsAnalyzer
*/
private $functionsAnalyzer;

/**
* {@inheritdoc}
*/
public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_STRING);
}

/**
* {@inheritdoc}
*/
Expand All @@ -40,6 +53,10 @@ public function isRisky(): bool
*/
protected function find(string $functionNameToSearch, Tokens $tokens, int $start = 0, ?int $end = null): ?array
{
if (null === $this->functionsAnalyzer) {
$this->functionsAnalyzer = new FunctionsAnalyzer();
}

// make interface consistent with findSequence
$end = $end ?? $tokens->count();

Expand All @@ -54,9 +71,7 @@ protected function find(string $functionNameToSearch, Tokens $tokens, int $start
// translate results for humans
[$functionName, $openParenthesis] = array_keys($matches);

$functionsAnalyzer = new FunctionsAnalyzer();

if (!$functionsAnalyzer->isGlobalFunctionCall($tokens, $functionName)) {
if (!$this->functionsAnalyzer->isGlobalFunctionCall($tokens, $functionName)) {
return $this->find($functionNameToSearch, $tokens, $openParenthesis, $end);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Cache/Cache.php
Expand Up @@ -78,7 +78,7 @@ public function toJson(): string

if (JSON_ERROR_NONE !== json_last_error()) {
throw new \UnexpectedValueException(sprintf(
'Can not encode cache signature to JSON, error: "%s". If you have non-UTF8 chars in your signature, like in license for `header_comment`, consider enabling `ext-mbstring` or install `symfony/polyfill-mbstring`.',
'Cannot encode cache signature to JSON, error: "%s". If you have non-UTF8 chars in your signature, like in license for `header_comment`, consider enabling `ext-mbstring` or install `symfony/polyfill-mbstring`.',
json_last_error_msg()
));
}
Expand Down
2 changes: 1 addition & 1 deletion src/Console/Command/DescribeCommand.php
Expand Up @@ -256,7 +256,7 @@ static function (string $type): string {

if (0 === \count($codeSamples)) {
$output->writeln([
'Fixing examples can not be demonstrated on the current PHP version.',
'Fixing examples cannot be demonstrated on the current PHP version.',
'',
]);
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/DocBlock/DocBlock.php
Expand Up @@ -244,7 +244,7 @@ private function getSingleLineDocBlockEntry(Line $line): string
{
$lineString = $line->getContent();

if (0 === \strlen($lineString)) {
if ('' === $lineString) {
return $lineString;
}

Expand Down
2 changes: 1 addition & 1 deletion src/FileReader.php
Expand Up @@ -17,7 +17,7 @@
/**
* File reader that unify access to regular file and stdin-alike file.
*
* Regular file could be read multiple times with `file_get_contents`, but file provided on stdin can not.
* Regular file could be read multiple times with `file_get_contents`, but file provided on stdin cannot.
* Consecutive try will provide empty content for stdin-alike file.
* This reader unifies access to them.
*
Expand Down
8 changes: 0 additions & 8 deletions src/Fixer/Alias/MbStrFunctionsFixer.php
Expand Up @@ -93,14 +93,6 @@ public function getDefinition(): FixerDefinitionInterface
);
}

/**
* {@inheritdoc}
*/
public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_STRING);
}

/**
* {@inheritdoc}
*/
Expand Down
20 changes: 10 additions & 10 deletions src/Fixer/Alias/ModernizeStrposFixer.php
Expand Up @@ -188,15 +188,15 @@ private function getCompareTokens(Tokens $tokens, int $offsetIndex, int $directi

private function isOfHigherPrecedence(Token $token): bool
{
static $operatorsPerId = [
T_DEC => true, // --
T_INC => true, // ++
T_INSTANCEOF => true, // instanceof
T_IS_GREATER_OR_EQUAL => true, // >=
T_IS_SMALLER_OR_EQUAL => true, // <=
T_POW => true, // **
T_SL => true, // <<
T_SR => true, // >>
static $operatorsKinds = [
T_DEC, // --
T_INC, // ++
T_INSTANCEOF, // instanceof
T_IS_GREATER_OR_EQUAL, // >=
T_IS_SMALLER_OR_EQUAL, // <=
T_POW, // **
T_SL, // <<
T_SR, // >>
];

static $operatorsPerContent = [
Expand All @@ -212,6 +212,6 @@ private function isOfHigherPrecedence(Token $token): bool
'~',
];

return isset($operatorsPerId[$token->getId()]) || $token->equalsAny($operatorsPerContent);
return $token->isGivenKind($operatorsKinds) || $token->equalsAny($operatorsPerContent);
}
}
2 changes: 1 addition & 1 deletion src/Fixer/Alias/PowToExponentiationFixer.php
Expand Up @@ -106,7 +106,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
}

/**
* @return array[]
* @return array<int[]>
*/
private function findPowCalls(Tokens $tokens): array
{
Expand Down
8 changes: 0 additions & 8 deletions src/Fixer/Alias/RandomApiMigrationFixer.php
Expand Up @@ -81,14 +81,6 @@ public function getDefinition(): FixerDefinitionInterface
);
}

/**
* {@inheritdoc}
*/
public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_STRING);
}

/**
* {@inheritdoc}
*/
Expand Down
4 changes: 2 additions & 2 deletions src/Fixer/Basic/PsrAutoloadingFixer.php
Expand Up @@ -124,11 +124,11 @@ public function supports(\SplFileInfo $file): bool
$tokens = Tokens::fromCode(sprintf('<?php class %s {}', $file->getBasename('.php')));

if ($tokens[3]->isKeyword() || $tokens[3]->isMagicConstant()) {
// name can not be a class name - detected by PHP 5.x
// name cannot be a class name - detected by PHP 5.x
return false;
}
} catch (\ParseError $e) {
// name can not be a class name - detected by PHP 7.x
// name cannot be a class name - detected by PHP 7.x
return false;
}

Expand Down
8 changes: 0 additions & 8 deletions src/Fixer/CastNotation/ModernizeTypesCastingFixer.php
Expand Up @@ -50,14 +50,6 @@ public function getDefinition(): FixerDefinitionInterface
);
}

/**
* {@inheritdoc}
*/
public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_STRING);
}

/**
* {@inheritdoc}
*/
Expand Down
6 changes: 1 addition & 5 deletions src/Fixer/FunctionNotation/FunctionDeclarationFixer.php
Expand Up @@ -57,11 +57,7 @@ final class FunctionDeclarationFixer extends AbstractFixer implements Configurab
*/
public function isCandidate(Tokens $tokens): bool
{
if (\PHP_VERSION_ID >= 70400 && $tokens->isTokenKindFound(T_FN)) {
return true;
}

return $tokens->isTokenKindFound(T_FUNCTION);
return $tokens->isTokenKindFound(T_FUNCTION) || (\PHP_VERSION_ID >= 70400 && $tokens->isTokenKindFound(T_FN));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Fixer/LanguageConstruct/DirConstantFixer.php
Expand Up @@ -44,7 +44,7 @@ public function getDefinition(): FixerDefinitionInterface
*/
public function isCandidate(Tokens $tokens): bool
{
return $tokens->isTokenKindFound(T_FILE);
return $tokens->isAllTokenKindsFound([T_STRING, T_FILE]);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Fixer/Operator/BinaryOperatorSpacesFixer.php
Expand Up @@ -720,7 +720,7 @@ private function replacePlaceholders(Tokens $tokens, string $alignStrategy): str
$before = substr($lines[$index], 0, $currentPosition);

if (self::ALIGN_SINGLE_SPACE === $alignStrategy) {
if (1 > \strlen($before) || ' ' !== substr($before, -1)) { // if last char of before-content is not ' '; add it
if (!str_ends_with($before, ' ')) { // if last char of before-content is not ' '; add it
$before .= ' ';
}
} elseif (self::ALIGN_SINGLE_SPACE_MINIMAL === $alignStrategy) {
Expand Down
5 changes: 5 additions & 0 deletions src/Fixer/Phpdoc/PhpdocLineSpanFixer.php
Expand Up @@ -102,6 +102,11 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
}

$type = $element['type'];

if (!isset($this->configuration[$type])) {
continue;
}

$docIndex = $this->getDocBlockIndex($tokens, $index);
$doc = new DocBlock($tokens[$docIndex]->getContent());

Expand Down

0 comments on commit c91a4dd

Please sign in to comment.