pocketmine/callback-validator

Fork of daverandom/callback-validator - Tools for validating callback signatures

Maintainers

👁 dktapps
👁 pmmp

Package info

github.com/pmmp/CallbackValidator

pkg:composer/pocketmine/callback-validator

Statistics

Installs: 589 427

Dependents: 7

Suggesters: 0

Stars: 2

Open Issues: 3

1.0.4 2025-12-24 01:25 UTC

Requires

  • php: ^8.0
  • ext-reflection: *

Requires (Dev)

Suggests

None

Provides

None

Conflicts

None

MIT 143fa6e13254f1ab90c31b223982016f95635c37

  • Chris Wright <cw.woop@daverandom.com>

README

Validates callback signatures against a prototype.

This is a fork of daverandom/callback-validator used by PocketMine-MP. There are no significant changes from the upstream repository apart from more test versions, updated dependencies, and tagged releases for packages to use.

Since the upstream version has no release, it affects the composer stability of packages that use it. This caused problems for packages depending on pocketmine/pocketmine-mp because they could not receive its latest versions.

Status

👁 CI

Usage

// Create a prototype function (can be any callable)
$prototype = function (A $a, B $b, $c): ?string {};

// Validate that callables match the prototype
$tests = [
 $prototype, // true
 function (A $a, B $b, $c) {}, // false - return type does not match
 function ($a, $b, $c): ?string {}, // true - arguments are contravariant
 function (A $a, B $b): ?string {}, // true - extra args don't cause errors
 function (A $a, B $b, $c, $d): ?string {}, // false - Insufficient args cause an error
 function (C $a, B $b, $c): ?string {}, // true if C is a supertype of A, false otherwise
 function (SuperTypeOfA $a, B $b, $c): ?string {}, // true
 function (A $a, B $b, $c): string {}, // true - return types are covariant
];

// Create a type from a prototype
$type = CallbackType::createFromCallable($prototype);

run_tests($type, $tests);

// ...or create a type by hand for more granular control over variance rules
$type = new CallbackType(
 new ReturnType(BuiltInTypes::STRING, ReturnType::NULLABLE | ReturnType::COVARIANT),
 new ParameterType('a', A::class),
 new ParameterType('b', B::class),
 new ParameterType('c')
);

run_tests($type, $tests);

function run_tests(CallbackType $type, array $tests)
{
 foreach ($tests as $test) {
 if ($type->isSatisfiedBy($test)) {
 echo "pass\n";
 } else {
 // CallbackType implements __toString() for easy inspections
 echo CallbackType::createFromCallable($test) . " does not satisfy {$type}\n";
 }
 }
}

TODO

  • Lots more tests
  • Explain (text explanation of why callback does not validate)