1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Merge pull request #7437 from orklah/mb_internal_encoding

create a return type provider for mb_internal_encoding
This commit is contained in:
orklah 2022-01-20 20:51:08 +01:00 committed by GitHub
commit 2f052a8781
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 0 deletions

View File

@ -30,6 +30,7 @@ use Psalm\Internal\Provider\ReturnTypeProvider\GetObjectVarsReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\HexdecReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\InArrayReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\IteratorToArrayReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\MbInternalEncodingReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\MinMaxReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\MktimeReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ParseUrlReturnTypeProvider;
@ -97,6 +98,7 @@ class FunctionReturnTypeProvider
$this->registerClass(RandReturnTypeProvider::class);
$this->registerClass(InArrayReturnTypeProvider::class);
$this->registerClass(RoundReturnTypeProvider::class);
$this->registerClass(MbInternalEncodingReturnTypeProvider::class);
}
/**

View File

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Union;
use function assert;
use function count;
/**
* @internal
*/
class MbInternalEncodingReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
/**
* @return array<lowercase-string>
*/
public static function getFunctionIds(): array
{
return ['mb_internal_encoding'];
}
public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Union
{
$call_args = $event->getCallArgs();
if (count($call_args) === 0) {
return Type::getString();
}
$statements_source = $event->getStatementsSource();
$nodeTypeProvider = $statements_source->getNodeTypeProvider();
$codebase = $statements_source->getCodebase();
$first_arg_type = $nodeTypeProvider->getType($call_args[0]->value);
if ($first_arg_type === null) {
if ($codebase->analysis_php_version_id >= 8_00_00) {
return new Union([new TString(), new TTrue()]);
} else {
return new Union([new TString(), new TBool()]);
}
}
$has_stringable = false;
$has_tostring = false;
$has_string = false;
$has_null = false;
$has_unknown = false;
foreach ($first_arg_type->getAtomicTypes() as $atomic_type) {
if ($atomic_type instanceof Type\Atomic\TNamedObject
&& $codebase->classlikes->classImplements($atomic_type->value, 'Stringable')
) {
$has_stringable = true;
continue;
}
if ($atomic_type instanceof Type\Atomic\TObjectWithProperties
&& isset($atomic_type->methods['__toString'])
) {
$has_tostring = true;
continue;
}
if ($atomic_type instanceof TString) {
$has_string = true;
continue;
}
if ($atomic_type instanceof TNull) {
$has_null = true;
continue;
}
$has_unknown = true;
}
$list_return_atomics = [];
if ($has_string || $has_stringable || $has_tostring) {
if ($codebase->analysis_php_version_id >= 8_00_00) {
$list_return_atomics[] = new TTrue();
} else {
$list_return_atomics[] = new TBool();
}
}
if ($has_null) {
if ($codebase->analysis_php_version_id >= 8_00_00) {
$list_return_atomics[] = new TString();
} else {
$list_return_atomics[] = new TFalse();
}
}
if ($has_unknown) {
if ($codebase->analysis_php_version_id >= 8_00_00) {
$list_return_atomics[] = new TNever();
} else {
$list_return_atomics[] = new TNull();
}
}
assert($list_return_atomics !== []);
return new Union($list_return_atomics);
}
}