Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions docs/AllRectorsOverview.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# All 369 Rectors Overview
# All 370 Rectors Overview

- [Projects](#projects)
- [General](#general)
Expand Down Expand Up @@ -636,6 +636,33 @@ Remove sprintf() wrapper if not needed

<br>

### `ShortenElseIfRector`

- class: `Rector\CodeQuality\Rector\If_\ShortenElseIfRector`

Shortens else/if to elseif

```diff
class SomeClass
{
public function run()
{
if ($cond1) {
return $action1;
- } else {
- if ($cond2) {
- return $action2;
- }
- }
+ } elseif ($cond2) {
+ return $action2;
+ }
}
}
```

<br>

### `SimplifyArraySearchRector`

- class: `Rector\CodeQuality\Rector\Identical\SimplifyArraySearchRector`
Expand Down Expand Up @@ -3941,7 +3968,7 @@ Remove 0 from break and continue

- class: `Rector\Php55\Rector\FuncCall\PregReplaceEModifierRector`

The /e modifier is no longer supported, use preg_replace_callback instead
The /e modifier is no longer supported, use preg_replace_callback instead

```diff
class SomeClass
Expand Down
2 changes: 1 addition & 1 deletion docs/NodesOverview.md
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ if (true) {

```php
?>
<strong>feel</strong><?php
<strong>feel</strong><?php
```
<br>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
use ReflectionClass;
use ReflectionMethod;
use ReflectionProperty;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Validator\Constraint;
use Throwable;

Expand All @@ -39,7 +37,7 @@ public function __construct(AnnotationReader $annotationReader, NameResolver $na
}

/**
* @return Template|Route|null
* @return object|null
*/
public function readMethodAnnotation(ClassMethod $classMethod, string $annotationClassName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use JMS\Serializer\Annotation\Type;
use PhpParser\Node;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
use PHPStan\PhpDocParser\Parser\TokenIterator;
Expand All @@ -20,17 +21,29 @@ public function getClass(): string

public function createFromNodeAndTokens(Node $node, TokenIterator $tokenIterator): ?PhpDocTagValueNode
{
if (! $node instanceof Property) {
throw new ShouldNotHappenException();
}

/** @var Type|null $type */
$type = $this->nodeAnnotationReader->readPropertyAnnotation($node, $this->getClass());
$type = $this->resolveTypeAnnotation($node);
if ($type === null) {
return null;
}

$annotationContent = $this->resolveContentFromTokenIterator($tokenIterator);
return new SerializerTypeTagValueNode($type->name, $annotationContent);
}

/**
* Can be even ClassMethod for virtual property
* @see https://github.com/rectorphp/rector/issues/2086
*/
private function resolveTypeAnnotation(Node $node): ?Type
{
if ($node instanceof Property) {
return $this->nodeAnnotationReader->readPropertyAnnotation($node, $this->getClass());
}

if ($node instanceof ClassMethod) {
return $this->nodeAnnotationReader->readMethodAnnotation($node, $this->getClass());
}

throw new ShouldNotHappenException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ final class MultilineTest extends AbstractPhpDocInfoPrinterTest
{
/**
* @dataProvider provideData()
* @dataProvider provideDataForTestSerialize()
* @dataProvider provideDataForProperty()
* @dataProvider provideDataClass()
*/
public function test(string $docFilePath, Node $node): void
Expand All @@ -38,34 +38,26 @@ public function provideData(): Iterator
yield [__DIR__ . '/Source/Multiline/multiline3.txt', new Nop()];
yield [__DIR__ . '/Source/Multiline/multiline4.txt', new Nop()];
yield [__DIR__ . '/Source/Multiline/multiline5.txt', new Nop()];

$property = $this->createPublicPropertyUnderClass('manyTo', ManyToPropertyClass::class);
yield [__DIR__ . '/Source/Multiline/many_to.txt', $property];
}

public function provideDataClass(): Iterator
{
yield [__DIR__ . '/Source/Class_/some_entity_class.txt', new Class_(SomeEntityClass::class)];
}

public function provideDataForTestSerialize(): Iterator
public function provideDataForProperty(): Iterator
{
$property = $this->createPublicPropertyUnderClass('manyTo', ManyToPropertyClass::class);
yield [__DIR__ . '/Source/Multiline/many_to.txt', $property];

$property = $this->createPublicPropertyUnderClass('anotherProperty', AnotherPropertyClass::class);
yield [__DIR__ . '/Source/Multiline/assert_serialize.txt', $property];

$property = $this->createPublicPropertyUnderClass('anotherSerializeSingleLine', SinglePropertyClass::class);
yield [__DIR__ . '/Source/Multiline/assert_serialize_single_line.txt', $property];
}

public function testDoctrine(): void
{
$docFilePath = __DIR__ . '/Source/Multiline/multiline6.txt';
$docComment = FileSystem::read($docFilePath);

$property = $this->createPublicPropertyUnderClass('someProperty', DoctrinePropertyClass::class);
$phpDocInfo = $this->createPhpDocInfoFromDocCommentAndNode($docComment, $property);

$this->assertSame($docComment, $this->phpDocInfoPrinter->printFormatPreserving($phpDocInfo));
yield [__DIR__ . '/Source/Multiline/multiline6.txt', $property];
}

private function createPublicPropertyUnderClass(string $name, string $class): Property
Expand Down
15 changes: 3 additions & 12 deletions packages/CodeQuality/src/Rector/If_/ShortenElseIfRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,8 @@

namespace Rector\CodeQuality\Rector\If_;

use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Else_;
use PhpParser\Node\Stmt\ElseIf_;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
Expand Down Expand Up @@ -76,10 +69,11 @@ public function refactor(Node $node): ?Node

private function shortenElseIf(If_ $node): ?Node
{
if (! $else = $node->else) {
if ($node->else === null) {
return null;
}

$else = $node->else;
if (count($else->stmts) > 1) {
return null;
}
Expand All @@ -96,10 +90,7 @@ private function shortenElseIf(If_ $node): ?Node
$if = $refactored;
}

$node->elseifs[] = new ElseIf_(
$if->cond,
$if->stmts
);
$node->elseifs[] = new ElseIf_($if->cond, $if->stmts);

$node->else = $if->else;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function __construct(Parser $parser)

public function getDefinition(): RectorDefinition
{
return new RectorDefinition('The /e modifier is no longer supported, use preg_replace_callback instead ', [
return new RectorDefinition('The /e modifier is no longer supported, use preg_replace_callback instead', [
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This finally fixes these repreated spaces in docs dump

new CodeSample(
<<<'PHP'
class SomeClass
Expand Down
21 changes: 4 additions & 17 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ parameters:
- '#Strict comparison using === between string and null will always evaluate to false#'
# subtype
- '#(.*?) expects ReflectionFunction\|ReflectionMethod, ReflectionFunctionAbstract given#'
- '#PHPDoc tag @return with type (.*?) is incompatible with native type Iterator#'

# nette container
- '#Method Rector\\NodeTypeResolver\\DependencyInjection\\PHPStanServicesFactory::create(.*?)() should return (.*?) but returns object#'
Expand Down Expand Up @@ -83,11 +82,7 @@ parameters:
# intentionally incorrect - part of the test
- '#Parameter \#2 \$codeSamples of class Rector\\RectorDefinition\\RectorDefinition constructor expects array<Rector\\Contract\\RectorDefinition\\CodeSampleInterface>, array<int, stdClass> given#'

# invalid interface type resolution
- '#Method Rector\\PhpParser\\NodeTraverser\\RectorNodeTraverser::getRectors\(\) should return array<Rector\\Contract\\Rector\\PhpRectorInterface> but returns array<PhpParser\\NodeVisitor>#'

# known values

- '#Cannot access property \$value on PhpParser\\Node\\Expr\\ArrayItem\|null#'
- '#Method Rector\\Symfony\\Rector\\New_\\StringToArrayArgumentProcessRector::findPreviousNodeAssign\(\) should return PhpParser\\Node\\Expr\\Assign\|null but returns PhpParser\\Node\|null#'

Expand Down Expand Up @@ -174,11 +169,9 @@ parameters:
- '#Ternary operator condition is always true#'
- '#Access to an undefined property PhpParser\\Node\\Expr\\Assign\|PhpParser\\Node\\Stmt\\ClassMethod\|PhpParser\\Node\\Stmt\\Property\:\:\$var#'

- '#Method Rector\\BetterPhpDocParser\\Tests\\PhpDocParser\\OrmTagParser\\AbstractOrmTagParserTest\:\:parseFileAndGetFirstNodeOfType\(\) should return PhpParser\\Node but returns PhpParser\\Node\|null#'
- '#Method Rector\\Symfony\\Bridge\\DefaultAnalyzedSymfonyApplicationContainer\:\:getService\(\) should return object but returns object\|null#'
- '#Call to function property_exists\(\) with string and (.*?) will always evaluate to false#'
- '#Method Rector\\Console\\Option\\SetOptionResolver\:\:separateVersionedAndUnversionedSets\(\) should return array<array<string\>\> but returns array<int, array<int\|string, array<int, string\>\|string\>\>#'
- '#Method Rector\\BetterPhpDocParser\\AnnotationReader\\NodeAnnotationReader\:\:readMethodAnnotation\(\) should return Sensio\\Bundle\\FrameworkExtraBundle\\Configuration\\Template but returns object\|null#'
- '#Access to an undefined property PhpParser\\Node\\FunctionLike\|PhpParser\\Node\\Stmt\\ClassLike\:\:\$stmts#'

- '#Property Rector\\TypeDeclaration\\TypeInferer\\(.*?)\:\:\$(.*?)TypeInferers \(array<Rector\\TypeDeclaration\\Contract\\TypeInferer\\(.*?)TypeInfererInterface\>\) does not accept array<Rector\\TypeDeclaration\\Contract\\TypeInferer\\PriorityAwareTypeInfererInterface\>#'
Expand All @@ -194,20 +187,14 @@ parameters:
- '#Property PhpParser\\Node\\Scalar\\DNumber\:\:\$value \(float\) does not accept string#'
- '#Call to function is_string\(\) with float will always evaluate to false#'

- '#PHPDoc tag @return with type array<string\> is incompatible with native type Iterator#'

- '#Method Rector\\BetterPhpDocParser\\PhpDocNodeFactory\\Doctrine\\TableTagValueNodeFactory\:\:createIndexTagValueNodes\(\) should return array<Rector\\BetterPhpDocParser\\Ast\\PhpDoc\\Class_\\IndexTagValueNode\> but returns array<int, Rector\\BetterPhpDocParser\\Ast\\PhpDoc\\Class_\\IndexTagValueNode\|Rector\\BetterPhpDocParser\\Ast\\PhpDoc\\Class_\\UniqueConstraintTagValueNode\>#'

- '#Method Rector\\BetterPhpDocParser\\PhpDocNodeFactory\\Doctrine\\TableTagValueNodeFactory\:\:createUniqueConstraintTagValueNodes\(\) should return array<Rector\\BetterPhpDocParser\\Ast\\PhpDoc\\Class_\\UniqueConstraintTagValueNode\> but returns array<int, Rector\\BetterPhpDocParser\\Ast\\PhpDoc\\Class_\\IndexTagValueNode\|Rector\\BetterPhpDocParser\\Ast\\PhpDoc\\Class_\\UniqueConstraintTagValueNode\>#'

- '#Parameter \#1 \$obj of function spl_object_hash expects object, PhpParser\\Comment\\Doc\|null given#'
- '#Method Rector\\BetterPhpDocParser\\AnnotationReader\\NodeAnnotationReader\:\:readMethodAnnotation\(\) should return Sensio\\Bundle\\FrameworkExtraBundle\\Configuration\\Template\|Symfony\\Component\\Routing\\Annotation\\Route\|null but returns object\|null#'

- '#Method Rector\\Doctrine\\Rector\\MethodCall\\ChangeSetIdToUuidValueRector\:\:getSetUuidMethodCallOnSameVariable\(\) should return PhpParser\\Node\\Expr\\MethodCall\|null but returns PhpParser\\Node\|null#'

# bugs
- '#In method "Rector\\FileSystemRector\\Rector\\AbstractFileSystemRector\:\:isDoctrineEntityClass", parameter \$class has no type\-hint and no @param annotation\. More info\: http\://bit\.ly/usetypehint#'
- '#In method "Rector\\Rector\\AbstractRector\:\:isDoctrineEntityClass", parameter \$class has no type\-hint and no @param annotation\. More info\: http\://bit\.ly/usetypehint#'
- '#In method "Rector\\FileSystemRector\\Rector\\AbstractFileSystemRector\:\:moveFile", parameter \$nodes type is "array"\. Please provide a @param annotation to further specify the type of the array\. For instance\: @param int\[\] \$nodes\. More info\: http\://bit\.ly/typehintarray#'
- '#Parameter \#1 \$items of class PhpParser\\Node\\Expr\\Array_ constructor expects array<PhpParser\\Node\\Expr\\ArrayItem\>, array<PhpParser\\Node\\Expr\\ArrayItem\|null\> given#'
- '#Parameter \#1 \$sprintfFuncCall of method Rector\\PhpParser\\NodeTransformer\:\:transformSprintfToArray\(\) expects PhpParser\\Node\\Expr\\FuncCall, PhpParser\\Node given#'
- '#Method Rector\\BetterPhpDocParser\\Tests\\PhpDocParser\\OrmTagParser\\AbstractPhpDocInfoTest\:\:parseFileAndGetFirstNodeOfType\(\) should return PhpParser\\Node but returns PhpParser\\Node\|null#'

- '#Method Rector\\BetterPhpDocParser\\PhpDocNodeFactory\\JMS\\SerializerTypePhpDocNodeFactory\:\:resolveTypeAnnotation\(\) should return JMS\\Serializer\\Annotation\\Type\|null but returns object\|null#'
- '#Method Rector\\BetterPhpDocParser\\PhpDocNodeFactory\\JMS\\SerializerTypePhpDocNodeFactory\:\:resolveTypeAnnotation\(\) should return JMS\\Serializer\\Annotation\\Type\|null but returns Doctrine\\ORM\\Mapping\\Annotation\|Symfony\\Component\\Validator\\Constraint\|null#'
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int

$this->nodeInfoResult->addNodeInfo($category, new NodeInfo(
$nodeClass,
$this->betterStandardPrinter->print($node),
trim($this->betterStandardPrinter->print($node)),
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This finally fixes these repreated spaces in docs dump

true
));

Expand Down