Skip to content

Commit 2529395

Browse files
authored
Fix static private member renaming for phpactor#2672 (phpactor#2674)
1 parent a680258 commit 2529395

File tree

10 files changed

+119
-5
lines changed

10 files changed

+119
-5
lines changed

lib/Rename/Adapter/ReferenceFinder/VariableRenamer.php

+7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Microsoft\PhpParser\Node;
66
use Microsoft\PhpParser\Node\CatchClause;
7+
use Microsoft\PhpParser\Node\Expression\ScopedPropertyAccessExpression;
78
use Microsoft\PhpParser\Node\Expression\Variable;
89
use Microsoft\PhpParser\Node\Parameter;
910
use Microsoft\PhpParser\Node\PropertyDeclaration;
@@ -14,13 +15,19 @@ class VariableRenamer extends AbstractReferenceRenamer
1415
{
1516
public function getRenameRangeForNode(Node $node): ?ByteOffsetRange
1617
{
18+
// do not try and rename static property names
19+
if ($node->parent instanceof ScopedPropertyAccessExpression) {
20+
return null;
21+
}
22+
1723
if (
1824
$node instanceof Variable &&
1925
!$node->getFirstAncestor(PropertyDeclaration::class)
2026
) {
2127
return $this->offsetRangeFromToken($node->name, true);
2228
}
2329

30+
2431
if ($node instanceof Parameter && $node->visibilityToken) {
2532
return null;
2633
}

lib/Rename/Tests/Adapter/WorseReflection/WorseReflectionMemberRenamerTest.php

+34
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,23 @@ function (Reflector $reflector): void {
4747
self::assertTrue($reflection->methods()->has('newName'));
4848
}
4949
];
50+
yield 'private static method declaration' => [
51+
'member_renamer/method_declaration_static_private',
52+
function (Reflector $reflector, Renamer $renamer): Generator {
53+
$reflection = $reflector->reflectClass('ClassOne');
54+
$method = $reflection->methods()->get('foobar');
55+
56+
return $renamer->rename(
57+
$reflection->sourceCode(),
58+
$method->nameRange()->start(),
59+
'newName'
60+
);
61+
},
62+
function (Reflector $reflector): void {
63+
$reflection = $reflector->reflectClass('ClassOne');
64+
self::assertTrue($reflection->methods()->has('newName'));
65+
}
66+
];
5067
yield 'private property declaration' => [
5168
'member_renamer/property_declaration_private',
5269
function (Reflector $reflector, Renamer $renamer): Generator {
@@ -64,6 +81,23 @@ function (Reflector $reflector): void {
6481
self::assertTrue($reflection->properties()->has('newName'));
6582
}
6683
];
84+
yield 'private static property declaration' => [
85+
'member_renamer/property_declaration_static_private',
86+
function (Reflector $reflector, Renamer $renamer): Generator {
87+
$reflection = $reflector->reflectClass('ClassOne');
88+
$method = $reflection->properties()->get('foobar');
89+
90+
return $renamer->rename(
91+
$reflection->sourceCode(),
92+
$method->nameRange()->start(),
93+
'newName'
94+
);
95+
},
96+
function (Reflector $reflector): void {
97+
$reflection = $reflector->reflectClass('ClassOne');
98+
self::assertTrue($reflection->properties()->has('newName'));
99+
}
100+
];
67101
yield 'private promoted property declaration' => [
68102
'member_renamer/property_promoted_private',
69103
function (Reflector $reflector, Renamer $renamer): Generator {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
class ClassOne
4+
{
5+
6+
public function hello(): string
7+
{
8+
return self::foobar();
9+
}
10+
private static function foobar(): string
11+
{
12+
return 'foobar';
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
require __DIR__ . '/ClassOne.php';
4+
5+
$one = new ClassOne();
6+
if (!$one->hello() === 'foobar') {
7+
echo 'expected "foobar" but didn\'t get it';
8+
exit(127);
9+
}
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
class ClassOne
4+
{
5+
private static string $foobar;
6+
7+
public function __construct(string $foobar)
8+
{
9+
self::$foobar = $foobar;
10+
}
11+
12+
public function foobar(): string
13+
{
14+
return self::$foobar;
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
require __DIR__ . '/ClassOne.php';
4+
5+
$two = new ClassOne('foobar');
6+
if (!$two->foobar() === 'foobar') {
7+
echo 'expected "foobar" but didn\'t get it';
8+
exit(127);
9+
}

lib/Rename/Tests/RenamerTestCase.php

+11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Phpactor\Rename\Tests;
44

55
use Closure;
6+
use RuntimeException;
67
use Generator;
78
use PHPUnit\Framework\TestCase;
89
use Phpactor\Indexer\Adapter\Worse\WorseRecordReferenceEnhancer;
@@ -50,6 +51,16 @@ protected function setUp(): void
5051
public function testRename(string $path, Closure $operation, Closure $assertion): void
5152
{
5253
$basePath = __DIR__ . '/Cases/' . $path;
54+
55+
56+
if (!file_exists($basePath)) {
57+
throw new RuntimeException(sprintf(
58+
'Case path "%s" does not yet exist',
59+
$basePath
60+
));
61+
}
62+
63+
5364
foreach ((array)glob($basePath . '/**.ph') as $path) {
5465
$this->workspace()->put(
5566
'project/' . ((string)substr((string)$path, strlen($basePath))) . 'p',

lib/WorseReflection/Bridge/TolerantParser/Reflection/ReflectionNavigation.php

+15-2
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,25 @@ public function __construct(private ServiceLocator $locator, private Node $node)
1818
}
1919

2020
/**
21-
* @return NavigatorElementCollection<ReflectionMethodCall>
21+
* @return NavigatorElementCollection<AbstractReflectionMethodCall>
2222
*/
2323
public function methodCalls(): NavigatorElementCollection
2424
{
2525
$calls = [];
2626
foreach ($this->node->getDescendantNodes() as $node) {
27+
if ($node instanceof ScopedPropertyAccessExpression) {
28+
if (!$node->parent instanceof CallExpression) {
29+
continue;
30+
}
31+
$calls[] = new ReflectionStaticMethodCall($this->locator, new Frame(), $node);
32+
continue;
33+
}
2734
if ($node instanceof MemberAccessExpression) {
2835
if (!$node->parent instanceof CallExpression) {
2936
continue;
3037
}
3138
$calls[] = new ReflectionMethodCall($this->locator, new Frame(), $node);
39+
continue;
3240
}
3341
}
3442
return new NavigatorElementCollection($calls);
@@ -40,12 +48,16 @@ public function at(ByteOffset $offset): self
4048
}
4149

4250
/**
43-
* @return NavigatorElementCollection<ReflectionPropertyAccess>
51+
* @return NavigatorElementCollection<ReflectionPropertyAccess|ReflectionStaticMemberAccess>
4452
*/
4553
public function propertyAccesses(): NavigatorElementCollection
4654
{
4755
$elements = [];
4856
foreach ($this->node->getDescendantNodes() as $node) {
57+
if ($node instanceof ScopedPropertyAccessExpression) {
58+
$elements[] = new ReflectionStaticMemberAccess($this->locator, new Frame(), $node);
59+
continue;
60+
}
4961
if (!$node instanceof MemberAccessExpression) {
5062
continue;
5163
}
@@ -55,6 +67,7 @@ public function propertyAccesses(): NavigatorElementCollection
5567

5668
$elements[] = new ReflectionPropertyAccess($node);
5769
}
70+
5871
return new NavigatorElementCollection($elements);
5972
}
6073

lib/WorseReflection/Bridge/TolerantParser/Reflection/ReflectionStaticMemberAccess.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function class(): ReflectionClassLike
6060

6161
public function name(): string
6262
{
63-
return NodeUtil::nameFromTokenOrNode($this->node, $this->node->memberName);
63+
return ltrim(NodeUtil::nameFromTokenOrNode($this->node, $this->node->memberName), '$');
6464
}
6565

6666
public function scope(): ReflectionScope
@@ -72,7 +72,7 @@ public function nameRange(): ByteOffsetRange
7272
{
7373
$memberName = $this->node->memberName;
7474
return ByteOffsetRange::fromInts(
75-
$memberName->getStartPosition(),
75+
$memberName->getStartPosition() + 1,
7676
$memberName->getEndPosition()
7777
);
7878
}

lib/WorseReflection/Core/NavigatorElementCollection.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use Traversable;
1010

1111
/**
12-
* @template T of object
12+
* @template-covariant T of object
1313
* @implements IteratorAggregate<array-key,T>
1414
*/
1515
class NavigatorElementCollection implements IteratorAggregate

0 commit comments

Comments
 (0)