From 0e1f34b5b31d723068290bcaf136f4a2e84cce3c 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 | 26 +++++++++- 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 | 9 ++-- .../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 | 6 ++- .../Codebase/InternalCallMapHandler.php | 4 +- .../Reflector/ClassLikeDocblockParser.php | 2 +- .../Reflector/ClassLikeNodeScanner.php | 3 +- .../Reflector/ExpressionResolver.php | 2 +- .../Reflector/FunctionLikeNodeScanner.php | 25 +++++----- .../PhpVisitor/Reflector/TypeHintResolver.php | 16 +++--- .../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, 276 insertions(+), 336 deletions(-) diff --git a/examples/TemplateScanner.php b/examples/TemplateScanner.php index 86afa8766a4..bf83f1d3eb0 100644 --- a/examples/TemplateScanner.php +++ b/examples/TemplateScanner.php @@ -24,7 +24,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 ca16490678d..5c339120550 100644 --- a/src/Psalm/Codebase.php +++ b/src/Psalm/Codebase.php @@ -35,6 +35,7 @@ use function explode; use function implode; use function in_array; +use function intdiv; use function is_string; use function krsort; use function ksort; @@ -48,6 +49,7 @@ use const PHP_MAJOR_VERSION; use const PHP_MINOR_VERSION; +use const PHP_VERSION_ID; class Codebase { @@ -270,14 +272,21 @@ class Codebase /** * @var int + * @deprecated will be removed in Psalm 5. Please use Codebase::$analysis_php_version_id */ public $php_major_version = PHP_MAJOR_VERSION; /** * @var int + * @deprecated will be removed in Psalm 5. Please use Codebase::$analysis_php_version_id */ public $php_minor_version = PHP_MINOR_VERSION; + /** + * @var int + */ + public $analysis_php_version_id = PHP_VERSION_ID; + /** * @var bool */ @@ -489,7 +498,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 ); } @@ -1967,4 +1976,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 a3ab486f8f0..7d350d7b838 100644 --- a/src/Psalm/Config.php +++ b/src/Psalm/Config.php @@ -1821,7 +1821,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)) { @@ -1831,7 +1831,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)) { @@ -1882,12 +1882,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 b7f4e5471a6..fe58d3acab8 100644 --- a/src/Psalm/Internal/Analyzer/ClassAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ClassAnalyzer.php @@ -1617,8 +1617,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( @@ -1627,8 +1626,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(), @@ -1642,7 +1640,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 a8d45b1dea2..8413ddb957c 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 322d931889f..61e3af9e987 100644 --- a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php @@ -1416,7 +1416,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 @@ -1430,8 +1430,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 74fcc847621..29fa923eeb9 100644 --- a/src/Psalm/Internal/Analyzer/MethodComparator.php +++ b/src/Psalm/Internal/Analyzer/MethodComparator.php @@ -82,7 +82,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 ); @@ -565,9 +565,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, @@ -581,7 +579,7 @@ private static function compareMethodSignatureParams( if (!$is_contained_by) { $config = \Psalm\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 @@ -867,9 +865,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, @@ -879,7 +875,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 d0d1766750e..7c6b106b033 100644 --- a/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php @@ -1273,16 +1273,15 @@ public function setPhpVersion(string $version): 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 \Psalm\Internal\Provider\StatementsProvider::clearLexer(); \Psalm\Internal\Provider\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; } /** diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php index 24e31b3dfd1..60c4de5d95d 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php @@ -490,9 +490,7 @@ private static function handleUnpackedArray( if ($unpacked_atomic_type instanceof Type\Atomic\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) { if (IssueBuffer::accepts( new DuplicateArrayKey( 'String keys are not supported in unpacked arrays', @@ -537,9 +535,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) { if (IssueBuffer::accepts( 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 3018183c3ec..bdbeefe9162 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php @@ -467,7 +467,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]) ) { @@ -535,7 +535,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; @@ -563,7 +563,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 ), @@ -573,7 +573,7 @@ private static function checkFunctionLikeTypeMatches( } } if ($invalid_string_key) { - if ($codebase->php_major_version < 8) { + if ($codebase->analysis_php_version_id < 80000) { if (IssueBuffer::accepts( 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 c6f2f9198bf..1a380d281b2 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php @@ -77,7 +77,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()) ) ] ]; @@ -87,8 +87,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 78080557a71..572bd3e5af0 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php @@ -544,7 +544,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()) ) ] ]; @@ -554,8 +554,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 da6cea51fbc..66954aec662 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php @@ -495,7 +495,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()) ) ] ]; @@ -505,8 +505,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 e6dc20960fb..080e0ee7157 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php @@ -242,7 +242,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 b720c61b0c3..e4835ce7b5b 100644 --- a/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php @@ -438,20 +438,20 @@ private static function handleExpression( return Expression\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 Expression\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 Expression\NullsafeAnalyzer::analyze($statements_analyzer, $stmt, $context); } @@ -464,7 +464,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 dc4dce52473..270db41c98b 100644 --- a/src/Psalm/Internal/Codebase/ClassLikes.php +++ b/src/Psalm/Internal/Codebase/ClassLikes.php @@ -6,6 +6,7 @@ use Psalm\Config; use Psalm\Exception\UnpopulatedClasslikeException; use Psalm\Internal\Analyzer\ClassLikeAnalyzer; +use Psalm\Internal\Analyzer\ProjectAnalyzer; use Psalm\Internal\FileManipulation\ClassDocblockManipulator; use Psalm\Internal\FileManipulation\FileManipulationBuffer; use Psalm\Internal\Provider\ClassLikeStorageProvider; @@ -784,7 +785,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 \Psalm\Internal\PhpVisitor\TraitFinder($fq_trait_name); diff --git a/src/Psalm/Internal/Codebase/InternalCallMapHandler.php b/src/Psalm/Internal/Codebase/InternalCallMapHandler.php index f79ef431b81..883b28e4d18 100644 --- a/src/Psalm/Internal/Codebase/InternalCallMapHandler.php +++ b/src/Psalm/Internal/Codebase/InternalCallMapHandler.php @@ -340,8 +340,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 8c62963a24b..9a7d5e8c682 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeDocblockParser.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeDocblockParser.php @@ -416,7 +416,7 @@ public static function parse( $statements = \Psalm\Internal\Provider\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 bb39e3af390..3af33029cd0 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php @@ -1407,8 +1407,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 c6df451a7b8..9f4cbb11b0f 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/ExpressionResolver.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/ExpressionResolver.php @@ -322,7 +322,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 4d85c3c8413..dee0a24c1ac 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php @@ -415,8 +415,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( @@ -467,12 +466,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; } @@ -810,8 +811,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) { @@ -1031,11 +1031,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; } @@ -1060,7 +1063,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 817127a4484..7374268e7a3 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/TypeHintResolver.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/TypeHintResolver.php @@ -19,12 +19,11 @@ class TypeHintResolver */ public static function resolve( PhpParser\NodeAbstract $hint, - CodebaseScanner $scanner, - FileStorage $file_storage, - ?ClassLikeStorage $classlike_storage, - Aliases $aliases, - int $php_major_version, - int $php_minor_version + CodebaseScanner $scanner, + FileStorage $file_storage, + ?ClassLikeStorage $classlike_storage, + Aliases $aliases, + int $analysis_php_version_id ) : Type\Union { if ($hint instanceof PhpParser\Node\UnionType) { $type = null; @@ -40,8 +39,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); @@ -89,7 +87,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 d528efca609..97c739bf763 100644 --- a/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php +++ b/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php @@ -225,7 +225,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 60035ada831..077205b2547 100644 --- a/src/Psalm/Internal/Provider/StatementsProvider.php +++ b/src/Psalm/Internal/Provider/StatementsProvider.php @@ -2,6 +2,7 @@ namespace Psalm\Internal\Provider; use PhpParser; +use Psalm\Codebase; use Psalm\Progress\Progress; use Psalm\Progress\VoidProgress; @@ -95,8 +96,11 @@ public function __construct( /** * @return list<\PhpParser\Node\Stmt> */ - 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) { @@ -119,7 +123,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 ?: []; } @@ -182,7 +186,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, @@ -403,22 +407,24 @@ public function resetDiffs(): void * @return list<\PhpParser\Node\Stmt> */ 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 c4c97f3a497..d12c5d4c97e 100644 --- a/src/Psalm/Internal/Scanner/FileScanner.php +++ b/src/Psalm/Internal/Scanner/FileScanner.php @@ -57,7 +57,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 efce50c0472..4e4e2fb984d 100644 --- a/src/Psalm/Internal/Stubs/Generator/StubsGenerator.php +++ b/src/Psalm/Internal/Stubs/Generator/StubsGenerator.php @@ -300,7 +300,7 @@ public static function getParserTypeFromPsalmType(Type\Union $type): ?PhpParser\ || $atomic_type instanceof Type\Atomic\TArray || $atomic_type instanceof Type\Atomic\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 d9dd94888d7..aea1be31467 100644 --- a/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php +++ b/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php @@ -522,7 +522,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 ab0da4d455b..4726bc6de1a 100644 --- a/src/Psalm/Internal/Type/TypeParser.php +++ b/src/Psalm/Internal/Type/TypeParser.php @@ -66,7 +66,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 { @@ -82,9 +82,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; @@ -98,7 +98,7 @@ public static function parseTokens( $parsed_type = self::getTypeFromTree( $parse_tree, $codebase, - $php_version, + $analysis_php_version_id, $template_type_map, $type_aliases ); @@ -111,18 +111,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 ParseTree\GenericTree) { return self::getTypeFromGenericTree( @@ -339,9 +338,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 f425d4c7caa..772df98de88 100644 --- a/src/Psalm/Internal/Type/TypeTokenizer.php +++ b/src/Psalm/Internal/Type/TypeTokenizer.php @@ -298,14 +298,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); @@ -328,14 +325,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 edd7dedeb5f..ab6d3aa35a5 100644 --- a/src/Psalm/Type.php +++ b/src/Psalm/Type.php @@ -68,14 +68,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 cbcdbdb3efb..cc6641d1c23 100644 --- a/src/Psalm/Type/Atomic.php +++ b/src/Psalm/Type/Atomic.php @@ -91,15 +91,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': @@ -115,10 +115,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(); } @@ -128,20 +125,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(); } @@ -153,10 +144,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(); } @@ -199,7 +187,7 @@ public static function create( return new Type\Atomic\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': @@ -209,33 +197,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(); } @@ -602,11 +590,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 cfb40635155..fe17813258e 100644 --- a/src/Psalm/Type/Atomic/CallableTrait.php +++ b/src/Psalm/Type/Atomic/CallableTrait.php @@ -136,8 +136,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 99c8d33b955..ec583246f56 100644 --- a/src/Psalm/Type/Atomic/Scalar.php +++ b/src/Psalm/Type/Atomic/Scalar.php @@ -3,7 +3,7 @@ abstract class Scalar extends \Psalm\Type\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 0388065e725..559b104e8fd 100644 --- a/src/Psalm/Type/Atomic/TAnonymousClassInstance.php +++ b/src/Psalm/Type/Atomic/TAnonymousClassInstance.php @@ -25,12 +25,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 0a975c99f75..6d1afcb27cb 100644 --- a/src/Psalm/Type/Atomic/TArray.php +++ b/src/Psalm/Type/Atomic/TArray.php @@ -45,13 +45,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 3960ea04cf2..e017b191fc2 100644 --- a/src/Psalm/Type/Atomic/TArrayKey.php +++ b/src/Psalm/Type/Atomic/TArrayKey.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 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 0e7fbd29c4a..3ae5e9594b7 100644 --- a/src/Psalm/Type/Atomic/TAssertionFalsy.php +++ b/src/Psalm/Type/Atomic/TAssertionFalsy.php @@ -28,13 +28,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 04ae8eb7ec2..fe98cd21b1d 100644 --- a/src/Psalm/Type/Atomic/TBool.php +++ b/src/Psalm/Type/Atomic/TBool.php @@ -23,9 +23,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 e8317ec3dcb..496874cc117 100644 --- a/src/Psalm/Type/Atomic/TCallable.php +++ b/src/Psalm/Type/Atomic/TCallable.php @@ -20,13 +20,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 5fb4308ab0a..c50fddb54c9 100644 --- a/src/Psalm/Type/Atomic/TCallableObject.php +++ b/src/Psalm/Type/Atomic/TCallableObject.php @@ -23,15 +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 $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 25b1edb0d4e..757a528e085 100644 --- a/src/Psalm/Type/Atomic/TCallableString.php +++ b/src/Psalm/Type/Atomic/TCallableString.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/TClassConstant.php b/src/Psalm/Type/Atomic/TClassConstant.php index 5a8182e1c6d..e2357700410 100644 --- a/src/Psalm/Type/Atomic/TClassConstant.php +++ b/src/Psalm/Type/Atomic/TClassConstant.php @@ -45,13 +45,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 06365f1157a..053dd06ad8e 100644 --- a/src/Psalm/Type/Atomic/TClassString.php +++ b/src/Psalm/Type/Atomic/TClassString.php @@ -62,8 +62,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'; } @@ -100,7 +99,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 70e3b05466a..24353a58291 100644 --- a/src/Psalm/Type/Atomic/TClassStringMap.php +++ b/src/Psalm/Type/Atomic/TClassStringMap.php @@ -118,13 +118,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 4715c75be3c..3834e237ea3 100644 --- a/src/Psalm/Type/Atomic/TClosedResource.php +++ b/src/Psalm/Type/Atomic/TClosedResource.php @@ -28,13 +28,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 356a932457a..f08b7fe1b7e 100644 --- a/src/Psalm/Type/Atomic/TClosure.php +++ b/src/Psalm/Type/Atomic/TClosure.php @@ -11,7 +11,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 57bee722607..d0371bee20e 100644 --- a/src/Psalm/Type/Atomic/TConditional.php +++ b/src/Psalm/Type/Atomic/TConditional.php @@ -104,8 +104,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; } @@ -128,7 +127,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 78da4f4adf5..ac44c2d9a24 100644 --- a/src/Psalm/Type/Atomic/TDependentGetClass.php +++ b/src/Psalm/Type/Atomic/TDependentGetClass.php @@ -54,7 +54,7 @@ public function getReplacement() : \Psalm\Type\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 cdd7ed24b0a..0283ee31788 100644 --- a/src/Psalm/Type/Atomic/TDependentGetDebugType.php +++ b/src/Psalm/Type/Atomic/TDependentGetDebugType.php @@ -36,7 +36,7 @@ public function getReplacement() : \Psalm\Type\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 777b7abb00a..fae40d0409f 100644 --- a/src/Psalm/Type/Atomic/TDependentGetType.php +++ b/src/Psalm/Type/Atomic/TDependentGetType.php @@ -21,7 +21,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 396c45c6bf3..0fbecef60ad 100644 --- a/src/Psalm/Type/Atomic/TDependentListKey.php +++ b/src/Psalm/Type/Atomic/TDependentListKey.php @@ -41,7 +41,7 @@ public function getReplacement() : \Psalm\Type\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 992178047ca..2fcdf3cccb2 100644 --- a/src/Psalm/Type/Atomic/TEmpty.php +++ b/src/Psalm/Type/Atomic/TEmpty.php @@ -25,8 +25,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 2040d59de0f..4ede1104f59 100644 --- a/src/Psalm/Type/Atomic/TEnumCase.php +++ b/src/Psalm/Type/Atomic/TEnumCase.php @@ -32,13 +32,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 dfd18a4303a..e74414455fb 100644 --- a/src/Psalm/Type/Atomic/TFalse.php +++ b/src/Psalm/Type/Atomic/TFalse.php @@ -16,7 +16,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 902e2bb7295..784c7c093ab 100644 --- a/src/Psalm/Type/Atomic/TFloat.php +++ b/src/Psalm/Type/Atomic/TFloat.php @@ -23,9 +23,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 ede08182bb6..ca6e4415540 100644 --- a/src/Psalm/Type/Atomic/TGenericObject.php +++ b/src/Psalm/Type/Atomic/TGenericObject.php @@ -55,7 +55,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; } @@ -67,16 +67,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 61cd5040217..ee0b360c0b0 100644 --- a/src/Psalm/Type/Atomic/THtmlEscapedString.php +++ b/src/Psalm/Type/Atomic/THtmlEscapedString.php @@ -16,7 +16,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 51f7bbb4641..c7551634928 100644 --- a/src/Psalm/Type/Atomic/TInt.php +++ b/src/Psalm/Type/Atomic/TInt.php @@ -23,9 +23,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 abb1e0cbfe7..efe239dde65 100644 --- a/src/Psalm/Type/Atomic/TIntMask.php +++ b/src/Psalm/Type/Atomic/TIntMask.php @@ -63,7 +63,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 de4f36c296c..5abb5daa694 100644 --- a/src/Psalm/Type/Atomic/TIntMaskOf.php +++ b/src/Psalm/Type/Atomic/TIntMaskOf.php @@ -47,7 +47,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 0f8032e3871..67658f6c1e0 100644 --- a/src/Psalm/Type/Atomic/TIntRange.php +++ b/src/Psalm/Type/Atomic/TIntRange.php @@ -37,7 +37,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 9169cee9ee2..22578895947 100644 --- a/src/Psalm/Type/Atomic/TIterable.php +++ b/src/Psalm/Type/Atomic/TIterable.php @@ -86,16 +86,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 53de5f0c493..f2c626b23ef 100644 --- a/src/Psalm/Type/Atomic/TKeyOfClassConstant.php +++ b/src/Psalm/Type/Atomic/TKeyOfClassConstant.php @@ -46,13 +46,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 8563f094413..c7ab3aa21bf 100644 --- a/src/Psalm/Type/Atomic/TKeyedArray.php +++ b/src/Psalm/Type/Atomic/TKeyedArray.php @@ -190,13 +190,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 05781ad092c..c2db46d8fdb 100644 --- a/src/Psalm/Type/Atomic/TList.php +++ b/src/Psalm/Type/Atomic/TList.php @@ -91,13 +91,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 564d6c7cd00..e2e59d31cb8 100644 --- a/src/Psalm/Type/Atomic/TLiteralClassString.php +++ b/src/Psalm/Type/Atomic/TLiteralClassString.php @@ -41,13 +41,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 b8414be8c21..151d8638782 100644 --- a/src/Psalm/Type/Atomic/TLowercaseString.php +++ b/src/Psalm/Type/Atomic/TLowercaseString.php @@ -8,7 +8,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 1f5be9821b1..4229090dd41 100644 --- a/src/Psalm/Type/Atomic/TMixed.php +++ b/src/Psalm/Type/Atomic/TMixed.php @@ -31,15 +31,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 0e57467f809..4d83ffe0dd0 100644 --- a/src/Psalm/Type/Atomic/TNamedObject.php +++ b/src/Psalm/Type/Atomic/TNamedObject.php @@ -117,32 +117,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 bf248844931..29b2226f9cd 100644 --- a/src/Psalm/Type/Atomic/TNever.php +++ b/src/Psalm/Type/Atomic/TNever.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/TNonEmptyLowercaseString.php b/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php index 3ab6ab6bf6b..8b0a9afcb87 100644 --- a/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php +++ b/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php @@ -14,7 +14,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 09481333a4f..194c1818eb9 100644 --- a/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php +++ b/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php @@ -12,7 +12,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 4d57f63782e..01bac528893 100644 --- a/src/Psalm/Type/Atomic/TNonspecificLiteralString.php +++ b/src/Psalm/Type/Atomic/TNonspecificLiteralString.php @@ -12,7 +12,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 ae65c98244a..6b33c82103e 100644 --- a/src/Psalm/Type/Atomic/TNull.php +++ b/src/Psalm/Type/Atomic/TNull.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 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 22be75706bc..8f6a1b7c3a0 100644 --- a/src/Psalm/Type/Atomic/TNumeric.php +++ b/src/Psalm/Type/Atomic/TNumeric.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 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 7579737c994..4e97d328559 100644 --- a/src/Psalm/Type/Atomic/TNumericString.php +++ b/src/Psalm/Type/Atomic/TNumericString.php @@ -21,7 +21,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 508b0524175..84cd237a360 100644 --- a/src/Psalm/Type/Atomic/TObject.php +++ b/src/Psalm/Type/Atomic/TObject.php @@ -23,16 +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 $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 90d555059a4..1144a192400 100644 --- a/src/Psalm/Type/Atomic/TObjectWithProperties.php +++ b/src/Psalm/Type/Atomic/TObjectWithProperties.php @@ -172,13 +172,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 72711c5295a..6760bf2dbf3 100644 --- a/src/Psalm/Type/Atomic/TPositiveInt.php +++ b/src/Psalm/Type/Atomic/TPositiveInt.php @@ -19,7 +19,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 0919324d71c..dca0bd31f6d 100644 --- a/src/Psalm/Type/Atomic/TResource.php +++ b/src/Psalm/Type/Atomic/TResource.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 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 320ab67c1cd..942630490d0 100644 --- a/src/Psalm/Type/Atomic/TScalar.php +++ b/src/Psalm/Type/Atomic/TScalar.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/TString.php b/src/Psalm/Type/Atomic/TString.php index 2d059e9e417..985400743dd 100644 --- a/src/Psalm/Type/Atomic/TString.php +++ b/src/Psalm/Type/Atomic/TString.php @@ -13,10 +13,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 4af9887df04..7f2e5ae9139 100644 --- a/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php +++ b/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php @@ -50,13 +50,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 b9e5ebc2117..32a9878612f 100644 --- a/src/Psalm/Type/Atomic/TTemplateParam.php +++ b/src/Psalm/Type/Atomic/TTemplateParam.php @@ -79,8 +79,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; } @@ -119,7 +118,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 d1fa1ab7816..495d7ccaada 100644 --- a/src/Psalm/Type/Atomic/TTraitString.php +++ b/src/Psalm/Type/Atomic/TTraitString.php @@ -28,8 +28,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'; } @@ -47,7 +46,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 b6e0be7a5bd..609daebcc1b 100644 --- a/src/Psalm/Type/Atomic/TTrue.php +++ b/src/Psalm/Type/Atomic/TTrue.php @@ -16,7 +16,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 1003c288c4e..a2b85b0ed89 100644 --- a/src/Psalm/Type/Atomic/TTypeAlias.php +++ b/src/Psalm/Type/Atomic/TTypeAlias.php @@ -67,13 +67,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 09918e0afbe..884a5ce11bd 100644 --- a/src/Psalm/Type/Atomic/TValueOfClassConstant.php +++ b/src/Psalm/Type/Atomic/TValueOfClassConstant.php @@ -40,13 +40,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 cd469a96d59..51c9134cc1a 100644 --- a/src/Psalm/Type/Atomic/TVoid.php +++ b/src/Psalm/Type/Atomic/TVoid.php @@ -23,15 +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 $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 89aaaae177a..098dd166c20 100644 --- a/src/Psalm/Type/Union.php +++ b/src/Psalm/Type/Union.php @@ -479,17 +479,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; } @@ -519,8 +518,7 @@ public function toPhpString( $namespace, $aliased_classes, $this_class, - $php_major_version, - $php_minor_version + $analysis_php_version_id ); if (!$php_type) { @@ -539,7 +537,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) { @@ -548,9 +546,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; } @@ -566,8 +564,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 5ec14bf3cae..6231f5d938d 100644 --- a/tests/AlgebraTest.php +++ b/tests/AlgebraTest.php @@ -81,7 +81,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 0db87afd3e8..45b5f700b1b 100644 --- a/tests/Config/Plugin/Hook/StringProvider/TSqlSelectString.php +++ b/tests/Config/Plugin/Hook/StringProvider/TSqlSelectString.php @@ -16,7 +16,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 2afb1c9e457..0807ebd6d07 100644 --- a/tests/FileDiffTest.php +++ b/tests/FileDiffTest.php @@ -32,8 +32,8 @@ public function testCode( $has_errors = false; - $a_stmts = \Psalm\Internal\Provider\StatementsProvider::parseStatements($a, '7.4', $has_errors); - $b_stmts = \Psalm\Internal\Provider\StatementsProvider::parseStatements($b, '7.4', $has_errors); + $a_stmts = \Psalm\Internal\Provider\StatementsProvider::parseStatements($a, 70400, $has_errors); + $b_stmts = \Psalm\Internal\Provider\StatementsProvider::parseStatements($b, 70400, $has_errors); $diff = \Psalm\Internal\Diff\FileStatementsDiffer::diff($a_stmts, $b_stmts, $a, $b); @@ -96,7 +96,7 @@ public function testPartialAstDiff( $has_errors = false; - $a_stmts = \Psalm\Internal\Provider\StatementsProvider::parseStatements($a, '7.4', $has_errors); + $a_stmts = \Psalm\Internal\Provider\StatementsProvider::parseStatements($a, 70400, $has_errors); $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new \Psalm\Internal\PhpVisitor\CloningVisitor); @@ -106,8 +106,8 @@ public function testPartialAstDiff( $this->assertTreesEqual($a_stmts, $a_stmts_copy); - $b_stmts = \Psalm\Internal\Provider\StatementsProvider::parseStatements($b, '7.4', $has_errors, null, $a, $a_stmts_copy, $file_changes); - $b_clean_stmts = \Psalm\Internal\Provider\StatementsProvider::parseStatements($b, '7.4', $has_errors); + $b_stmts = \Psalm\Internal\Provider\StatementsProvider::parseStatements($b, 70400, $has_errors, null, $a, $a_stmts_copy, $file_changes); + $b_clean_stmts = \Psalm\Internal\Provider\StatementsProvider::parseStatements($b, 70400, $has_errors); $this->assertTreesEqual($b_clean_stmts, $b_stmts);