2020-05-13 22:43:48 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Rector\PSR4\Composer;
|
|
|
|
|
|
|
|
use Nette\Utils\Strings;
|
|
|
|
use PhpParser\Node;
|
2020-11-18 21:25:59 +00:00
|
|
|
use Rector\Core\Exception\ShouldNotHappenException;
|
2020-11-18 20:37:17 +00:00
|
|
|
use Rector\NodeTypeResolver\FileSystem\CurrentFileInfoProvider;
|
2020-05-13 22:43:48 +02:00
|
|
|
use Rector\PSR4\Contract\PSR4AutoloadNamespaceMatcherInterface;
|
|
|
|
use Symplify\SmartFileSystem\SmartFileInfo;
|
|
|
|
|
|
|
|
final class PSR4NamespaceMatcher implements PSR4AutoloadNamespaceMatcherInterface
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var PSR4AutoloadPathsProvider
|
|
|
|
*/
|
|
|
|
private $psr4AutoloadPathsProvider;
|
|
|
|
|
2020-11-18 20:37:17 +00:00
|
|
|
/**
|
|
|
|
* @var CurrentFileInfoProvider
|
|
|
|
*/
|
|
|
|
private $currentFileInfoProvider;
|
|
|
|
|
|
|
|
public function __construct(
|
|
|
|
PSR4AutoloadPathsProvider $psr4AutoloadPathsProvider,
|
|
|
|
CurrentFileInfoProvider $currentFileInfoProvider
|
|
|
|
) {
|
2020-05-13 22:43:48 +02:00
|
|
|
$this->psr4AutoloadPathsProvider = $psr4AutoloadPathsProvider;
|
2020-11-18 20:37:17 +00:00
|
|
|
$this->currentFileInfoProvider = $currentFileInfoProvider;
|
2020-05-13 22:43:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getExpectedNamespace(Node $node): ?string
|
|
|
|
{
|
2020-11-18 20:37:17 +00:00
|
|
|
$smartFileInfo = $this->currentFileInfoProvider->getSmartFileInfo();
|
2021-01-20 18:41:35 +07:00
|
|
|
if (! $smartFileInfo instanceof SmartFileInfo) {
|
2020-11-18 21:25:59 +00:00
|
|
|
throw new ShouldNotHappenException();
|
|
|
|
}
|
2020-05-13 22:43:48 +02:00
|
|
|
|
|
|
|
$psr4Autoloads = $this->psr4AutoloadPathsProvider->provide();
|
|
|
|
|
|
|
|
foreach ($psr4Autoloads as $namespace => $path) {
|
|
|
|
// remove extra slash
|
|
|
|
$paths = is_array($path) ? $path : [$path];
|
|
|
|
|
2020-06-10 12:05:27 +02:00
|
|
|
foreach ($paths as $singlePath) {
|
|
|
|
$singlePath = rtrim($singlePath, '/');
|
|
|
|
if (! Strings::startsWith($smartFileInfo->getRelativeDirectoryPath(), $singlePath)) {
|
2020-05-13 22:43:48 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-06-10 12:05:27 +02:00
|
|
|
$expectedNamespace = $namespace . $this->resolveExtraNamespace($smartFileInfo, $singlePath);
|
2020-05-13 22:43:48 +02:00
|
|
|
|
|
|
|
return rtrim($expectedNamespace, '\\');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the extra path that is not included in root PSR-4 namespace
|
|
|
|
*/
|
|
|
|
private function resolveExtraNamespace(SmartFileInfo $smartFileInfo, string $path): string
|
|
|
|
{
|
|
|
|
$extraNamespace = Strings::substring($smartFileInfo->getRelativeDirectoryPath(), Strings::length($path) + 1);
|
|
|
|
$extraNamespace = Strings::replace($extraNamespace, '#/#', '\\');
|
|
|
|
|
|
|
|
return trim($extraNamespace);
|
|
|
|
}
|
|
|
|
}
|