mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 12:24:49 +01:00
Ensure Stringable is always available to tests that need it
This commit is contained in:
parent
7c1c2f77f7
commit
fb81fa13f4
@ -96,6 +96,11 @@
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="StubsAttributeType">
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:attribute name="preloadClasses" type="xs:boolean" default="false" />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="IgnoreFilesType">
|
||||
<xs:choice maxOccurs="unbounded">
|
||||
<xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
|
||||
@ -144,7 +149,7 @@
|
||||
|
||||
<xs:complexType name="StubsType">
|
||||
<xs:sequence>
|
||||
<xs:element name="file" maxOccurs="unbounded" type="NameAttributeType" />
|
||||
<xs:element name="file" maxOccurs="unbounded" type="StubsAttributeType" />
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
|
||||
|
@ -258,6 +258,11 @@ class Config
|
||||
*/
|
||||
private $mock_classes = [];
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
private $preloaded_stub_files = [];
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
@ -1031,7 +1036,17 @@ class Config
|
||||
);
|
||||
}
|
||||
|
||||
$config->addStubFile($file_path);
|
||||
if (isset($stub_file['preloadClasses'])) {
|
||||
$preload_classes = (string)$stub_file['preloadClasses'];
|
||||
|
||||
if ($preload_classes === 'true' || $preload_classes === '1') {
|
||||
$config->addPreloadedStubFile($file_path);
|
||||
} else {
|
||||
$config->addStubFile($file_path);
|
||||
}
|
||||
} else {
|
||||
$config->addStubFile($file_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1700,6 +1715,56 @@ class Config
|
||||
return $this->mock_classes;
|
||||
}
|
||||
|
||||
public function visitPreloadedStubFiles(Codebase $codebase, ?Progress $progress = null): void
|
||||
{
|
||||
if ($progress === null) {
|
||||
$progress = new VoidProgress();
|
||||
}
|
||||
|
||||
$core_generic_files = [];
|
||||
|
||||
if (\PHP_VERSION_ID < 80000 && $codebase->php_major_version >= 8) {
|
||||
$stringable_path = dirname(__DIR__, 2) . '/stubs/Stringable.php';
|
||||
|
||||
if (!file_exists($stringable_path)) {
|
||||
throw new \UnexpectedValueException('Cannot locate core generic classes');
|
||||
}
|
||||
|
||||
$core_generic_files[] = $stringable_path;
|
||||
}
|
||||
|
||||
$stub_files = array_merge($core_generic_files, $this->preloaded_stub_files);
|
||||
|
||||
if ($this->load_xdebug_stub) {
|
||||
$xdebug_stub_path = dirname(__DIR__, 2) . '/stubs/Xdebug.php';
|
||||
|
||||
if (!file_exists($xdebug_stub_path)) {
|
||||
throw new \UnexpectedValueException('Cannot locate XDebug stub');
|
||||
}
|
||||
|
||||
$stub_files[] = $xdebug_stub_path;
|
||||
}
|
||||
|
||||
if (!$stub_files) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($stub_files as $file_path) {
|
||||
$file_path = \str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $file_path);
|
||||
$codebase->scanner->addFileToDeepScan($file_path);
|
||||
}
|
||||
|
||||
$progress->debug('Registering preloaded stub files' . "\n");
|
||||
|
||||
$codebase->register_stub_files = true;
|
||||
|
||||
$codebase->scanFiles();
|
||||
|
||||
$codebase->register_stub_files = false;
|
||||
|
||||
$progress->debug('Finished registering preloaded stub files' . "\n");
|
||||
}
|
||||
|
||||
public function visitStubFiles(Codebase $codebase, ?Progress $progress = null): void
|
||||
{
|
||||
if ($progress === null) {
|
||||
@ -1741,16 +1806,6 @@ class Config
|
||||
$core_generic_files[] = $ext_ds_path;
|
||||
}
|
||||
|
||||
if (\version_compare(\PHP_VERSION, '8.0', '<') && $codebase->php_major_version >= 8) {
|
||||
$stringable_path = dirname(__DIR__, 2) . '/stubs/Stringable.php';
|
||||
|
||||
if (!file_exists($stringable_path)) {
|
||||
throw new \UnexpectedValueException('Cannot locate core generic classes');
|
||||
}
|
||||
|
||||
$core_generic_files[] = $stringable_path;
|
||||
}
|
||||
|
||||
$stub_files = array_merge($core_generic_files, $this->stub_files);
|
||||
|
||||
$phpstorm_meta_path = $this->base_dir . DIRECTORY_SEPARATOR . '.phpstorm.meta.php';
|
||||
@ -1769,16 +1824,6 @@ class Config
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->load_xdebug_stub) {
|
||||
$xdebug_stub_path = dirname(__DIR__, 2) . '/stubs/Xdebug.php';
|
||||
|
||||
if (!file_exists($xdebug_stub_path)) {
|
||||
throw new \UnexpectedValueException('Cannot locate XDebug stub');
|
||||
}
|
||||
|
||||
$stub_files[] = $xdebug_stub_path;
|
||||
}
|
||||
|
||||
foreach ($stub_files as $file_path) {
|
||||
$file_path = \str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $file_path);
|
||||
$codebase->scanner->addFileToDeepScan($file_path);
|
||||
@ -2016,6 +2061,11 @@ class Config
|
||||
return $this->stub_files;
|
||||
}
|
||||
|
||||
public function addPreloadedStubFile(string $stub_file): void
|
||||
{
|
||||
$this->preloaded_stub_files[$stub_file] = $stub_file;
|
||||
}
|
||||
|
||||
public function getPhpVersion(): ?string
|
||||
{
|
||||
if (isset($this->configured_php_version)) {
|
||||
|
@ -582,6 +582,8 @@ class ProjectAnalyzer
|
||||
|
||||
$this->config->initializePlugins($this);
|
||||
|
||||
$this->config->visitPreloadedStubFiles($this->codebase, $this->progress);
|
||||
|
||||
$this->codebase->scanFiles($this->threads);
|
||||
|
||||
$this->codebase->infer_types_from_usage = true;
|
||||
@ -604,6 +606,8 @@ class ProjectAnalyzer
|
||||
|
||||
$this->config->initializePlugins($this);
|
||||
|
||||
$this->config->visitPreloadedStubFiles($this->codebase, $this->progress);
|
||||
|
||||
$this->codebase->scanFiles($this->threads);
|
||||
} else {
|
||||
$diff_no_files = true;
|
||||
@ -987,6 +991,8 @@ class ProjectAnalyzer
|
||||
|
||||
$this->config->initializePlugins($this);
|
||||
|
||||
$this->config->visitPreloadedStubFiles($this->codebase, $this->progress);
|
||||
|
||||
$this->codebase->scanFiles($this->threads);
|
||||
|
||||
$this->config->visitStubFiles($this->codebase, $this->progress);
|
||||
@ -1120,6 +1126,8 @@ class ProjectAnalyzer
|
||||
|
||||
$this->config->initializePlugins($this);
|
||||
|
||||
$this->config->visitPreloadedStubFiles($this->codebase, $this->progress);
|
||||
|
||||
$this->codebase->scanFiles($this->threads);
|
||||
|
||||
$this->config->visitStubFiles($this->codebase, $this->progress);
|
||||
@ -1158,6 +1166,8 @@ class ProjectAnalyzer
|
||||
|
||||
$this->config->initializePlugins($this);
|
||||
|
||||
$this->config->visitPreloadedStubFiles($this->codebase, $this->progress);
|
||||
|
||||
$this->codebase->scanFiles($this->threads);
|
||||
|
||||
$this->config->visitStubFiles($this->codebase, $this->progress);
|
||||
|
@ -245,7 +245,9 @@ class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements FileSour
|
||||
$classlike_storage->class_implements['stringable'] = 'Stringable';
|
||||
}
|
||||
|
||||
$this->codebase->scanner->queueClassLikeForScanning('Stringable');
|
||||
if (\PHP_VERSION_ID >= 80000) {
|
||||
$this->codebase->scanner->queueClassLikeForScanning('Stringable');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->scan_deep) {
|
||||
|
@ -171,6 +171,9 @@ class DocumentationTest extends TestCase
|
||||
$this->expectException(\Psalm\Exception\CodeException::class);
|
||||
$this->expectExceptionMessageRegExp('/\b' . preg_quote($error_message, '/') . '\b/');
|
||||
|
||||
$codebase = $this->project_analyzer->getCodebase();
|
||||
$codebase->config->visitPreloadedStubFiles($codebase);
|
||||
|
||||
$file_path = self::$src_dir_path . 'somefile.php';
|
||||
|
||||
$this->addFile($file_path, $code);
|
||||
|
@ -94,6 +94,7 @@ class TestCase extends BaseTestCase
|
||||
public function analyzeFile($file_path, \Psalm\Context $context, bool $track_unused_suppressions = true): void
|
||||
{
|
||||
$codebase = $this->project_analyzer->getCodebase();
|
||||
|
||||
$codebase->addFilesToAnalyze([$file_path => $file_path]);
|
||||
|
||||
$codebase->scanFiles();
|
||||
|
@ -391,6 +391,9 @@ class ToStringTest extends TestCase
|
||||
],
|
||||
'implicitStringableDisallowed' => [
|
||||
'<?php
|
||||
interface Stringable {
|
||||
function __toString() {}
|
||||
}
|
||||
function foo(Stringable $s): void {}
|
||||
|
||||
class Bar {
|
||||
|
@ -84,6 +84,9 @@ trait InvalidCodeAnalysisTestTrait
|
||||
$this->expectExceptionMessageRegExp('/\b' . preg_quote($error_message, '/') . '\b/');
|
||||
}
|
||||
|
||||
$codebase = $this->project_analyzer->getCodebase();
|
||||
$codebase->config->visitPreloadedStubFiles($codebase);
|
||||
|
||||
$this->addFile($file_path, $code);
|
||||
$this->analyzeFile($file_path, new Context());
|
||||
}
|
||||
|
@ -76,6 +76,9 @@ trait ValidCodeAnalysisTestTrait
|
||||
|
||||
$this->project_analyzer->setPhpVersion($php_version);
|
||||
|
||||
$codebase = $this->project_analyzer->getCodebase();
|
||||
$codebase->config->visitPreloadedStubFiles($codebase);
|
||||
|
||||
$file_path = self::$src_dir_path . 'somefile.php';
|
||||
|
||||
$this->addFile($file_path, $code);
|
||||
|
Loading…
Reference in New Issue
Block a user