Skip to content

Commit 41af658

Browse files
committed
Replace deprecated PropertyFetchToMethodCallRector with custom rule
PropertyFetchToMethodCallRector was deprecated in Rector 2.2.6 as it was considered too generic. This commit introduces a custom FakerPropertyToMethodCallRector that specifically handles the transformation of Faker\Generator property access to method calls. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 93dd3ae commit 41af658

File tree

12 files changed

+1927
-26
lines changed

12 files changed

+1927
-26
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@
55
/vendor-bin/psalm/vendor/
66
/vendor-bin/rector/vendor/
77
/.php-cs-fixer.cache
8+
/.phpunit.cache/
89
/composer.lock
10+
/vendor-bin/rector/.phpunit.cache/

rector-migrate.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
declare(strict_types=1);
44

5-
use Faker\Generator;
6-
use Rector\Config;
7-
use Rector\Transform;
5+
require_once __DIR__ . '/rector/FakerPropertyToMethodCallRector.php';
6+
7+
use Faker\Rector\FakerPropertyToMethodCallRector;
8+
use Rector\Config\RectorConfig;
89

910
// This file configures rector/rector to replace all deprecated property usages with their equivalent functions.
10-
return static function (Config\RectorConfig $rectorConfig): void {
11+
return static function (RectorConfig $rectorConfig): void {
1112
$properties = [
1213
'address',
1314
'amPm',
@@ -149,13 +150,7 @@
149150
];
150151

151152
$rectorConfig->ruleWithConfiguration(
152-
Transform\Rector\Assign\PropertyFetchToMethodCallRector::class,
153-
array_map(static function (string $property): Transform\ValueObject\PropertyFetchToMethodCall {
154-
return new Transform\ValueObject\PropertyFetchToMethodCall(
155-
Generator::class,
156-
$property,
157-
$property,
158-
);
159-
}, $properties),
153+
FakerPropertyToMethodCallRector::class,
154+
$properties,
160155
);
161156
};
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Faker package.
7+
*
8+
* (c) Oskar Stark <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Faker\Rector;
15+
16+
use Faker\Generator;
17+
use PhpParser\Node;
18+
use PhpParser\Node\Expr\PropertyFetch;
19+
use PhpParser\Node\Identifier;
20+
use PHPStan\Type\ObjectType;
21+
use Rector\Contract\Rector\ConfigurableRectorInterface;
22+
use Rector\Rector\AbstractRector;
23+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
24+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
25+
26+
final class FakerPropertyToMethodCallRector extends AbstractRector implements ConfigurableRectorInterface
27+
{
28+
/**
29+
* @var list<string>
30+
*/
31+
private array $propertyNames = [];
32+
33+
/**
34+
* @param array<mixed> $configuration
35+
*/
36+
public function configure(array $configuration): void
37+
{
38+
$this->propertyNames = array_values(array_filter($configuration, 'is_string'));
39+
}
40+
41+
public function getRuleDefinition(): RuleDefinition
42+
{
43+
return new RuleDefinition(
44+
'Replaces deprecated Faker property access with method calls',
45+
[
46+
new ConfiguredCodeSample(
47+
<<<'CODE_SAMPLE'
48+
$faker->name;
49+
CODE_SAMPLE
50+
,
51+
<<<'CODE_SAMPLE'
52+
$faker->name();
53+
CODE_SAMPLE
54+
,
55+
['name', 'email', 'address'],
56+
),
57+
],
58+
);
59+
}
60+
61+
/**
62+
* @return array<class-string<Node>>
63+
*/
64+
public function getNodeTypes(): array
65+
{
66+
return [PropertyFetch::class];
67+
}
68+
69+
/**
70+
* @param PropertyFetch $node
71+
*/
72+
public function refactor(Node $node): ?Node
73+
{
74+
if (!$node->name instanceof Identifier) {
75+
return null;
76+
}
77+
78+
$propertyName = $node->name->toString();
79+
80+
if (!\in_array($propertyName, $this->propertyNames, true)) {
81+
return null;
82+
}
83+
84+
if (!$this->isObjectType($node->var, new ObjectType(Generator::class))) {
85+
return null;
86+
}
87+
88+
return $this->nodeFactory->createMethodCall($node->var, $propertyName);
89+
}
90+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Faker package.
7+
*
8+
* (c) Oskar Stark <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Faker\Rector\Tests\FakerPropertyToMethodCallRector;
15+
16+
use Iterator;
17+
use PHPUnit\Framework\Attributes\DataProvider;
18+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
19+
20+
final class FakerPropertyToMethodCallRectorTest extends AbstractRectorTestCase
21+
{
22+
#[DataProvider('provideData')]
23+
public function test(string $filePath): void
24+
{
25+
$this->doTestFile($filePath);
26+
}
27+
28+
public static function provideData(): Iterator
29+
{
30+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
31+
}
32+
33+
public function provideConfigFilePath(): string
34+
{
35+
return __DIR__ . '/config/config.php';
36+
}
37+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
use Faker\Generator;
4+
5+
/** @var Generator $faker */
6+
$faker = new Generator();
7+
8+
$name = $faker->name;
9+
$email = $faker->email;
10+
$address = $faker->address;
11+
12+
?>
13+
-----
14+
<?php
15+
16+
use Faker\Generator;
17+
18+
/** @var Generator $faker */
19+
$faker = new Generator();
20+
21+
$name = $faker->name();
22+
$email = $faker->email();
23+
$address = $faker->address();
24+
25+
?>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
use Faker\Generator;
4+
5+
/** @var Generator $faker */
6+
$faker = new Generator();
7+
8+
// Already method calls - should not change
9+
$name = $faker->name();
10+
$email = $faker->email();
11+
$address = $faker->address();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
class SomeOtherClass
4+
{
5+
public string $name;
6+
public string $email;
7+
}
8+
9+
$other = new SomeOtherClass();
10+
11+
// Should not change - not a Faker\Generator instance
12+
$name = $other->name;
13+
$email = $other->email;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
use Faker\Generator;
4+
5+
/** @var Generator $faker */
6+
$faker = new Generator();
7+
8+
// Should not change - 'firstName' is not in the configured list
9+
$firstName = $faker->firstName;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Faker package.
7+
*
8+
* (c) Oskar Stark <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
use Faker\Rector\FakerPropertyToMethodCallRector;
15+
use Rector\Config\RectorConfig;
16+
17+
return RectorConfig::configure()
18+
->withRules([FakerPropertyToMethodCallRector::class])
19+
->withConfiguredRule(FakerPropertyToMethodCallRector::class, [
20+
'name',
21+
'email',
22+
'address',
23+
]);

vendor-bin/rector/composer.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
"php": "^8.1",
44
"rector/rector": "^2.2.6"
55
},
6+
"require-dev": {
7+
"phpunit/phpunit": "^10.5 || ^11.0"
8+
},
9+
"autoload": {
10+
"psr-4": {
11+
"Faker\\Rector\\": "../../rector/"
12+
}
13+
},
14+
"autoload-dev": {
15+
"psr-4": {
16+
"Faker\\Rector\\Tests\\": "../../rector/tests/"
17+
}
18+
},
619
"config": {
720
"platform": {
821
"php": "8.1.12"

0 commit comments

Comments
 (0)