-
-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Hack new PHPStan 2.x compatible ReflectionCache (#716)
- Loading branch information
Showing
20 changed files
with
1,668 additions
and
67,097 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace staabm\PHPStanDba\QueryReflection; | ||
|
||
use PHPStan\DependencyInjection\Container; | ||
|
||
/** | ||
* Utility class to access the PHPStan container from phpstan-dba internal classes which cannot access the DI because of BC. | ||
* | ||
* @internal | ||
*/ | ||
final class DIContainerBridge | ||
{ | ||
private static Container $container; | ||
|
||
public function __construct(Container $container) | ||
{ | ||
self::$container = $container; | ||
} | ||
|
||
/** | ||
* @phpstan-template T of object | ||
* @phpstan-param class-string<T> $className | ||
* @phpstan-return T | ||
* @return mixed | ||
*/ | ||
public static function getByType(string $className): object | ||
{ | ||
return self::$container->getByType($className); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace staabm\PHPStanDba\QueryReflection; | ||
|
||
use PHPStan\PhpDoc\TypeStringResolver; | ||
use PHPStan\PhpDocParser\Printer\Printer; | ||
use PHPStan\ShouldNotHappenException; | ||
use PHPStan\Type\Type; | ||
use staabm\PHPStanDba\Error; | ||
|
||
final class TypeSerializer | ||
{ | ||
private ?Printer $printer = null; | ||
|
||
private ?TypeStringResolver $typeStringResolver = null; | ||
|
||
/** | ||
* @param array<string, array{error?: ?Error, result?: array<QueryReflector::FETCH_TYPE*, ?Type>}> $records | ||
* @return array<string, array{error?: ?Error, result?: array<QueryReflector::FETCH_TYPE*, ?array<string>>}> | ||
*/ | ||
public function serialize(array $records): array | ||
{ | ||
// serialize types, see https://github.com/phpstan/phpstan/discussions/12046 | ||
foreach ($records as &$record) { | ||
if (! array_key_exists('result', $record)) { | ||
continue; | ||
} | ||
$record['result'] = array_map(function (?Type $type) { | ||
if ($type === null) { | ||
return null; | ||
} | ||
|
||
return [ | ||
'type-description' => $this->getPhpdocPrinter()->print($type->toPhpDocNode()), | ||
]; | ||
}, $record['result']); | ||
} | ||
|
||
return $records; // @phpstan-ignore return.type | ||
} | ||
|
||
/** | ||
* @param array<string, array{error?: ?Error, result?: array<QueryReflector::FETCH_TYPE*, ?array<string>>}> $records | ||
* @return array<string, array{error?: ?Error, result?: array<QueryReflector::FETCH_TYPE*, ?Type>}> | ||
*/ | ||
public function unserialize(array $records): array | ||
{ | ||
// serialize types, see https://github.com/phpstan/phpstan/discussions/12046 | ||
foreach ($records as &$record) { | ||
if (! array_key_exists('result', $record)) { | ||
continue; | ||
} | ||
$record['result'] = array_map(function ($serialized): Type { | ||
if (is_array($serialized) && array_key_exists('type-description', $serialized)) { | ||
try { | ||
return $this->getTypeStringResolver()->resolve($serialized['type-description']); | ||
} catch (\Throwable $e) { | ||
throw new ShouldNotHappenException("unexpected type " . print_r($serialized, true) . ': ' . $e->getMessage()); | ||
} | ||
} | ||
throw new ShouldNotHappenException("unexpected type " . print_r($serialized, true)); | ||
}, $record['result']); | ||
} | ||
|
||
return $records; // @phpstan-ignore return.type | ||
} | ||
|
||
private function getPhpdocPrinter(): Printer | ||
{ | ||
if ($this->printer === null) { | ||
$this->printer = DIContainerBridge::getByType(Printer::class); | ||
} | ||
return $this->printer; | ||
} | ||
|
||
private function getTypeStringResolver(): TypeStringResolver | ||
{ | ||
if ($this->typeStringResolver === null) { | ||
$this->typeStringResolver = DIContainerBridge::getByType(TypeStringResolver::class); | ||
} | ||
return $this->typeStringResolver; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.