From 4a414916c1eb69aea0f6c62f03c00f1e5e39ff94 Mon Sep 17 00:00:00 2001 From: klimick Date: Sat, 4 May 2024 11:39:59 +0300 Subject: [PATCH] Use StatementsAnalyzer insteadof Codebase --- src/Psalm/ContextualTypeResolver.php | 11 ++-- .../CallLikeContextualTypeExtractor.php | 13 ++--- .../Expression/Call/FunctionCallAnalyzer.php | 2 +- .../ExistingAtomicMethodCallAnalyzer.php | 2 +- .../Call/Method/MissingMethodCallHandler.php | 4 +- .../Expression/Call/NewAnalyzer.php | 2 +- .../ExistingAtomicStaticCallAnalyzer.php | 2 +- .../Analyzer/Statements/ReturnAnalyzer.php | 2 +- .../TemplateContextualBoundsCollector.php | 51 +++++++++---------- 9 files changed, 43 insertions(+), 46 deletions(-) diff --git a/src/Psalm/ContextualTypeResolver.php b/src/Psalm/ContextualTypeResolver.php index 6a4549125c6..62323734569 100644 --- a/src/Psalm/ContextualTypeResolver.php +++ b/src/Psalm/ContextualTypeResolver.php @@ -4,6 +4,7 @@ namespace Psalm; +use Psalm\Internal\Analyzer\StatementsAnalyzer; use Psalm\Internal\Type\TemplateInferredTypeReplacer; use Psalm\Internal\Type\TemplateResult; use Psalm\Internal\Type\TemplateStandinTypeReplacer; @@ -14,13 +15,13 @@ final class ContextualTypeResolver public function __construct( private readonly Union $contextual_type, private readonly TemplateResult $template_result, - private readonly Codebase $codebase, + private readonly StatementsAnalyzer $statements_analyzer, ) { } public function withContextualType(Union $type): self { - return new self($type, $this->template_result, $this->codebase); + return new self($type, $this->template_result, $this->statements_analyzer); } public function resolve(): Union @@ -28,7 +29,7 @@ public function resolve(): Union return TemplateInferredTypeReplacer::replace( $this->contextual_type, $this->template_result, - $this->codebase, + $this->statements_analyzer->getCodebase(), ); } @@ -37,8 +38,8 @@ public function fillTemplateResult(Union $input_type): void TemplateStandinTypeReplacer::fillTemplateResult( $this->contextual_type, $this->template_result, - $this->codebase, - null, + $this->statements_analyzer->getCodebase(), + $this->statements_analyzer, $input_type, ); } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsTemplate/CallLikeContextualTypeExtractor.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsTemplate/CallLikeContextualTypeExtractor.php index ddc72d79452..7295284f93a 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsTemplate/CallLikeContextualTypeExtractor.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsTemplate/CallLikeContextualTypeExtractor.php @@ -7,6 +7,7 @@ use Psalm\Codebase; use Psalm\Context; use Psalm\ContextualTypeResolver; +use Psalm\Internal\Analyzer\StatementsAnalyzer; use Psalm\Internal\Type\TemplateContextualBoundsCollector; use Psalm\Internal\Type\TemplateResult; use Psalm\Storage\FunctionLikeStorage; @@ -23,7 +24,7 @@ final class CallLikeContextualTypeExtractor { public static function extract( Context $context, - Codebase $codebase, + StatementsAnalyzer $statements_analyzer, ?FunctionLikeStorage $function_storage, CollectedArgumentTemplates $collected_templates, ): ContextualTypeResolver { @@ -38,12 +39,12 @@ public static function extract( return new ContextualTypeResolver( $empty_contextual_type, $template_result_without_contextual_bounds, - $codebase, + $statements_analyzer, ); } $return_type = $function_storage->return_type - ?? self::getReturnTypeFromDeclaringConstructor($codebase, $function_storage); + ?? self::getReturnTypeFromDeclaringConstructor($statements_analyzer->getCodebase(), $function_storage); if ($return_type === null) { $template_result_without_contextual_bounds = new TemplateResult( @@ -54,14 +55,14 @@ public static function extract( return new ContextualTypeResolver( $empty_contextual_type, $template_result_without_contextual_bounds, - $codebase, + $statements_analyzer, ); } $template_result_with_contextual_bounds = new TemplateResult( $collected_templates->template_types, array_merge($collected_templates->lower_bounds, TemplateContextualBoundsCollector::collect( - $codebase, + $statements_analyzer, $context->contextual_type_resolver->resolve(), $return_type, $collected_templates->template_types, @@ -71,7 +72,7 @@ public static function extract( return new ContextualTypeResolver( $return_type, $template_result_with_contextual_bounds, - $codebase, + $statements_analyzer, ); } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php index 60e04466e77..b1f13e7a950 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php @@ -178,7 +178,7 @@ public static function analyze( $context->contextual_type_resolver = CallLikeContextualTypeExtractor::extract( $context, - $codebase, + $statements_analyzer, $function_call_info->function_storage, $collected_argument_templates, ); diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php index 6b8c427628c..83167976b69 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php @@ -206,7 +206,7 @@ public static function analyze( $was_contextual_type_resolver = $context->contextual_type_resolver; $context->contextual_type_resolver = CallLikeContextualTypeExtractor::extract( $context, - $codebase, + $statements_analyzer, $method_storage, $collected_argument_templates, ); diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MissingMethodCallHandler.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MissingMethodCallHandler.php index ef33ef13ce4..fb14fc44d8e 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MissingMethodCallHandler.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MissingMethodCallHandler.php @@ -133,7 +133,7 @@ public static function handleMagicMethod( $was_contextual_type_resolver = $context->contextual_type_resolver; $context->contextual_type_resolver = CallLikeContextualTypeExtractor::extract( $context, - $codebase, + $statements_analyzer, $pseudo_method_storage, $collected_argument_templates, ); @@ -310,7 +310,7 @@ public static function handleMissingOrMagicMethod( $was_contextual_type_resolver = $context->contextual_type_resolver; $context->contextual_type_resolver = CallLikeContextualTypeExtractor::extract( $context, - $codebase, + $statements_analyzer, $pseudo_method_storage, $collected_argument_templates, ); diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php index 710fabb87fd..619f43b648d 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php @@ -426,7 +426,7 @@ private static function analyzeNamedConstructor( $was_contextual_type_resolver = $context->contextual_type_resolver; $context->contextual_type_resolver = CallLikeContextualTypeExtractor::extract( $context, - $codebase, + $statements_analyzer, $method_storage, $collected_argument_templates, ); diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php index 0782318cc4f..448d9354c62 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php @@ -159,7 +159,7 @@ public static function analyze( $was_contextual_type_resolver = $context->contextual_type_resolver; $context->contextual_type_resolver = CallLikeContextualTypeExtractor::extract( $context, - $codebase, + $statements_analyzer, $method_storage, $collected_argument_templates, ); diff --git a/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php index bd52a6dd65a..a05aacd3231 100644 --- a/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php @@ -156,7 +156,7 @@ public static function analyze( ? new ContextualTypeResolver( $next_contextual_type, new TemplateResult([], []), - $codebase, + $statements_analyzer, ) : null; diff --git a/src/Psalm/Internal/Type/TemplateContextualBoundsCollector.php b/src/Psalm/Internal/Type/TemplateContextualBoundsCollector.php index 349494cf52e..5c3455e607c 100644 --- a/src/Psalm/Internal/Type/TemplateContextualBoundsCollector.php +++ b/src/Psalm/Internal/Type/TemplateContextualBoundsCollector.php @@ -4,7 +4,7 @@ namespace Psalm\Internal\Type; -use Psalm\Codebase; +use Psalm\Internal\Analyzer\StatementsAnalyzer; use Psalm\Internal\Type\Comparator\CallableTypeComparator; use Psalm\Type; use Psalm\Type\Atomic; @@ -25,21 +25,16 @@ */ final class TemplateContextualBoundsCollector { - private Codebase $codebase; - /** @var array>> */ private array $collected_atomics = []; - /** @var array> */ - private array $template_types; - /** * @param array> $template_types */ - private function __construct(Codebase $codebase, array $template_types) - { - $this->codebase = $codebase; - $this->template_types = $template_types; + private function __construct( + private readonly StatementsAnalyzer $statements_analyzer, + private readonly array $template_types, + ) { } /** @@ -47,14 +42,16 @@ private function __construct(Codebase $codebase, array $template_types) * @return array> */ public static function collect( - Codebase $codebase, + StatementsAnalyzer $statements_analyzer, Union $contextual_type, Union $return_type, array $template_types, ): array { - $collector = new self($codebase, $template_types); + $collector = new self($statements_analyzer, $template_types); $collector->collectUnion($contextual_type, $return_type); + $codebase = $statements_analyzer->getCodebase(); + return array_map( static fn(array $template_map): array => array_map( static fn(array $collected_atomics): Union => TypeCombiner::combine($collected_atomics, $codebase), @@ -107,15 +104,14 @@ private function collectTemplateType(Atomic $contextual_atomic, TTemplateParam $ */ private function collectCallable(Atomic $contextual_atomic, Atomic $return_atomic): void { + $codebase = $this->statements_analyzer->getCodebase(); + if ($return_atomic instanceof TNamedObject && $return_atomic->value !== 'Closure' - && $this->codebase->classOrInterfaceExists($return_atomic->value) - && $this->codebase->methodExists($return_atomic->value . '::__invoke') + && $codebase->classOrInterfaceExists($return_atomic->value) + && $codebase->methodExists($return_atomic->value . '::__invoke') ) { - $return_atomic = CallableTypeComparator::getCallableFromAtomic( - $this->codebase, - $return_atomic, - ); + $return_atomic = CallableTypeComparator::getCallableFromAtomic($codebase, $return_atomic); } if ($return_atomic instanceof TCallable || $return_atomic instanceof TClosure) { @@ -171,12 +167,14 @@ private function collectKeyedArray(TKeyedArray $contextual_atomic, Atomic $retur private function collectGenericObject(TGenericObject $contextual_atomic, Atomic $return_atomic): void { + $codebase = $this->statements_analyzer->getCodebase(); + if ($return_atomic instanceof TGenericObject - && $this->codebase->classExists($return_atomic->value) - && $this->codebase->classExtends($return_atomic->value, $contextual_atomic->value) + && $codebase->classExists($return_atomic->value) + && $codebase->classExtends($return_atomic->value, $contextual_atomic->value) ) { - $contextual_storage = $this->codebase->classlike_storage_provider->get($contextual_atomic->value); - $return_storage = $this->codebase->classlike_storage_provider->get($return_atomic->value); + $contextual_storage = $codebase->classlike_storage_provider->get($contextual_atomic->value); + $return_storage = $codebase->classlike_storage_provider->get($return_atomic->value); $contextual_raw_atomic = $contextual_storage->getNamedObjectAtomic(); $return_raw_atomic = $return_storage->getNamedObjectAtomic(); @@ -190,15 +188,12 @@ private function collectGenericObject(TGenericObject $contextual_atomic, Atomic TemplateStandinTypeReplacer::fillTemplateResult( new Union([$contextual_raw_atomic]), $template_result, - $this->codebase, - null, + $codebase, + $this->statements_analyzer, new Union([$return_raw_atomic]), ); - $return_atomic = $contextual_raw_atomic->replaceTemplateTypesWithArgTypes( - $template_result, - $this->codebase, - ); + $return_atomic = $contextual_raw_atomic->replaceTemplateTypesWithArgTypes($template_result, $codebase); } if ($return_atomic instanceof TIterable