2019-10-13 05:59:52 +00:00
< ? php
2021-05-09 20:15:43 +00:00
declare ( strict_types = 1 );
2022-06-06 17:12:56 +00:00
namespace Rector\CodeQuality\Rector\FuncCall ;
2019-09-26 11:43:26 +00:00
2022-06-06 17:12:56 +00:00
use PhpParser\Node ;
use PhpParser\Node\Arg ;
use PhpParser\Node\Expr\FuncCall ;
use PhpParser\Node\Scalar\String_ ;
use PHPStan\Type\StringType ;
use Rector\Core\NodeAnalyzer\ArgsAnalyzer ;
use Rector\Core\Rector\AbstractRector ;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample ;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition ;
2019-09-26 11:43:26 +00:00
/**
2021-03-12 22:20:25 +00:00
* @ see \Rector\Tests\CodeQuality\Rector\FuncCall\RemoveSoleValueSprintfRector\RemoveSoleValueSprintfRectorTest
2019-09-26 11:43:26 +00:00
*/
2022-06-06 17:12:56 +00:00
final class RemoveSoleValueSprintfRector extends \Rector\Core\Rector\AbstractRector
2019-09-26 11:43:26 +00:00
{
2021-09-27 15:43:15 +00:00
/**
2021-12-04 12:47:17 +00:00
* @ readonly
2021-09-27 15:43:15 +00:00
* @ var \Rector\Core\NodeAnalyzer\ArgsAnalyzer
*/
private $argsAnalyzer ;
2022-06-06 17:12:56 +00:00
public function __construct ( \Rector\Core\NodeAnalyzer\ArgsAnalyzer $argsAnalyzer )
2021-09-27 15:43:15 +00:00
{
$this -> argsAnalyzer = $argsAnalyzer ;
}
2022-06-06 17:12:56 +00:00
public function getRuleDefinition () : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
2019-09-26 11:43:26 +00:00
{
2022-06-06 17:12:56 +00:00
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition ( 'Remove sprintf() wrapper if not needed' , [ new \Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample ( <<< 'CODE_SAMPLE'
2019-09-26 11:43:26 +00:00
class SomeClass
{
public function run ()
{
$value = sprintf ( '%s' , 'hi' );
$welcome = 'hello' ;
$value = sprintf ( '%s' , $welcome );
}
}
2020-09-15 08:23:13 +00:00
CODE_SAMPLE
2021-05-09 20:15:43 +00:00
, <<< 'CODE_SAMPLE'
2019-09-26 11:43:26 +00:00
class SomeClass
{
public function run ()
{
$value = 'hi' ;
$welcome = 'hello' ;
$value = $welcome ;
}
}
2020-09-15 08:23:13 +00:00
CODE_SAMPLE
2021-05-09 20:15:43 +00:00
)]);
2019-09-26 11:43:26 +00:00
}
/**
2021-02-27 00:06:15 +00:00
* @ return array < class - string < Node >>
2019-09-26 11:43:26 +00:00
*/
2021-05-09 20:15:43 +00:00
public function getNodeTypes () : array
2019-09-26 11:43:26 +00:00
{
2022-06-06 17:12:56 +00:00
return [ \PhpParser\Node\Expr\FuncCall :: class ];
2019-09-26 11:43:26 +00:00
}
/**
2021-12-10 10:22:23 +00:00
* @ param FuncCall $node
2019-09-26 11:43:26 +00:00
*/
2022-06-06 17:12:56 +00:00
public function refactor ( \PhpParser\Node $node ) : ? \PhpParser\Node
2019-09-26 11:43:26 +00:00
{
2021-05-09 20:15:43 +00:00
if ( ! $this -> isName ( $node , 'sprintf' )) {
2019-09-26 11:43:26 +00:00
return null ;
}
2021-05-09 20:15:43 +00:00
if ( \count ( $node -> args ) !== 2 ) {
2019-09-26 11:43:26 +00:00
return null ;
}
2021-09-27 15:43:15 +00:00
if ( ! $this -> argsAnalyzer -> isArgsInstanceInArgsPositions ( $node -> args , [ 0 , 1 ])) {
return null ;
}
/** @var Arg $firstArg */
$firstArg = $node -> args [ 0 ];
$maskArgument = $firstArg -> value ;
2022-06-06 17:12:56 +00:00
if ( ! $maskArgument instanceof \PhpParser\Node\Scalar\String_ ) {
2019-09-26 11:43:26 +00:00
return null ;
}
if ( $maskArgument -> value !== '%s' ) {
return null ;
}
2021-09-27 15:43:15 +00:00
/** @var Arg $secondArg */
$secondArg = $node -> args [ 1 ];
$valueArgument = $secondArg -> value ;
2021-10-07 17:46:41 +00:00
$valueType = $this -> getType ( $valueArgument );
2022-06-06 17:12:56 +00:00
if ( ! $valueType instanceof \PHPStan\Type\StringType ) {
2019-09-26 11:43:26 +00:00
return null ;
}
return $valueArgument ;
}
}