Skip to content

Commit

Permalink
Merge pull request #6898 from orklah/php-version-consistency
Browse files Browse the repository at this point in the history
  • Loading branch information
weirdan committed Jan 3, 2022
2 parents 3366eef + ba4a25b commit 2f50070
Show file tree
Hide file tree
Showing 95 changed files with 388 additions and 350 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr-labels.yml
Expand Up @@ -10,4 +10,4 @@ jobs:
with:
mode: minimum
count: 1
labels: "release:typo, release:fix, release:feature, release:deprecation, release:internal, release:docs"
labels: "release:typo, release:fix, release:feature, release:deprecation, release:internal, release:docs, release:removed"
123 changes: 123 additions & 0 deletions UPGRADING.md
@@ -0,0 +1,123 @@
# Upgrading from Psalm 4 to Psalm 5
## Changed
- [BC] The parameter `$php_version` of `Psalm\Type\Atomic::create()` renamed
to `$analysis_php_version_id` and changed from `array|null` to `int|null`.
Previously it accepted PHP version as `array{major_version, minor_version}`
while now it accepts version ID, similar to how [`PHP_VERSION_ID` is
calculated](https://www.php.net/manual/en/reserved.constants.php#constant.php-version-id).

- [BC] The parameter `$php_version` of `Psalm\Type::parseString()` renamed to
`$analysis_php_version_id` and changed from `array|null` to `int|null`.
Previously it accepted PHP version as `array{major_version, minor_version}`
while now it accepts version ID.

- [BC] Parameter 0 of `canBeFullyExpressedInPhp()` of the classes listed below
changed name from `php_major_version` to `analysis_php_version_id`.
Previously it accepted major PHP version as int (e.g. `7`), while now it
accepts version ID. Classes affected:
- `Psalm\Type\Atomic`
- `Psalm\Type\Atomic\Scalar`
- `Psalm\Type\Atomic\TArray`
- `Psalm\Type\Atomic\TArrayKey`
- `Psalm\Type\Atomic\TAssertionFalsy`
- `Psalm\Type\Atomic\TCallable`
- `Psalm\Type\Atomic\TCallableObject`
- `Psalm\Type\Atomic\TCallableString`
- `Psalm\Type\Atomic\TClassConstant`
- `Psalm\Type\Atomic\TClassString`
- `Psalm\Type\Atomic\TClassStringMap`
- `Psalm\Type\Atomic\TClosedResource`
- `Psalm\Type\Atomic\TClosure`
- `Psalm\Type\Atomic\TConditional`
- `Psalm\Type\Atomic\TDependentGetClass`
- `Psalm\Type\Atomic\TDependentGetDebugType`
- `Psalm\Type\Atomic\TDependentGetType`
- `Psalm\Type\Atomic\TDependentListKey`
- `Psalm\Type\Atomic\TEnumCase`
- `Psalm\Type\Atomic\TFalse`
- `Psalm\Type\Atomic\TGenericObject`
- `Psalm\Type\Atomic\THtmlEscapedString`
- `Psalm\Type\Atomic\TIntMask`
- `Psalm\Type\Atomic\TIntMaskOf`
- `Psalm\Type\Atomic\TIntRange`
- `Psalm\Type\Atomic\TIterable`
- `Psalm\Type\Atomic\TKeyedArray`
- `Psalm\Type\Atomic\TKeyOfClassConstant`
- `Psalm\Type\Atomic\TList`
- `Psalm\Type\Atomic\TLiteralClassString`
- `Psalm\Type\Atomic\TLowercaseString`
- `Psalm\Type\Atomic\TMixed`
- `Psalm\Type\Atomic\TNamedObject`
- `Psalm\Type\Atomic\TNever`
- `Psalm\Type\Atomic\TNonEmptyLowercaseString`
- `Psalm\Type\Atomic\TNonspecificLiteralInt`
- `Psalm\Type\Atomic\TNonspecificLiteralString`
- `Psalm\Type\Atomic\TNull`
- `Psalm\Type\Atomic\TNumeric`
- `Psalm\Type\Atomic\TNumericString`
- `Psalm\Type\Atomic\TObject`
- `Psalm\Type\Atomic\TObjectWithProperties`
- `Psalm\Type\Atomic\TPositiveInt`
- `Psalm\Type\Atomic\TResource`
- `Psalm\Type\Atomic\TScalar`
- `Psalm\Type\Atomic\TTemplateIndexedAccess`
- `Psalm\Type\Atomic\TTemplateParam`
- `Psalm\Type\Atomic\TTraitString`
- `Psalm\Type\Atomic\TTrue`
- `Psalm\Type\Atomic\TTypeAlias`
- `Psalm\Type\Atomic\TValueOfClassConstant`
- `Psalm\Type\Atomic\TVoid`
- `Psalm\Type\Union`

- [BC] Parameter 3 of `toPhpString()` of methods listed below changed name
from `php_major_version` to `analysis_php_version_id`. Previously it
accepted major PHP version as int (e.g. `7`), while now it accepts version
ID. Classes affected:
- `Psalm\Type\Atomic`
- `Psalm\Type\Atomic\CallableTrait`
- `Psalm\Type\Atomic\TAnonymousClassInstance`
- `Psalm\Type\Atomic\TArray`
- `Psalm\Type\Atomic\TArrayKey`
- `Psalm\Type\Atomic\TAssertionFalsy`
- `Psalm\Type\Atomic\TBool`
- `Psalm\Type\Atomic\TCallable`
- `Psalm\Type\Atomic\TCallableObject`
- `Psalm\Type\Atomic\TClassConstant`
- `Psalm\Type\Atomic\TClassString`
- `Psalm\Type\Atomic\TClassStringMap`
- `Psalm\Type\Atomic\TClosedResource`
- `Psalm\Type\Atomic\TConditional`
- `Psalm\Type\Atomic\TEmpty`
- `Psalm\Type\Atomic\TEnumCase`
- `Psalm\Type\Atomic\TFloat`
- `Psalm\Type\Atomic\TGenericObject`
- `Psalm\Type\Atomic\TInt`
- `Psalm\Type\Atomic\TIterable`
- `Psalm\Type\Atomic\TKeyedArray`
- `Psalm\Type\Atomic\TKeyOfClassConstant`
- `Psalm\Type\Atomic\TList`
- `Psalm\Type\Atomic\TLiteralClassString`
- `Psalm\Type\Atomic\TMixed`
- `Psalm\Type\Atomic\TNamedObject`
- `Psalm\Type\Atomic\TNever`
- `Psalm\Type\Atomic\TNull`
- `Psalm\Type\Atomic\TNumeric`
- `Psalm\Type\Atomic\TObject`
- `Psalm\Type\Atomic\TObjectWithProperties`
- `Psalm\Type\Atomic\TResource`
- `Psalm\Type\Atomic\TScalar`
- `Psalm\Type\Atomic\TString`
- `Psalm\Type\Atomic\TTemplateIndexedAccess`
- `Psalm\Type\Atomic\TTemplateParam`
- `Psalm\Type\Atomic\TTraitString`
- `Psalm\Type\Atomic\TTypeAlias`
- `Psalm\Type\Atomic\TValueOfClassConstant`
- `Psalm\Type\Atomic\TVoid`
- `Psalm\Type\Union`

## Removed
- [BC] Property `Psalm\Codebase::$php_major_version` was removed, use
`Psalm\Codebase::$analysis_php_version_id`.
- [BC] Property `Psalm\Codebase::$php_minor_version` was removed, use
`Psalm\Codebase::$analysis_php_version_id`.

2 changes: 1 addition & 1 deletion examples/TemplateScanner.php
Expand Up @@ -25,7 +25,7 @@ public function scan(
): void {
$stmts = $codebase->statements_provider->getStatementsForFile(
$file_storage->file_path,
'7.4',
70400,
$progress
);

Expand Down
32 changes: 17 additions & 15 deletions src/Psalm/Codebase.php
Expand Up @@ -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;
Expand All @@ -90,8 +91,6 @@
use function substr;
use function substr_count;

use const PHP_MAJOR_VERSION;
use const PHP_MINOR_VERSION;
use const PHP_VERSION_ID;

class Codebase
Expand Down Expand Up @@ -305,18 +304,6 @@ class Codebase
*/
public $allow_backwards_incompatible_changes = true;

/**
* @var int
* @deprecated Removed in Psalm 5, use Codebase::$analysis_php_version_id
*/
public $php_major_version = PHP_MAJOR_VERSION;

/**
* @var int
* @deprecated Removed in Psalm 5, use Codebase::$analysis_php_version_id
*/
public $php_minor_version = PHP_MINOR_VERSION;

/** @var int */
public $analysis_php_version_id = PHP_VERSION_ID;

Expand Down Expand Up @@ -534,7 +521,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
);
}
Expand Down Expand Up @@ -2010,4 +1997,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);
}
}
8 changes: 4 additions & 4 deletions src/Psalm/Config.php
Expand Up @@ -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)) {
Expand All @@ -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)) {
Expand Down Expand Up @@ -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;
}
Expand Down
8 changes: 3 additions & 5 deletions src/Psalm/Internal/Analyzer/ClassAnalyzer.php
Expand Up @@ -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(
Expand All @@ -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(),
Expand All @@ -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)
);
}

Expand Down
Expand Up @@ -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
Expand All @@ -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(),
Expand All @@ -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
);
}
Expand Down
5 changes: 2 additions & 3 deletions src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php
Expand Up @@ -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
Expand All @@ -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(),
Expand Down
14 changes: 5 additions & 9 deletions src/Psalm/Internal/Analyzer/MethodComparator.php
Expand Up @@ -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
);
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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
Expand Down
12 changes: 5 additions & 7 deletions src/Psalm/Internal/Analyzer/ProjectAnalyzer.php
Expand Up @@ -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':
Expand Down Expand Up @@ -1297,17 +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 = $php_major_version * 10000 + $php_minor_version * 100;
$this->codebase->analysis_php_version_id = $analysis_php_version_id;
$this->codebase->php_version_source = $source;
}

Expand Down

0 comments on commit 2f50070

Please sign in to comment.