Skip to content

Commit

Permalink
Check for indirect circular dependencies with stubbed parents.
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrolGenhald committed Jan 22, 2022
1 parent 9a064c0 commit 3510f55
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 14 deletions.
32 changes: 21 additions & 11 deletions src/Psalm/Internal/Codebase/Populator.php
Expand Up @@ -20,8 +20,10 @@
use function array_intersect_key;
use function array_keys;
use function array_merge;
use function array_splice;
use function count;
use function in_array;
use function key;
use function reset;
use function strlen;
use function strpos;
Expand Down Expand Up @@ -251,18 +253,26 @@ private function populateClassLikeStorage(ClassLikeStorage $storage, array $depe

if (isset($this->invalid_class_storages[$fq_classlike_name_lc])) {
foreach ($this->invalid_class_storages[$fq_classlike_name_lc] as $dependency) {
if (isset($dependency->dependent_classlikes[$fq_classlike_name_lc])) {
if ($dependency->location) {
IssueBuffer::maybeAdd(
new CircularReference(
'Circular reference discovered when loading ' . $dependency->name,
$dependency->location
)
);
}
// Dependencies may not be fully set yet, so we have to loop through dependencies of dependencies
$dependencies = [strtolower($dependency->name) => true];
do {
$current_dependency_name = key(array_splice($dependencies, 0, 1)); // Key shift
$current_dependency = $storage_provider->get($current_dependency_name);
$dependencies += $current_dependency->dependent_classlikes;

if (isset($current_dependency->dependent_classlikes[$fq_classlike_name_lc])) {
if ($dependency->location) {
IssueBuffer::maybeAdd(
new CircularReference(
'Circular reference discovered when loading ' . $dependency->name,
$dependency->location
)
);
}

continue;
}
continue 2;
}
} while (!empty($dependencies));

$dependency->populated = false;
unset($dependency->invalid_dependencies[$fq_classlike_name_lc]);
Expand Down
4 changes: 1 addition & 3 deletions tests/StubTest.php
Expand Up @@ -281,9 +281,7 @@ public function testStubFileCircularReference(): void
$this->addFile(
$file_path,
'<?php
class Foo extends Bar
{
}
class Foo extends Baz {}
'
);

Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures/stubs/CircularReference.phpstub
@@ -1,3 +1,5 @@
<?php

class Bar extends Foo {}

class Baz extends Bar {}

0 comments on commit 3510f55

Please sign in to comment.