Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Psalm v6 #10040

Merged
merged 13 commits into from
Jul 29, 2023
16 changes: 16 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,22 @@

- [BC] The `TDependentListKey` type was removed and replaced with an optional property of the `TIntRange` type.

- [BC] Property `Config::$shepherd_host` was replaced with `Config::$shepherd_endpoint`

- [BC] Methods `Codebase::getSymbolLocation()` and `Codebase::getSymbolInformation()` were replaced with `Codebase::getSymbolLocationByReference()`

- [BC] Method `Psalm\Type\Atomic\TKeyedArray::getList()` was removed

- [BC] Method `Psalm\Storage\FunctionLikeStorage::getSignature()` was replaced with `FunctionLikeStorage::getCompletionSignature()`

- [BC] Property `Psalm\Storage\FunctionLikeStorage::$unused_docblock_params` was replaced with `FunctionLikeStorage::$unused_docblock_parameters`

- [BC] Method `Plugin\Shepherd::getCurlErrorMessage()` was removed

- [BC] Property `Config::$find_unused_code` changed default value from false to true

- [BC] Property `Config::$find_unused_baseline_entry` changed default value from false to true

- [BC] The return type of `Psalm\Internal\LanguageServer\ProtocolWriter#write() changed from `Amp\Promise` to `void` due to the switch to Amp v3

# Upgrading from Psalm 4 to Psalm 5
Expand Down
48 changes: 1 addition & 47 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="dev-master@2e5235a0be1f106c251f69b4943ae4f027cef761">
<files psalm-version="dev-master@f799b68a3cbc91e9056bb972cfe66b7ae0da3f76">
<file src="examples/TemplateChecker.php">
<PossiblyUndefinedIntArrayOffset>
<code><![CDATA[$comment_block->tags['variablesfrom'][0]]]></code>
Expand All @@ -12,14 +12,6 @@
<code>$matches[1]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Codebase.php">
<PossiblyUndefinedIntArrayOffset>
<code>$const_name</code>
<code>$const_name</code>
<code>$symbol_name</code>
<code>$symbol_parts[1]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Config/FileFilter.php">
<PossiblyUndefinedIntArrayOffset>
<code><![CDATA[explode('::', $method_id)[1]]]></code>
Expand Down Expand Up @@ -379,9 +371,6 @@
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php">
<ComplexMethod>
<code>isContainedBy</code>
</ComplexMethod>
<PossiblyUndefinedIntArrayOffset>
<code><![CDATA[$array->properties[0]]]></code>
<code><![CDATA[$array->properties[0]]]></code>
Expand Down Expand Up @@ -502,11 +491,6 @@
<code>getMostSpecificTypeFromBounds</code>
</ImpureMethodCall>
</file>
<file src="src/Psalm/Type/Atomic/TCallableList.php">
<DeprecatedClass>
<code>TNonEmptyList</code>
</DeprecatedClass>
</file>
<file src="src/Psalm/Type/Atomic/TClassString.php">
<ImpureMethodCall>
<code>replace</code>
Expand All @@ -528,17 +512,7 @@
<code>replace</code>
</ImpureMethodCall>
</file>
<file src="src/Psalm/Type/Atomic/TDependentListKey.php">
<PossiblyUnusedMethod>
<code>__construct</code>
</PossiblyUnusedMethod>
</file>
<file src="src/Psalm/Type/Atomic/TKeyedArray.php">
<DeprecatedClass>
<code>TList</code>
<code><![CDATA[new TList($this->getGenericValueType())]]></code>
<code><![CDATA[new TNonEmptyList($this->getGenericValueType())]]></code>
</DeprecatedClass>
<ImpureMethodCall>
<code>combine</code>
<code>combine</code>
Expand All @@ -561,26 +535,6 @@
<code><![CDATA[$this->properties[0]]]></code>
<code><![CDATA[$this->properties[0]]]></code>
</PossiblyUndefinedIntArrayOffset>
<PossiblyUnusedMethod>
<code>getList</code>
</PossiblyUnusedMethod>
</file>
<file src="src/Psalm/Type/Atomic/TList.php">
<ImpureMethodCall>
<code>replace</code>
<code>replace</code>
</ImpureMethodCall>
<ImpurePropertyAssignment>
<code><![CDATA[$cloned->type_param]]></code>
</ImpurePropertyAssignment>
</file>
<file src="src/Psalm/Type/Atomic/TNonEmptyList.php">
<DeprecatedClass>
<code>TList</code>
</DeprecatedClass>
<PossiblyUnusedMethod>
<code>setCount</code>
</PossiblyUnusedMethod>
</file>
<file src="src/Psalm/Type/Atomic/TObjectWithProperties.php">
<ImpureMethodCall>
Expand Down
218 changes: 0 additions & 218 deletions src/Psalm/Codebase.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@

use const PHP_VERSION_ID;

final class Codebase

Check failure on line 99 in src/Psalm/Codebase.php

View workflow job for this annotation

GitHub Actions / Check backward compatibility

Method Psalm\Codebase#getSymbolInformation() was removed
{
/**
* @var Config
Expand Down Expand Up @@ -1198,224 +1198,6 @@
return new PHPMarkdownContent($reference->symbol);
}

/**
* @psalm-suppress PossiblyUnusedMethod
* @deprecated will be removed in Psalm 6. use {@see Codebase::getSymbolLocationByReference()} instead
*/
public function getSymbolInformation(string $file_path, string $symbol): ?array
{
if (is_numeric($symbol[0])) {
return ['type' => preg_replace('/^[^:]*:/', '', $symbol)];
}

try {
if (strpos($symbol, '::')) {
if (strpos($symbol, '()')) {
$symbol = substr($symbol, 0, -2);

/** @psalm-suppress ArgumentTypeCoercion */
$method_id = new MethodIdentifier(...explode('::', $symbol));

$declaring_method_id = $this->methods->getDeclaringMethodId($method_id);

if (!$declaring_method_id) {
return null;
}

$storage = $this->methods->getStorage($declaring_method_id);

return [
'type' => '<?php ' . $storage->getCompletionSignature(),
'description' => $storage->description,
];
}

[, $symbol_name] = explode('::', $symbol);

if (strpos($symbol, '$') !== false) {
$storage = $this->properties->getStorage($symbol);

return [
'type' => '<?php ' . $storage->getInfo() . ' ' . $symbol_name,
'description' => $storage->description,
];
}

[$fq_classlike_name, $const_name] = explode('::', $symbol);

$class_constants = $this->classlikes->getConstantsForClass(
$fq_classlike_name,
ReflectionProperty::IS_PRIVATE,
);

if (!isset($class_constants[$const_name])) {
return null;
}

return [
'type' => '<?php ' . $const_name,
'description' => $class_constants[$const_name]->description,
];
}

if (strpos($symbol, '()')) {
$function_id = strtolower(substr($symbol, 0, -2));
$file_storage = $this->file_storage_provider->get($file_path);

if (isset($file_storage->functions[$function_id])) {
$function_storage = $file_storage->functions[$function_id];

return [
'type' => '<?php ' . $function_storage->getCompletionSignature(),
'description' => $function_storage->description,
];
}

if (!$function_id) {
return null;
}

$function = $this->functions->getStorage(null, $function_id);
return [
'type' => '<?php ' . $function->getCompletionSignature(),
'description' => $function->description,
];
}

if (strpos($symbol, '$') === 0) {
$type = VariableFetchAnalyzer::getGlobalType($symbol, $this->analysis_php_version_id);
if (!$type->isMixed()) {
return ['type' => '<?php ' . $type];
}
}

try {
$storage = $this->classlike_storage_provider->get($symbol);
return [
'type' => '<?php ' . ($storage->abstract ? 'abstract ' : '') . 'class ' . $storage->name,
'description' => $storage->description,
];
} catch (InvalidArgumentException $e) {
}

if (strpos($symbol, '\\')) {
$const_name_parts = explode('\\', $symbol);
$const_name = array_pop($const_name_parts);
$namespace_name = implode('\\', $const_name_parts);

$namespace_constants = NamespaceAnalyzer::getConstantsForNamespace(
$namespace_name,
ReflectionProperty::IS_PUBLIC,
);
if (isset($namespace_constants[$const_name])) {
$type = $namespace_constants[$const_name];
return ['type' => '<?php const ' . $symbol . ' ' . $type];
}
} else {
$file_storage = $this->file_storage_provider->get($file_path);
if (isset($file_storage->constants[$symbol])) {
return ['type' => '<?php const ' . $symbol . ' ' . $file_storage->constants[$symbol]];
}
$constant = ConstFetchAnalyzer::getGlobalConstType($this, $symbol, $symbol);

if ($constant) {
return ['type' => '<?php const ' . $symbol . ' ' . $constant];
}
}
return null;
} catch (Exception $e) {
error_log($e->getMessage());

return null;
}
}

/**
* @psalm-suppress PossiblyUnusedMethod
* @deprecated will be removed in Psalm 6. use {@see Codebase::getSymbolLocationByReference()} instead
*/
public function getSymbolLocation(string $file_path, string $symbol): ?CodeLocation
{
if (is_numeric($symbol[0])) {
$symbol = preg_replace('/:.*/', '', $symbol);
$symbol_parts = explode('-', $symbol);

$file_contents = $this->getFileContents($file_path);

return new Raw(
$file_contents,
$file_path,
$this->config->shortenFileName($file_path),
(int) $symbol_parts[0],
(int) $symbol_parts[1],
);
}

try {
if (strpos($symbol, '::')) {
if (strpos($symbol, '()')) {
$symbol = substr($symbol, 0, -2);

/** @psalm-suppress ArgumentTypeCoercion */
$method_id = new MethodIdentifier(...explode('::', $symbol));

$declaring_method_id = $this->methods->getDeclaringMethodId($method_id);

if (!$declaring_method_id) {
return null;
}

$storage = $this->methods->getStorage($declaring_method_id);

return $storage->location;
}

if (strpos($symbol, '$') !== false) {
$storage = $this->properties->getStorage($symbol);

return $storage->location;
}

[$fq_classlike_name, $const_name] = explode('::', $symbol);

$class_constants = $this->classlikes->getConstantsForClass(
$fq_classlike_name,
ReflectionProperty::IS_PRIVATE,
);

if (!isset($class_constants[$const_name])) {
return null;
}

return $class_constants[$const_name]->location;
}

if (strpos($symbol, '()')) {
$file_storage = $this->file_storage_provider->get($file_path);

$function_id = strtolower(substr($symbol, 0, -2));

if (isset($file_storage->functions[$function_id])) {
return $file_storage->functions[$function_id]->location;
}

if (!$function_id) {
return null;
}

return $this->functions->getStorage(null, $function_id)->location;
}

return $this->classlike_storage_provider->get($symbol)->location;
} catch (UnexpectedValueException $e) {
error_log($e->getMessage());

return null;
} catch (InvalidArgumentException $e) {
return null;
}
}

public function getSymbolLocationByReference(Reference $reference): ?CodeLocation
{
if (is_numeric($reference->symbol[0])) {
Expand Down
Loading
Loading