Skip to content

Commit

Permalink
Autogenerate base callmaps
Browse files Browse the repository at this point in the history
  • Loading branch information
danog committed Dec 1, 2024
1 parent bb092f7 commit 8cfb3c1
Show file tree
Hide file tree
Showing 20 changed files with 199,700 additions and 82 deletions.
7 changes: 3 additions & 4 deletions bin/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
ARG VERSION
FROM php:${VERSION}
FROM php:${VERSION}-alpine

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions pcntl uv-beta ffi pgsql intl gmp mbstring pdo_mysql xml dom iconv zip igbinary gd && \
rm /usr/local/bin/install-php-extensions
install-php-extensions amqp apcu zmq ds event ev redis mongodb imagick pcntl uv-beta ffi pgsql intl gmp mbstring pdo_mysql xml dom iconv zip igbinary gd bcmath

ADD php.ini /usr/local/etc/php/php.ini
RUN echo 'zend_extension=opcache' > /usr/local/etc/php/php.ini
58 changes: 55 additions & 3 deletions bin/gen_base_callmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,58 @@

$callmap = [];

require __DIR__ . '/gen_callmap_utils.php';
function typeToString(?ReflectionType $reflection_type = null): string
{
if (!$reflection_type) {
return 'string';
}

if ($reflection_type instanceof ReflectionNamedType) {
$type = $reflection_type->getName();
} elseif ($reflection_type instanceof ReflectionUnionType) {
$type = implode(
'|',
array_map(
static fn(ReflectionNamedType $reflection): string => $reflection->getName(),
$reflection_type->getTypes(),
),
);
} else {
throw new LogicException('Unexpected reflection class ' . $reflection_type::class . ' found.');
}

if ($reflection_type->allowsNull()) {
$type .= '|null';
}

return $type;
}

/**
* @return array<string, array{byRef: bool, refMode: 'rw'|'w'|'r', variadic: bool, optional: bool, type: string}>
*/
function paramsToEntries(ReflectionFunctionAbstract $reflectionFunction): array
{
$res = [typeToString($reflectionFunction->getReturnType())];

foreach ($reflectionFunction->getParameters() as $param) {
$key = $param->getName();
if ($param->isPassedByReference()) {
$key = "&$key";
}
if ($param->isVariadic()) {
$key = "...$key";
}
if ($param->isOptional()) {
$key .= '=';
}

$res[$key] = typeToString($param->getType());
}

return $res;
}


foreach (get_defined_functions()['internal'] as $name) {
$func = new ReflectionFunction($name);
Expand All @@ -27,5 +78,6 @@
}
}

$callmap = normalizeCallMap($callmap);
writeCallMap(__DIR__.'/../dictionaries/CallMap.php', $callmap);
file_put_contents(__DIR__.'/../dictionaries/base/CallMap_'.PHP_MAJOR_VERSION.PHP_MINOR_VERSION.'.php', '<?php // phpcs:ignoreFile
return '.var_export($callmap, true).';');
10 changes: 4 additions & 6 deletions bin/gen_base_callmap.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
#!/bin/bash
#!/bin/bash -e

VERSIONS="7.0 7.1 7.2 7.3 7.4 8.0 8.1 8.2 8.3 8.4"

cd bin
VERSIONS="8.0 8.1 8.2 8.3 8.4"

for f in $VERSIONS; do
docker build --build-arg VERSION=$f . -t psalm_test_$f &
docker build --build-arg VERSION=$f . -f bin/Dockerfile -t psalm_test_$f &
done

wait

for f in $VERSIONS; do

docker run --rm -it -v $PWD:/app psalm_test_$f php /app/bin/gen_base_callmap.php
done
59 changes: 4 additions & 55 deletions bin/gen_callmap_utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
use Psalm\Tests\TestConfig;
use Psalm\Type;

function internalNormalizeCallMap(array|string $callMap, string|int $key = 0): array|string {
function internalNormalizeCallMap(array|string $callMap, string|int $key = 0): array|string
{
if (is_string($callMap)) {
return Type::parseString($callMap === '' ? 'mixed' : $callMap)->getId(true);
}
Expand All @@ -29,63 +30,11 @@ function internalNormalizeCallMap(array|string $callMap, string|int $key = 0): a
return $new;
}

function normalizeCallMap(array $callMap): array {
return internalNormalizeCallMap($callMap);
}

function typeToString(?ReflectionType $reflection_type = null): string
{
if (!$reflection_type) {
return 'string';
}

if ($reflection_type instanceof ReflectionNamedType) {
$type = $reflection_type->getName();
} elseif ($reflection_type instanceof ReflectionUnionType) {
$type = implode(
'|',
array_map(
static fn(ReflectionNamedType $reflection): string => $reflection->getName(),
$reflection_type->getTypes(),
),
);
} else {
throw new LogicException('Unexpected reflection class ' . $reflection_type::class . ' found.');
}

if ($reflection_type->allowsNull()) {
$type .= '|null';
}

return $type;
}

/**
* @return array<string, array{byRef: bool, refMode: 'rw'|'w'|'r', variadic: bool, optional: bool, type: string}>
*/
function paramsToEntries(ReflectionFunctionAbstract $reflectionFunction): array
function normalizeCallMap(array $callMap): array
{
$res = [typeToString($reflectionFunction->getReturnType())];

foreach ($reflectionFunction->getParameters() as $param) {
$key = $param->getName();
if ($param->isPassedByReference()) {
$key = "&$key";
}
if ($param->isVariadic()) {
$key = "...$key";
}
if ($param->isOptional()) {
$key .= '=';
}

$res[$key] = typeToString($param->getType());
}

return $res;
return internalNormalizeCallMap($callMap);
}


/**
* Returns the correct reflection type for function or method name.
*/
Expand Down
14 changes: 0 additions & 14 deletions bin/php.ini

This file was deleted.

Loading

0 comments on commit 8cfb3c1

Please sign in to comment.