Skip to content

Commit

Permalink
Merge branch 'master' into xx
Browse files Browse the repository at this point in the history
  • Loading branch information
keradus committed Oct 31, 2023
2 parents c937dbf + 877bfb6 commit 2cbc40d
Show file tree
Hide file tree
Showing 15 changed files with 329 additions and 86 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/issues_and_pull_requests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ env:
DAYS_BEFORE_ISSUE_STALE: 90
DAYS_BEFORE_PR_CLOSE: 14
DAYS_BEFORE_PR_STALE: 90
EXEMPT_MILESTONES: "long-term-ideas"
STALE_CLARIFICATION: |
The purpose of this action is to enforce backlog review once in a while. This is mostly for maintainers and helps with keeping repository in good condition, because stale issues and PRs can accumulate over time and make it harder for others to find relevant information. It is also possible that some changes has been made to the repo already, and issue or PR became outdated, but wasn't closed for some reason. This action helps with periodic review and closing of such stale items in automated way.
Expand All @@ -37,7 +36,7 @@ jobs:
days-before-issue-stale: "${{ env.DAYS_BEFORE_ISSUE_STALE }}"
days-before-pr-close: "${{ env.DAYS_BEFORE_PR_CLOSE }}"
days-before-pr-stale: "${{ env.DAYS_BEFORE_PR_STALE }}"
exempt-milestones: "${{ env.EXEMPT_MILESTONES }}"
exempt-all-milestones: true
labels-to-add-when-unstale: "status/to verify"
repo-token: "${{ secrets.GITHUB_TOKEN }}"
stale-issue-label: "status/stale"
Expand Down
14 changes: 14 additions & 0 deletions src/Fixer/ClassNotation/SelfAccessorFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,21 @@ private function replaceNameOccurrences(Tokens $tokens, string $namespace, strin
continue;
}

if ($token->isGivenKind(T_FN)) {
$i = $tokensAnalyzer->getLastTokenIndexOfArrowFunction($i);
$i = $tokens->getNextMeaningfulToken($i);

continue;
}

if ($token->isGivenKind(T_FUNCTION)) {
if ($tokensAnalyzer->isLambda($i)) {
$i = $tokens->getNextTokenOfKind($i, ['{']);
$i = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $i);

continue;
}

$i = $tokens->getNextTokenOfKind($i, ['(']);
$insideMethodSignatureUntil = $tokens->getNextTokenOfKind($i, ['{', ';']);

