Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into readonly3
Browse files Browse the repository at this point in the history
  • Loading branch information
keradus committed Dec 16, 2024
2 parents 3e47054 + a3726ef commit fd9e822
Show file tree
Hide file tree
Showing 9 changed files with 366 additions and 45 deletions.
5 changes: 5 additions & 0 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Security Policy

To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/security/advisories/new) tab.

Report security bugs in third-party libraries to the person or team maintaining that library.
2 changes: 1 addition & 1 deletion doc/rules/function_notation/use_arrow_functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Rule ``use_arrow_functions``
============================

Anonymous functions with one-liner return statement must use arrow functions.
Anonymous functions with return as the only statement must use arrow functions.

Warning
-------
Expand Down
2 changes: 1 addition & 1 deletion doc/rules/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ Function Notation
Lambdas not (indirectly) referencing ``$this`` must be declared ``static``.
- `use_arrow_functions <./function_notation/use_arrow_functions.rst>`_ *(risky)*

Anonymous functions with one-liner return statement must use arrow functions.
Anonymous functions with return as the only statement must use arrow functions.
- `void_return <./function_notation/void_return.rst>`_ *(risky)*

Add ``void`` return type to functions with missing or empty return statements, but priority is given to ``@return`` annotations.
Expand Down
26 changes: 2 additions & 24 deletions src/Fixer/FunctionNotation/UseArrowFunctionsFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final class UseArrowFunctionsFixer extends AbstractFixer
public function getDefinition(): FixerDefinitionInterface
{
return new FixerDefinition(
'Anonymous functions with one-liner return statement must use arrow functions.',
'Anonymous functions with return as the only statement must use arrow functions.',
[
new CodeSample(
<<<'SAMPLE'
Expand Down Expand Up @@ -78,8 +78,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
continue;
}

// Find parameters end
// Abort if they are multilined
// Find parameters

$parametersStart = $tokens->getNextMeaningfulToken($index);

Expand All @@ -89,10 +88,6 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void

$parametersEnd = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $parametersStart);

if ($this->isMultilined($tokens, $parametersStart, $parametersEnd)) {
continue;
}

// Find `use ()` start and end
// Abort if it contains reference variables

Expand Down Expand Up @@ -158,29 +153,12 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
continue;
}

// Abort if the `return` statement is multilined

if ($this->isMultilined($tokens, $return, $semicolon)) {
continue;
}

// Transform the function to an arrow function

$this->transform($tokens, $index, $useStart, $useEnd, $braceOpen, $return, $semicolon, $braceClose);
}
}

private function isMultilined(Tokens $tokens, int $start, int $end): bool
{
for ($i = $start; $i < $end; ++$i) {
if (str_contains($tokens[$i]->getContent(), "\n")) {
return true;
}
}

return false;
}

