diff --git a/src/Psalm/Internal/Codebase/Analyzer.php b/src/Psalm/Internal/Codebase/Analyzer.php index d703b702d30..17bf7186bcd 100644 --- a/src/Psalm/Internal/Codebase/Analyzer.php +++ b/src/Psalm/Internal/Codebase/Analyzer.php @@ -257,6 +257,7 @@ function () { $file_reference_provider = $codebase->file_reference_provider; + $file_reference_provider->setFileReferencesToClasses([]); $file_reference_provider->setCallingMethodReferencesToClassMembers([]); $file_reference_provider->setFileReferencesToClassMembers([]); $file_reference_provider->setCallingMethodReferencesToMissingClassMembers([]); @@ -446,6 +447,8 @@ public function loadCachedResults(ProjectAnalyzer $project_analyzer) $all_referencing_methods = $method_references_to_class_members + $method_references_to_missing_class_members; + $file_references_to_classes = $file_reference_provider->getAllFileReferencesToClasses(); + $file_references_to_class_members = $file_reference_provider->getAllFileReferencesToClassMembers(); $file_references_to_missing_class_members @@ -511,6 +514,11 @@ public function loadCachedResults(ProjectAnalyzer $project_analyzer) $member_stub = preg_replace('/::.*$/', '::*', $member_id); + if (strpos($member_id, '::')) { + $fqcln = explode('::', $member_id)[0]; + unset($file_references_to_classes[$fqcln]); + } + if (isset($all_referencing_methods[$member_stub])) { $newly_invalidated_methods = array_merge( $all_referencing_methods[$member_stub], @@ -563,6 +571,10 @@ public function loadCachedResults(ProjectAnalyzer $project_analyzer) unset($referencing_file_paths[$file_path]); } + foreach ($file_references_to_classes as &$referencing_file_paths) { + unset($referencing_file_paths[$file_path]); + } + foreach ($references_to_mixed_member_names as &$references) { unset($references[$file_path]); } @@ -607,6 +619,13 @@ function (array $a) : bool { } ); + $file_references_to_classes = array_filter( + $file_references_to_classes, + function (array $a) : bool { + return !!$a; + } + ); + $file_reference_provider->setCallingMethodReferencesToClassMembers( $method_references_to_class_members ); @@ -626,6 +645,10 @@ function (array $a) : bool { $file_reference_provider->setReferencesToMixedMemberNames( $references_to_mixed_member_names ); + + $file_reference_provider->setFileReferencesToClasses( + $file_references_to_classes + ); } /** diff --git a/src/Psalm/Internal/Provider/FileReferenceProvider.php b/src/Psalm/Internal/Provider/FileReferenceProvider.php index cd64cd608c7..85ca4993afa 100644 --- a/src/Psalm/Internal/Provider/FileReferenceProvider.php +++ b/src/Psalm/Internal/Provider/FileReferenceProvider.php @@ -594,6 +594,17 @@ public function isClassReferenced(string $fq_class_name_lc) : bool return isset(self::$file_references_to_classes[$fq_class_name_lc]); } + /** + * @param array> $references + * @psalm-suppress MixedTypeCoercion + * + * @return void + */ + public function setFileReferencesToClasses(array $references) + { + self::$file_references_to_classes = $references; + } + /** * @return array> */ diff --git a/tests/FileUpdates/ErrorAfterUpdateTest.php b/tests/FileUpdates/ErrorAfterUpdateTest.php index cf57b7448ca..2a4de124448 100644 --- a/tests/FileUpdates/ErrorAfterUpdateTest.php +++ b/tests/FileUpdates/ErrorAfterUpdateTest.php @@ -646,6 +646,25 @@ public function foo() : void {} ], 'error_message' => 'DuplicateMethod', ], + 'unusedClassReferencedInFile' => [ + 'file_stages' => [ + [ + getcwd() . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'A.php' => ' ' 'UnusedClass', + ], 'unusedMethodReferencedInFile' => [ 'file_stages' => [ [ @@ -664,7 +683,9 @@ public function foo() : void {} class A { public function foo() : void {} - }', + } + + $a = new A();', ], ], 'error_message' => 'PossiblyUnusedMethod', @@ -697,6 +718,7 @@ public function foo() : void {} class B { public function bar() : void { + new A(); } } @@ -725,7 +747,9 @@ class A { class A { /** @var string */ public $foo = "hello"; - }', + } + + $a = new A();', ], ], 'error_message' => 'PossiblyUnusedProperty', @@ -760,6 +784,7 @@ class A { class B { public function bar() : void { + new A(); } } diff --git a/tests/Internal/Provider/FakeFileReferenceCacheProvider.php b/tests/Internal/Provider/FakeFileReferenceCacheProvider.php index f0b720b65bd..bb92fa59c70 100644 --- a/tests/Internal/Provider/FakeFileReferenceCacheProvider.php +++ b/tests/Internal/Provider/FakeFileReferenceCacheProvider.php @@ -10,6 +10,9 @@ class FakeFileReferenceCacheProvider extends \Psalm\Internal\Provider\FileRefere /** @var ?array */ private $cached_file_references; + /** @var ?array */ + private $cached_file_class_references; + /** @var ?array */ private $cached_method_member_references; @@ -50,6 +53,17 @@ public function getCachedFileReferences() return $this->cached_file_references; } + /** + * @return ?array + * + * @psalm-suppress MixedAssignment + * @psalm-suppress MixedTypeCoercion + */ + public function getCachedFileClassReferences() + { + return $this->cached_file_class_references; + } + /** * @return ?array * @@ -124,6 +138,14 @@ public function setCachedFileReferences(array $file_references) $this->cached_file_references = $file_references; } + /** + * @return void + */ + public function setCachedFileClassReferences(array $file_references) + { + $this->cached_file_class_references = $file_references; + } + /** * @return void */