Expand Down
1 change: 0 additions & 1 deletion src/Fixer/FunctionNotation/PhpdocToParamTypeFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ final class PhpdocToParamTypeFixer extends AbstractPhpdocToTypeDeclarationFixer
* @var array<string, true>
*/
private const SKIPPED_TYPES = [
'mixed' => true,
'resource' => true,
'static' => true,
'void' => true,
Expand Down
1 change: 0 additions & 1 deletion src/Fixer/FunctionNotation/PhpdocToPropertyTypeFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ final class PhpdocToPropertyTypeFixer extends AbstractPhpdocToTypeDeclarationFix
* @var array<string, true>
*/
private array $skippedTypes = [
'mixed' => true,
'resource' => true,
'null' => true,
];
Expand Down
5 changes: 0 additions & 5 deletions src/Fixer/FunctionNotation/PhpdocToReturnTypeFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ final class PhpdocToReturnTypeFixer extends AbstractPhpdocToTypeDeclarationFixer
* @var array<string, true>
*/
private array $skippedTypes = [
'mixed' => true,
'resource' => true,
'null' => true,
];
Expand Down Expand Up @@ -120,10 +119,6 @@ protected function isSkippedType(string $type): bool

protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
{
if (\PHP_VERSION_ID >= 8_00_00) {
unset($this->skippedTypes['mixed']);
}

for ($index = $tokens->count() - 1; 0 < $index; --$index) {
if (!$tokens[$index]->isGivenKind([T_FUNCTION, T_FN])) {
continue;
Expand Down
27 changes: 1 addition & 26 deletions src/Fixer/FunctionNotation/StaticLambdaFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
$lambdaEndIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $lambdaOpenIndex);
} else { // T_FN
$lambdaOpenIndex = $tokens->getNextTokenOfKind($argumentsEndIndex, [[T_DOUBLE_ARROW]]);
$lambdaEndIndex = $this->findExpressionEnd($tokens, $lambdaOpenIndex);
$lambdaEndIndex = $analyzer->getLastTokenIndexOfArrowFunction($index);
}

if ($this->hasPossibleReferenceToThis($tokens, $lambdaOpenIndex, $lambdaEndIndex)) {
Expand All @@ -91,31 +91,6 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
}
}

private function findExpressionEnd(Tokens $tokens, int $index): int
{
$nextIndex = $tokens->getNextMeaningfulToken($index);

while (null !== $nextIndex) {
/** @var Token $nextToken */
$nextToken = $tokens[$nextIndex];

if ($nextToken->equalsAny([',', ';', [T_CLOSE_TAG]])) {
break;
}

$blockType = Tokens::detectBlockType($nextToken);

if (null !== $blockType && $blockType['isStart']) {
$nextIndex = $tokens->findBlockEnd($blockType['type'], $nextIndex);
}

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

return $index;
}

/**
* Returns 'true' if there is a possible reference to '$this' within the given tokens index range.
*/
Expand Down
10 changes: 9 additions & 1 deletion src/Fixer/Import/OrderedImportsFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,16 @@ private function setNewOrder(Tokens $tokens, array $usesOrder): void
$use['namespace']
);

$numberOfInitialTokensToClear = 3; // clear `<?php use `
if (self::IMPORT_TYPE_CLASS !== $use['importType']) {
$prevIndex = $tokens->getPrevMeaningfulToken($index);
if ($tokens[$prevIndex]->equals(',')) {
$numberOfInitialTokensToClear = 5; // clear `<?php use const ` or `<?php use function `
}
}

$declarationTokens = Tokens::fromCode($code);
$declarationTokens->clearRange(0, 2); // clear `<?php use `
$declarationTokens->clearRange(0, $numberOfInitialTokensToClear - 1);
$declarationTokens->clearAt(\count($declarationTokens) - 1); // clear `;`
$declarationTokens->clearEmptyTokens();

Expand Down
33 changes: 2 additions & 31 deletions src/Fixer/Operator/BinaryOperatorSpacesFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ private function injectAlignmentPlaceholdersDefault(Tokens $tokens, int $startAt

if ($token->isGivenKind(T_FN)) {
$from = $tokens->getNextMeaningfulToken($index);
$until = $this->getLastTokenIndexOfFn($tokens, $index);
$until = $this->tokensAnalyzer->getLastTokenIndexOfArrowFunction($index);
$this->injectAlignmentPlaceholders($tokens, $from + 1, $until - 1, $tokenContent);
$index = $until;

Expand Down Expand Up @@ -715,7 +715,7 @@ private function injectAlignmentPlaceholdersForArrow(Tokens $tokens, int $startA
if ($token->isGivenKind(T_FN)) {
$yieldFoundSinceLastPlaceholder = false;
$from = $tokens->getNextMeaningfulToken($index);
$until = $this->getLastTokenIndexOfFn($tokens, $index);
$until = $this->tokensAnalyzer->getLastTokenIndexOfArrowFunction($index);
$this->injectArrayAlignmentPlaceholders($tokens, $from + 1, $until - 1);
$index = $until;

Expand Down Expand Up @@ -935,33 +935,4 @@ private function replacePlaceholders(Tokens $tokens, string $alignStrategy, stri

return $tmpCode;
}

private function getLastTokenIndexOfFn(Tokens $tokens, int $index): int
{
$index = $tokens->getNextTokenOfKind($index, [[T_DOUBLE_ARROW]]);

while (true) {
$index = $tokens->getNextMeaningfulToken($index);

if ($tokens[$index]->equalsAny([';', ',', [T_CLOSE_TAG]])) {
break;
}

$blockType = Tokens::detectBlockType($tokens[$index]);

if (null === $blockType) {
continue;
}

if ($blockType['isStart']) {
$index = $tokens->findBlockEnd($blockType['type'], $index);

continue;
}

break;
}

return $index;
}
}
34 changes: 34 additions & 0 deletions src/Tokenizer/TokensAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,40 @@ public function isLambda(int $index): bool
return $startParenthesisToken->equals('(');
}

public function getLastTokenIndexOfArrowFunction(int $index): int
{
if (!$this->tokens[$index]->isGivenKind(T_FN)) {
throw new \InvalidArgumentException(sprintf('Not an "arrow function" at given index %d.', $index));
}

$stopTokens = [')', ']', ',', ';', [T_CLOSE_TAG]];
$index = $this->tokens->getNextTokenOfKind($index, [[T_DOUBLE_ARROW]]);

while (true) {
$index = $this->tokens->getNextMeaningfulToken($index);

if ($this->tokens[$index]->equalsAny($stopTokens)) {
break;
}

$blockType = Tokens::detectBlockType($this->tokens[$index]);

if (null === $blockType) {
continue;
}

if ($blockType['isStart']) {
$index = $this->tokens->findBlockEnd($blockType['type'], $index);

continue;
}

break;
}

return $this->tokens->getPrevMeaningfulToken($index);
}

/**
* Check if the T_STRING under given index is a constant invocation.
*/
Expand Down
32 changes: 27 additions & 5 deletions tests/Fixer/ClassNotation/SelfAccessorFixerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,6 @@ public static function provideFixCases(): iterable
'<?php class Foo { function bar() { Baz\Foo::class; } }',
];

yield [
'<?php class Foo { function bar() { function ($a = self::BAZ) { new self(); }; } }',
'<?php class Foo { function bar() { function ($a = Foo::BAZ) { new Foo(); }; } }',
];

yield [
// In trait "self" will reference the class it's used in, not the actual trait, so we can't replace "Foo" with "self" here
'<?php trait Foo { function bar() { Foo::bar(); } } class Bar { use Foo; }',
Expand Down Expand Up @@ -194,6 +189,33 @@ public function baz31(\Test\Foo\Foo2\Bar $bar);
"<?php interface Foo{ public function bar()\t/**/:?/**/self; }",
"<?php interface Foo{ public function bar()\t/**/:?/**/Foo; }",
];

yield 'do not replace in lambda' => [
'<?php
final class A
{
public static function Z(): void
{
(function () {
var_dump(self::class, A::class);
})->bindTo(null, B::class)();
}
}',
];

yield 'do not replace in arrow function' => [
'<?php
final class A
{
public function Z($b): void
{
$a = fn($b) => self::class. A::class . $b;
echo $a;
}
}',
];
}

/**
Expand Down
55 changes: 47 additions & 8 deletions tests/Fixer/FunctionNotation/PhpdocToParamTypeFixerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,6 @@ function my_foo(string $bar, int $baz, float $tab) {}',
function my_foo($bar, $baz, $tab) {}',
];

yield 'non-root class with mixed type of param' => [
'<?php
/**
* @param mixed $bar
*/
function my_foo($bar) {}',
];

