Skip to content

Commit

Permalink
[PHP 8.0] Add downgrade for str_starts_with() (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed May 30, 2021
1 parent b42fc3d commit f7e9986
Show file tree
Hide file tree
Showing 33 changed files with 426 additions and 97 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"phpstan/phpstan-nette": "^0.12.18",
"phpunit/phpunit": "^9.5",
"rector/rector-generator": "^0.1.7",
"rector/phpstan-rules": "^0.2.8",
"rector/phpstan-rules": "^0.3",
"symplify/coding-standard": "^9.3.10",
"symplify/easy-ci": "^9.3.10",
"symplify/easy-coding-standard": "^9.3.10",
Expand Down
3 changes: 2 additions & 1 deletion config/set/downgrade-php80.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@
$services->set(DowngradeClassOnObjectToGetClassRector::class);
$services->set(DowngradeNullsafeToTernaryOperatorRector::class);
$services->set(DowngradeTrailingCommasInParamUseRector::class);
$services->set(\Rector\DowngradePhp80\Rector\Class_\DowngradeAttributeToAnnotationRector::class);
$services->set(\Rector\DowngradePhp80\Rector\FuncCall\DowngradeStrStartsWithRector::class);
$services->set(\Rector\DowngradePhp80\Rector\FuncCall\DowngradeStrEndsWithRector::class);
};
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,14 @@ public function dataProvider(): Iterator

yield [__DIR__ . '/Source/ClassWithParentTrait.php', 0, new ObjectType(ClassWithParentTrait::class)];
}

