diff --git a/src/Psalm/Checker/ClassLikeChecker.php b/src/Psalm/Checker/ClassLikeChecker.php index 4515d1f3d..d21993639 100644 --- a/src/Psalm/Checker/ClassLikeChecker.php +++ b/src/Psalm/Checker/ClassLikeChecker.php @@ -332,7 +332,43 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc $implemented_method_id = $this->fq_class_name . '::' . $method_name; MethodChecker::setOverriddenMethodId($implemented_method_id, $mentioned_method_id); + } + } + } + } + return null; + } + + /** + * @param Context|null $class_context + * @param Context|null $global_context + * @param bool $update_docblocks + * @return null|false + */ + public function analyze( + Context $class_context = null, + Context $global_context = null, + $update_docblocks = false + ) { + $config = Config::getInstance(); + + $fq_class_name = $class_context && $class_context->self ? $class_context->self : $this->fq_class_name; + + $storage = self::$storage[$fq_class_name]; + + if ($this instanceof ClassChecker && $this->class instanceof PhpParser\Node\Stmt\Class_) { + foreach (ClassChecker::getInterfacesForClass( + $this->fq_class_name + ) as $interface_id => $interface_name) { + $interface_storage = self::$storage[$interface_name]; + + $storage->public_class_constants += $interface_storage->public_class_constants; + + foreach ($interface_storage->methods as $method_name => $method) { + if ($method->visibility === self::VISIBILITY_PUBLIC) { + $implemented_method_id = $this->fq_class_name . '::' . $method_name; + $mentioned_method_id = $interface_name . '::' . $method_name; $declaring_method_id = MethodChecker::getDeclaringMethodId($implemented_method_id); $method_storage = $declaring_method_id @@ -374,26 +410,6 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc } } - return null; - } - - /** - * @param Context|null $class_context - * @param Context|null $global_context - * @param bool $update_docblocks - * @return void - */ - public function analyzeMethods( - Context $class_context = null, - Context $global_context = null, - $update_docblocks = false - ) { - $config = Config::getInstance(); - - $fq_class_name = $class_context && $class_context->self ? $class_context->self : $this->fq_class_name; - - $storage = self::$storage[$fq_class_name]; - if (!$class_context) { $class_context = new Context($this->source->getFileName(), $this->fq_class_name); $class_context->parent = $this->parent_fq_class_name; @@ -444,7 +460,7 @@ abstract class ClassLikeChecker extends SourceChecker implements StatementsSourc $trait_checker = self::$trait_checkers[$trait_name]; - $trait_checker->analyzeMethods($class_context, $global_context, $update_docblocks); + $trait_checker->analyze($class_context, $global_context, $update_docblocks); } } } diff --git a/src/Psalm/Checker/FileChecker.php b/src/Psalm/Checker/FileChecker.php index f18e81924..583b7d74a 100644 --- a/src/Psalm/Checker/FileChecker.php +++ b/src/Psalm/Checker/FileChecker.php @@ -289,7 +289,7 @@ class FileChecker extends SourceChecker implements StatementsSource * @param boolean $update_docblocks * @return void */ - public function analyzeMethods($update_docblocks = false) + public function analyze($update_docblocks = false) { $config = Config::getInstance(); @@ -298,11 +298,11 @@ class FileChecker extends SourceChecker implements StatementsSource } foreach ($this->namespace_checkers as $namespace_checker) { - $namespace_checker->analyzeMethods(clone $this->context); + $namespace_checker->analyze(clone $this->context); } foreach ($this->class_checkers as $class_checker) { - $class_checker->analyzeMethods(null, $this->context, $update_docblocks); + $class_checker->analyze(null, $this->context, $update_docblocks); } foreach ($this->function_checkers as $function_checker) { @@ -332,6 +332,8 @@ class FileChecker extends SourceChecker implements StatementsSource } } + $this->namespace_checkers = []; + $this->class_checkers = []; $this->function_checkers = []; @@ -361,7 +363,7 @@ class FileChecker extends SourceChecker implements StatementsSource public function visitAndAnalyzeMethods(Context $file_context = null, $update_docblocks = false) { $this->visit($file_context); - $this->analyzeMethods($update_docblocks); + $this->analyze($update_docblocks); } /** diff --git a/src/Psalm/Checker/MethodChecker.php b/src/Psalm/Checker/MethodChecker.php index 97406c69f..6719e4ab7 100644 --- a/src/Psalm/Checker/MethodChecker.php +++ b/src/Psalm/Checker/MethodChecker.php @@ -202,7 +202,7 @@ class MethodChecker extends FunctionLikeChecker * @param array $suppressed_issues * @return bool */ - public static function analyzeMethodstatic( + public static function analyzetatic( $method_id, $self_call, CodeLocation $code_location, diff --git a/src/Psalm/Checker/NamespaceChecker.php b/src/Psalm/Checker/NamespaceChecker.php index f83d107a8..7c9ec777e 100644 --- a/src/Psalm/Checker/NamespaceChecker.php +++ b/src/Psalm/Checker/NamespaceChecker.php @@ -102,10 +102,10 @@ class NamespaceChecker extends SourceChecker implements StatementsSource * @param Context $context * @return void */ - public function analyzeMethods(Context $context) + public function analyze(Context $context) { foreach ($this->class_checkers as $class_checker) { - $class_checker->analyzeMethods(null, $context); + $class_checker->analyze(null, $context); } $this->class_checkers = []; diff --git a/src/Psalm/Checker/ProjectChecker.php b/src/Psalm/Checker/ProjectChecker.php index c63384d83..c02b1cfd8 100644 --- a/src/Psalm/Checker/ProjectChecker.php +++ b/src/Psalm/Checker/ProjectChecker.php @@ -204,7 +204,7 @@ class ProjectChecker echo 'Analyzing ' . $file_checker->getFilePath() . PHP_EOL; } - $file_checker->analyzeMethods(); + $file_checker->analyze(); } } @@ -368,7 +368,7 @@ class ProjectChecker } $file_checker->visit(); - $file_checker->analyzeMethods(); + $file_checker->analyze(); } } @@ -414,7 +414,7 @@ class ProjectChecker echo 'Analyzing ' . $file_checker->getFilePath() . PHP_EOL; } - $file_checker->analyzeMethods(); + $file_checker->analyze(); IssueBuffer::finish(false, $start_checks, $this->debug_output); } @@ -451,7 +451,7 @@ class ProjectChecker echo 'Analyzing ' . $file_checker->getFilePath() . PHP_EOL; } - $file_checker->analyzeMethods(); + $file_checker->analyze(); } /** diff --git a/src/Psalm/Checker/Statements/Expression/CallChecker.php b/src/Psalm/Checker/Statements/Expression/CallChecker.php index 48f5d77df..b924181cd 100644 --- a/src/Psalm/Checker/Statements/Expression/CallChecker.php +++ b/src/Psalm/Checker/Statements/Expression/CallChecker.php @@ -796,7 +796,7 @@ class CallChecker || !ClassChecker::classExtends($context->self, $fq_class_name) ) ) { - if (MethodChecker::analyzeMethodstatic( + if (MethodChecker::analyzetatic( $method_id, $stmt->class instanceof PhpParser\Node\Name && $stmt->class->parts[0] === 'self', new CodeLocation($statements_checker->getSource(), $stmt),