From 38089ebec39973107aecca9e3725dcdbe84c4c76 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Mon, 27 Jun 2022 11:38:06 +0200 Subject: [PATCH] Avoid re-parsing template types --- .../Reflector/FunctionLikeDocblockScanner.php | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockScanner.php b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockScanner.php index 90628a8922c..a2c62a76943 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockScanner.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockScanner.php @@ -451,39 +451,44 @@ private static function getConditionalSanitizedTypeTokens( ); $param_type_mapping = []; + $template_function_id = 'fn-' . strtolower($cased_function_id); // This checks for param references in the return type tokens // If found, the param is replaced with a generated template param foreach ($fixed_type_tokens as $i => $type_token) { $token_body = $type_token[0]; - $template_function_id = 'fn-' . strtolower($cased_function_id); if ($token_body[0] === '$') { foreach ($storage->params as $j => $param_storage) { if ('$' . $param_storage->name === $token_body) { if (!isset($param_type_mapping[$token_body])) { $template_name = 'TGeneratedFromParam' . $j; - - $template_as_type = $param_storage->type - ? clone $param_storage->type - : Type::getMixed(); - - $storage->template_types[$template_name] = [ - $template_function_id => $template_as_type, - ]; - - $function_template_types[$template_name] - = $storage->template_types[$template_name]; - - $param_type_mapping[$token_body] = $template_name; - - $param_storage->type = new Union([ - new TTemplateParam( - $template_name, - $template_as_type, - $template_function_id - ) - ]); + if (isset($storage->template_types[$template_name])) { + $function_template_types[$template_name] + = $storage->template_types[$template_name]; + $param_type_mapping[$token_body] = $template_name; + } else { + $template_as_type = $param_storage->type + ? clone $param_storage->type + : Type::getMixed(); + + $storage->template_types[$template_name] = [ + $template_function_id => $template_as_type, + ]; + + $function_template_types[$template_name] + = $storage->template_types[$template_name]; + + $param_type_mapping[$token_body] = $template_name; + + $param_storage->type = new Union([ + new TTemplateParam( + $template_name, + $template_as_type, + $template_function_id + ) + ]); + } } // spaces are allowed before $foo in get(string $foo) magic method