public function testAnonymousClass(): void
{
$file = __DIR__ . '/Source/AnonymousClass.php';
$nodePosition = 0;


$variableNodes = $this->getNodesForFileOfType($file, Class_::class);

$resolvedType = $this->nodeTypeResolver->resolve($variableNodes[$nodePosition]);
$resolvedType = $this->nodeTypeResolver->resolve($variableNodes[0]);
$this->assertInstanceOf(TypeWithClassName::class, $resolvedType);

/** @var TypeWithClassName $resolvedType */
Expand Down
3 changes: 1 addition & 2 deletions packages/Comments/CommentRemover.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@ public function __construct(
}

/**
* @param Node[]|Node|null $node

This comment has been minimized.

Copy link
@staabm

staabm May 30, 2021

Contributor

Was this comment removed by rector, or manually?

asking because the native type is lost the type-information of the array..?

This comment has been minimized.

Copy link
@TomasVotruba

TomasVotruba May 30, 2021

Author Member

I'm not sure. You can check the previous code in rector-src to compare.
Type is missing, you're right. PR? :)

* @return Node[]|null
*/
public function removeFromNode($node): ?array
public function removeFromNode(array | Node | null $node): array | null
{
if ($node === null) {
return null;
Expand Down
11 changes: 5 additions & 6 deletions packages/NodeRemoval/NodeRemover.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,12 @@ public function removeNode(Node $node): void
$this->rectorChangeCollector->notifyNodeFileInfo($node);
}

/**
* @param Class_|ClassMethod|Function_ $nodeWithStatements
*/
public function removeNodeFromStatements(Node $nodeWithStatements, Node $nodeToRemove): void
{
public function removeNodeFromStatements(
Class_ | ClassMethod | Function_ $nodeWithStatements,
Node $toBeRemovedNode
): void {
foreach ((array) $nodeWithStatements->stmts as $key => $stmt) {
if ($nodeToRemove !== $stmt) {
if ($toBeRemovedNode !== $stmt) {
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\Trait_;
use PhpParser\NodeTraverser;
Expand Down Expand Up @@ -121,10 +120,7 @@ private function removeDeepChainMethodCallNodes(array $nodes): void
$nodeTraverser->traverse($nodes);
}

/**
* @param Class_|Interface_ $classLike
*/
private function resolveClassOrInterfaceScope(ClassLike $classLike, Scope $scope): Scope
private function resolveClassOrInterfaceScope(Class_ | Interface_ $classLike, Scope $scope): Scope
{
$className = $this->resolveClassName($classLike);

Expand Down Expand Up @@ -172,10 +168,7 @@ private function reportCacheDebugAndSaveDependentFiles(SmartFileInfo $smartFileI
$this->changedFilesDetector->addFileWithDependencies($smartFileInfo, $dependentFiles);
}

/**
* @param Class_|Interface_|Trait_ $classLike
*/
private function resolveClassName(ClassLike $classLike): string
private function resolveClassName(Class_ | Interface_ | Trait_ $classLike): string
{
if (property_exists($classLike, 'namespacedName')) {
return (string) $classLike->namespacedName;
Expand Down
9 changes: 2 additions & 7 deletions packages/PHPStanStaticTypeMapper/PHPStanStaticTypeMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@

namespace Rector\PHPStanStaticTypeMapper;

use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\UnionType as PhpParserUnionType;
use PhpParser\Node\UnionType;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\Type\Type;
use Rector\Core\Exception\NotImplementedYetException;
Expand Down Expand Up @@ -36,11 +35,7 @@ public function mapToPHPStanPhpDocTypeNode(Type $type): TypeNode
throw new NotImplementedYetException(__METHOD__ . ' for ' . get_class($type));
}

/**
* @return Name|NullableType|PhpParserUnionType|null
*/
public function mapToPhpParserNode(Type $type, ?string $kind = null): ?Node
{
public function mapToPhpParserNode(Type $type, ?string $kind = null): Name | NullableType | UnionType | null {
foreach ($this->typeMappers as $typeMapper) {
if (! is_a($type, $typeMapper->getNodeClass(), true)) {
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,7 @@ private function shouldSkipIterable(UnionType $unionType): bool
return $unionTypeAnalysis->hasArray();
}

/**
* @return Name|NullableType|null
*/
private function matchArrayTypes(UnionType $unionType): ?Node
private function matchArrayTypes(UnionType $unionType): Name | NullableType | null
{
$unionTypeAnalysis = $this->unionTypeAnalyzer->analyseForNullableAndIterable($unionType);
if (! $unionTypeAnalysis instanceof UnionTypeAnalysis) {
Expand Down
6 changes: 6 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -487,3 +487,9 @@ parameters:
-
message: '#Use separate function calls with readable variable names#'
path: 'src/FileSystem/PhpFilesFinder.php'

# union false positive
- '#Method Rector\\Comments\\CommentRemover\:\:removeFromNode\(\) has parameter \$node with no value type specified in iterable type array#'

# should be refactored to collector
- '#Cognitive complexity for "Rector\\CodingStyle\\Naming\\NameRenamer\:\:renameNameNode\(\)" is 10, keep it under 9#'
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;

use PhpParser\Node\Scalar\String_;
use PhpParser\Node\UnionType as PhpParserUnionType;

final class UsedUnionType
{
public function param(String_ | PhpParserUnionType $node)
{
}
}

?>
-----
<?php

namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;

use PhpParser\Node\Scalar\String_;
use PhpParser\Node\UnionType;

final class UsedUnionType
{
public function param(String_ | UnionType $node)
{
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@

namespace Rector\Tests\Defluent\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;

use Cassandra\Date;
use Nette\Utils\DateTime;

final class SetGetDateTime
{
/**
* @var DateTime|null
*/
private $dateMin = null;
private ?DateTime $dateMin = null;

public function setDateMin(?DateTime $dateTime = null)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrEndsWithRector;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;

final class DowngradeStrEndsWithRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}

/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrEndsWithRector\Fixture;

! str_ends_with($haystack, $needle);

?>
-----
<?php

namespace Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrEndsWithRector\Fixture;

substr_compare($haystack, $needle, -strlen($needle)) !== 0;

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrEndsWithRector\Fixture;

str_ends_with($haystack, $needle);

?>
-----
<?php

namespace Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrEndsWithRector\Fixture;

substr_compare($haystack, $needle, -strlen($needle)) === 0;

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

use Rector\DowngradePhp80\Rector\FuncCall\DowngradeStrEndsWithRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(DowngradeStrEndsWithRector::class);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrStartsWithRector;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;

final class DowngradeStrStartsWithRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}

/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrStartsWithRector\Fixture;

return ! str_starts_with($haystack, $needle);

?>
-----
<?php

namespace Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrStartsWithRector\Fixture;

return strncmp($haystack, $needle, strlen($needle)) !== 0;

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrStartsWithRector\Fixture;

str_starts_with($haystack, $needle);

?>
-----
<?php

namespace Rector\Tests\DowngradePhp80\Rector\FuncCall\DowngradeStrStartsWithRector\Fixture;

strncmp($haystack, $needle, strlen($needle)) === 0;

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

use Rector\DowngradePhp80\Rector\FuncCall\DowngradeStrStartsWithRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(DowngradeStrStartsWithRector::class);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Tests\EarlyReturn\Rector\If_\ChangeOrIfContinueToMultiContinueRector\Fixture;

class NotIdentical
final class SomeNotIdentical
{
public function canDrive(Car $newCar)
{
Expand All @@ -22,7 +22,7 @@ class NotIdentical

namespace Rector\Tests\EarlyReturn\Rector\If_\ChangeOrIfContinueToMultiContinueRector\Fixture;

class NotIdentical
final class SomeNotIdentical
{
public function canDrive(Car $newCar)
{
Expand Down
9 changes: 4 additions & 5 deletions rules/Arguments/Rector/ClassMethod/ArgumentAdderRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,10 @@ private function isObjectTypeMatch(Node $node, ObjectType $objectType): bool
return $this->isObjectType($classLike, $objectType);
}

/**
* @param ClassMethod|MethodCall|StaticCall $node
*/
private function processPositionWithDefaultValues(Node $node, ArgumentAdder $argumentAdder): void
{
private function processPositionWithDefaultValues(
ClassMethod | MethodCall | StaticCall $node,
ArgumentAdder $argumentAdder
): void {
if ($this->shouldSkipParameter($node, $argumentAdder)) {
return;
}
Expand Down
5 changes: 1 addition & 4 deletions rules/CodingStyle/Naming/ClassNaming.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ public function getVariableName($name): string
return lcfirst($shortName);
}

/**
* @param string|Name|Identifier|ClassLike $name
*/
public function getShortName($name): string
public function getShortName(string | Name | Identifier | ClassLike $name): string
{
if ($name instanceof ClassLike) {
if ($name->name === null) {
Expand Down
Loading

0 comments on commit f7e9986

Please sign in to comment.