From c0f319779078723a1145882a6f2e07069f8e8bdf Mon Sep 17 00:00:00 2001 From: Brown Date: Fri, 25 Jan 2019 10:10:22 -0500 Subject: [PATCH] Fix #1238 - only emit MissingTemplateParam on direct interface implementers --- src/Psalm/Internal/Analyzer/ClassAnalyzer.php | 45 ++++++++++++------- tests/TemplateTest.php | 21 +++++++++ 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php index c7b6a90ca..511a95de5 100644 --- a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php @@ -277,6 +277,35 @@ class ClassAnalyzer extends ClassLikeAnalyzer $fq_interface_name ); } + + try { + $interface_storage = $classlike_storage_provider->get($fq_interface_name); + } catch (\InvalidArgumentException $e) { + continue; + } + + if ($storage->template_type_extends_count !== null + && $interface_storage->template_types + && $storage->template_type_extends_count !== count($interface_storage->template_types) + ) { + $code_location = new CodeLocation( + $this, + $interface_name, + $class_context ? $class_context->include_location : null, + true + ); + + if (IssueBuffer::accepts( + new MissingTemplateParam( + $interface_name . ' has unextended template params, expecting ' + . count($interface_storage->template_types), + $code_location + ), + array_merge($storage->suppressed_issues, $this->getSuppressedIssues()) + )) { + // fall through + } + } } if ($storage->template_type_extends) { @@ -329,22 +358,6 @@ class ClassAnalyzer extends ClassLikeAnalyzer } } - if ($storage->template_type_extends_count !== null - && $interface_storage->template_types - && $storage->template_type_extends_count !== count($interface_storage->template_types) - ) { - if (IssueBuffer::accepts( - new MissingTemplateParam( - $interface_name . ' has unextended template params, expecting ' - . count($interface_storage->template_types), - $code_location - ), - array_merge($storage->suppressed_issues, $this->getSuppressedIssues()) - )) { - // fall through - } - } - foreach ($interface_storage->methods as $method_name => $interface_method_storage) { if ($interface_method_storage->visibility === self::VISIBILITY_PUBLIC) { $implementer_declaring_method_id = $codebase->methods->getDeclaringMethodId( diff --git a/tests/TemplateTest.php b/tests/TemplateTest.php index f8b9cc6c9..6e15cc5be 100644 --- a/tests/TemplateTest.php +++ b/tests/TemplateTest.php @@ -2012,6 +2012,27 @@ class TemplateTest extends TestCase '$i' => 'Traversable', ] ], + 'templateCountOnExtendedAndImplemented' => [ + ' + */ + class Repository implements Selectable {} + + interface SomeEntity {} + + /** + * @template-extends Repository + */ + class SomeRepository extends Repository {}' + ], ]; }