From e60fbd18b772c3e3e012c20761f585e3bfcf037f Mon Sep 17 00:00:00 2001 From: Daniel Schreiber Date: Thu, 25 May 2023 20:52:47 +0200 Subject: [PATCH 1/3] fix: prevent generating "namespace ;" for classes without declared namespace --- composer.json | 3 ++- src/Proxy/ClassProxyGenerator.php | 2 +- tests/Go/Proxy/ClassProxyGeneratorTest.php | 1 + tests/Go/Stubs/ClassWithoutNamespace.php | 11 +++++++++++ 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 tests/Go/Stubs/ClassWithoutNamespace.php diff --git a/composer.json b/composer.json index 841d6b36..97f9050e 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,8 @@ "Go\\Tests\\TestProject\\": "tests/Fixtures/project/src/" }, "files": [ - "tests/functions.php" + "tests/functions.php", + "tests/Go/Stubs/ClassWithoutNamespace.php" ] }, diff --git a/src/Proxy/ClassProxyGenerator.php b/src/Proxy/ClassProxyGenerator.php index b151d146..2e31cef8 100644 --- a/src/Proxy/ClassProxyGenerator.php +++ b/src/Proxy/ClassProxyGenerator.php @@ -109,7 +109,7 @@ public function __construct( $this->generator = new ClassGenerator( $originalClass->getShortName(), - $originalClass->getNamespaceName(), + !empty($originalClass->getNamespaceName()) ? $originalClass->getNamespaceName() : null, $originalClass->isFinal() ? ClassGenerator::FLAG_FINAL : null, $parentClassName, $introducedInterfaces, diff --git a/tests/Go/Proxy/ClassProxyGeneratorTest.php b/tests/Go/Proxy/ClassProxyGeneratorTest.php index 9c2eee17..d13158f7 100644 --- a/tests/Go/Proxy/ClassProxyGeneratorTest.php +++ b/tests/Go/Proxy/ClassProxyGeneratorTest.php @@ -93,6 +93,7 @@ public function dataGenerator(): array [First::class, 'publicMethod'], [First::class, 'protectedMethod'], [First::class, 'passByReference'], + [\ClassWithoutNamespace::class, 'publicMethod'], ]; } } diff --git a/tests/Go/Stubs/ClassWithoutNamespace.php b/tests/Go/Stubs/ClassWithoutNamespace.php new file mode 100644 index 00000000..d14eef67 --- /dev/null +++ b/tests/Go/Stubs/ClassWithoutNamespace.php @@ -0,0 +1,11 @@ + Date: Fri, 26 May 2023 12:30:10 +0200 Subject: [PATCH 2/3] fix: prevent error for classes without namespace: Call to a member function toString() on null fixes #420 --- .../Transformer/SelfValueVisitor.php | 2 +- .../Transformer/SelfValueTransformerTest.php | 10 +++ ...ile-with-self-no-namespace-transformed.php | 61 +++++++++++++++++++ .../_files/file-with-self-no-namespace.php | 61 +++++++++++++++++++ 4 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 tests/Go/Instrument/Transformer/_files/file-with-self-no-namespace-transformed.php create mode 100644 tests/Go/Instrument/Transformer/_files/file-with-self-no-namespace.php diff --git a/src/Instrument/Transformer/SelfValueVisitor.php b/src/Instrument/Transformer/SelfValueVisitor.php index 3e8c7924..a8339a6b 100644 --- a/src/Instrument/Transformer/SelfValueVisitor.php +++ b/src/Instrument/Transformer/SelfValueVisitor.php @@ -81,7 +81,7 @@ public function beforeTraverse(array $nodes) public function enterNode(Node $node) { if ($node instanceof Namespace_) { - $this->namespace = $node->name->toString(); + $this->namespace = !empty($node->name) ? $node->name->toString() : null; } elseif ($node instanceof Class_) { if ($node->name !== null) { $this->className = new Name($node->name->toString()); diff --git a/tests/Go/Instrument/Transformer/SelfValueTransformerTest.php b/tests/Go/Instrument/Transformer/SelfValueTransformerTest.php index 89bb6d0e..98f4b991 100644 --- a/tests/Go/Instrument/Transformer/SelfValueTransformerTest.php +++ b/tests/Go/Instrument/Transformer/SelfValueTransformerTest.php @@ -72,4 +72,14 @@ public function testTransformerReplacesAllSelfPlaces(): void $expected = file_get_contents(__DIR__ . '/_files/file-with-self-transformed.php'); $this->assertSame($expected, (string) $metadata->source); } + + public function testTransformerReplacesAllSelfPlacesWithoutNamespace(): void + { + $testFile = fopen(__DIR__ . '/_files/file-with-self-no-namespace.php', 'rb'); + $content = stream_get_contents($testFile); + $metadata = new StreamMetaData($testFile, $content); + $this->transformer->transform($metadata); + $expected = file_get_contents(__DIR__ . '/_files/file-with-self-no-namespace-transformed.php'); + $this->assertSame($expected, (string) $metadata->source); + } } diff --git a/tests/Go/Instrument/Transformer/_files/file-with-self-no-namespace-transformed.php b/tests/Go/Instrument/Transformer/_files/file-with-self-no-namespace-transformed.php new file mode 100644 index 00000000..25324abd --- /dev/null +++ b/tests/Go/Instrument/Transformer/_files/file-with-self-no-namespace-transformed.php @@ -0,0 +1,61 @@ + Date: Sun, 11 Jun 2023 21:43:18 +0200 Subject: [PATCH 3/3] fix: prevent "AbstractMethodInvocation::$instance must not be accessed before initialization" for recursive calls see #481 --- src/Aop/Framework/AbstractInterceptor.php | 2 +- .../Framework/AbstractMethodInvocation.php | 2 +- .../AbstractMethodInvocationTest.php | 37 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/Aop/Framework/AbstractInterceptor.php b/src/Aop/Framework/AbstractInterceptor.php index 069ad44e..be2ff5ca 100644 --- a/src/Aop/Framework/AbstractInterceptor.php +++ b/src/Aop/Framework/AbstractInterceptor.php @@ -65,7 +65,7 @@ abstract class AbstractInterceptor implements Interceptor, OrderedAdvice, Serial /** * Advice order */ - private int $adviceOrder; + private int $adviceOrder = 0; /** * Default constructor for interceptor diff --git a/src/Aop/Framework/AbstractMethodInvocation.php b/src/Aop/Framework/AbstractMethodInvocation.php index 932c7589..a711685d 100644 --- a/src/Aop/Framework/AbstractMethodInvocation.php +++ b/src/Aop/Framework/AbstractMethodInvocation.php @@ -27,7 +27,7 @@ abstract class AbstractMethodInvocation extends AbstractInvocation implements Me /** * Instance of object for invoking */ - protected ?object $instance; + protected ?object $instance = null; /** * Instance of reflection method for invocation diff --git a/tests/Go/Aop/Framework/AbstractMethodInvocationTest.php b/tests/Go/Aop/Framework/AbstractMethodInvocationTest.php index 6ffc80a2..e6a54adb 100644 --- a/tests/Go/Aop/Framework/AbstractMethodInvocationTest.php +++ b/tests/Go/Aop/Framework/AbstractMethodInvocationTest.php @@ -29,4 +29,41 @@ public function testProvidesAccessToAnnotations(): void { $this->assertInstanceOf(AnnotationAccess::class, $this->invocation->getMethod()); } + + public function testInstanceIsInitialized(): void + { + $this->expectNotToPerformAssertions(); + $o = new class extends AbstractMethodInvocation { + + protected static string $propertyName = 'scope'; + public function __construct() + { + parent::__construct([new AroundInterceptor(function () {})], '\Go\Aop\Framework\AbstractMethodInvocationTest', 'testInstanceIsInitialized'); + } + + public function isDynamic(): bool + { + return false; + } + + public function getThis(): ?object + { + return null; + } + + public function getScope(): string + { + return 'testScope'; + } + + public function proceed() + { + if ($this->level < 3) { + $this->__invoke('testInstance'); + } + } + }; + + $o->__invoke('testInstance'); + } }