2023-01-18 12:08:19 +00:00
< ? php
declare ( strict_types = 1 );
namespace Rector\Php82\Rector\New_ ;
use PhpParser\Node ;
use PhpParser\Node\Arg ;
use PhpParser\Node\Expr ;
use PhpParser\Node\Expr\BinaryOp\BitwiseOr ;
use PhpParser\Node\Expr\ClassConstFetch ;
use PhpParser\Node\Expr\New_ ;
use PhpParser\Node\Name\FullyQualified ;
2023-01-21 13:08:39 +00:00
use PHPStan\Type\ObjectType ;
2024-03-11 03:08:10 +00:00
use Rector\PhpParser\Node\Value\ValueResolver ;
2024-01-02 02:40:38 +00:00
use Rector\Rector\AbstractRector ;
use Rector\ValueObject\PhpVersionFeature ;
2023-01-18 12:08:19 +00:00
use Rector\VersionBonding\Contract\MinPhpVersionInterface ;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample ;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition ;
/**
2024-03-11 03:08:10 +00:00
* @ see \Rector\Tests\Php82\Rector\New_\FilesystemIteratorSkipDotsRector\FilesystemIteratorSkipDotsRectorTest
2023-01-18 12:08:19 +00:00
*/
2023-01-20 20:25:25 +00:00
final class FilesystemIteratorSkipDotsRector extends AbstractRector implements MinPhpVersionInterface
2023-01-18 12:08:19 +00:00
{
/**
2023-06-11 23:01:39 +00:00
* @ readonly
2024-03-11 03:08:10 +00:00
* @ var \Rector\PhpParser\Node\Value\ValueResolver
2023-01-18 12:08:19 +00:00
*/
2024-03-11 03:08:10 +00:00
private $valueResolver ;
public function __construct ( ValueResolver $valueResolver )
2023-01-18 12:08:19 +00:00
{
2024-03-11 03:08:10 +00:00
$this -> valueResolver = $valueResolver ;
2023-01-18 12:08:19 +00:00
}
public function getRuleDefinition () : RuleDefinition
{
2024-03-11 03:08:10 +00:00
return new RuleDefinition ( 'Prior PHP 8.2 FilesystemIterator::SKIP_DOTS was always set and could not be removed, therefore FilesystemIterator::SKIP_DOTS is added in order to keep this behaviour.' , [ new CodeSample ( 'new FilesystemIterator(__DIR__, FilesystemIterator::KEY_AS_FILENAME);' , 'new FilesystemIterator(__DIR__, FilesystemIterator::KEY_AS_FILENAME | FilesystemIterator::SKIP_DOTS);' )]);
2023-01-18 12:08:19 +00:00
}
public function getNodeTypes () : array
{
return [ New_ :: class ];
}
/**
* Add { @ see \FilesystemIterator :: SKIP_DOTS } to $node when required .
*
* @ param New_ $node
*/
public function refactor ( Node $node ) : ? New_
{
2023-03-22 14:20:22 +00:00
if ( $node -> isFirstClassCallable ()) {
2023-01-21 13:08:39 +00:00
return null ;
}
2023-03-22 14:20:22 +00:00
if ( ! $this -> isObjectType ( $node -> class , new ObjectType ( 'FilesystemIterator' ))) {
2023-01-18 12:08:19 +00:00
return null ;
}
2023-05-08 12:54:32 +00:00
if ( ! isset ( $node -> args [ 1 ])) {
2023-01-18 12:08:19 +00:00
return null ;
}
2023-05-08 12:54:32 +00:00
$flags = $node -> getArgs ()[ 1 ] -> value ;
2023-01-18 12:08:19 +00:00
if ( $this -> isSkipDotsPresent ( $flags )) {
return null ;
}
2023-01-20 20:25:25 +00:00
$classConstFetch = new ClassConstFetch ( new FullyQualified ( 'FilesystemIterator' ), 'SKIP_DOTS' );
$node -> args [ 1 ] = new Arg ( new BitwiseOr ( $flags , $classConstFetch ));
2023-01-18 12:08:19 +00:00
return $node ;
}
public function provideMinPhpVersion () : int
{
return PhpVersionFeature :: FILESYSTEM_ITERATOR_SKIP_DOTS ;
}
/**
* Is the constant { @ see \FilesystemIterator :: SKIP_DOTS } present within $node ?
*/
2023-01-20 20:25:25 +00:00
private function isSkipDotsPresent ( Expr $expr ) : bool
2023-01-18 12:08:19 +00:00
{
2023-01-20 20:25:25 +00:00
while ( $expr instanceof BitwiseOr ) {
if ( $this -> isSkipDots ( $expr -> right )) {
2023-01-18 12:08:19 +00:00
return \true ;
}
2023-01-20 20:25:25 +00:00
$expr = $expr -> left ;
2023-01-18 12:08:19 +00:00
}
2023-01-20 20:25:25 +00:00
return $this -> isSkipDots ( $expr );
2023-01-18 12:08:19 +00:00
}
/**
* Tells if $expr is equal to { @ see \FilesystemIterator :: SKIP_DOTS } .
*/
private function isSkipDots ( Expr $expr ) : bool
{
if ( ! $expr instanceof ClassConstFetch ) {
2023-01-21 13:08:39 +00:00
// can be anything
return \true ;
2023-01-18 12:08:19 +00:00
}
2024-03-11 03:08:10 +00:00
if ( ! \defined ( 'FilesystemIterator::SKIP_DOTS' )) {
return \true ;
}
$value = \constant ( 'FilesystemIterator::SKIP_DOTS' );
return $this -> valueResolver -> isValue ( $expr , $value );
2023-01-18 12:08:19 +00:00
}
}