From effc0ad5dababb05bbd5a75efb5d6885dbe6ddcc Mon Sep 17 00:00:00 2001 From: orklah Date: Fri, 12 Nov 2021 02:29:17 +0100 Subject: [PATCH] use consistent way to compare php version --- examples/TemplateScanner.php | 2 +- src/Psalm/Codebase.php | 32 +++++++----- src/Psalm/Config.php | 8 +-- src/Psalm/Internal/Analyzer/ClassAnalyzer.php | 8 ++- .../FunctionLike/ReturnTypeAnalyzer.php | 7 ++- .../Analyzer/FunctionLikeAnalyzer.php | 5 +- .../Internal/Analyzer/MethodComparator.php | 14 ++---- .../Internal/Analyzer/ProjectAnalyzer.php | 11 ++--- .../Statements/Expression/ArrayAnalyzer.php | 8 +-- .../Expression/Call/ArgumentAnalyzer.php | 8 +-- .../Call/FunctionCallReturnTypeFetcher.php | 5 +- .../Method/MethodCallReturnTypeFetcher.php | 5 +- .../ExistingAtomicStaticCallAnalyzer.php | 5 +- .../Statements/Expression/CastAnalyzer.php | 2 +- .../Statements/ExpressionAnalyzer.php | 12 ++--- src/Psalm/Internal/Codebase/ClassLikes.php | 5 +- .../Codebase/InternalCallMapHandler.php | 4 +- .../Reflector/ClassLikeDocblockParser.php | 2 +- .../Reflector/ClassLikeNodeScanner.php | 3 +- .../Reflector/ExpressionResolver.php | 2 +- .../Reflector/FunctionLikeNodeScanner.php | 25 +++++----- .../PhpVisitor/Reflector/TypeHintResolver.php | 8 ++- .../Internal/PhpVisitor/ReflectorVisitor.php | 2 +- .../Internal/Provider/StatementsProvider.php | 26 ++++++---- src/Psalm/Internal/Scanner/FileScanner.php | 2 +- .../Stubs/Generator/StubsGenerator.php | 2 +- .../Type/Comparator/AtomicTypeComparator.php | 2 +- src/Psalm/Internal/Type/TypeParser.php | 23 +++++---- src/Psalm/Internal/Type/TypeTokenizer.php | 11 ++--- src/Psalm/Type.php | 4 +- src/Psalm/Type/Atomic.php | 49 +++++++------------ src/Psalm/Type/Atomic/CallableTrait.php | 3 +- src/Psalm/Type/Atomic/Scalar.php | 2 +- .../Type/Atomic/TAnonymousClassInstance.php | 7 +-- src/Psalm/Type/Atomic/TArray.php | 5 +- src/Psalm/Type/Atomic/TArrayKey.php | 5 +- src/Psalm/Type/Atomic/TAssertionFalsy.php | 5 +- src/Psalm/Type/Atomic/TBool.php | 5 +- src/Psalm/Type/Atomic/TCallable.php | 5 +- src/Psalm/Type/Atomic/TCallableObject.php | 9 ++-- src/Psalm/Type/Atomic/TCallableString.php | 2 +- src/Psalm/Type/Atomic/TClassConstant.php | 5 +- src/Psalm/Type/Atomic/TClassString.php | 5 +- src/Psalm/Type/Atomic/TClassStringMap.php | 5 +- src/Psalm/Type/Atomic/TClosedResource.php | 5 +- src/Psalm/Type/Atomic/TClosure.php | 2 +- src/Psalm/Type/Atomic/TConditional.php | 5 +- src/Psalm/Type/Atomic/TDependentGetClass.php | 2 +- .../Type/Atomic/TDependentGetDebugType.php | 2 +- src/Psalm/Type/Atomic/TDependentGetType.php | 2 +- src/Psalm/Type/Atomic/TDependentListKey.php | 2 +- src/Psalm/Type/Atomic/TEmpty.php | 3 +- src/Psalm/Type/Atomic/TEnumCase.php | 5 +- src/Psalm/Type/Atomic/TFalse.php | 2 +- src/Psalm/Type/Atomic/TFloat.php | 5 +- src/Psalm/Type/Atomic/TGenericObject.php | 11 ++--- src/Psalm/Type/Atomic/THtmlEscapedString.php | 2 +- src/Psalm/Type/Atomic/TInt.php | 5 +- src/Psalm/Type/Atomic/TIntMask.php | 2 +- src/Psalm/Type/Atomic/TIntMaskOf.php | 2 +- src/Psalm/Type/Atomic/TIntRange.php | 2 +- src/Psalm/Type/Atomic/TIterable.php | 10 ++-- src/Psalm/Type/Atomic/TKeyOfClassConstant.php | 5 +- src/Psalm/Type/Atomic/TKeyedArray.php | 5 +- src/Psalm/Type/Atomic/TList.php | 5 +- src/Psalm/Type/Atomic/TLiteralClassString.php | 5 +- src/Psalm/Type/Atomic/TLowercaseString.php | 2 +- src/Psalm/Type/Atomic/TMixed.php | 9 ++-- src/Psalm/Type/Atomic/TNamedObject.php | 17 +++---- src/Psalm/Type/Atomic/TNever.php | 5 +- .../Type/Atomic/TNonEmptyLowercaseString.php | 2 +- .../Type/Atomic/TNonspecificLiteralInt.php | 2 +- .../Type/Atomic/TNonspecificLiteralString.php | 2 +- src/Psalm/Type/Atomic/TNull.php | 5 +- src/Psalm/Type/Atomic/TNumeric.php | 5 +- src/Psalm/Type/Atomic/TNumericString.php | 2 +- src/Psalm/Type/Atomic/TObject.php | 10 ++-- .../Type/Atomic/TObjectWithProperties.php | 5 +- src/Psalm/Type/Atomic/TPositiveInt.php | 2 +- src/Psalm/Type/Atomic/TResource.php | 5 +- src/Psalm/Type/Atomic/TScalar.php | 5 +- src/Psalm/Type/Atomic/TString.php | 5 +- .../Type/Atomic/TTemplateIndexedAccess.php | 5 +- src/Psalm/Type/Atomic/TTemplateParam.php | 5 +- src/Psalm/Type/Atomic/TTraitString.php | 5 +- src/Psalm/Type/Atomic/TTrue.php | 2 +- src/Psalm/Type/Atomic/TTypeAlias.php | 5 +- .../Type/Atomic/TValueOfClassConstant.php | 5 +- src/Psalm/Type/Atomic/TVoid.php | 9 ++-- src/Psalm/Type/Union.php | 24 +++++---- tests/AlgebraTest.php | 2 +- .../Hook/StringProvider/TSqlSelectString.php | 2 +- tests/FileDiffTest.php | 10 ++-- 93 files changed, 268 insertions(+), 343 deletions(-) diff --git a/examples/TemplateScanner.php b/examples/TemplateScanner.php index f713dfcc8ac..4775758e325 100644 --- a/examples/TemplateScanner.php +++ b/examples/TemplateScanner.php @@ -25,7 +25,7 @@ public function scan( ): void { $stmts = $codebase->statements_provider->getStatementsForFile( $file_storage->file_path, - '7.4', + 70400, $progress ); diff --git a/src/Psalm/Codebase.php b/src/Psalm/Codebase.php index 67b8f38d063..06a522a34e8 100644 --- a/src/Psalm/Codebase.php +++ b/src/Psalm/Codebase.php @@ -77,6 +77,7 @@ use function explode; use function implode; use function in_array; +use function intdiv; use function is_numeric; use function is_string; use function krsort; @@ -90,8 +91,7 @@ use function substr; use function substr_count; -use const PHP_MAJOR_VERSION; -use const PHP_MINOR_VERSION; +use const PHP_VERSION_ID; class Codebase { @@ -304,18 +304,13 @@ class Codebase */ public $allow_backwards_incompatible_changes = true; - /** - * @var int - */ - public $php_major_version = PHP_MAJOR_VERSION; + /** @var 'cli'|'config'|'composer'|'tests'|'runtime' */ + public $php_version_source = 'runtime'; /** * @var int */ - public $php_minor_version = PHP_MINOR_VERSION; - - /** @var 'cli'|'config'|'composer'|'tests'|'runtime' */ - public $php_version_source = 'runtime'; + public $analysis_php_version_id = PHP_VERSION_ID; /** * @var bool @@ -528,7 +523,7 @@ public function getStatementsForFile(string $file_path): array { return $this->statements_provider->getStatementsForFile( $file_path, - $this->php_major_version . '.' . $this->php_minor_version, + $this->analysis_php_version_id, $this->progress ); } @@ -2004,4 +1999,19 @@ public function addTaintSink( $this->taint_flow_graph->addSink($sink); } + + public function getMinorAnalysisPhpVersion(): int + { + return self::transformPhpVersionId($this->analysis_php_version_id % 10000, 100); + } + + public function getMajorAnalysisPhpVersion(): int + { + return self::transformPhpVersionId($this->analysis_php_version_id, 10000); + } + + public static function transformPhpVersionId(int $php_version_id, int $div): int + { + return intdiv($php_version_id, $div); + } } diff --git a/src/Psalm/Config.php b/src/Psalm/Config.php index 9584302113e..0f725769ad0 100644 --- a/src/Psalm/Config.php +++ b/src/Psalm/Config.php @@ -1871,7 +1871,7 @@ public function visitPreloadedStubFiles(Codebase $codebase, ?Progress $progress $core_generic_files = []; - if (PHP_VERSION_ID < 80000 && $codebase->php_major_version >= 8) { + if (PHP_VERSION_ID < 80000 && $codebase->analysis_php_version_id >= 80000) { $stringable_path = dirname(__DIR__, 2) . '/stubs/Php80.phpstub'; if (!file_exists($stringable_path)) { @@ -1881,7 +1881,7 @@ public function visitPreloadedStubFiles(Codebase $codebase, ?Progress $progress $core_generic_files[] = $stringable_path; } - if (PHP_VERSION_ID < 80100 && $codebase->php_major_version >= 8 && $codebase->php_minor_version >= 1) { + if (PHP_VERSION_ID < 80100 && $codebase->analysis_php_version_id >= 80100) { $stringable_path = dirname(__DIR__, 2) . '/stubs/Php81.phpstub'; if (!file_exists($stringable_path)) { @@ -1932,12 +1932,12 @@ public function visitStubFiles(Codebase $codebase, ?Progress $progress = null): $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'SPL.phpstub', ]; - if (PHP_VERSION_ID >= 80000 && $codebase->php_major_version >= 8) { + if (PHP_VERSION_ID >= 80000 && $codebase->analysis_php_version_id >= 80000) { $stringable_path = $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'Php80.phpstub'; $this->internal_stubs[] = $stringable_path; } - if (PHP_VERSION_ID >= 80100 && $codebase->php_major_version >= 8 && $codebase->php_minor_version >= 1) { + if (PHP_VERSION_ID >= 80100 && $codebase->analysis_php_version_id >= 80100) { $stringable_path = $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'Php81.phpstub'; $this->internal_stubs[] = $stringable_path; } diff --git a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php index 2e21a870e59..b4800c82f69 100644 --- a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php @@ -1608,8 +1608,7 @@ private static function addOrUpdatePropertyType( $codebase = $project_analyzer->getCodebase(); $allow_native_type = !$docblock_only - && $codebase->php_major_version >= 7 - && ($codebase->php_major_version > 7 || $codebase->php_minor_version >= 4) + && $codebase->analysis_php_version_id >= 70400 && $codebase->allow_backwards_incompatible_changes; $manipulator->setType( @@ -1618,8 +1617,7 @@ private static function addOrUpdatePropertyType( $source->getNamespace(), $source->getAliasedClassesFlipped(), $source->getFQCLN(), - $codebase->php_major_version, - $codebase->php_minor_version + $codebase->analysis_php_version_id ) : null, $inferred_type->toNamespacedString( $source->getNamespace(), @@ -1633,7 +1631,7 @@ private static function addOrUpdatePropertyType( $source->getFQCLN(), true ), - $inferred_type->canBeFullyExpressedInPhp($codebase->php_major_version, $codebase->php_minor_version) + $inferred_type->canBeFullyExpressedInPhp($codebase->analysis_php_version_id) ); } diff --git a/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php b/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php index 2566009bcba..e8722b1bfdc 100644 --- a/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php @@ -942,7 +942,7 @@ private static function addOrUpdateReturnType( } $allow_native_type = !$docblock_only - && $codebase->php_major_version >= 7 + && $codebase->analysis_php_version_id >= 70000 && ( $codebase->allow_backwards_incompatible_changes || $is_final @@ -955,8 +955,7 @@ private static function addOrUpdateReturnType( $source->getNamespace(), $source->getAliasedClassesFlipped(), $source->getFQCLN(), - $codebase->php_major_version, - $codebase->php_minor_version + $codebase->analysis_php_version_id ) : null, $inferred_return_type->toNamespacedString( $source->getNamespace(), @@ -970,7 +969,7 @@ private static function addOrUpdateReturnType( $source->getFQCLN(), true ), - $inferred_return_type->canBeFullyExpressedInPhp($codebase->php_major_version, $codebase->php_minor_version), + $inferred_return_type->canBeFullyExpressedInPhp($codebase->analysis_php_version_id), $function_like_storage->return_type_description ?? null ); } diff --git a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php index 99a11cbb337..11beca2d23d 100644 --- a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php @@ -1443,7 +1443,7 @@ public function addOrUpdateParamType( } $allow_native_type = !$docblock_only - && $codebase->php_major_version >= 7 + && $codebase->analysis_php_version_id >= 70000 && ( $codebase->allow_backwards_incompatible_changes || $is_final @@ -1457,8 +1457,7 @@ public function addOrUpdateParamType( $this->source->getNamespace(), $this->source->getAliasedClassesFlipped(), $this->source->getFQCLN(), - $project_analyzer->getCodebase()->php_major_version, - $project_analyzer->getCodebase()->php_minor_version + $project_analyzer->getCodebase()->analysis_php_version_id ) : null, $inferred_return_type->toNamespacedString( $this->source->getNamespace(), diff --git a/src/Psalm/Internal/Analyzer/MethodComparator.php b/src/Psalm/Internal/Analyzer/MethodComparator.php index 16ff2d9d98b..1f26cbd43b8 100644 --- a/src/Psalm/Internal/Analyzer/MethodComparator.php +++ b/src/Psalm/Internal/Analyzer/MethodComparator.php @@ -92,7 +92,7 @@ public static function compare( $cased_implementer_method_id, $prevent_method_signature_mismatch, $prevent_abstract_override, - $codebase->php_major_version >= 8, + $codebase->analysis_php_version_id >= 80000, $code_location, $suppressed_issues ); @@ -559,9 +559,7 @@ private static function compareMethodSignatureParams( $implementer_classlike_storage->parent_class ); - $is_contained_by = (($codebase->php_major_version === 7 - && $codebase->php_minor_version === 4) - || $codebase->php_major_version >= 8) + $is_contained_by = $codebase->analysis_php_version_id >= 70400 && $guide_param_signature_type ? UnionTypeComparator::isContainedBy( $codebase, @@ -575,7 +573,7 @@ private static function compareMethodSignatureParams( if (!$is_contained_by) { $config = Config::getInstance(); - if ($codebase->php_major_version >= 8 + if ($codebase->analysis_php_version_id >= 80000 || $guide_classlike_storage->is_trait === $implementer_classlike_storage->is_trait || !in_array($guide_classlike_storage->name, $implementer_classlike_storage->used_traits) || $implementer_method_storage->defining_fqcln !== $implementer_classlike_storage->name @@ -853,9 +851,7 @@ private static function compareMethodSignatureReturnTypes( $implementer_classlike_storage->parent_class ) : null; - $is_contained_by = (($codebase->php_major_version === 7 - && $codebase->php_minor_version === 4) - || $codebase->php_major_version >= 8) + $is_contained_by = $codebase->analysis_php_version_id >= 70400 && $implementer_signature_return_type ? UnionTypeComparator::isContainedBy( $codebase, @@ -865,7 +861,7 @@ private static function compareMethodSignatureReturnTypes( : UnionTypeComparator::isContainedByInPhp($implementer_signature_return_type, $guide_signature_return_type); if (!$is_contained_by) { - if ($codebase->php_major_version >= 8 + if ($codebase->analysis_php_version_id >= 80000 || $guide_classlike_storage->is_trait === $implementer_classlike_storage->is_trait || !in_array($guide_classlike_storage->name, $implementer_classlike_storage->used_traits) || $implementer_method_storage->defining_fqcln !== $implementer_classlike_storage->name diff --git a/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php b/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php index 6600f6e3ca9..abe4d6e562b 100644 --- a/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php @@ -569,7 +569,7 @@ private function generatePHPVersionMessage(): string { $codebase = $this->codebase; - $version = $codebase->php_major_version . '.' . $codebase->php_minor_version; + $version = $codebase->getMajorAnalysisPhpVersion() . '.' . $codebase->getMinorAnalysisPhpVersion(); switch ($codebase->php_version_source) { case 'cli': @@ -1297,16 +1297,15 @@ public function setPhpVersion(string $version, string $source): void $php_major_version = (int) $php_major_version; $php_minor_version = (int) $php_minor_version; - if ($this->codebase->php_major_version !== $php_major_version - || $this->codebase->php_minor_version !== $php_minor_version - ) { + $analysis_php_version_id = $php_major_version * 10000 + $php_minor_version * 100; + + if ($this->codebase->analysis_php_version_id !== $analysis_php_version_id) { // reset lexer and parser when php version changes StatementsProvider::clearLexer(); StatementsProvider::clearParser(); } - $this->codebase->php_major_version = $php_major_version; - $this->codebase->php_minor_version = $php_minor_version; + $this->codebase->analysis_php_version_id = $analysis_php_version_id; $this->codebase->php_version_source = $source; } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php index bfee36f3ac7..d5df517ce26 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php @@ -510,9 +510,7 @@ private static function handleUnpackedArray( if ($unpacked_atomic_type instanceof TKeyedArray) { foreach ($unpacked_atomic_type->properties as $key => $property_value) { if (is_string($key)) { - if ($codebase->php_major_version < 8 || - ($codebase->php_major_version === 8 && $codebase->php_minor_version < 1) - ) { + if ($codebase->analysis_php_version_id <= 80000) { IssueBuffer::maybeAdd( new DuplicateArrayKey( 'String keys are not supported in unpacked arrays', @@ -555,9 +553,7 @@ private static function handleUnpackedArray( $array_creation_info->can_create_objectlike = false; if ($unpacked_atomic_type->type_params[0]->hasString()) { - if ($codebase->php_major_version < 8 || - ($codebase->php_major_version === 8 && $codebase->php_minor_version < 1) - ) { + if ($codebase->analysis_php_version_id <= 80000) { IssueBuffer::maybeAdd( new DuplicateArrayKey( 'String keys are not supported in unpacked arrays', diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php index 84b777c7e20..4a4ac8c3afb 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php @@ -486,7 +486,7 @@ private static function checkFunctionLikeTypeMatches( if ($function_param->is_variadic) { $arg_type = $unpacked_atomic_array->getGenericValueType(); - } elseif ($codebase->php_major_version >= 8 + } elseif ($codebase->analysis_php_version_id >= 80000 && $allow_named_args && isset($unpacked_atomic_array->properties[$function_param->name]) ) { @@ -552,7 +552,7 @@ private static function checkFunctionLikeTypeMatches( continue; } - if (($codebase->php_major_version < 8 || !$allow_named_args) && !$key_type->isInt()) { + if (($codebase->analysis_php_version_id < 80000 || !$allow_named_args) && !$key_type->isInt()) { $invalid_string_key = true; continue; @@ -578,7 +578,7 @@ private static function checkFunctionLikeTypeMatches( 'Method ' . $cased_method_id . ' called with unpacked iterable ' . $arg_type->getId() . ' with invalid key (must be ' - . ($codebase->php_major_version < 8 ? 'int' : 'int|string') . ')', + . ($codebase->analysis_php_version_id < 80000 ? 'int' : 'int|string') . ')', new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id ), @@ -586,7 +586,7 @@ private static function checkFunctionLikeTypeMatches( ); } if ($invalid_string_key) { - if ($codebase->php_major_version < 8) { + if ($codebase->analysis_php_version_id < 80000) { IssueBuffer::maybeAdd( new $issue_type( 'String keys not supported in unpacked arguments', diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php index 7a61039cdc1..af190ce1d20 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php @@ -125,7 +125,7 @@ public static function fetch( $template_result->lower_bounds[$template_name] = [ 'fn-' . $function_id => [ new TemplateBound( - Type::getInt(false, $codebase->php_major_version) + Type::getInt(false, $codebase->getMajorAnalysisPhpVersion()) ) ] ]; @@ -135,8 +135,7 @@ public static function fetch( new TemplateBound( Type::getInt( false, - 10000 * $codebase->php_major_version - + 100 * $codebase->php_minor_version + $codebase->analysis_php_version_id ) ) ] diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php index cc99d748ec5..44bd32a59b3 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php @@ -570,7 +570,7 @@ public static function replaceTemplateTypes( $template_result->lower_bounds[$template_type->param_name] = [ 'fn-' . strtolower((string) $method_id) => [ new TemplateBound( - Type::getInt(false, $codebase->php_major_version) + Type::getInt(false, $codebase->getMajorAnalysisPhpVersion()) ) ] ]; @@ -580,8 +580,7 @@ public static function replaceTemplateTypes( new TemplateBound( Type::getInt( false, - 10000 * $codebase->php_major_version - + 100 * $codebase->php_minor_version + $codebase->analysis_php_version_id ) ) ] 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 6951396f72a..97435117100 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php @@ -504,7 +504,7 @@ private static function getMethodReturnType( $template_result->lower_bounds[$template_type->param_name] = [ 'fn-' . strtolower((string)$method_id) => [ new TemplateBound( - Type::getInt(false, $codebase->php_major_version) + Type::getInt(false, $codebase->getMajorAnalysisPhpVersion()) ) ] ]; @@ -514,8 +514,7 @@ private static function getMethodReturnType( new TemplateBound( Type::getInt( false, - 10000 * $codebase->php_major_version - + 100 * $codebase->php_minor_version + $codebase->analysis_php_version_id ) ) ] diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php index 4f80b23e0a7..6aee61d6dc9 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php @@ -261,7 +261,7 @@ public static function analyze( } if ($stmt instanceof PhpParser\Node\Expr\Cast\Unset_ - && $statements_analyzer->getCodebase()->php_major_version < 8 + && $statements_analyzer->getCodebase()->analysis_php_version_id <= 70400 ) { if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === false) { return false; diff --git a/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php index 0ce2af836e8..bbb020fab50 100644 --- a/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php @@ -470,20 +470,20 @@ private static function handleExpression( return YieldFromAnalyzer::analyze($statements_analyzer, $stmt, $context); } - $php_major_version = $statements_analyzer->getCodebase()->php_major_version; - $php_minor_version = $statements_analyzer->getCodebase()->php_minor_version; + $codebase = $statements_analyzer->getCodebase(); + $analysis_php_version_id = $codebase->analysis_php_version_id; - if ($stmt instanceof PhpParser\Node\Expr\Match_ && $php_major_version >= 8) { + if ($stmt instanceof PhpParser\Node\Expr\Match_ && $analysis_php_version_id >= 80000) { return MatchAnalyzer::analyze($statements_analyzer, $stmt, $context); } - if ($stmt instanceof PhpParser\Node\Expr\Throw_ && $php_major_version >= 8) { + if ($stmt instanceof PhpParser\Node\Expr\Throw_ && $analysis_php_version_id >= 80000) { return ThrowAnalyzer::analyze($statements_analyzer, $stmt, $context); } if (($stmt instanceof PhpParser\Node\Expr\NullsafePropertyFetch || $stmt instanceof PhpParser\Node\Expr\NullsafeMethodCall) - && $php_major_version >= 8 + && $analysis_php_version_id >= 80000 ) { return NullsafeAnalyzer::analyze($statements_analyzer, $stmt, $context); } @@ -496,7 +496,7 @@ private static function handleExpression( if (IssueBuffer::accepts( new UnrecognizedExpression( 'Psalm does not understand ' . get_class($stmt) . ' for PHP ' . - $php_major_version . ' ' . $php_minor_version, + $codebase->getMajorAnalysisPhpVersion() . '.' . $codebase->getMinorAnalysisPhpVersion(), new CodeLocation($statements_analyzer->getSource(), $stmt) ), $statements_analyzer->getSuppressedIssues() diff --git a/src/Psalm/Internal/Codebase/ClassLikes.php b/src/Psalm/Internal/Codebase/ClassLikes.php index 372d1da901f..12119c7e8b8 100644 --- a/src/Psalm/Internal/Codebase/ClassLikes.php +++ b/src/Psalm/Internal/Codebase/ClassLikes.php @@ -806,7 +806,10 @@ public function getTraitNode(string $fq_trait_name): PhpParser\Node\Stmt\Trait_ throw new UnexpectedValueException('Storage should exist for ' . $fq_trait_name); } - $file_statements = $this->statements_provider->getStatementsForFile($storage->location->file_path, '7.4'); + $file_statements = $this->statements_provider->getStatementsForFile( + $storage->location->file_path, + ProjectAnalyzer::getInstance()->getCodebase()->analysis_php_version_id + ); $trait_finder = new TraitFinder($fq_trait_name); diff --git a/src/Psalm/Internal/Codebase/InternalCallMapHandler.php b/src/Psalm/Internal/Codebase/InternalCallMapHandler.php index 8af4d0cbd75..a41fa171f0c 100644 --- a/src/Psalm/Internal/Codebase/InternalCallMapHandler.php +++ b/src/Psalm/Internal/Codebase/InternalCallMapHandler.php @@ -347,8 +347,8 @@ public static function getCallablesFromCallMap(string $function_id): ?array public static function getCallMap(): array { $codebase = ProjectAnalyzer::getInstance()->getCodebase(); - $analyzer_major_version = $codebase->php_major_version; - $analyzer_minor_version = $codebase->php_minor_version; + $analyzer_major_version = $codebase->getMajorAnalysisPhpVersion(); + $analyzer_minor_version = $codebase->getMinorAnalysisPhpVersion(); $analyzer_version = $analyzer_major_version . '.' . $analyzer_minor_version; $current_version = self::PHP_MAJOR_VERSION . '.' . self::PHP_MINOR_VERSION; diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeDocblockParser.php b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeDocblockParser.php index d2bb03ce945..cc913806c19 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeDocblockParser.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeDocblockParser.php @@ -422,7 +422,7 @@ public static function parse( $statements = StatementsProvider::parseStatements( $php_string, - $codebase->php_major_version . '.' . $codebase->php_minor_version, + $codebase->analysis_php_version_id, $has_errors ); } catch (Exception $e) { diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php index 476cb781eef..7e573e449c1 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php @@ -1495,8 +1495,7 @@ private function visitPropertyDeclaration( $this->file_storage, $this->storage, $this->aliases, - $this->codebase->php_major_version, - $this->codebase->php_minor_version + $this->codebase->analysis_php_version_id ); $signature_type_location = new CodeLocation( diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/ExpressionResolver.php b/src/Psalm/Internal/PhpVisitor/Reflector/ExpressionResolver.php index 3cf9d02950d..f4fec865b1c 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/ExpressionResolver.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/ExpressionResolver.php @@ -340,7 +340,7 @@ public static function enterConditional( ) ) ) { - $php_version_id = $codebase->php_major_version * 10000 + $codebase->php_minor_version * 100; + $php_version_id = $codebase->analysis_php_version_id; $evaluator = new ConstExprEvaluator(function (Expr $expr) use ($php_version_id) { if ($expr instanceof ConstFetch && $expr->name->parts === ['PHP_VERSION_ID']) { return $php_version_id; diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php index de938d517b7..01a1aada6fd 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php @@ -434,8 +434,7 @@ public function start(PhpParser\Node\FunctionLike $stmt, bool $fake_method = fal $this->file_storage, $this->classlike_storage, $this->aliases, - $this->codebase->php_major_version, - $this->codebase->php_minor_version + $this->codebase->analysis_php_version_id ); $storage->return_type_location = new CodeLocation( @@ -486,12 +485,14 @@ public function start(PhpParser\Node\FunctionLike $stmt, bool $fake_method = fal if ($docblock_info) { if ($docblock_info->since_php_major_version && !$this->aliases->namespace) { - if ($docblock_info->since_php_major_version > $this->codebase->php_major_version) { + $analysis_major_php_version = $this->codebase->getMajorAnalysisPhpVersion(); + $analysis_minor_php_version = $this->codebase->getMajorAnalysisPhpVersion(); + if ($docblock_info->since_php_major_version > $analysis_major_php_version) { return false; } - if ($docblock_info->since_php_major_version === $this->codebase->php_major_version - && $docblock_info->since_php_minor_version > $this->codebase->php_minor_version + if ($docblock_info->since_php_major_version === $analysis_major_php_version + && $docblock_info->since_php_minor_version > $analysis_minor_php_version ) { return false; } @@ -828,8 +829,7 @@ private function getTranslatedFunctionParam( $this->file_storage, $this->classlike_storage, $this->aliases, - $this->codebase->php_major_version, - $this->codebase->php_minor_version + $this->codebase->analysis_php_version_id ); if ($is_nullable) { @@ -1043,11 +1043,14 @@ private function createStorageForFunctionLike( } if ($docblock_info) { if ($docblock_info->since_php_major_version && !$this->aliases->namespace) { - if ($docblock_info->since_php_major_version > $this->codebase->php_major_version) { + $analysis_major_php_version = $this->codebase->getMajorAnalysisPhpVersion(); + $analysis_minor_php_version = $this->codebase->getMajorAnalysisPhpVersion(); + if ($docblock_info->since_php_major_version > $analysis_major_php_version) { return false; } - if ($docblock_info->since_php_major_version === $this->codebase->php_major_version - && $docblock_info->since_php_minor_version > $this->codebase->php_minor_version + + if ($docblock_info->since_php_major_version === $analysis_major_php_version + && $docblock_info->since_php_minor_version > $analysis_minor_php_version ) { return false; } @@ -1072,7 +1075,7 @@ private function createStorageForFunctionLike( if ($method_name_lc === strtolower($class_name) && !isset($classlike_storage->methods['__construct']) && strpos($fq_classlike_name, '\\') === false - && $this->codebase->php_major_version < 8 + && $this->codebase->analysis_php_version_id <= 70400 ) { $this->codebase->methods->setDeclaringMethodId( $fq_classlike_name, diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/TypeHintResolver.php b/src/Psalm/Internal/PhpVisitor/Reflector/TypeHintResolver.php index 3dfb0859075..6b992cedd82 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/TypeHintResolver.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/TypeHintResolver.php @@ -27,8 +27,7 @@ public static function resolve( FileStorage $file_storage, ?ClassLikeStorage $classlike_storage, Aliases $aliases, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): Union { if ($hint instanceof PhpParser\Node\UnionType) { $type = null; @@ -44,8 +43,7 @@ public static function resolve( $file_storage, $classlike_storage, $aliases, - $php_major_version, - $php_minor_version + $analysis_php_version_id ); $type = Type::combineUnionTypes($resolved_type, $type); @@ -93,7 +91,7 @@ public static function resolve( $type = Type::parseString( $fq_type_string, - [$php_major_version, $php_minor_version], + $analysis_php_version_id, [] ); diff --git a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php index e99259cfca0..1dccc6dc6f5 100644 --- a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php +++ b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php @@ -237,7 +237,7 @@ public function enterNode(PhpParser\Node $node): ?int $this->functionlike_node_scanners[] = $functionlike_node_scanner; if ($classlike_storage - && $this->codebase->php_major_version >= 8 + && $this->codebase->analysis_php_version_id >= 80000 && $node instanceof PhpParser\Node\Stmt\ClassMethod && strtolower($node->name->name) === '__tostring' ) { diff --git a/src/Psalm/Internal/Provider/StatementsProvider.php b/src/Psalm/Internal/Provider/StatementsProvider.php index 3a5cb57fd80..92ab2887653 100644 --- a/src/Psalm/Internal/Provider/StatementsProvider.php +++ b/src/Psalm/Internal/Provider/StatementsProvider.php @@ -6,6 +6,7 @@ use PhpParser\ErrorHandler\Collecting; use PhpParser\Node\Stmt; use Psalm\CodeLocation\ParseErrorLocation; +use Psalm\Codebase; use Psalm\Config; use Psalm\Internal\Diff\FileDiffer; use Psalm\Internal\Diff\FileStatementsDiffer; @@ -109,8 +110,11 @@ public function __construct( /** * @return list */ - public function getStatementsForFile(string $file_path, string $php_version, ?Progress $progress = null): array - { + public function getStatementsForFile( + string $file_path, + int $analysis_php_version_id, + ?Progress $progress = null + ): array { unset($this->errors[$file_path]); if ($progress === null) { @@ -133,7 +137,7 @@ public function getStatementsForFile(string $file_path, string $php_version, ?Pr $has_errors = false; - $stmts = self::parseStatements($file_contents, $php_version, $has_errors, $file_path); + $stmts = self::parseStatements($file_contents, $analysis_php_version_id, $has_errors, $file_path); return $stmts ?: []; } @@ -195,7 +199,7 @@ public function getStatementsForFile(string $file_path, string $php_version, ?Pr $stmts = self::parseStatements( $file_contents, - $php_version, + $analysis_php_version_id, $has_errors, $file_path, $existing_file_contents, @@ -416,22 +420,24 @@ public function resetDiffs(): void * @return list */ public static function parseStatements( - string $file_contents, - string $php_version, - bool &$has_errors, + string $file_contents, + int $analysis_php_version_id, + bool &$has_errors, ?string $file_path = null, ?string $existing_file_contents = null, - ?array $existing_statements = null, - ?array $file_changes = null + ?array $existing_statements = null, + ?array $file_changes = null ): array { $attributes = [ 'comments', 'startLine', 'startFilePos', 'endFilePos', ]; if (!self::$lexer) { + $major_version = Codebase::transformPhpVersionId($analysis_php_version_id, 10000); + $minor_version = Codebase::transformPhpVersionId($analysis_php_version_id % 10000, 100); self::$lexer = new PhpParser\Lexer\Emulative([ 'usedAttributes' => $attributes, - 'phpVersion' => $php_version, + 'phpVersion' => $major_version . '.' . $minor_version, ]); } diff --git a/src/Psalm/Internal/Scanner/FileScanner.php b/src/Psalm/Internal/Scanner/FileScanner.php index 1cc9b6fffe9..b77a8794556 100644 --- a/src/Psalm/Internal/Scanner/FileScanner.php +++ b/src/Psalm/Internal/Scanner/FileScanner.php @@ -59,7 +59,7 @@ public function scan( $stmts = $codebase->statements_provider->getStatementsForFile( $file_storage->file_path, - $codebase->php_major_version . '.' . $codebase->php_minor_version, + $codebase->analysis_php_version_id, $progress ); diff --git a/src/Psalm/Internal/Stubs/Generator/StubsGenerator.php b/src/Psalm/Internal/Stubs/Generator/StubsGenerator.php index 23b1ca16ef0..19c6266bbca 100644 --- a/src/Psalm/Internal/Stubs/Generator/StubsGenerator.php +++ b/src/Psalm/Internal/Stubs/Generator/StubsGenerator.php @@ -384,7 +384,7 @@ public static function getParserTypeFromPsalmType(Union $type): ?PhpParser\NodeA || $atomic_type instanceof TArray || $atomic_type instanceof TIterable ) { - $identifier_string = $atomic_type->toPhpString(null, [], null, 8, 0); + $identifier_string = $atomic_type->toPhpString(null, [], null, 80000); if ($identifier_string === null) { throw new UnexpectedValueException( diff --git a/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php b/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php index 6f35b1ff3a3..b6045f4df91 100644 --- a/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php +++ b/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php @@ -509,7 +509,7 @@ public static function isContainedBy( if ($input_type_part instanceof TNamedObject) { // check whether the object has a __toString method if ($codebase->classOrInterfaceExists($input_type_part->value)) { - if ($codebase->php_major_version >= 8 + if ($codebase->analysis_php_version_id >= 80000 && ($input_type_part->value === 'Stringable' || ($codebase->classlikes->classExists($input_type_part->value) && $codebase->classlikes->classImplements($input_type_part->value, 'Stringable')) diff --git a/src/Psalm/Internal/Type/TypeParser.php b/src/Psalm/Internal/Type/TypeParser.php index 20c9308b2bd..cfd0b12908e 100644 --- a/src/Psalm/Internal/Type/TypeParser.php +++ b/src/Psalm/Internal/Type/TypeParser.php @@ -105,7 +105,7 @@ class TypeParser */ public static function parseTokens( array $type_tokens, - ?array $php_version = null, + ?int $analysis_php_version_id = null, array $template_type_map = [], array $type_aliases = [] ): Union { @@ -121,9 +121,9 @@ public static function parseTokens( throw new TypeParseTreeException("Invalid type '$only_token[0]'"); } } else { - $only_token[0] = TypeTokenizer::fixScalarTerms($only_token[0], $php_version); + $only_token[0] = TypeTokenizer::fixScalarTerms($only_token[0], $analysis_php_version_id); - $atomic = Atomic::create($only_token[0], $php_version, $template_type_map, $type_aliases); + $atomic = Atomic::create($only_token[0], $analysis_php_version_id, $template_type_map, $type_aliases); $atomic->offset_start = 0; $atomic->offset_end = strlen($only_token[0]); $atomic->text = isset($only_token[2]) && $only_token[2] !== $only_token[0] ? $only_token[2] : null; @@ -137,7 +137,7 @@ public static function parseTokens( $parsed_type = self::getTypeFromTree( $parse_tree, $codebase, - $php_version, + $analysis_php_version_id, $template_type_map, $type_aliases ); @@ -150,18 +150,17 @@ public static function parseTokens( } /** - * @param array{int,int}|null $php_version * @param array> $template_type_map - * @param array $type_aliases + * @param array $type_aliases * * @return Atomic|Union */ public static function getTypeFromTree( ParseTree $parse_tree, - Codebase $codebase, - ?array $php_version = null, - array $template_type_map = [], - array $type_aliases = [] + Codebase $codebase, + ?int $analysis_php_version_id = null, + array $template_type_map = [], + array $type_aliases = [] ): TypeNode { if ($parse_tree instanceof GenericTree) { return self::getTypeFromGenericTree( @@ -378,9 +377,9 @@ public static function getTypeFromTree( throw new TypeParseTreeException('Invalid type \'' . $parse_tree->value . '\''); } - $atomic_type_string = TypeTokenizer::fixScalarTerms($parse_tree->value, $php_version); + $atomic_type_string = TypeTokenizer::fixScalarTerms($parse_tree->value, $analysis_php_version_id); - $atomic_type = Atomic::create($atomic_type_string, $php_version, $template_type_map, $type_aliases); + $atomic_type = Atomic::create($atomic_type_string, $analysis_php_version_id, $template_type_map, $type_aliases); $atomic_type->offset_start = $parse_tree->offset_start; $atomic_type->offset_end = $parse_tree->offset_end; diff --git a/src/Psalm/Internal/Type/TypeTokenizer.php b/src/Psalm/Internal/Type/TypeTokenizer.php index 020a3b270ca..996eb2d41e3 100644 --- a/src/Psalm/Internal/Type/TypeTokenizer.php +++ b/src/Psalm/Internal/Type/TypeTokenizer.php @@ -300,14 +300,11 @@ public static function tokenize(string $string_type, bool $ignore_space = true): } /** - * @param array{int,int}|null $php_version - * - * * @psalm-pure */ public static function fixScalarTerms( string $type_string, - ?array $php_version = null + ?int $analysis_php_version_id = null ): string { $type_string_lc = strtolower($type_string); @@ -330,14 +327,14 @@ public static function fixScalarTerms( switch ($type_string) { case 'boolean': - return $php_version !== null ? $type_string : 'bool'; + return $analysis_php_version_id !== null ? $type_string : 'bool'; case 'integer': - return $php_version !== null ? $type_string : 'int'; + return $analysis_php_version_id !== null ? $type_string : 'int'; case 'double': case 'real': - return $php_version !== null ? $type_string : 'float'; + return $analysis_php_version_id !== null ? $type_string : 'float'; } return $type_string; diff --git a/src/Psalm/Type.php b/src/Psalm/Type.php index 6d0c9e0fb45..e71d91d4faf 100644 --- a/src/Psalm/Type.php +++ b/src/Psalm/Type.php @@ -75,14 +75,14 @@ abstract class Type */ public static function parseString( string $type_string, - ?array $php_version = null, + ?int $analysis_php_version_id = null, array $template_type_map = [] ): Union { return TypeParser::parseTokens( TypeTokenizer::tokenize( $type_string ), - $php_version, + $analysis_php_version_id, $template_type_map ); } diff --git a/src/Psalm/Type/Atomic.php b/src/Psalm/Type/Atomic.php index 91378836e53..0385879db43 100644 --- a/src/Psalm/Type/Atomic.php +++ b/src/Psalm/Type/Atomic.php @@ -113,15 +113,15 @@ abstract class Atomic implements TypeNode public $text; /** - * @param array{int,int}|null $php_version contains php version when the type comes from signature + * @param int $analysis_php_version_id contains php version when the type comes from signature * @param array> $template_type_map * @param array $type_aliases */ public static function create( string $value, - ?array $php_version = null, - array $template_type_map = [], - array $type_aliases = [] + ?int $analysis_php_version_id = null, + array $template_type_map = [], + array $type_aliases = [] ): Atomic { switch ($value) { case 'int': @@ -137,10 +137,7 @@ public static function create( return new TBool(); case 'void': - if ($php_version === null - || ($php_version[0] > 7) - || ($php_version[0] === 7 && $php_version[1] >= 1) - ) { + if ($analysis_php_version_id === null || $analysis_php_version_id >= 70100) { return new TVoid(); } @@ -150,20 +147,14 @@ public static function create( return new TArrayKey(); case 'iterable': - if ($php_version === null - || ($php_version[0] > 7) - || ($php_version[0] === 7 && $php_version[1] >= 1) - ) { + if ($analysis_php_version_id === null || $analysis_php_version_id >= 70100) { return new TIterable(); } break; case 'never': - if ($php_version === null - || ($php_version[0] > 8) - || ($php_version[0] === 8 && $php_version[1] >= 1) - ) { + if ($analysis_php_version_id === null || $analysis_php_version_id >= 80100) { return new TNever(); } @@ -175,10 +166,7 @@ public static function create( return new TNever(); case 'object': - if ($php_version === null - || ($php_version[0] > 7) - || ($php_version[0] === 7 && $php_version[1] >= 2) - ) { + if ($analysis_php_version_id === null || $analysis_php_version_id >= 70200) { return new TObject(); } @@ -221,7 +209,7 @@ public static function create( return new TNonEmptyLowercaseString(); case 'resource': - return $php_version !== null ? new TNamedObject($value) : new TResource(); + return $analysis_php_version_id !== null ? new TNamedObject($value) : new TResource(); case 'resource (closed)': case 'closed-resource': @@ -231,33 +219,33 @@ public static function create( return new TPositiveInt(); case 'numeric': - return $php_version !== null ? new TNamedObject($value) : new TNumeric(); + return $analysis_php_version_id !== null ? new TNamedObject($value) : new TNumeric(); case 'true': - return $php_version !== null ? new TNamedObject($value) : new TTrue(); + return $analysis_php_version_id !== null ? new TNamedObject($value) : new TTrue(); case 'false': - if ($php_version === null || $php_version[0] >= 8) { + if ($analysis_php_version_id === null || $analysis_php_version_id >= 80000) { return new TFalse(); } return new TNamedObject($value); case 'empty': - return $php_version !== null ? new TNamedObject($value) : new TEmpty(); + return $analysis_php_version_id !== null ? new TNamedObject($value) : new TEmpty(); case 'scalar': - return $php_version !== null ? new TNamedObject($value) : new TScalar(); + return $analysis_php_version_id !== null ? new TNamedObject($value) : new TScalar(); case 'null': - if ($php_version === null || $php_version[0] >= 8) { + if ($analysis_php_version_id === null || $analysis_php_version_id >= 80000) { return new TNull(); } return new TNamedObject($value); case 'mixed': - if ($php_version === null || $php_version[0] >= 8) { + if ($analysis_php_version_id === null || $analysis_php_version_id >= 80000) { return new TMixed(); } @@ -625,11 +613,10 @@ abstract public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string; - abstract public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool; + abstract public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool; public function replaceTemplateTypesWithStandins( TemplateResult $template_result, diff --git a/src/Psalm/Type/Atomic/CallableTrait.php b/src/Psalm/Type/Atomic/CallableTrait.php index cd0c026d0c1..062cd647187 100644 --- a/src/Psalm/Type/Atomic/CallableTrait.php +++ b/src/Psalm/Type/Atomic/CallableTrait.php @@ -141,8 +141,7 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): string { if ($this instanceof TNamedObject) { return parent::toNamespacedString($namespace, $aliased_classes, $this_class, true); diff --git a/src/Psalm/Type/Atomic/Scalar.php b/src/Psalm/Type/Atomic/Scalar.php index f37518cd289..dbc2f1a4691 100644 --- a/src/Psalm/Type/Atomic/Scalar.php +++ b/src/Psalm/Type/Atomic/Scalar.php @@ -6,7 +6,7 @@ abstract class Scalar extends Atomic { - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return true; } diff --git a/src/Psalm/Type/Atomic/TAnonymousClassInstance.php b/src/Psalm/Type/Atomic/TAnonymousClassInstance.php index 1d8583e41f8..57cda6dc01d 100644 --- a/src/Psalm/Type/Atomic/TAnonymousClassInstance.php +++ b/src/Psalm/Type/Atomic/TAnonymousClassInstance.php @@ -26,12 +26,9 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { - return $php_major_version > 7 - || ($php_major_version === 7 && $php_minor_version >= 2) - ? ($this->extends ?? 'object') : null; + return $analysis_php_version_id >= 70200 ? ($this->extends ?? 'object') : null; } /** diff --git a/src/Psalm/Type/Atomic/TArray.php b/src/Psalm/Type/Atomic/TArray.php index 05e31a4762f..eabbe75e72b 100644 --- a/src/Psalm/Type/Atomic/TArray.php +++ b/src/Psalm/Type/Atomic/TArray.php @@ -47,13 +47,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): string { return $this->getKey(); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return $this->type_params[0]->isArrayKey() && $this->type_params[1]->isMixed(); } diff --git a/src/Psalm/Type/Atomic/TArrayKey.php b/src/Psalm/Type/Atomic/TArrayKey.php index 038b85cfc73..7c53bd1dc6c 100644 --- a/src/Psalm/Type/Atomic/TArrayKey.php +++ b/src/Psalm/Type/Atomic/TArrayKey.php @@ -24,13 +24,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TAssertionFalsy.php b/src/Psalm/Type/Atomic/TAssertionFalsy.php index db43e12bf75..01ca6cc429c 100644 --- a/src/Psalm/Type/Atomic/TAssertionFalsy.php +++ b/src/Psalm/Type/Atomic/TAssertionFalsy.php @@ -31,13 +31,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TBool.php b/src/Psalm/Type/Atomic/TBool.php index adae27f9d58..bdd48fb463d 100644 --- a/src/Psalm/Type/Atomic/TBool.php +++ b/src/Psalm/Type/Atomic/TBool.php @@ -24,9 +24,8 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { - return $php_major_version >= 7 ? 'bool' : null; + return $analysis_php_version_id >= 70000 ? 'bool' : null; } } diff --git a/src/Psalm/Type/Atomic/TCallable.php b/src/Psalm/Type/Atomic/TCallable.php index fb92d7e6786..217c717fe00 100644 --- a/src/Psalm/Type/Atomic/TCallable.php +++ b/src/Psalm/Type/Atomic/TCallable.php @@ -23,13 +23,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): string { return 'callable'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return $this->params === null && $this->return_type === null; } diff --git a/src/Psalm/Type/Atomic/TCallableObject.php b/src/Psalm/Type/Atomic/TCallableObject.php index 3ba0a8a7b56..c210976beec 100644 --- a/src/Psalm/Type/Atomic/TCallableObject.php +++ b/src/Psalm/Type/Atomic/TCallableObject.php @@ -24,15 +24,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { - return $php_major_version > 7 - || ($php_major_version === 7 && $php_minor_version >= 2) - ? 'object' : null; + return $analysis_php_version_id >= 72000 ? 'object' : null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TCallableString.php b/src/Psalm/Type/Atomic/TCallableString.php index 803120df672..c4cdeb42662 100644 --- a/src/Psalm/Type/Atomic/TCallableString.php +++ b/src/Psalm/Type/Atomic/TCallableString.php @@ -18,7 +18,7 @@ public function getId(bool $nested = false): string return $this->getKey(); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TClassConstant.php b/src/Psalm/Type/Atomic/TClassConstant.php index 7790806d32a..2b71c1ae33d 100644 --- a/src/Psalm/Type/Atomic/TClassConstant.php +++ b/src/Psalm/Type/Atomic/TClassConstant.php @@ -49,13 +49,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TClassString.php b/src/Psalm/Type/Atomic/TClassString.php index 745778c7369..33658d0e203 100644 --- a/src/Psalm/Type/Atomic/TClassString.php +++ b/src/Psalm/Type/Atomic/TClassString.php @@ -66,8 +66,7 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return 'string'; } @@ -104,7 +103,7 @@ public function toNamespacedString( return 'class-string<\\' . $this->as . '>'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TClassStringMap.php b/src/Psalm/Type/Atomic/TClassStringMap.php index edef7eec388..6c13a7acd6a 100644 --- a/src/Psalm/Type/Atomic/TClassStringMap.php +++ b/src/Psalm/Type/Atomic/TClassStringMap.php @@ -126,13 +126,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): string { return 'array'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TClosedResource.php b/src/Psalm/Type/Atomic/TClosedResource.php index c8391b4c532..8ebbbfaeffd 100644 --- a/src/Psalm/Type/Atomic/TClosedResource.php +++ b/src/Psalm/Type/Atomic/TClosedResource.php @@ -31,13 +31,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TClosure.php b/src/Psalm/Type/Atomic/TClosure.php index 5e3a9dfe08f..7703aa82cb7 100644 --- a/src/Psalm/Type/Atomic/TClosure.php +++ b/src/Psalm/Type/Atomic/TClosure.php @@ -12,7 +12,7 @@ class TClosure extends TNamedObject /** @var array */ public $byref_uses = []; - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TConditional.php b/src/Psalm/Type/Atomic/TConditional.php index 2c12fea6078..496e1b3d492 100644 --- a/src/Psalm/Type/Atomic/TConditional.php +++ b/src/Psalm/Type/Atomic/TConditional.php @@ -106,8 +106,7 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } @@ -130,7 +129,7 @@ public function getChildNodes(): array return [$this->conditional_type, $this->if_type, $this->else_type]; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TDependentGetClass.php b/src/Psalm/Type/Atomic/TDependentGetClass.php index d53e53b2b6c..a22e8476132 100644 --- a/src/Psalm/Type/Atomic/TDependentGetClass.php +++ b/src/Psalm/Type/Atomic/TDependentGetClass.php @@ -56,7 +56,7 @@ public function getReplacement(): Atomic return new TClassString(); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TDependentGetDebugType.php b/src/Psalm/Type/Atomic/TDependentGetDebugType.php index 1ca555270f5..1bdf96486eb 100644 --- a/src/Psalm/Type/Atomic/TDependentGetDebugType.php +++ b/src/Psalm/Type/Atomic/TDependentGetDebugType.php @@ -39,7 +39,7 @@ public function getReplacement(): Atomic return new TString(); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TDependentGetType.php b/src/Psalm/Type/Atomic/TDependentGetType.php index 1c06fcda5df..4b91601c33b 100644 --- a/src/Psalm/Type/Atomic/TDependentGetType.php +++ b/src/Psalm/Type/Atomic/TDependentGetType.php @@ -22,7 +22,7 @@ public function __construct(string $typeof) $this->typeof = $typeof; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TDependentListKey.php b/src/Psalm/Type/Atomic/TDependentListKey.php index c5bbd991e76..74f59173330 100644 --- a/src/Psalm/Type/Atomic/TDependentListKey.php +++ b/src/Psalm/Type/Atomic/TDependentListKey.php @@ -44,7 +44,7 @@ public function getReplacement(): Atomic return new TInt(); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TEmpty.php b/src/Psalm/Type/Atomic/TEmpty.php index 2cfa456f779..d0fd4a78537 100644 --- a/src/Psalm/Type/Atomic/TEmpty.php +++ b/src/Psalm/Type/Atomic/TEmpty.php @@ -26,8 +26,7 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } diff --git a/src/Psalm/Type/Atomic/TEnumCase.php b/src/Psalm/Type/Atomic/TEnumCase.php index a6242306f8d..de6f0a52fe9 100644 --- a/src/Psalm/Type/Atomic/TEnumCase.php +++ b/src/Psalm/Type/Atomic/TEnumCase.php @@ -33,13 +33,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return $this->value; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TFalse.php b/src/Psalm/Type/Atomic/TFalse.php index 5ffd3112f39..c52fa09bed0 100644 --- a/src/Psalm/Type/Atomic/TFalse.php +++ b/src/Psalm/Type/Atomic/TFalse.php @@ -17,7 +17,7 @@ public function getKey(bool $include_extra = true): string return 'false'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TFloat.php b/src/Psalm/Type/Atomic/TFloat.php index 76a7666a2ff..d5ac7ea901b 100644 --- a/src/Psalm/Type/Atomic/TFloat.php +++ b/src/Psalm/Type/Atomic/TFloat.php @@ -24,9 +24,8 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { - return $php_major_version >= 7 ? 'float' : null; + return $analysis_php_version_id >= 70000 ? 'float' : null; } } diff --git a/src/Psalm/Type/Atomic/TGenericObject.php b/src/Psalm/Type/Atomic/TGenericObject.php index e0f77432e19..79bff4589a0 100644 --- a/src/Psalm/Type/Atomic/TGenericObject.php +++ b/src/Psalm/Type/Atomic/TGenericObject.php @@ -57,7 +57,7 @@ public function getKey(bool $include_extra = true): string return $this->value . '<' . substr($s, 0, -2) . '>' . $extra_types; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } @@ -69,16 +69,11 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { $result = $this->toNamespacedString($namespace, $aliased_classes, $this_class, true); $intersection = strrpos($result, '&'); - if ($intersection === false || ( - ($php_major_version === 8 && $php_minor_version >= 1) || - ($php_major_version >= 9) - ) - ) { + if ($intersection === false || $analysis_php_version_id >= 80100) { return $result; } return substr($result, $intersection+1); diff --git a/src/Psalm/Type/Atomic/THtmlEscapedString.php b/src/Psalm/Type/Atomic/THtmlEscapedString.php index b6a77f56e38..99d1056fc23 100644 --- a/src/Psalm/Type/Atomic/THtmlEscapedString.php +++ b/src/Psalm/Type/Atomic/THtmlEscapedString.php @@ -17,7 +17,7 @@ public function getId(bool $nested = false): string return $this->getKey(); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TInt.php b/src/Psalm/Type/Atomic/TInt.php index 27191b81866..c40c6d23244 100644 --- a/src/Psalm/Type/Atomic/TInt.php +++ b/src/Psalm/Type/Atomic/TInt.php @@ -24,9 +24,8 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { - return $php_major_version >= 7 ? 'int' : null; + return $analysis_php_version_id >= 70000 ? 'int' : null; } } diff --git a/src/Psalm/Type/Atomic/TIntMask.php b/src/Psalm/Type/Atomic/TIntMask.php index cf6cd4c61b9..86a4b5fccfe 100644 --- a/src/Psalm/Type/Atomic/TIntMask.php +++ b/src/Psalm/Type/Atomic/TIntMask.php @@ -64,7 +64,7 @@ public function toNamespacedString( return 'int-mask<' . substr($s, 0, -2) . '>'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TIntMaskOf.php b/src/Psalm/Type/Atomic/TIntMaskOf.php index 70e5645239e..512dd42bc3b 100644 --- a/src/Psalm/Type/Atomic/TIntMaskOf.php +++ b/src/Psalm/Type/Atomic/TIntMaskOf.php @@ -50,7 +50,7 @@ public function toNamespacedString( . '>'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TIntRange.php b/src/Psalm/Type/Atomic/TIntRange.php index 5571823f271..dbdbadb9db1 100644 --- a/src/Psalm/Type/Atomic/TIntRange.php +++ b/src/Psalm/Type/Atomic/TIntRange.php @@ -38,7 +38,7 @@ public function getKey(bool $include_extra = true): string return 'int<' . ($this->min_bound ?? 'min') . ', ' . ($this->max_bound ?? 'max') . '>'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TIterable.php b/src/Psalm/Type/Atomic/TIterable.php index b7aea22cf56..010dcd2aac7 100644 --- a/src/Psalm/Type/Atomic/TIterable.php +++ b/src/Psalm/Type/Atomic/TIterable.php @@ -89,16 +89,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { - return $php_major_version > 7 - || ($php_major_version === 7 && $php_minor_version >= 1) - ? 'iterable' - : null; + return $analysis_php_version_id >= 70100 ? 'iterable' : null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return $this->type_params[0]->isMixed() && $this->type_params[1]->isMixed(); } diff --git a/src/Psalm/Type/Atomic/TKeyOfClassConstant.php b/src/Psalm/Type/Atomic/TKeyOfClassConstant.php index 05d2e7101a0..189cda0df2a 100644 --- a/src/Psalm/Type/Atomic/TKeyOfClassConstant.php +++ b/src/Psalm/Type/Atomic/TKeyOfClassConstant.php @@ -47,13 +47,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TKeyedArray.php b/src/Psalm/Type/Atomic/TKeyedArray.php index aea960c8346..002e63548f6 100644 --- a/src/Psalm/Type/Atomic/TKeyedArray.php +++ b/src/Psalm/Type/Atomic/TKeyedArray.php @@ -213,13 +213,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): string { return $this->getKey(); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TList.php b/src/Psalm/Type/Atomic/TList.php index 3d5136530d4..75919c8b44d 100644 --- a/src/Psalm/Type/Atomic/TList.php +++ b/src/Psalm/Type/Atomic/TList.php @@ -97,13 +97,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): string { return 'array'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TLiteralClassString.php b/src/Psalm/Type/Atomic/TLiteralClassString.php index a36429d3cf7..5cdb2125109 100644 --- a/src/Psalm/Type/Atomic/TLiteralClassString.php +++ b/src/Psalm/Type/Atomic/TLiteralClassString.php @@ -42,13 +42,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): string { return 'string'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TLowercaseString.php b/src/Psalm/Type/Atomic/TLowercaseString.php index b1b34cd4a43..5fc884fe570 100644 --- a/src/Psalm/Type/Atomic/TLowercaseString.php +++ b/src/Psalm/Type/Atomic/TLowercaseString.php @@ -9,7 +9,7 @@ public function getId(bool $nested = false): string return 'lowercase-string'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TMixed.php b/src/Psalm/Type/Atomic/TMixed.php index 00aaa08ade7..bbb21545d2f 100644 --- a/src/Psalm/Type/Atomic/TMixed.php +++ b/src/Psalm/Type/Atomic/TMixed.php @@ -34,15 +34,14 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { - return $php_major_version >= 8 ? 'mixed' : null; + return $analysis_php_version_id >= 80000 ? 'mixed' : null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { - return $php_major_version >= 8; + return $analysis_php_version_id >= 80000; } public function getAssertionString(bool $exact = false): string diff --git a/src/Psalm/Type/Atomic/TNamedObject.php b/src/Psalm/Type/Atomic/TNamedObject.php index e9eebc94656..1e5113fbe29 100644 --- a/src/Psalm/Type/Atomic/TNamedObject.php +++ b/src/Psalm/Type/Atomic/TNamedObject.php @@ -118,32 +118,27 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { if ($this->value === 'static') { - return $php_major_version >= 8 ? 'static' : null; + return $analysis_php_version_id >= 80000 ? 'static' : null; } if ($this->was_static && $this->value === $this_class) { - return $php_major_version >= 8 ? 'static' : 'self'; + return $analysis_php_version_id >= 80000 ? 'static' : 'self'; } $result = $this->toNamespacedString($namespace, $aliased_classes, $this_class, false); $intersection = strrpos($result, '&'); - if ($intersection === false || ( - ($php_major_version === 8 && $php_minor_version >= 1) || - ($php_major_version >= 9) - ) - ) { + if ($intersection === false || $analysis_php_version_id >= 80100) { return $result; } return substr($result, $intersection+1); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { - return ($this->value !== 'static' && $this->was_static === false) || $php_major_version >= 8; + return ($this->value !== 'static' && $this->was_static === false) || $analysis_php_version_id >= 80000; } public function replaceTemplateTypesWithArgTypes( diff --git a/src/Psalm/Type/Atomic/TNever.php b/src/Psalm/Type/Atomic/TNever.php index 1b972d0b3ea..5e624c0ab49 100644 --- a/src/Psalm/Type/Atomic/TNever.php +++ b/src/Psalm/Type/Atomic/TNever.php @@ -27,13 +27,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php b/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php index 1d331e8d138..9769e7f605b 100644 --- a/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php +++ b/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php @@ -15,7 +15,7 @@ public function getId(bool $nested = false): string /** * @return false */ - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php b/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php index 8a04903969a..ac920d5a68c 100644 --- a/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php +++ b/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php @@ -13,7 +13,7 @@ public function __toString(): string return 'literal-int'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TNonspecificLiteralString.php b/src/Psalm/Type/Atomic/TNonspecificLiteralString.php index 30d6ac97c1d..fe4c46b57f0 100644 --- a/src/Psalm/Type/Atomic/TNonspecificLiteralString.php +++ b/src/Psalm/Type/Atomic/TNonspecificLiteralString.php @@ -13,7 +13,7 @@ public function __toString(): string return 'literal-string'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TNull.php b/src/Psalm/Type/Atomic/TNull.php index d95759e63d9..2efc36d2417 100644 --- a/src/Psalm/Type/Atomic/TNull.php +++ b/src/Psalm/Type/Atomic/TNull.php @@ -26,13 +26,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TNumeric.php b/src/Psalm/Type/Atomic/TNumeric.php index 8651ff1c998..6b988210a6d 100644 --- a/src/Psalm/Type/Atomic/TNumeric.php +++ b/src/Psalm/Type/Atomic/TNumeric.php @@ -24,13 +24,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TNumericString.php b/src/Psalm/Type/Atomic/TNumericString.php index c86027a442f..001eed685d0 100644 --- a/src/Psalm/Type/Atomic/TNumericString.php +++ b/src/Psalm/Type/Atomic/TNumericString.php @@ -22,7 +22,7 @@ public function getId(bool $nested = false): string return $this->getKey(); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TObject.php b/src/Psalm/Type/Atomic/TObject.php index e2a87219457..c7cc67fff5b 100644 --- a/src/Psalm/Type/Atomic/TObject.php +++ b/src/Psalm/Type/Atomic/TObject.php @@ -26,16 +26,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { - return $php_major_version > 7 - || ($php_major_version === 7 && $php_minor_version >= 2) - ? $this->getKey() - : null; + return $analysis_php_version_id >= 70200 ? $this->getKey() : null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return true; } diff --git a/src/Psalm/Type/Atomic/TObjectWithProperties.php b/src/Psalm/Type/Atomic/TObjectWithProperties.php index fa68b797275..34f799b3f68 100644 --- a/src/Psalm/Type/Atomic/TObjectWithProperties.php +++ b/src/Psalm/Type/Atomic/TObjectWithProperties.php @@ -175,13 +175,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): string { return $this->getKey(); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TPositiveInt.php b/src/Psalm/Type/Atomic/TPositiveInt.php index eb345a0ba1a..b8335df859a 100644 --- a/src/Psalm/Type/Atomic/TPositiveInt.php +++ b/src/Psalm/Type/Atomic/TPositiveInt.php @@ -20,7 +20,7 @@ public function __toString(): string /** * @return false */ - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TResource.php b/src/Psalm/Type/Atomic/TResource.php index 49ee650902b..47bde1d24aa 100644 --- a/src/Psalm/Type/Atomic/TResource.php +++ b/src/Psalm/Type/Atomic/TResource.php @@ -26,13 +26,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TScalar.php b/src/Psalm/Type/Atomic/TScalar.php index 0cb6f0b80c1..5954a75e7f0 100644 --- a/src/Psalm/Type/Atomic/TScalar.php +++ b/src/Psalm/Type/Atomic/TScalar.php @@ -25,13 +25,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TString.php b/src/Psalm/Type/Atomic/TString.php index 7312b16f43f..986d585b85a 100644 --- a/src/Psalm/Type/Atomic/TString.php +++ b/src/Psalm/Type/Atomic/TString.php @@ -14,10 +14,9 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { - return $php_major_version >= 7 ? 'string' : null; + return $analysis_php_version_id >= 70000 ? 'string' : null; } public function __toString(): string diff --git a/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php b/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php index 72e72c38f7c..69de28a65d6 100644 --- a/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php +++ b/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php @@ -53,13 +53,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TTemplateParam.php b/src/Psalm/Type/Atomic/TTemplateParam.php index 66c0af836c5..517955bd3f3 100644 --- a/src/Psalm/Type/Atomic/TTemplateParam.php +++ b/src/Psalm/Type/Atomic/TTemplateParam.php @@ -81,8 +81,7 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } @@ -121,7 +120,7 @@ public function getChildNodes(): array return [$this->as]; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TTraitString.php b/src/Psalm/Type/Atomic/TTraitString.php index 65008a4d061..d06a057ec34 100644 --- a/src/Psalm/Type/Atomic/TTraitString.php +++ b/src/Psalm/Type/Atomic/TTraitString.php @@ -29,8 +29,7 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return 'string'; } @@ -48,7 +47,7 @@ public function toNamespacedString( return 'trait-string'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TTrue.php b/src/Psalm/Type/Atomic/TTrue.php index 29313a0d457..637e52ba24b 100644 --- a/src/Psalm/Type/Atomic/TTrue.php +++ b/src/Psalm/Type/Atomic/TTrue.php @@ -17,7 +17,7 @@ public function getKey(bool $include_extra = true): string return 'true'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TTypeAlias.php b/src/Psalm/Type/Atomic/TTypeAlias.php index 788669128b7..9341e2e4a97 100644 --- a/src/Psalm/Type/Atomic/TTypeAlias.php +++ b/src/Psalm/Type/Atomic/TTypeAlias.php @@ -70,13 +70,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TValueOfClassConstant.php b/src/Psalm/Type/Atomic/TValueOfClassConstant.php index cbeb6b4c241..6821650bae1 100644 --- a/src/Psalm/Type/Atomic/TValueOfClassConstant.php +++ b/src/Psalm/Type/Atomic/TValueOfClassConstant.php @@ -44,13 +44,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { return null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/src/Psalm/Type/Atomic/TVoid.php b/src/Psalm/Type/Atomic/TVoid.php index cec58cd4e99..4241c5e0818 100644 --- a/src/Psalm/Type/Atomic/TVoid.php +++ b/src/Psalm/Type/Atomic/TVoid.php @@ -26,15 +26,12 @@ public function toPhpString( ?string $namespace, array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { - return $php_major_version > 7 - || ($php_major_version === 7 && $php_minor_version >= 1) - ? $this->getKey() : null; + return $analysis_php_version_id >= 70100 ? $this->getKey() : null; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return true; } diff --git a/src/Psalm/Type/Union.php b/src/Psalm/Type/Union.php index d43fb967936..5972e03a12a 100644 --- a/src/Psalm/Type/Union.php +++ b/src/Psalm/Type/Union.php @@ -511,17 +511,16 @@ public function toNamespacedString( */ public function toPhpString( ?string $namespace, - array $aliased_classes, + array $aliased_classes, ?string $this_class, - int $php_major_version, - int $php_minor_version + int $analysis_php_version_id ): ?string { if (!$this->isSingleAndMaybeNullable()) { - if ($php_major_version < 8) { + if ($analysis_php_version_id < 80000) { return null; } - } elseif ($php_major_version < 7 - || (isset($this->types['null']) && $php_major_version === 7 && $php_minor_version < 1) + } elseif ($analysis_php_version_id < 70000 + || (isset($this->types['null']) && $analysis_php_version_id < 70100) ) { return null; } @@ -551,8 +550,7 @@ public function toPhpString( $namespace, $aliased_classes, $this_class, - $php_major_version, - $php_minor_version + $analysis_php_version_id ); if (!$php_type) { @@ -571,7 +569,7 @@ public function toPhpString( return implode('|', array_unique($php_types)); } - if ($php_major_version < 8) { + if ($analysis_php_version_id < 80000) { return ($nullable ? '?' : '') . implode('|', array_unique($php_types)); } if ($nullable) { @@ -580,9 +578,9 @@ public function toPhpString( return implode('|', array_unique($php_types)); } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { - if (!$this->isSingleAndMaybeNullable() && $php_major_version < 8) { + if (!$this->isSingleAndMaybeNullable() && $analysis_php_version_id < 80000) { return false; } @@ -598,8 +596,8 @@ public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_ return !array_filter( $types, - function ($atomic_type) use ($php_major_version, $php_minor_version) { - return !$atomic_type->canBeFullyExpressedInPhp($php_major_version, $php_minor_version); + function ($atomic_type) use ($analysis_php_version_id) { + return !$atomic_type->canBeFullyExpressedInPhp($analysis_php_version_id); } ); } diff --git a/tests/AlgebraTest.php b/tests/AlgebraTest.php index ac5c42f0f79..406e66816d6 100644 --- a/tests/AlgebraTest.php +++ b/tests/AlgebraTest.php @@ -85,7 +85,7 @@ public function testCombinatorialExpansion(): void $has_errors = false; - $dnf_stmt = StatementsProvider::parseStatements($dnf, '7.4', $has_errors)[0]; + $dnf_stmt = StatementsProvider::parseStatements($dnf, 70400, $has_errors)[0]; $this->assertInstanceOf(PhpParser\Node\Stmt\Expression::class, $dnf_stmt); diff --git a/tests/Config/Plugin/Hook/StringProvider/TSqlSelectString.php b/tests/Config/Plugin/Hook/StringProvider/TSqlSelectString.php index 8540f3bd097..4be059215ef 100644 --- a/tests/Config/Plugin/Hook/StringProvider/TSqlSelectString.php +++ b/tests/Config/Plugin/Hook/StringProvider/TSqlSelectString.php @@ -19,7 +19,7 @@ public function getId(bool $nested = true): string return 'sql-select-string(' . $this->value . ')'; } - public function canBeFullyExpressedInPhp(int $php_major_version, int $php_minor_version): bool + public function canBeFullyExpressedInPhp(int $analysis_php_version_id): bool { return false; } diff --git a/tests/FileDiffTest.php b/tests/FileDiffTest.php index 86b8e0ee105..f634abbc530 100644 --- a/tests/FileDiffTest.php +++ b/tests/FileDiffTest.php @@ -37,8 +37,8 @@ public function testCode( $has_errors = false; - $a_stmts = StatementsProvider::parseStatements($a, '7.4', $has_errors); - $b_stmts = StatementsProvider::parseStatements($b, '7.4', $has_errors); + $a_stmts = StatementsProvider::parseStatements($a, 70400, $has_errors); + $b_stmts = StatementsProvider::parseStatements($b, 70400, $has_errors); $diff = FileStatementsDiffer::diff($a_stmts, $b_stmts, $a, $b); @@ -101,7 +101,7 @@ public function testPartialAstDiff( $has_errors = false; - $a_stmts = StatementsProvider::parseStatements($a, '7.4', $has_errors); + $a_stmts = StatementsProvider::parseStatements($a, 70400, $has_errors); $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new CloningVisitor); @@ -111,8 +111,8 @@ public function testPartialAstDiff( $this->assertTreesEqual($a_stmts, $a_stmts_copy); - $b_stmts = StatementsProvider::parseStatements($b, '7.4', $has_errors, null, $a, $a_stmts_copy, $file_changes); - $b_clean_stmts = StatementsProvider::parseStatements($b, '7.4', $has_errors); + $b_stmts = StatementsProvider::parseStatements($b, 70400, $has_errors, null, $a, $a_stmts_copy, $file_changes); + $b_clean_stmts = StatementsProvider::parseStatements($b, 70400, $has_errors); $this->assertTreesEqual($b_clean_stmts, $b_stmts);