From 3b3afd53692e270f5c8b7c1b9178465b08268943 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Mon, 17 Oct 2022 13:10:12 +0200 Subject: [PATCH] Fixes --- psalm-baseline.xml | 20 +-- .../ExistingAtomicStaticCallAnalyzer.php | 15 +- .../Fetch/VariableFetchAnalyzer.php | 168 +++++++++--------- .../TypeVisitor/ContainsStaticVisitor.php | 30 ++++ 4 files changed, 123 insertions(+), 110 deletions(-) create mode 100644 src/Psalm/Internal/TypeVisitor/ContainsStaticVisitor.php diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 61a039758b6..a1dcc3a49a3 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + $comment_block->tags['variablesfrom'][0] @@ -68,7 +68,7 @@ - + $assertion->rule[0] $assertion->rule[0] $assertion->rule[0] @@ -90,12 +90,6 @@ $expr->getArgs()[0] $expr->getArgs()[0] $expr->getArgs()[0] - $expr->getArgs()[0] - $expr->getArgs()[0] - $expr->getArgs()[0] - $expr->getArgs()[0] - $expr->getArgs()[0] - $expr->getArgs()[0] $expr->getArgs()[1] $expr->getArgs()[1] $get_debug_type_expr->getArgs()[0] @@ -220,16 +214,9 @@ - - !$this->is_accepting_new_requests - $this->is_accepting_new_requests - $parts[1] - - TypeDoesNotContainType - @@ -306,11 +293,12 @@ - + get get get getClassTemplateTypes + has $candidate_param_type->from_template_default 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 a4d502bd61a..8cdfd6c7560 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php @@ -21,6 +21,7 @@ use Psalm\Internal\Type\TemplateInferredTypeReplacer; use Psalm\Internal\Type\TemplateResult; use Psalm\Internal\Type\TypeExpander; +use Psalm\Internal\TypeVisitor\ContainsStaticVisitor; use Psalm\Issue\AbstractMethodCall; use Psalm\Issue\ImpureMethodCall; use Psalm\IssueBuffer; @@ -630,16 +631,8 @@ private static function getMethodReturnType( */ private static function hasStaticInType(Type\TypeNode $type): bool { - if ($type instanceof TNamedObject && ($type->value === 'static' || $type->is_static)) { - return true; - } - - foreach ($type->getChildNodes() as $child_type) { - if (self::hasStaticInType($child_type)) { - return true; - } - } - - return false; + $visitor = new ContainsStaticVisitor; + $visitor->traverse($type); + return $visitor->matches(); } } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php index 740daa859d7..ee327d72eeb 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php @@ -668,89 +668,91 @@ public static function getGlobalType(string $var_id, int $codebase_analysis_php_ $bool_string_helper = new Union([new TBool(), new TString()]); $bool_string_helper->possibly_undefined = true; - $detailed_type = new TKeyedArray([ - // https://www.php.net/manual/en/reserved.variables.server.php - 'PHP_SELF' => $non_empty_string_helper, - 'argv' => $argv_helper, - 'argc' => $argc_helper, - 'GATEWAY_INTERFACE' => $non_empty_string_helper, - 'SERVER_ADDR' => $non_empty_string_helper, - 'SERVER_NAME' => $non_empty_string_helper, - 'SERVER_SOFTWARE' => $non_empty_string_helper, - 'SERVER_PROTOCOL' => $non_empty_string_helper, - 'REQUEST_METHOD' => $non_empty_string_helper, - 'REQUEST_TIME' => $request_time_helper, - 'REQUEST_TIME_FLOAT' => $request_time_float_helper, - 'QUERY_STRING' => $string_helper, - 'DOCUMENT_ROOT' => $non_empty_string_helper, - 'HTTP_ACCEPT' => $non_empty_string_helper, - 'HTTP_ACCEPT_CHARSET' => $non_empty_string_helper, - 'HTTP_ACCEPT_ENCODING' => $non_empty_string_helper, - 'HTTP_ACCEPT_LANGUAGE' => $non_empty_string_helper, - 'HTTP_CONNECTION' => $non_empty_string_helper, - 'HTTP_HOST' => $non_empty_string_helper, - 'HTTP_REFERER' => $non_empty_string_helper, - 'HTTP_USER_AGENT' => $non_empty_string_helper, - 'HTTPS' => $string_helper, - 'REMOTE_ADDR' => $non_empty_string_helper, - 'REMOTE_HOST' => $non_empty_string_helper, - 'REMOTE_PORT' => $string_helper, - 'REMOTE_USER' => $non_empty_string_helper, - 'REDIRECT_REMOTE_USER' => $non_empty_string_helper, - 'SCRIPT_FILENAME' => $non_empty_string_helper, - 'SERVER_ADMIN' => $non_empty_string_helper, - 'SERVER_PORT' => $non_empty_string_helper, - 'SERVER_SIGNATURE' => $non_empty_string_helper, - 'PATH_TRANSLATED' => $non_empty_string_helper, - 'SCRIPT_NAME' => $non_empty_string_helper, - 'REQUEST_URI' => $non_empty_string_helper, - 'PHP_AUTH_DIGEST' => $non_empty_string_helper, - 'PHP_AUTH_USER' => $non_empty_string_helper, - 'PHP_AUTH_PW' => $non_empty_string_helper, - 'AUTH_TYPE' => $non_empty_string_helper, - 'PATH_INFO' => $non_empty_string_helper, - 'ORIG_PATH_INFO' => $non_empty_string_helper, - // misc from RFC not included above already http://www.faqs.org/rfcs/rfc3875.html - 'CONTENT_LENGTH' => $string_helper, - 'CONTENT_TYPE' => $string_helper, - // common, misc stuff - 'FCGI_ROLE' => $non_empty_string_helper, - 'HOME' => $non_empty_string_helper, - 'HTTP_CACHE_CONTROL' => $non_empty_string_helper, - 'HTTP_COOKIE' => $non_empty_string_helper, - 'HTTP_PRIORITY' => $non_empty_string_helper, - 'PATH' => $non_empty_string_helper, - 'REDIRECT_STATUS' => $non_empty_string_helper, - 'REQUEST_SCHEME' => $non_empty_string_helper, - 'USER' => $non_empty_string_helper, - // common, misc headers - 'HTTP_UPGRADE_INSECURE_REQUESTS' => $non_empty_string_helper, - 'HTTP_X_FORWARDED_PROTO' => $non_empty_string_helper, - 'HTTP_CLIENT_IP' => $non_empty_string_helper, - 'HTTP_X_REAL_IP' => $non_empty_string_helper, - 'HTTP_X_FORWARDED_FOR' => $non_empty_string_helper, - 'HTTP_CF_CONNECTING_IP' => $non_empty_string_helper, - 'HTTP_CF_IPCOUNTRY' => $non_empty_string_helper, - 'HTTP_CF_VISITOR' => $non_empty_string_helper, - 'HTTP_CDN_LOOP' => $non_empty_string_helper, - // common, misc browser headers - 'HTTP_DNT' => $non_empty_string_helper, - 'HTTP_SEC_FETCH_DEST' => $non_empty_string_helper, - 'HTTP_SEC_FETCH_USER' => $non_empty_string_helper, - 'HTTP_SEC_FETCH_MODE' => $non_empty_string_helper, - 'HTTP_SEC_FETCH_SITE' => $non_empty_string_helper, - 'HTTP_SEC_CH_UA_PLATFORM' => $non_empty_string_helper, - 'HTTP_SEC_CH_UA_MOBILE' => $non_empty_string_helper, - 'HTTP_SEC_CH_UA' => $non_empty_string_helper, - // phpunit - 'APP_DEBUG' => $bool_string_helper, - 'APP_ENV' => $string_helper, - ]); - - // generic case for all other elements - $detailed_type->previous_key_type = Type::getNonEmptyString(); - $detailed_type->previous_value_type = Type::getString(); - + $detailed_type = new TKeyedArray( + [ + // https://www.php.net/manual/en/reserved.variables.server.php + 'PHP_SELF' => $non_empty_string_helper, + 'argv' => $argv_helper, + 'argc' => $argc_helper, + 'GATEWAY_INTERFACE' => $non_empty_string_helper, + 'SERVER_ADDR' => $non_empty_string_helper, + 'SERVER_NAME' => $non_empty_string_helper, + 'SERVER_SOFTWARE' => $non_empty_string_helper, + 'SERVER_PROTOCOL' => $non_empty_string_helper, + 'REQUEST_METHOD' => $non_empty_string_helper, + 'REQUEST_TIME' => $request_time_helper, + 'REQUEST_TIME_FLOAT' => $request_time_float_helper, + 'QUERY_STRING' => $string_helper, + 'DOCUMENT_ROOT' => $non_empty_string_helper, + 'HTTP_ACCEPT' => $non_empty_string_helper, + 'HTTP_ACCEPT_CHARSET' => $non_empty_string_helper, + 'HTTP_ACCEPT_ENCODING' => $non_empty_string_helper, + 'HTTP_ACCEPT_LANGUAGE' => $non_empty_string_helper, + 'HTTP_CONNECTION' => $non_empty_string_helper, + 'HTTP_HOST' => $non_empty_string_helper, + 'HTTP_REFERER' => $non_empty_string_helper, + 'HTTP_USER_AGENT' => $non_empty_string_helper, + 'HTTPS' => $string_helper, + 'REMOTE_ADDR' => $non_empty_string_helper, + 'REMOTE_HOST' => $non_empty_string_helper, + 'REMOTE_PORT' => $string_helper, + 'REMOTE_USER' => $non_empty_string_helper, + 'REDIRECT_REMOTE_USER' => $non_empty_string_helper, + 'SCRIPT_FILENAME' => $non_empty_string_helper, + 'SERVER_ADMIN' => $non_empty_string_helper, + 'SERVER_PORT' => $non_empty_string_helper, + 'SERVER_SIGNATURE' => $non_empty_string_helper, + 'PATH_TRANSLATED' => $non_empty_string_helper, + 'SCRIPT_NAME' => $non_empty_string_helper, + 'REQUEST_URI' => $non_empty_string_helper, + 'PHP_AUTH_DIGEST' => $non_empty_string_helper, + 'PHP_AUTH_USER' => $non_empty_string_helper, + 'PHP_AUTH_PW' => $non_empty_string_helper, + 'AUTH_TYPE' => $non_empty_string_helper, + 'PATH_INFO' => $non_empty_string_helper, + 'ORIG_PATH_INFO' => $non_empty_string_helper, + // misc from RFC not included above already http://www.faqs.org/rfcs/rfc3875.html + 'CONTENT_LENGTH' => $string_helper, + 'CONTENT_TYPE' => $string_helper, + // common, misc stuff + 'FCGI_ROLE' => $non_empty_string_helper, + 'HOME' => $non_empty_string_helper, + 'HTTP_CACHE_CONTROL' => $non_empty_string_helper, + 'HTTP_COOKIE' => $non_empty_string_helper, + 'HTTP_PRIORITY' => $non_empty_string_helper, + 'PATH' => $non_empty_string_helper, + 'REDIRECT_STATUS' => $non_empty_string_helper, + 'REQUEST_SCHEME' => $non_empty_string_helper, + 'USER' => $non_empty_string_helper, + // common, misc headers + 'HTTP_UPGRADE_INSECURE_REQUESTS' => $non_empty_string_helper, + 'HTTP_X_FORWARDED_PROTO' => $non_empty_string_helper, + 'HTTP_CLIENT_IP' => $non_empty_string_helper, + 'HTTP_X_REAL_IP' => $non_empty_string_helper, + 'HTTP_X_FORWARDED_FOR' => $non_empty_string_helper, + 'HTTP_CF_CONNECTING_IP' => $non_empty_string_helper, + 'HTTP_CF_IPCOUNTRY' => $non_empty_string_helper, + 'HTTP_CF_VISITOR' => $non_empty_string_helper, + 'HTTP_CDN_LOOP' => $non_empty_string_helper, + // common, misc browser headers + 'HTTP_DNT' => $non_empty_string_helper, + 'HTTP_SEC_FETCH_DEST' => $non_empty_string_helper, + 'HTTP_SEC_FETCH_USER' => $non_empty_string_helper, + 'HTTP_SEC_FETCH_MODE' => $non_empty_string_helper, + 'HTTP_SEC_FETCH_SITE' => $non_empty_string_helper, + 'HTTP_SEC_CH_UA_PLATFORM' => $non_empty_string_helper, + 'HTTP_SEC_CH_UA_MOBILE' => $non_empty_string_helper, + 'HTTP_SEC_CH_UA' => $non_empty_string_helper, + // phpunit + 'APP_DEBUG' => $bool_string_helper, + 'APP_ENV' => $string_helper, + ], + null, + false, + Type::getNonEmptyString(), + Type::getString() + ); + return new Union([$detailed_type]); } diff --git a/src/Psalm/Internal/TypeVisitor/ContainsStaticVisitor.php b/src/Psalm/Internal/TypeVisitor/ContainsStaticVisitor.php new file mode 100644 index 00000000000..da0a266b0e7 --- /dev/null +++ b/src/Psalm/Internal/TypeVisitor/ContainsStaticVisitor.php @@ -0,0 +1,30 @@ +value === 'static' || $type->is_static)) { + $this->contains_static = true; + return TypeVisitor::STOP_TRAVERSAL; + } + return null; + } + + public function matches(): bool + { + return $this->contains_static; + } +}