mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +01:00
Add means to guess PSR4 file path
This commit is contained in:
parent
f309c755f8
commit
ad4e2f72e2
@ -882,7 +882,7 @@ class Config
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setComposerClassLoader(ClassLoader $loader = null)
|
||||
public function setComposerClassLoader(?ClassLoader $loader = null)
|
||||
{
|
||||
$this->composer_class_loader = $loader;
|
||||
}
|
||||
@ -1642,6 +1642,47 @@ class Config
|
||||
return $this->composer_class_loader->findFile($fq_classlike_name);
|
||||
}
|
||||
|
||||
public function getPotentialComposerFilePathForClassLike(string $class) : ?string
|
||||
{
|
||||
if (!$this->composer_class_loader) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var array<string, array<int, string>> */
|
||||
$psr4_prefixes = $this->composer_class_loader->getPrefixesPsr4();
|
||||
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . '.php';
|
||||
|
||||
$candidate_path = null;
|
||||
|
||||
$maxDepth = 0;
|
||||
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($psr4_prefixes[$search])) {
|
||||
$depth = substr_count($search, '\\');
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
|
||||
foreach ($psr4_prefixes[$search] as $dir) {
|
||||
$dir = realpath($dir);
|
||||
|
||||
if ($dir
|
||||
&& $depth > $maxDepth
|
||||
&& $this->isInProjectDirs($dir . DIRECTORY_SEPARATOR . 'testdummy.php')
|
||||
) {
|
||||
$maxDepth = $depth;
|
||||
$candidate_path = realpath($dir) . $pathEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $candidate_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $dir
|
||||
*
|
||||
|
@ -118,7 +118,7 @@ class ForeachAnalyzer
|
||||
$statements_analyzer,
|
||||
$var_comment->type_start,
|
||||
$var_comment->type_end,
|
||||
$var_comment->line_number,
|
||||
$var_comment->line_number
|
||||
);
|
||||
|
||||
$codebase->classlikes->handleDocblockTypeInMigration(
|
||||
|
@ -128,7 +128,7 @@ class AssignmentAnalyzer
|
||||
$statements_analyzer,
|
||||
$var_comment->type_start,
|
||||
$var_comment->type_end,
|
||||
$var_comment->line_number,
|
||||
$var_comment->line_number
|
||||
);
|
||||
|
||||
$codebase->classlikes->handleDocblockTypeInMigration(
|
||||
|
@ -1310,4 +1310,58 @@ class ConfigTest extends \Psalm\Tests\TestCase
|
||||
|
||||
$this->analyzeFile($file_path, new Context());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function testGetPossiblePsr4Path()
|
||||
{
|
||||
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
||||
Config::loadFromXML(
|
||||
dirname(__DIR__, 2),
|
||||
'<?xml version="1.0"?>
|
||||
<psalm>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
<directory name="tests" />
|
||||
</projectFiles>
|
||||
</psalm>'
|
||||
)
|
||||
);
|
||||
|
||||
$config = $this->project_analyzer->getConfig();
|
||||
|
||||
$classloader = new \Composer\Autoload\ClassLoader();
|
||||
$classloader->addPsr4(
|
||||
'Psalm\\',
|
||||
[
|
||||
dirname(__DIR__, 2)
|
||||
. DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR
|
||||
. '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR
|
||||
. 'src' . DIRECTORY_SEPARATOR . 'Psalm'
|
||||
]
|
||||
);
|
||||
|
||||
$classloader->addPsr4(
|
||||
'Psalm\\Tests\\',
|
||||
[
|
||||
dirname(__DIR__, 2)
|
||||
. DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR
|
||||
. '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR
|
||||
. 'tests'
|
||||
]
|
||||
);
|
||||
|
||||
$config->setComposerClassLoader($classloader);
|
||||
|
||||
$this->assertSame(
|
||||
dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'Psalm' . DIRECTORY_SEPARATOR . 'Foo.php',
|
||||
$config->getPotentialComposerFilePathForClassLike("Psalm\\Foo")
|
||||
);
|
||||
|
||||
$this->assertSame(
|
||||
dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR . 'Foo.php',
|
||||
$config->getPotentialComposerFilePathForClassLike("Psalm\\Tests\\Foo")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user