private function transform(Tokens $tokens, int $index, ?int $useStart, ?int $useEnd, int $braceOpen, int $return, int $semicolon, int $braceClose): void
{
$tokensToInsert = [new Token([T_DOUBLE_ARROW, '=>'])];
Expand Down
52 changes: 52 additions & 0 deletions src/Fixer/PhpUnit/PhpUnitTestCaseStaticMethodCallsFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,35 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i
'assertClassNotHasStaticAttribute' => true,
'assertContains' => true,
'assertContainsEquals' => true,
'assertContainsNotOnlyArray' => true,
'assertContainsNotOnlyBool' => true,
'assertContainsNotOnlyCallable' => true,
'assertContainsNotOnlyClosedResource' => true,
'assertContainsNotOnlyFloat' => true,
'assertContainsNotOnlyInstancesOf' => true,
'assertContainsNotOnlyInt' => true,
'assertContainsNotOnlyIterable' => true,
'assertContainsNotOnlyNull' => true,
'assertContainsNotOnlyNumeric' => true,
'assertContainsNotOnlyObject' => true,
'assertContainsNotOnlyResource' => true,
'assertContainsNotOnlyScalar' => true,
'assertContainsNotOnlyString' => true,
'assertContainsOnly' => true,
'assertContainsOnlyArray' => true,
'assertContainsOnlyBool' => true,
'assertContainsOnlyCallable' => true,
'assertContainsOnlyClosedResource' => true,
'assertContainsOnlyFloat' => true,
'assertContainsOnlyInstancesOf' => true,
'assertContainsOnlyInt' => true,
'assertContainsOnlyIterable' => true,
'assertContainsOnlyNull' => true,
'assertContainsOnlyNumeric' => true,
'assertContainsOnlyObject' => true,
'assertContainsOnlyResource' => true,
'assertContainsOnlyScalar' => true,
'assertContainsOnlyString' => true,
'assertCount' => true,
'assertDirectoryDoesNotExist' => true,
'assertDirectoryExists' => true,
Expand Down Expand Up @@ -254,7 +281,20 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i
'containsEqual' => true,
'containsIdentical' => true,
'containsOnly' => true,
'containsOnlyArray' => true,
'containsOnlyBool' => true,
'containsOnlyCallable' => true,
'containsOnlyClosedResource' => true,
'containsOnlyFloat' => true,
'containsOnlyInstancesOf' => true,
'containsOnlyInt' => true,
'containsOnlyIterable' => true,
'containsOnlyNull' => true,
'containsOnlyNumeric' => true,
'containsOnlyObject' => true,
'containsOnlyResource' => true,
'containsOnlyScalar' => true,
'containsOnlyString' => true,
'countOf' => true,
'directoryExists' => true,
'equalTo' => true,
Expand All @@ -269,16 +309,28 @@ final class PhpUnitTestCaseStaticMethodCallsFixer extends AbstractPhpUnitFixer i
'greaterThan' => true,
'greaterThanOrEqual' => true,
'identicalTo' => true,
'isArray' => true,
'isBool' => true,
'isCallable' => true,
'isClosedResource' => true,
'isEmpty' => true,
'isFalse' => true,
'isFinite' => true,
'isFloat' => true,
'isInfinite' => true,
'isInstanceOf' => true,
'isInt' => true,
'isIterable' => true,
'isJson' => true,
'isList' => true,
'isNan' => true,
'isNull' => true,
'isNumeric' => true,
'isObject' => true,
'isReadable' => true,
'isResource' => true,
'isScalar' => true,
'isString' => true,
'isTrue' => true,
'isType' => true,
'isWritable' => true,
Expand Down
2 changes: 2 additions & 0 deletions src/Tokenizer/CT.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ final class CT
public const T_DISJUNCTIVE_NORMAL_FORM_TYPE_PARENTHESIS_CLOSE = 10_037;
public const T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN = 10_038;
public const T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE = 10_039;
public const T_PROPERTY_HOOK_BRACE_OPEN = 10_040;
public const T_PROPERTY_HOOK_BRACE_CLOSE = 10_041;

private function __construct() {}

Expand Down
84 changes: 69 additions & 15 deletions src/Tokenizer/Transformer/BraceTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
* - in `$foo->{$bar}` into CT::T_DYNAMIC_PROP_BRACE_OPEN and CT::T_DYNAMIC_PROP_BRACE_CLOSE,
* - in `${$foo}` into CT::T_DYNAMIC_VAR_BRACE_OPEN and CT::T_DYNAMIC_VAR_BRACE_CLOSE,
* - in `$array{$index}` into CT::T_ARRAY_INDEX_CURLY_BRACE_OPEN and CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE,
* - in `use some\a\{ClassA, ClassB, ClassC as C}` into CT::T_GROUP_IMPORT_BRACE_OPEN, CT::T_GROUP_IMPORT_BRACE_CLOSE.
* - in `use some\a\{ClassA, ClassB, ClassC as C}` into CT::T_GROUP_IMPORT_BRACE_OPEN, CT::T_GROUP_IMPORT_BRACE_CLOSE,
* - in `class PropertyHooks { public string $bar _{_ set(string $value) { } _}_` into CT::T_PROPERTY_HOOK_BRACE_OPEN, CT::T_PROPERTY_HOOK_BRACE_CLOSE.
*
* @author Dariusz Rumiński <[email protected]>
*
Expand All @@ -43,13 +44,14 @@ public function getRequiredPhpVersionId(): int

public function process(Tokens $tokens, Token $token, int $index): void
{
$this->transformIntoCurlyCloseBrace($tokens, $token, $index);
$this->transformIntoDollarCloseBrace($tokens, $token, $index);
$this->transformIntoDynamicPropBraces($tokens, $token, $index);
$this->transformIntoDynamicVarBraces($tokens, $token, $index);
$this->transformIntoCurlyIndexBraces($tokens, $token, $index);
$this->transformIntoGroupUseBraces($tokens, $token, $index);
$this->transformIntoDynamicClassConstantFetchBraces($tokens, $token, $index);
$this->transformIntoCurlyCloseBrace($tokens, $index);
$this->transformIntoDollarCloseBrace($tokens, $index);
$this->transformIntoDynamicPropBraces($tokens, $index);
$this->transformIntoDynamicVarBraces($tokens, $index);
$this->transformIntoPropertyHookBraces($tokens, $index);
$this->transformIntoCurlyIndexBraces($tokens, $index);
$this->transformIntoGroupUseBraces($tokens, $index);
$this->transformIntoDynamicClassConstantFetchBraces($tokens, $index);
}

public function getCustomTokens(): array
Expand All @@ -67,6 +69,8 @@ public function getCustomTokens(): array
CT::T_GROUP_IMPORT_BRACE_CLOSE,
CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_OPEN,
CT::T_DYNAMIC_CLASS_CONSTANT_FETCH_CURLY_BRACE_CLOSE,
CT::T_PROPERTY_HOOK_BRACE_OPEN,
CT::T_PROPERTY_HOOK_BRACE_CLOSE,
];
}

