[Regex] add capture_groups() return type provider (#5)

This commit is contained in:
Toon Verwerft 2021-04-09 21:07:34 +02:00 committed by GitHub
parent af8580e603
commit a9b20179b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 0 deletions

View File

@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
namespace Psl\Psalm\EventHandler\Regex\CaptureGroups;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
final class FunctionReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
/**
* @return array<lowercase-string>
*/
public static function getFunctionIds(): array
{
return [
'psl\regex\capture_groups'
];
}
public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union
{
$statements_source = $event->getStatementsSource();
$call_args = $event->getCallArgs();
$argument = $call_args[0] ?? null;
if (null === $argument) {
return self::fallbackType();
}
$argument_value = $argument->value;
$type = $statements_source->getNodeTypeProvider()->getType($argument_value);
if (null === $type) {
return self::fallbackType();
}
$atomic = $type->getAtomicTypes();
$capture_groups = $atomic['array'] ?? null;
if (!$capture_groups instanceof Type\Atomic\TKeyedArray) {
return self::fallbackType();
}
$string = static fn (): Type\Union => new Type\Union([new Type\Atomic\TString()]);
$properties = [
0 => $string()
];
foreach ($capture_groups->properties as $value) {
$type = array_values($value->getAtomicTypes())[0] ?? null;
if (!$type instanceof Type\Atomic\TLiteralInt && !$type instanceof Type\Atomic\TLiteralString) {
return self::fallbackType();
}
$name = $type->value;
$properties[$name] = $string();
}
return new Type\Union([new Type\Atomic\TGenericObject('Psl\Type\TypeInterface', [
new Type\Union([
new Type\Atomic\TKeyedArray($properties)
])
])]);
}
private static function fallbackType(): Type\Union
{
return new Type\Union([new Type\Atomic\TGenericObject('Psl\Type\TypeInterface', [
new Type\Union([
new Type\Atomic\TArray([
new Type\Union([new Type\Atomic\TArrayKey()]),
new Type\Union([new Type\Atomic\TString()])
])
])
])]);
}
}

View File

@ -34,6 +34,9 @@ final class Plugin implements PluginEntryPointInterface
yield EventHandler\Iter\Last\FunctionReturnTypeProvider::class;
yield EventHandler\Iter\Count\FunctionReturnTypeProvider::class;
// Psl\Regex hooks
yield EventHandler\Regex\CaptureGroups\FunctionReturnTypeProvider::class;
// Psl\Str hooks
yield EventHandler\Str\After\FunctionReturnTypeProvider::class;
yield EventHandler\Str\Before\FunctionReturnTypeProvider::class;