Skip to content

Commit

Permalink
[PhpParser] Re-add back get value from __DIR__ and __FILE__ on ValueR…
Browse files Browse the repository at this point in the history
…esolver (#6756)

* [PhpParser] Re-add back get value from __DIR__ and __FILE__ on ValueResolver

* Fix

* add more use case for inside array
  • Loading branch information
samsonasik authored Feb 24, 2025
1 parent 7231ba8 commit c09dd52
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 1 deletion.
36 changes: 35 additions & 1 deletion src/PhpParser/Node/Value/ValueResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@
use PhpParser\Node\InterpolatedStringPart;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\MagicConst\Class_;
use PhpParser\Node\Scalar\MagicConst\Dir;
use PhpParser\Node\Scalar\MagicConst\File;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\ConstantScalarType;
use PHPStan\Type\Type;
use Rector\Application\Provider\CurrentFileProvider;
use Rector\Enum\ObjectReference;
use Rector\Exception\ShouldNotHappenException;
use Rector\NodeAnalyzer\ConstFetchAnalyzer;
Expand All @@ -47,7 +50,8 @@ public function __construct(
private readonly ConstFetchAnalyzer $constFetchAnalyzer,
private readonly ReflectionProvider $reflectionProvider,
private readonly ReflectionResolver $reflectionResolver,
private readonly ClassReflectionAnalyzer $classReflectionAnalyzer
private readonly ClassReflectionAnalyzer $classReflectionAnalyzer,
private readonly CurrentFileProvider $currentFileProvider,
) {
}

Expand Down Expand Up @@ -186,6 +190,16 @@ private function getConstExprEvaluator(): ConstExprEvaluator
}

$this->constExprEvaluator = new ConstExprEvaluator(function (Expr $expr) {
if ($expr instanceof Dir) {
// __DIR__
return $this->resolveDirConstant();
}

if ($expr instanceof File) {
// __FILE__
return $this->resolveFileConstant($expr);
}

// resolve "SomeClass::SOME_CONST"
if ($expr instanceof ClassConstFetch && $expr->class instanceof Name) {
return $this->resolveClassConstFetch($expr);
Expand All @@ -200,6 +214,26 @@ private function getConstExprEvaluator(): ConstExprEvaluator
return $this->constExprEvaluator;
}

private function resolveDirConstant(): string
{
$file = $this->currentFileProvider->getFile();
if (! $file instanceof \Rector\ValueObject\Application\File) {
throw new ShouldNotHappenException();
}

return dirname($file->getFilePath());
}

private function resolveFileConstant(File $file): string
{
$file = $this->currentFileProvider->getFile();
if (! $file instanceof \Rector\ValueObject\Application\File) {
throw new ShouldNotHappenException();
}

return $file->getFilePath();
}

/**
* @return mixed[]|null
*/
Expand Down
33 changes: 33 additions & 0 deletions tests/Issues/GetValueMagicDir/Fixture/fixture.php.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Rector\Tests\Issues\GetValueMagicDir\Fixture;

class Fixture
{
public function run()
{
strlen(__DIR__);
strlen(__FILE__);

new \Foo(['bar' => ['foo' => __DIR__ . '/bar']]);
}
}

?>
-----
<?php

namespace Rector\Tests\Issues\GetValueMagicDir\Fixture;

class Fixture
{
public function run()
{
'tests/Issues/GetValueMagicDir/Fixture';
'tests/Issues/GetValueMagicDir/Fixture/fixture.php';

['bar' => ['foo' => 'tests/Issues/GetValueMagicDir/Fixture/bar']];
}
}

?>
28 changes: 28 additions & 0 deletions tests/Issues/GetValueMagicDir/GetValueMagicDirTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Issues\GetValueMagicDir;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class GetValueMagicDirTest extends AbstractRectorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
49 changes: 49 additions & 0 deletions tests/Issues/GetValueMagicDir/Source/GetValueMagicDirRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Issues\GetValueMagicDir\Source;

use PhpParser\Builder;
use PhpParser\Node;
use PhpParser\Node\ArrayItem;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Scalar\String_;
use Rector\FileSystem\FilePathHelper;
use Rector\PhpParser\Node\NodeFactory;
use Rector\PhpParser\Node\Value\ValueResolver;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

final class GetValueMagicDirRector extends AbstractRector
{
public function __construct(
private readonly ValueResolver $valueResolver,
private readonly FilePathHelper $filePathHelper,
) {
}

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('', []);
}

public function getNodeTypes(): array
{
return [FuncCall::class, New_::class];
}

public function refactor(Node $node): String_|Array_
{
$value = $this->valueResolver->getValue($node->args[0]->value);

if ($node instanceof FuncCall) {
return new String_($this->filePathHelper->relativePath($value));
}

$value['bar']['foo'] = $this->filePathHelper->relativePath($value['bar']['foo']);
return $this->nodeFactory->createArray($value);
}
}
9 changes: 9 additions & 0 deletions tests/Issues/GetValueMagicDir/config/configured_rule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Tests\Issues\GetValueMagicDir\Source\GetValueMagicDirRector;

return RectorConfig::configure()
->withRules([GetValueMagicDirRector::class]);

0 comments on commit c09dd52

Please sign in to comment.