Skip to content

Instantly share code, notes, and snippets.

@mikeschinkel
Created October 5, 2021 17:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikeschinkel/6f8c9cf6700a75e75e2725db1ed4da61 to your computer and use it in GitHub Desktop.
Save mikeschinkel/6f8c9cf6700a75e75e2725db1ed4da61 to your computer and use it in GitHub Desktop.
A reimagining of Sebastian Bergmann's Type.php if PHP had a "function list" declaration.
<?php declare(strict_types=1);
/*
* This file is part of sebastian/type.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\Type;
use const PHP_VERSION;
use function get_class;
use function gettype;
use function strtolower;
use function version_compare;
abstract class Type
{
public static function fromValue(mixed $value, bool $allowsNull): self
{
if ($value === false) {
return new FalseType;
}
$typeName = gettype($value);
if ($typeName === 'object') {
return new ObjectType(TypeName::fromQualifiedName(get_class($value)), $allowsNull);
}
$type = self::fromName($typeName, $allowsNull);
if ($type instanceof SimpleType) {
$type = new SimpleType($typeName, $allowsNull, $value);
}
return $type;
}
public static function fromName(string $typeName, bool $allowsNull): self
{
if (version_compare(PHP_VERSION, '8.1.0-dev', '>=') && strtolower($typeName) === 'never') {
return new NeverType;
}
return match (strtolower($typeName)) {
'callable' => new CallableType($allowsNull),
'false' => new FalseType,
'iterable' => new IterableType($allowsNull),
'null' => new NullType,
'object' => new GenericObjectType($allowsNull),
'unknown type' => new UnknownType,
'void' => new VoidType,
'array', 'bool', 'boolean', 'double', 'float', 'int', 'integer', 'real', 'resource', 'resource (closed)', 'string' => new SimpleType($typeName, $allowsNull),
default => new ObjectType(TypeName::fromQualifiedName($typeName), $allowsNull),
};
}
public function asString(): string
{
return ($this->allowsNull() ? '?' : '') . $this->name();
}
public function list: bool
{
isCallable() => false,
isFalse() => false,
isGenericObject() => false,
isIntersection() => false,
isIterable() => false,
isMixed() => false,
isNever() => false,
isNull() => false,
isObject() => false,
isSimple() => false,
isStatic() => false,
isUnion() => false,
isUnknown() => false,
isVoid() => false,
}
abstract public function list
{
isAssignable(self $other): bool;
name(): string;
allowsNull(): bool;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment