Skip to content

Commit 0372feb

Browse files
committed
Merge remote-tracking branch 'origin/3.x'
2 parents a0930b2 + 45c19c9 commit 0372feb

10 files changed

+196
-4
lines changed

Diff for: composer.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@
5353
"Go\\Tests\\TestProject\\": "tests/Fixtures/project/src/"
5454
},
5555
"files": [
56-
"tests/functions.php"
56+
"tests/functions.php",
57+
"tests/Go/Stubs/ClassWithoutNamespace.php"
5758
]
5859
},
5960

Diff for: src/Instrument/Transformer/SelfValueVisitor.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public function beforeTraverse(array $nodes)
8181
public function enterNode(Node $node)
8282
{
8383
if ($node instanceof Namespace_) {
84-
$this->namespace = $node->name->toString();
84+
$this->namespace = !empty($node->name) ? $node->name->toString() : null;
8585
} elseif ($node instanceof Class_) {
8686
if ($node->name !== null) {
8787
$this->className = new Name($node->name->toString());

Diff for: src/Proxy/ClassProxyGenerator.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public function __construct(
109109

110110
$this->generator = new ClassGenerator(
111111
$originalClass->getShortName(),
112-
$originalClass->getNamespaceName(),
112+
!empty($originalClass->getNamespaceName()) ? $originalClass->getNamespaceName() : null,
113113
$originalClass->isFinal() ? ClassGenerator::FLAG_FINAL : null,
114114
$parentClassName,
115115
$introducedInterfaces,

Diff for: src/Proxy/Part/InterceptedMethodGenerator.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public function __construct(ReflectionMethod $reflectionMethod, string $body, bo
3939
if ($reflectionMethod->hasReturnType()) {
4040
$reflectionReturnType = $reflectionMethod->getReturnType();
4141
if ($reflectionReturnType instanceof ReflectionNamedType) {
42-
$returnTypeName = $reflectionReturnType->getName();
42+
$returnTypeName = ($reflectionReturnType->allowsNull() ? '?' : '') . $reflectionReturnType->getName();
4343
} else {
4444
$returnTypeName = (string)$reflectionReturnType;
4545
}

Diff for: tests/Go/Aop/Framework/AbstractMethodInvocationTest.php

+47
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,51 @@ public function testInvocationReturnsMethod(): void
2424
$this->assertEquals(parent::class, $this->invocation->getMethod()->class);
2525
$this->assertEquals('setUp', $this->invocation->getMethod()->name);
2626
}
27+
28+
/**
29+
* @link https://github.com/goaop/framework/issues/481
30+
*/
31+
public function testInstanceIsInitialized(): void
32+
{
33+
$this->expectNotToPerformAssertions();
34+
35+
$o = new class extends AbstractMethodInvocation {
36+
37+
protected static string $propertyName = 'scope';
38+
39+
/**
40+
* @var (string&class-string) Class name scope for static invocation
41+
*/
42+
protected string $scope;
43+
44+
public function __construct()
45+
{
46+
parent::__construct([new AroundInterceptor(function () {})], AbstractMethodInvocationTest::class, 'testInstanceIsInitialized');
47+
}
48+
49+
public function isDynamic(): bool
50+
{
51+
return false;
52+
}
53+
54+
public function getThis(): ?object
55+
{
56+
return null;
57+
}
58+
59+
public function getScope(): string
60+
{
61+
return self::class;
62+
}
63+
64+
public function proceed(): void
65+
{
66+
if ($this->level < 3) {
67+
$this->__invoke($this->scope);
68+
}
69+
}
70+
};
71+
72+
$o->__invoke($o::class);
73+
}
2774
}

Diff for: tests/Go/Instrument/Transformer/SelfValueTransformerTest.php

+10
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,14 @@ public function testTransformerReplacesAllSelfPlaces(): void
7272
$expected = file_get_contents(__DIR__ . '/_files/file-with-self-transformed.php');
7373
$this->assertSame($expected, (string) $metadata->source);
7474
}
75+
76+
public function testTransformerReplacesAllSelfPlacesWithoutNamespace(): void
77+
{
78+
$testFile = fopen(__DIR__ . '/_files/file-with-self-no-namespace.php', 'rb');
79+
$content = stream_get_contents($testFile);
80+
$metadata = new StreamMetaData($testFile, $content);
81+
$this->transformer->transform($metadata);
82+
$expected = file_get_contents(__DIR__ . '/_files/file-with-self-no-namespace-transformed.php');
83+
$this->assertSame($expected, (string) $metadata->source);
84+
}
7585
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/** @noinspection PhpIllegalPsrClassPathInspection */
3+
declare(strict_types=1);
4+
5+
class ClassWithSelfNoNamespace extends \Exception
6+
{
7+
const CLASS_CONST = \ClassWithSelfNoNamespace::class;
8+
9+
private static $foo = 42;
10+
11+
private \ClassWithSelfNoNamespace $instance;
12+
13+
public function acceptsAndReturnsSelf(\ClassWithSelfNoNamespace $instance): \ClassWithSelfNoNamespace
14+
{
15+
return $instance;
16+
}
17+
18+
public function containsClosureWithSelf()
19+
{
20+
$func = function (\ClassWithSelfNoNamespace $instance): \ClassWithSelfNoNamespace {
21+
return $instance;
22+
};
23+
$func($this);
24+
}
25+
26+
public function staticMethodCall()
27+
{
28+
return \ClassWithSelfNoNamespace::staticPropertyAccess();
29+
}
30+
31+
public function classConstantFetch()
32+
{
33+
return \ClassWithSelfNoNamespace::class . \ClassWithSelfNoNamespace::CLASS_CONST;
34+
}
35+
36+
public static function staticPropertyAccess()
37+
{
38+
return self::$foo;
39+
}
40+
41+
public function newInstanceCreation()
42+
{
43+
return new \ClassWithSelfNoNamespace;
44+
}
45+
46+
public function catchSection()
47+
{
48+
try {
49+
throw new \ClassWithSelfNoNamespace;
50+
} catch (\ClassWithSelfNoNamespace $exception) {
51+
// Nop
52+
}
53+
}
54+
55+
public function instanceCheck()
56+
{
57+
if ($this instanceof \ClassWithSelfNoNamespace) {
58+
// Nop
59+
}
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
/** @noinspection PhpIllegalPsrClassPathInspection */
3+
declare(strict_types=1);
4+
5+
class ClassWithSelfNoNamespace extends \Exception
6+
{
7+
const CLASS_CONST = self::class;
8+
9+
private static $foo = 42;
10+
11+
private self $instance;
12+
13+
public function acceptsAndReturnsSelf(self $instance): self
14+
{
15+
return $instance;
16+
}
17+
18+
public function containsClosureWithSelf()
19+
{
20+
$func = function (self $instance): self {
21+
return $instance;
22+
};
23+
$func($this);
24+
}
25+
26+
public function staticMethodCall()
27+
{
28+
return self::staticPropertyAccess();
29+
}
30+
31+
public function classConstantFetch()
32+
{
33+
return self::class . self::CLASS_CONST;
34+
}
35+
36+
public static function staticPropertyAccess()
37+
{
38+
return self::$foo;
39+
}
40+
41+
public function newInstanceCreation()
42+
{
43+
return new self;
44+
}
45+
46+
public function catchSection()
47+
{
48+
try {
49+
throw new self;
50+
} catch (self $exception) {
51+
// Nop
52+
}
53+
}
54+
55+
public function instanceCheck()
56+
{
57+
if ($this instanceof self) {
58+
// Nop
59+
}
60+
}
61+
}

Diff for: tests/Go/Proxy/ClassProxyGeneratorTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public static function dataGenerator(): array
9292
[First::class, 'publicMethod'],
9393
[First::class, 'protectedMethod'],
9494
[First::class, 'passByReference'],
95+
[\ClassWithoutNamespace::class, 'publicMethod'],
9596
];
9697
}
9798
}

Diff for: tests/Go/Stubs/ClassWithoutNamespace.php

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php /** @noinspection PhpIllegalPsrClassPathInspection */
2+
3+
4+
class ClassWithoutNamespace
5+
{
6+
public function publicMethod(): int
7+
{
8+
return 1;
9+
}
10+
11+
}

0 commit comments

Comments
 (0)