Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ function it_forces_all_class_methods_except_constructor_to_proxy_calls_into_prop
MethodNode $method1,
MethodNode $method2,
MethodNode $method3,
MethodNode $method4
MethodNode $method4,
MethodNode $destructor
) {
$node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface')->willReturn(null);
$node->addProperty('objectProphecyClosure', 'private')->willReturn(null);
Expand All @@ -58,17 +59,20 @@ function it_forces_all_class_methods_except_constructor_to_proxy_calls_into_prop
$method2->getName()->willReturn('method2');
$method3->getName()->willReturn('method3');
$method4->getName()->willReturn('method4');
$destructor->getName()->willReturn('__destruct');

$method1->getReturnTypeNode()->willReturn(new ReturnTypeNode(new BuiltinType('int')));
$method2->getReturnTypeNode()->willReturn(new ReturnTypeNode(new BuiltinType('int')));
$method3->getReturnTypeNode()->willReturn(new ReturnTypeNode(new BuiltinType('void')));
$method4->getReturnTypeNode()->willReturn(new ReturnTypeNode(new BuiltinType('never')));
$destructor->getReturnTypeNode()->shouldNotBeCalled();

$node->getMethods()->willReturn(array(
'method1' => $method1,
'method2' => $method2,
'method3' => $method3,
'method4' => $method4,
'__destruct' => $destructor,
));

$constructor->setCode(Argument::any())->shouldNotBeCalled();
Expand All @@ -81,6 +85,8 @@ function it_forces_all_class_methods_except_constructor_to_proxy_calls_into_prop
->shouldBeCalled();
$method4->setCode('$this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());')
->shouldBeCalled();
$destructor->setCode('$this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());')
->shouldBeCalled();

$this->apply($node);
}
Expand Down
6 changes: 4 additions & 2 deletions src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ public function apply(ClassNode $node)
$node->addProperty('objectProphecyClosure', 'private');

foreach ($node->getMethods() as $name => $method) {
if ('__construct' === strtolower($name)) {
$methodName = strtolower($name);

if ('__construct' === $methodName) {
continue;
}

if (!$method->getReturnTypeNode()->hasReturnStatement()) {
if ('__destruct' === $methodName || !$method->getReturnTypeNode()->hasReturnStatement()) {
$method->setCode(
'$this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());'
);
Comment on lines 48 to 60

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does make sense but I was wondering if the special case should be handled at the source. Digging down hasReturnTypeStatement I found its providing some convenience wrapping of BetterReflection's logic. Their issues seem closed and I'm not sure where I'd start with a PR so this is probably a logical fix for now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for idea, need to dig it deeper

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

special case should be handled at the source

exactly, PHP 8.6 constructors and destructors are symmetric: neither may return a value, so both must be proxied rather than return-typed so pushing it down will invert deps

Expand Down