Expand All @@ -75,8 +79,10 @@ public function getCustomTokens(): array
*
* This should be done at very beginning of curly braces transformations.
*/
private function transformIntoCurlyCloseBrace(Tokens $tokens, Token $token, int $index): void
private function transformIntoCurlyCloseBrace(Tokens $tokens, int $index): void
{
$token = $tokens[$index];

if (!$token->isGivenKind(T_CURLY_OPEN)) {
return;
}
Expand All @@ -96,16 +102,20 @@ private function transformIntoCurlyCloseBrace(Tokens $tokens, Token $token, int
$tokens[$index] = new Token([CT::T_CURLY_CLOSE, '}']);
}

private function transformIntoDollarCloseBrace(Tokens $tokens, Token $token, int $index): void
private function transformIntoDollarCloseBrace(Tokens $tokens, int $index): void
{
$token = $tokens[$index];

if ($token->isGivenKind(T_DOLLAR_OPEN_CURLY_BRACES)) {
$nextIndex = $tokens->getNextTokenOfKind($index, ['}']);
$tokens[$nextIndex] = new Token([CT::T_DOLLAR_CLOSE_CURLY_BRACES, '}']);
}
}

private function transformIntoDynamicPropBraces(Tokens $tokens, Token $token, int $index): void
private function transformIntoDynamicPropBraces(Tokens $tokens, int $index): void
{
$token = $tokens[$index];

if (!$token->isObjectOperator()) {
return;
}
Expand All @@ -121,8 +131,10 @@ private function transformIntoDynamicPropBraces(Tokens $tokens, Token $token, in
$tokens[$closeIndex] = new Token([CT::T_DYNAMIC_PROP_BRACE_CLOSE, '}']);
}

private function transformIntoDynamicVarBraces(Tokens $tokens, Token $token, int $index): void
private function transformIntoDynamicVarBraces(Tokens $tokens, int $index): void
{
$token = $tokens[$index];

if (!$token->equals('$')) {
return;
}
Expand All @@ -145,8 +157,46 @@ private function transformIntoDynamicVarBraces(Tokens $tokens, Token $token, int
$tokens[$closeIndex] = new Token([CT::T_DYNAMIC_VAR_BRACE_CLOSE, '}']);
}

private function transformIntoCurlyIndexBraces(Tokens $tokens, Token $token, int $index): void
private function transformIntoPropertyHookBraces(Tokens $tokens, int $index): void
{
if (\PHP_VERSION_ID < 8_04_00) {
return; // @TODO: drop condition when PHP 8.4+ is required or majority of the users are using 8.4+
}

$token = $tokens[$index];

if (!$token->equals('{')) {
return;
}

$nextIndex = $tokens->getNextMeaningfulToken($index);

// @TODO: drop condition when PHP 8.0+ is required
if (\defined('T_ATTRIBUTE')) {
// skip attributes
while ($tokens[$nextIndex]->isGivenKind(T_ATTRIBUTE)) {
$nextIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ATTRIBUTE, $nextIndex);
$nextIndex = $tokens->getNextMeaningfulToken($nextIndex);
}
}

if (!$tokens[$nextIndex]->equalsAny([
[T_STRING, 'get'],
[T_STRING, 'set'],
])) {
return;
}

$closeIndex = $this->naivelyFindCurlyBlockEnd($tokens, $index);

$tokens[$index] = new Token([CT::T_PROPERTY_HOOK_BRACE_OPEN, '{']);
$tokens[$closeIndex] = new Token([CT::T_PROPERTY_HOOK_BRACE_CLOSE, '}']);
}

private function transformIntoCurlyIndexBraces(Tokens $tokens, int $index): void
{
$token = $tokens[$index];

if (!$token->equals('{')) {
return;
}
Expand Down Expand Up @@ -185,8 +235,10 @@ private function transformIntoCurlyIndexBraces(Tokens $tokens, Token $token, int
$tokens[$closeIndex] = new Token([CT::T_ARRAY_INDEX_CURLY_BRACE_CLOSE, '}']);
}

private function transformIntoGroupUseBraces(Tokens $tokens, Token $token, int $index): void
private function transformIntoGroupUseBraces(Tokens $tokens, int $index): void
{
$token = $tokens[$index];

if (!$token->equals('{')) {
return;
}
Expand All @@ -203,12 +255,14 @@ private function transformIntoGroupUseBraces(Tokens $tokens, Token $token, int $
$tokens[$closeIndex] = new Token([CT::T_GROUP_IMPORT_BRACE_CLOSE, '}']);
}

private function transformIntoDynamicClassConstantFetchBraces(Tokens $tokens, Token $token, int $index): void
private function transformIntoDynamicClassConstantFetchBraces(Tokens $tokens, int $index): void
{
if (\PHP_VERSION_ID < 8_03_00) {
return; // @TODO: drop condition when PHP 8.3+ is required or majority of the users are using 8.3+
}

$token = $tokens[$index];

if (!$token->equals('{')) {
return;
}
Expand Down
Loading

0 comments on commit fd9e822

Please sign in to comment.