PHP DNF (Disjunctive Normal Form) Signature Compatibility Solver
MIT License
PHP DNF (Disjunctive Normal Form) Signature Compatibility Solver - see: https://wiki.php.net/rfc/dnf_types
Install the latest version with:
composer require 'donatj/php-dnf-solver'
<?php
namespace Examples;
use donatj\PhpDnfSolver\DNF;
use donatj\PhpDnfSolver\Types\UserDefinedType;
require __DIR__ . '/../vendor/autoload.php';
interface A {}
interface B {}
interface C {}
interface D {}
class Foo implements A, B {}
class Bar implements B, C {}
class Baz implements C, D {}
$qux = function ( A|(B&C) $aOrB ) : void {};
$quxParamType = (new \ReflectionFunction($qux))->getParameters()[0]->getType();
$quxDnf = DNF::getFromReflectionType($quxParamType);
var_dump($quxDnf->isSatisfiedBy(
new UserDefinedType(Foo::class)
)); // true
var_dump($quxDnf->isSatisfiedBy(
new UserDefinedType(Bar::class)
)); // true
var_dump($quxDnf->isSatisfiedBy(
new UserDefinedType(Baz::class)
)); // false
Outputs:
bool(true)
bool(true)
bool(false)
<?php
namespace Examples;
use donatj\PhpDnfSolver\Types\AndClause;
use donatj\PhpDnfSolver\Types\BuiltInType;
use donatj\PhpDnfSolver\Types\OrClause;
use donatj\PhpDnfSolver\Types\UserDefinedType;
require __DIR__ . '/../vendor/autoload.php';
interface A {}
interface B {}
interface C {}
var_dump((new OrClause(
new UserDefinedType(A::class),
new UserDefinedType(B::class),
new UserDefinedType(C::class)
))->dnf()); // A|B|C
var_dump((new OrClause(
new UserDefinedType(A::class),
new AndClause(
new UserDefinedType(B::class),
new UserDefinedType(C::class)
)
))->dnf()); // A|(B&C)
var_dump((new OrClause(
new AndClause(new UserDefinedType(A::class), new UserDefinedType(B::class)),
new AndClause(
new UserDefinedType(B::class),
new UserDefinedType(C::class)
),
new BuiltInType('null'),
))->dnf()); // (A&B)|(B&C)|null
Outputs:
string(32) "Examples\A|Examples\B|Examples\C"
string(34) "Examples\A|(Examples\B&Examples\C)"
string(52) "(Examples\A&Examples\B)|(Examples\B&Examples\C)|null"
function getFromReflectionType(\ReflectionType $type) : \donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface
Helper to convert a ReflectionType into it's DNF representation
function reflectionTypeSatisfiesReflectionType(\ReflectionType $satisfyingType, \ReflectionType $satisfiedType) : bool
Helper to quickly check if a ReflectionType satisfies another ReflectionType
$satisfyingType
- The type which must be satisfied (e.g. a parameter type)$satisfiedType
- The type which must satisfy the other (e.g. a return type)function getFromVarType(\ReflectionParameter|\ReflectionProperty $parameter) : \donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface|null
Helper to quickly get a DNF representation of a (ReflectionParameter or ReflectionProperty)'s return type
function getFromReturnType(\ReflectionFunctionAbstract $func) : \donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface|null
Helper to quickly get a DNF representation of a ReflectionFunctionAbstract (ReflectionFunction / ReflectionMethod)'s return type
Represents an "and clause" - a set of types which must all be satisfied - e.g. "A&B&C"
function __construct(\donatj\PhpDnfSolver\SingularDnfTypeInterface ...$types)
$types
- The list of types to be satisfiedfunction dnf() : string
Return the canonical string representation of the DNF representation of this type
function isSatisfiedBy(\donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface $value) : bool
Tests if this type is satisfied by the given type
For example, if this type is "A|(B&C)" and the given type matches just "A", this method returns true. If the given type matches just "B", this method returns false. If the given type matches "B&C", this method returns true.
function count() : int
Returns the number of types in this DNF type
function getTypes() : array
Represents a "built in type" as defined by ReflectionNamedType::isBuiltin()
This includes:
function __construct(string $name)
$name
- The name of the built-in typefunction dnf() : string
Return the canonical string representation of the DNF representation of this type
function getTypeName() : string
Returns the fully qualified type name of this type
function isSatisfiedBy(\donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface $value) : bool
Tests if this type is satisfied by the given type
For example, if this type is "A|(B&C)" and the given type matches just "A", this method returns true. If the given type matches just "B", this method returns false. If the given type matches "B&C", this method returns true.
function count() : int
Always 1 for singular types
Returns the number of types in this DNF type
Represents a "callable" type
This includes:
function dnf() : string
Return the canonical string representation of the DNF representation of this type
function isSatisfiedBy(\donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface $value) : bool
Tests if this type is satisfied by the given type
For example, if this type is "A|(B&C)" and the given type matches just "A", this method returns true. If the given type matches just "B", this method returns false. If the given type matches "B&C", this method returns true.
function getTypeName() : string
Returns the fully qualified type name of this type
function count() : int
Always 1 for singular types
Returns the number of types in this DNF type
Represents a "or" clause - a set of types where any one of them must be satisfied - e.g. "A|B|(C&D)"
function __construct(\donatj\PhpDnfSolver\Types\AndClause|\donatj\PhpDnfSolver\SingularDnfTypeInterface ...$types)
$types
- The list of types to be satisfied. Does not accept an OrClause as DNF defines that as invalid.function dnf() : string
Return the canonical string representation of the DNF representation of this type
function isSatisfiedBy(\donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface $value) : bool
Tests if this type is satisfied by the given type
For example, if this type is "A|(B&C)" and the given type matches just "A", this method returns true. If the given type matches just "B", this method returns false. If the given type matches "B&C", this method returns true.
function count() : int
Returns the number of types in this DNF type
function getTypes() : array
Represents a "user defined type" - a class, interface, or trait, etc.
<?php
namespace donatj\PhpDnfSolver\Types;
class UserDefinedType {
public $className;
}
function __construct(string $className)
$className
- The name of the class, interface, or trait to be satisfiedThrows: \donatj\PhpDnfSolver\Exceptions\InvalidArgumentException
- if the user defined type does not exist after triggering registered autoloaders
function dnf() : string
Return the canonical string representation of the DNF representation of this type
function getTypeName() : string
Returns the fully qualified type name of this type
function isSatisfiedBy(\donatj\PhpDnfSolver\SingularDnfTypeInterface|\donatj\PhpDnfSolver\NestedDnfTypeInterface $value) : bool
Tests if this type is satisfied by the given type
For example, if this type is "A|(B&C)" and the given type matches just "A", this method returns true. If the given type matches just "B", this method returns false. If the given type matches "B&C", this method returns true.
function count() : int
Always 1 for singular types
Returns the number of types in this DNF type