Skip to content
Merged
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 @@ -12,16 +12,16 @@
* @psalm-import-type MethodBindings from Types
* @psalm-import-type Arguments from Types
*/
trait Php82InterceptTrait
trait ReadOnlyInterceptTrait
{
private readonly InterceptTraitState $_state;

/**
* @param MethodBindings $bindings
*
* @see WeavedInterface::_initState()
* @see WeavedInterface::_setBindings()
*/
public function _initState(array $bindings): void
public function _setBindings(array $bindings): void
{
$this->_state = new InterceptTraitState($bindings);
}
Expand Down
26 changes: 21 additions & 5 deletions src/AopCode.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ private function parseClass(ReflectionClass $sourceClass, string $postfix): void

$isClassSignatureEnds = $inClass && $text === '{';
if ($isClassSignatureEnds) {
$this->addIntercepterTrait();
$this->resolveInterceptTrait($sourceClass);

return;
}
Expand Down Expand Up @@ -201,11 +201,15 @@ private function addMethods(ReflectionClass $class, BindInterface $bind): void
}

/** @psalm-external-mutation-free */
private function addIntercepterTrait(): void
private function addInterceporTrait(): void
{
PHP_VERSION_ID >= 80200
? $this->add(sprintf("{\n use \%s;\n}\n", Php82InterceptTrait::class))
: $this->add(sprintf("{\n use \%s;\n}\n", InterceptTrait::class));
$this->add(sprintf("{\n use \%s;\n}\n", InterceptTrait::class));
}

/** @psalm-external-mutation-free */
private function addReadOnlyInterceptorTrait(): void
{
$this->add(sprintf("{\n use \%s;\n}\n", ReadOnlyInterceptTrait::class));
}

/** @psalm-external-mutation-free */
Expand All @@ -219,4 +223,16 @@ private function getCodeText(): string

return $this->code;
}

/** @param ReflectionClass<object> $sourceClass */
public function resolveInterceptTrait(ReflectionClass $sourceClass): void
{
if (PHP_VERSION_ID >= 80200 && $sourceClass->isReadOnly()) {
$this->addReadOnlyInterceptorTrait();

return;
}

$this->addInterceporTrait();
}
}
2 changes: 1 addition & 1 deletion src/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function newInstance(string $class, array $args, BindInterface $bind): ob
assert(class_exists($compiledClass));
$instance = (new ReflectionClass($compiledClass))->newInstanceArgs($args);
if ($instance instanceof WeavedInterface) {
$instance->_initState($bind->getBindings());
$instance->_setBindings($bind->getBindings());
}

assert($instance instanceof $class);
Expand Down
25 changes: 14 additions & 11 deletions src/InterceptTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,24 @@
trait InterceptTrait
{
/**
* @var InterceptTraitState
* @var MethodBindings
* @readonly
* @psalm-suppress MissingConstructor
* @deprecated Do not use this property directly. Use the `_setBindings` setter method instead for initialization.
*/
private $_state;
public $bindings = [];

/** @var bool Flag controlling whether aspect interception is active */
private $_isAspect = true;

/**
* @param MethodBindings $bindings
*
* @see WeavedInterface::_initState()
* @see WeavedInterface::_setBindings()
* @SuppressWarnings(PHPMD.CamelCaseMethodName)
*/
public function _initState(array $bindings): void // phpcs:ignore
public function _setBindings(array $bindings): void // @phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore
{
$this->_state = new InterceptTraitState($bindings);
$this->bindings = $bindings;
}

/**
Expand All @@ -38,15 +41,15 @@ public function _initState(array $bindings): void // phpcs:ignore
*/
private function _intercept(string $func, array $args) // phpcs:ignore
{
if (! $this->_state->isAspect) {
$this->_state->isAspect = true;
if (! $this->_isAspect) {
$this->_isAspect = true;

return call_user_func_array([parent::class, $func], $args);
}

$this->_state->isAspect = false;
$result = (new Invocation($this, $func, $args, $this->_state->bindings[$func]))->proceed();
$this->_state->isAspect = true;
$this->_isAspect = false;
$result = (new Invocation($this, $func, $args, $this->bindings[$func]))->proceed();
$this->_isAspect = true;

return $result;
}
Expand Down
2 changes: 1 addition & 1 deletion src/InterceptTraitState.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final class InterceptTraitState
*/
public $bindings;

/** @var bool */
/** @var bool Flag controlling whether aspect interception is active */
public $isAspect = true;

/** @param MethodBindings $bindings */
Expand Down
2 changes: 1 addition & 1 deletion src/WeavedInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ interface WeavedInterface
*
* @SuppressWarnings(PHPMD.CamelCaseMethodName)
*/
public function _initState(array $bindings): void; // phpcs:ignore
public function _setBindings(array $bindings): void; // phpcs:ignore
}
2 changes: 1 addition & 1 deletion src/Weaver.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function newInstance(string $class, array $args): object
return $instance;
}

$instance->_initState($this->bind->getBindings());
$instance->_setBindings($this->bind->getBindings());
assert($instance instanceof $class);

return $instance;
Expand Down
4 changes: 0 additions & 4 deletions tests/CompilerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
use function class_exists;
use function file_get_contents;
use function passthru;
use function property_exists;
use function serialize;
use function unserialize;

Expand Down Expand Up @@ -115,7 +114,6 @@ public function testParentMethodIntercept(): void
{
$mock = $this->compiler->newInstance(FakeMockGrandChild::class, [], $this->bind);
assert($mock instanceof FakeMockGrandChild);
assert(property_exists($mock, '_state'));
$result = $mock->returnSame(1);
$this->assertSame(2, $result);
}
Expand All @@ -125,7 +123,6 @@ public function testTypedParentMethodIntercept(): void
$bind = (new Bind())->bindInterceptors('passIterator', [new NullInterceptor()]);
$mock = $this->compiler->newInstance(FakeTypedMockGrandChild::class, [], $bind);
assert($mock instanceof FakeTypedMockGrandChild);
assert(property_exists($mock, '_state'));
$result = $mock->passIterator(new ArrayIterator());
$this->assertInstanceOf(ArrayIterator::class, $result);
}
Expand All @@ -134,7 +131,6 @@ public function testParentOfParentMethodIntercept(): void
{
$mock = $this->compiler->newInstance(FakeMockChildChild::class, [], $this->bind);
assert($mock instanceof FakeMockChild);
assert(property_exists($mock, '_state'));
$result = $mock->returnSame(1);
$this->assertSame(2, $result);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/Fake/FakeWeavedClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ class FakeWeavedClass extends FakeClass implements WeavedInterface
/**
* {@inheritDoc}
*/
public function _initState(array $bindings): void {}
public function _setBindings(array $bindings): void {}
}
6 changes: 3 additions & 3 deletions tests/tmp_unerase/Ray_Aop_FakeWeaverMock_523567342.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace Ray\Aop;

/** doc comment of FakeMock */
class FakeWeaverMock_523567342 extends FakeWeaverMock implements \Ray\Aop\WeavedInterface
class FakeWeaverMock_523567342 extends FakeWeaverMock implements \Ray\Aop\WeavedInterface
{
use \Ray\Aop\Php82InterceptTrait;
use \Ray\Aop\ReadOnlyInterceptTrait;
/**
* doc comment of returnSame
*/
Expand All @@ -33,4 +33,4 @@ public function getPrivateVal()
{
return $this->_intercept(__FUNCTION__, func_get_args());
}
}
}
Loading