Skip to content

Commit

Permalink
Merge pull request #6 from kbond/self-typehint
Browse files Browse the repository at this point in the history
Support "self" typehint
  • Loading branch information
kbond authored Mar 26, 2022
2 parents dfb961b + 3eb5356 commit b65a8d6
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
17 changes: 15 additions & 2 deletions src/Callback/Argument.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,20 @@ public function type(): ?string
*/
public function types(): array
{
return \array_map(static function(\ReflectionNamedType $type) { return $type->getName(); }, $this->reflectionTypes());
return \array_map(
function(\ReflectionNamedType $type) {
if ('self' !== $name = $type->getName()) {
return $name;
}

if (!$class = $this->parameter->getDeclaringClass()) {
throw new \LogicException('Unable to parse context of "self" typehint.');
}

return $class->name;
},
$this->reflectionTypes()
);
}

public function hasType(): bool
Expand Down Expand Up @@ -139,7 +152,7 @@ public function supports(string $type, int $options = self::EXACT|self::COVARIAN
return true;
}

if (\method_exists($type, '__toString')) {
if ('string' === $supportedType && \method_exists($type, '__toString')) {
return true;
}
}
Expand Down
48 changes: 48 additions & 0 deletions tests/CallbackTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,26 @@ public function argument_allows(): void
$this->assertFalse($callback2->argument(0)->allows(new Object3()));
}

/**
* @test
*/
public function self_parameter_type(): void
{
$callback = Callback::createFor(Object6::closureSelf());

$this->assertSame(Object6::class, $callback->argument(0)->type());

$this->assertTrue($callback->argument(0)->supports(Object6::class));
$this->assertTrue($callback->argument(0)->supports(Object7::class));
$this->assertFalse($callback->argument(0)->supports(Object5::class));
$this->assertFalse($callback->argument(0)->supports('int'));

$this->assertTrue($callback->argument(0)->allows(new Object6()));
$this->assertTrue($callback->argument(0)->allows(new Object7()));
$this->assertFalse($callback->argument(0)->allows(new Object5()));
$this->assertFalse($callback->argument(0)->allows(6));
}

/**
* @test
*/
Expand Down Expand Up @@ -624,6 +644,20 @@ public function invoke_all_union_parameter_with_defaults(): void

$this->assertSame(['a', $b, null], $ret);
}

/**
* @test
*/
public function to_string_object(): void
{
$callback = Callback::createFor(function(Object1 $o, string $s) {});

$this->assertFalse($callback->argument(0)->supports(Object5::class));
$this->assertTrue($callback->argument(1)->supports(Object5::class));

$this->assertFalse($callback->argument(0)->allows(new Object5()));
$this->assertTrue($callback->argument(1)->allows(new Object5()));
}
}

class Object1
Expand Down Expand Up @@ -660,3 +694,17 @@ public function __toString(): string
function test_function()
{
}

class Object6
{
public static function closureSelf(): \Closure
{
return function(self $object) {
return $object;
};
}
}

class Object7 extends Object6
{
}

0 comments on commit b65a8d6

Please sign in to comment.