yield 'non-root namespaced class' => [
'<?php /** @param My\Bar $foo */ function my_foo(My\Bar $foo) {}',
'<?php /** @param My\Bar $foo */ function my_foo($foo) {}',
Expand Down Expand Up @@ -505,4 +497,51 @@ function bar($x) {}
',
];
}

/**
* @dataProvider provideFixPre80Cases
*
* @requires PHP <8.0
*/
public function testFixPre80(string $expected, string $input = null): void
{
$this->doTest($expected, $input);
}

public static function provideFixPre80Cases(): iterable
{
yield 'skip mixed type of param' => [
'<?php
/**
* @param mixed $bar
*/
function my_foo($bar) {}',
];
}

/**
* @dataProvider provideFixPhp80Cases
*
* @requires PHP 8.0
*/
public function testFixPhp80(string $expected, ?string $input = null): void
{
$this->doTest($expected, $input);
}

public static function provideFixPhp80Cases(): iterable
{
yield 'non-root class with mixed type of param for php >= 8' => [
'<?php
/**
* @param mixed $bar
*/
function my_foo(mixed $bar) {}',
'<?php
/**
* @param mixed $bar
*/
function my_foo($bar) {}',
];
}
}
39 changes: 35 additions & 4 deletions tests/Fixer/FunctionNotation/PhpdocToPropertyTypeFixerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,6 @@ class Foo {
'<?php class Foo { /** @var resource */ private $foo; }',
];

yield 'skip mixed special type' => [
'<?php class Foo { /** @var mixed */ private $foo; }',
];

yield 'null alone cannot be a property type' => [
'<?php class Foo { /** @var null */ private $foo; }',
];
Expand Down Expand Up @@ -522,6 +518,41 @@ public abstract function getFoo();
];
}

/**
* @dataProvider provideFixPre80Cases
*
* @requires PHP <8.0
*/
public function testFixPre80(string $expected, string $input = null): void
{
$this->doTest($expected, $input);
}

public static function provideFixPre80Cases(): iterable
{
yield 'skip mixed type' => [
'<?php class Foo { /** @var mixed */ private $foo; }',
];
}

/**
* @dataProvider provideFixPhp80Cases
*
* @requires PHP 8.0
*/
public function testFixPhp80(string $expected, ?string $input = null): void
{
$this->doTest($expected, $input);
}

public static function provideFixPhp80Cases(): iterable
{
yield 'fix mixed type' => [
'<?php class Foo { /** @var mixed */ private mixed $foo; }',
'<?php class Foo { /** @var mixed */ private $foo; }',
];
}

/**
* @dataProvider provideFix81Cases
*
Expand Down

0 comments on commit 2cbc40d

Please sign in to comment.