2019-10-13 05:59:52 +00:00
< ? php
2021-05-09 20:15:43 +00:00
declare ( strict_types = 1 );
2020-08-30 13:47:36 +00:00
namespace Rector\Transform\Rector\Assign ;
2017-11-18 15:20:10 +00:00
use PhpParser\Node ;
2017-11-18 15:48:20 +00:00
use PhpParser\Node\Expr\Assign ;
2017-11-18 15:20:10 +00:00
use PhpParser\Node\Expr\PropertyFetch ;
2017-12-27 20:44:10 +00:00
use PhpParser\Node\Expr\Variable ;
2020-07-29 23:39:41 +00:00
use Rector\Core\Contract\Rector\ConfigurableRectorInterface ;
2020-08-26 10:54:53 +00:00
use Rector\Core\Exception\ShouldNotHappenException ;
2020-02-06 21:48:18 +00:00
use Rector\Core\Rector\AbstractRector ;
2021-01-28 23:32:20 +00:00
use Rector\Transform\ValueObject\PropertyFetchToMethodCall ;
2020-11-16 17:50:38 +00:00
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample ;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition ;
2021-08-13 11:57:49 +00:00
use RectorPrefix20210813\Webmozart\Assert\Assert ;
2019-09-03 09:11:45 +00:00
/**
2021-03-12 22:20:25 +00:00
* @ see \Rector\Tests\Transform\Rector\Assign\PropertyFetchToMethodCallRector\PropertyFetchToMethodCallRectorTest
2019-09-03 09:11:45 +00:00
*/
2021-05-10 22:23:08 +00:00
final class PropertyFetchToMethodCallRector extends \Rector\Core\Rector\AbstractRector implements \Rector\Core\Contract\Rector\ConfigurableRectorInterface
2017-11-18 15:20:10 +00:00
{
2020-07-29 23:39:41 +00:00
/**
* @ var string
*/
2020-08-26 10:54:53 +00:00
public const PROPERTIES_TO_METHOD_CALLS = 'properties_to_method_calls' ;
2020-05-06 21:39:33 +00:00
/**
2021-01-28 23:32:20 +00:00
* @ var PropertyFetchToMethodCall []
2017-11-18 15:20:10 +00:00
*/
2020-08-26 10:54:53 +00:00
private $propertiesToMethodCalls = [];
2021-05-10 22:23:08 +00:00
public function getRuleDefinition () : \Symplify\RuleDocGenerator\ValueObject\RuleDefinition
2018-04-08 11:51:26 +00:00
{
2021-05-10 22:23:08 +00:00
$firstConfiguration = [ self :: PROPERTIES_TO_METHOD_CALLS => [ new \Rector\Transform\ValueObject\PropertyFetchToMethodCall ( 'SomeObject' , 'property' , 'getProperty' , 'setProperty' )]];
$secondConfiguration = [ self :: PROPERTIES_TO_METHOD_CALLS => [ new \Rector\Transform\ValueObject\PropertyFetchToMethodCall ( 'SomeObject' , 'property' , 'getConfig' , null , [ 'someArg' ])]];
return new \Symplify\RuleDocGenerator\ValueObject\RuleDefinition ( 'Replaces properties assign calls be defined methods.' , [ new \Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample ( <<< 'CODE_SAMPLE'
2018-04-08 11:51:26 +00:00
$result = $object -> property ;
$object -> property = $value ;
2020-09-15 08:23:13 +00:00
CODE_SAMPLE
2021-05-09 20:15:43 +00:00
, <<< 'CODE_SAMPLE'
2018-04-08 11:51:26 +00:00
$result = $object -> getProperty ();
$object -> setProperty ( $value );
2020-09-15 08:23:13 +00:00
CODE_SAMPLE
2021-05-10 22:23:08 +00:00
, $firstConfiguration ), new \Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample ( <<< 'CODE_SAMPLE'
2018-09-19 22:45:34 +00:00
$result = $object -> property ;
2020-09-15 08:23:13 +00:00
CODE_SAMPLE
2021-05-09 20:15:43 +00:00
, <<< 'CODE_SAMPLE'
2018-09-19 22:45:34 +00:00
$result = $object -> getProperty ( 'someArg' );
2020-09-15 08:23:13 +00:00
CODE_SAMPLE
2021-05-09 20:15:43 +00:00
, $secondConfiguration )]);
2018-04-08 11:51:26 +00:00
}
2018-08-14 22:12:41 +00:00
/**
2021-02-27 00:06:15 +00:00
* @ return array < class - string < Node >>
2018-08-14 22:12:41 +00:00
*/
2021-05-09 20:15:43 +00:00
public function getNodeTypes () : array
2017-11-18 15:20:10 +00:00
{
2021-05-23 17:26:56 +00:00
return [ \PhpParser\Node\Expr\Assign :: class , \PhpParser\Node\Expr\PropertyFetch :: class ];
2017-11-18 15:20:10 +00:00
}
/**
2021-05-23 17:26:56 +00:00
* @ param PropertyFetch | Assign $node
2017-11-18 15:20:10 +00:00
*/
2021-07-05 22:50:18 +00:00
public function refactor ( \PhpParser\Node $node ) : ? \PhpParser\Node
2017-11-18 15:20:10 +00:00
{
2021-05-23 17:26:56 +00:00
if ( $node instanceof \PhpParser\Node\Expr\Assign && $node -> var instanceof \PhpParser\Node\Expr\PropertyFetch ) {
2018-10-15 04:36:58 +00:00
return $this -> processSetter ( $node );
2018-08-14 21:33:39 +00:00
}
2021-05-23 17:26:56 +00:00
if ( $node instanceof \PhpParser\Node\Expr\PropertyFetch ) {
2018-10-15 04:36:58 +00:00
return $this -> processGetter ( $node );
2018-08-14 21:33:39 +00:00
}
2018-09-19 22:45:34 +00:00
return null ;
}
2021-01-28 23:32:20 +00:00
/**
* @ param array < string , PropertyFetchToMethodCall [] > $configuration
*/
2021-05-09 20:15:43 +00:00
public function configure ( array $configuration ) : void
2020-07-29 23:39:41 +00:00
{
2020-08-26 10:54:53 +00:00
$propertiesToMethodCalls = $configuration [ self :: PROPERTIES_TO_METHOD_CALLS ] ? ? [];
2021-08-13 11:57:49 +00:00
\RectorPrefix20210813\Webmozart\Assert\Assert :: allIsInstanceOf ( $propertiesToMethodCalls , \Rector\Transform\ValueObject\PropertyFetchToMethodCall :: class );
2020-08-26 10:54:53 +00:00
$this -> propertiesToMethodCalls = $propertiesToMethodCalls ;
2020-07-29 23:39:41 +00:00
}
2021-05-10 22:23:08 +00:00
private function processSetter ( \PhpParser\Node\Expr\Assign $assign ) : ? \PhpParser\Node
2018-09-19 22:45:34 +00:00
{
/** @var PropertyFetch $propertyFetchNode */
2019-02-22 17:25:31 +00:00
$propertyFetchNode = $assign -> var ;
2020-08-26 10:54:53 +00:00
$propertyToMethodCall = $this -> matchPropertyFetchCandidate ( $propertyFetchNode );
2021-05-10 22:23:08 +00:00
if ( ! $propertyToMethodCall instanceof \Rector\Transform\ValueObject\PropertyFetchToMethodCall ) {
2018-09-19 22:45:34 +00:00
return null ;
2017-11-18 15:48:20 +00:00
}
2020-08-26 10:54:53 +00:00
if ( $propertyToMethodCall -> getNewSetMethod () === null ) {
2021-05-10 22:23:08 +00:00
throw new \Rector\Core\Exception\ShouldNotHappenException ();
2020-08-26 10:54:53 +00:00
}
2021-01-30 21:41:25 +00:00
$args = $this -> nodeFactory -> createArgs ([ $assign -> expr ]);
2018-09-19 22:45:34 +00:00
/** @var Variable $variable */
$variable = $propertyFetchNode -> var ;
2021-01-30 21:41:25 +00:00
return $this -> nodeFactory -> createMethodCall ( $variable , $propertyToMethodCall -> getNewSetMethod (), $args );
2018-09-19 22:45:34 +00:00
}
2021-05-23 17:26:56 +00:00
private function processGetter ( \PhpParser\Node\Expr\PropertyFetch $propertyFetch ) : ? \PhpParser\Node
2018-09-19 22:45:34 +00:00
{
2021-05-23 17:26:56 +00:00
$propertyToMethodCall = $this -> matchPropertyFetchCandidate ( $propertyFetch );
2021-05-10 22:23:08 +00:00
if ( ! $propertyToMethodCall instanceof \Rector\Transform\ValueObject\PropertyFetchToMethodCall ) {
2018-09-19 22:45:34 +00:00
return null ;
}
// simple method name
2020-08-26 10:54:53 +00:00
if ( $propertyToMethodCall -> getNewGetMethod () !== '' ) {
2021-05-23 17:26:56 +00:00
$methodCall = $this -> nodeFactory -> createMethodCall ( $propertyFetch -> var , $propertyToMethodCall -> getNewGetMethod ());
2020-08-26 10:54:53 +00:00
if ( $propertyToMethodCall -> getNewGetArguments () !== []) {
2021-01-30 21:41:25 +00:00
$args = $this -> nodeFactory -> createArgs ( $propertyToMethodCall -> getNewGetArguments ());
2021-05-23 17:26:56 +00:00
$methodCall -> args = $args ;
2020-08-26 10:54:53 +00:00
}
2021-05-23 17:26:56 +00:00
return $methodCall ;
2017-11-18 15:48:20 +00:00
}
2021-05-23 17:26:56 +00:00
return $propertyFetch ;
2017-11-18 15:48:20 +00:00
}
2021-05-10 22:23:08 +00:00
private function matchPropertyFetchCandidate ( \PhpParser\Node\Expr\PropertyFetch $propertyFetch ) : ? \Rector\Transform\ValueObject\PropertyFetchToMethodCall
2017-11-18 15:48:20 +00:00
{
2020-08-26 10:54:53 +00:00
foreach ( $this -> propertiesToMethodCalls as $propertyToMethodCall ) {
2021-05-09 20:15:43 +00:00
if ( ! $this -> isObjectType ( $propertyFetch -> var , $propertyToMethodCall -> getOldObjectType ())) {
2018-10-15 04:36:58 +00:00
continue ;
}
2021-05-09 20:15:43 +00:00
if ( ! $this -> isName ( $propertyFetch , $propertyToMethodCall -> getOldProperty ())) {
2018-10-15 04:36:58 +00:00
continue ;
2017-11-18 15:48:20 +00:00
}
2020-08-26 10:54:53 +00:00
return $propertyToMethodCall ;
2017-11-18 15:48:20 +00:00
}
2018-09-19 22:45:34 +00:00
return null ;
2017-11-18 15:20:10 +00:00
}
}