mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +01:00
Fix #971 - be more robust in face of duplicate classes
This commit is contained in:
parent
5d6fb4efdf
commit
cbfebb7a69
@ -838,6 +838,8 @@ class ClassChecker extends ClassLikeChecker
|
||||
|
||||
$analyzed_method_id = $actual_method_id;
|
||||
|
||||
$classlike_storage_provider = $project_checker->classlike_storage_provider;
|
||||
|
||||
if ($class_context->self && $class_context->self !== $source->getFQCLN()) {
|
||||
$analyzed_method_id = (string)$method_checker->getMethodId($class_context->self);
|
||||
|
||||
@ -853,7 +855,6 @@ class ClassChecker extends ClassLikeChecker
|
||||
}
|
||||
|
||||
if ($declaring_method_id && $implementer_method_storage->abstract) {
|
||||
$classlike_storage_provider = $project_checker->classlike_storage_provider;
|
||||
$appearing_storage = $classlike_storage_provider->get($class_context->self);
|
||||
$declaring_method_storage = $codebase->methods->getStorage($declaring_method_id);
|
||||
|
||||
@ -888,6 +889,12 @@ class ClassChecker extends ClassLikeChecker
|
||||
$return_type_location = null;
|
||||
$secondary_return_type_location = null;
|
||||
|
||||
$self_class = $classlike_storage_provider->get($class_context->self);
|
||||
|
||||
if ($self_class->has_visitor_issues) {
|
||||
return;
|
||||
}
|
||||
|
||||
$actual_method_storage = $codebase->methods->getStorage($actual_method_id);
|
||||
|
||||
if (!$actual_method_storage->has_template_return_type) {
|
||||
|
@ -155,6 +155,10 @@ abstract class FunctionLikeChecker extends SourceChecker implements StatementsSo
|
||||
try {
|
||||
$storage = $codebase->methods->getStorage($real_method_id);
|
||||
} catch (\UnexpectedValueException $e) {
|
||||
if ($class_storage->has_visitor_issues) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$class_storage->parent_classes) {
|
||||
throw $e;
|
||||
}
|
||||
|
@ -26,6 +26,10 @@ class InterfaceChecker extends ClassLikeChecker
|
||||
throw new \LogicException('Something went badly wrong');
|
||||
}
|
||||
|
||||
if (isset($class->isDuplicate)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->class->extends) {
|
||||
foreach ($this->class->extends as $extended_interface) {
|
||||
$extended_interface_name = self::getFQCLNFromNameObject(
|
||||
|
@ -298,6 +298,10 @@ class Populator
|
||||
$parent_storage->invalid_dependencies
|
||||
);
|
||||
|
||||
if ($parent_storage->has_visitor_issues) {
|
||||
$storage->has_visitor_issues = true;
|
||||
}
|
||||
|
||||
$storage->public_class_constants += $parent_storage->public_class_constants;
|
||||
$storage->protected_class_constants += $parent_storage->protected_class_constants;
|
||||
|
||||
|
@ -580,6 +580,8 @@ class DependencyFinderVisitor extends PhpParser\NodeVisitorAbstract implements P
|
||||
$this->file_storage->has_visitor_issues = true;
|
||||
}
|
||||
|
||||
$duplicate_storage->has_visitor_issues = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
} elseif (!$duplicate_storage->location
|
||||
|
@ -14,8 +14,12 @@ class IncludeTest extends TestCase
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testValidInclude(array $files, array $files_to_check, $hoist_constants = false)
|
||||
{
|
||||
public function testValidInclude(
|
||||
array $files,
|
||||
array $files_to_check,
|
||||
$hoist_constants = false,
|
||||
array $error_levels = []
|
||||
) {
|
||||
$codebase = $this->project_checker->getCodebase();
|
||||
|
||||
foreach ($files as $file_path => $contents) {
|
||||
@ -27,9 +31,14 @@ class IncludeTest extends TestCase
|
||||
$codebase->addFilesToAnalyze([$file_path => $file_path]);
|
||||
}
|
||||
|
||||
$config = $codebase->config;
|
||||
|
||||
foreach ($error_levels as $error_level) {
|
||||
$config->setCustomErrorLevel($error_level, \Psalm\Config::REPORT_SUPPRESS);
|
||||
}
|
||||
|
||||
$codebase->scanFiles();
|
||||
|
||||
$config = $codebase->config;
|
||||
$config->hoist_constants = $hoist_constants;
|
||||
|
||||
foreach ($files_to_check as $file_path) {
|
||||
@ -51,8 +60,7 @@ class IncludeTest extends TestCase
|
||||
public function testInvalidInclude(
|
||||
array $files,
|
||||
array $files_to_check,
|
||||
$error_message,
|
||||
$hoist_constants = false
|
||||
$error_message
|
||||
) {
|
||||
$codebase = $this->project_checker->getCodebase();
|
||||
|
||||
@ -65,13 +73,12 @@ class IncludeTest extends TestCase
|
||||
$codebase->addFilesToAnalyze([$file_path => $file_path]);
|
||||
}
|
||||
|
||||
$codebase->scanFiles();
|
||||
$config = $codebase->config;
|
||||
|
||||
$this->expectException('\Psalm\Exception\CodeException');
|
||||
$this->expectExceptionMessageRegexp('/\b' . preg_quote($error_message, '/') . '\b/');
|
||||
|
||||
$config = $codebase->config;
|
||||
$config->hoist_constants = $hoist_constants;
|
||||
$codebase->scanFiles();
|
||||
|
||||
foreach ($files_to_check as $file_path) {
|
||||
$file_checker = new FileChecker($this->project_checker, $file_path, $config->shortenFileName($file_path));
|
||||
@ -433,9 +440,30 @@ class IncludeTest extends TestCase
|
||||
],
|
||||
'files_to_check' => [
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file1.php',
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file2.php',
|
||||
],
|
||||
'hoist_constants' => true,
|
||||
],
|
||||
'duplicateClasses' => [
|
||||
'files' => [
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file1.php' => '<?php
|
||||
class A {
|
||||
public function aa() : void {}
|
||||
public function bb() : void { $this->aa(); }
|
||||
}',
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file2.php' => '<?php
|
||||
class A {
|
||||
public function dd() : void {}
|
||||
public function zz() : void { $this->dd(); }
|
||||
}',
|
||||
],
|
||||
'files_to_check' => [
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file1.php',
|
||||
getcwd() . DIRECTORY_SEPARATOR . 'file2.php',
|
||||
],
|
||||
'hoist_constants' => false,
|
||||
'error_levels' => ['DuplicateClass'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user