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
16 changes: 14 additions & 2 deletions src/Reflection/BetterReflection/BetterReflectionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\Type;
use function array_key_exists;
use function array_key_first;
use function array_map;
use function base64_decode;
use function in_array;
Expand Down Expand Up @@ -217,12 +218,23 @@ public function getAnonymousClassReflection(Node\Stmt\Class_ $classNode, Scope $
null,
);

$displayParentName = $reflectionClass->getParentClassName();
if ($displayParentName === null) {
// https://3v4l.org/6FBuP
$classInterfaceNames = $reflectionClass->getInterfaceNames();
if ($classInterfaceNames !== []) {
$displayParentName = $classInterfaceNames[array_key_first($classInterfaceNames)];
} else {
$displayParentName = 'class';
}
}

/** @var int|null $classLineIndex */
$classLineIndex = $classNode->getAttribute(AnonymousClassVisitor::ATTRIBUTE_LINE_INDEX);
if ($classLineIndex === null) {
$displayName = sprintf('class@anonymous/%s:%s', $filename, $classNode->getStartLine());
$displayName = sprintf('%s@anonymous/%s:%s', $displayParentName, $filename, $classNode->getStartLine());
} else {
$displayName = sprintf('class@anonymous/%s:%s:%d', $filename, $classNode->getStartLine(), $classLineIndex);
$displayName = sprintf('%s@anonymous/%s:%s:%d', $displayParentName, $filename, $classNode->getStartLine(), $classLineIndex);
}

self::$anonymousClasses[$className] = new ClassReflection(
Expand Down
4 changes: 2 additions & 2 deletions tests/PHPStan/Analyser/AnalyserIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -541,9 +541,9 @@ public function testBug6442(): void
{
$errors = $this->runAnalyse(__DIR__ . '/data/bug-6442.php');
$this->assertCount(2, $errors);
$this->assertSame('Dumped type: \'Bug6442\\\A\'', $errors[0]->getMessage());
$this->assertSame('Dumped type: \'Bug6442\\\B\'', $errors[0]->getMessage());
$this->assertSame(9, $errors[0]->getLine());
$this->assertSame('Dumped type: \'Bug6442\\\B\'', $errors[1]->getMessage());
$this->assertSame('Dumped type: \'Bug6442\\\A\'', $errors[1]->getMessage());
$this->assertSame(9, $errors[1]->getLine());
}

Expand Down
4 changes: 2 additions & 2 deletions tests/PHPStan/Levels/data/stubValidator-0.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
"ignorable": false
},
{
"message": "Method class@anonymous/stubValidator/stubs.php:27::doFoo() has no return type specified.",
"message": "Method ArrayIterator@anonymous/stubValidator/stubs.php:27::doFoo() has no return type specified.",
"line": 30,
"ignorable": false
},
{
"message": "Parameter $foo of method class@anonymous/stubValidator/stubs.php:27::doFoo() has invalid type StubValidator\\Foooooooo.",
"message": "Parameter $foo of method ArrayIterator@anonymous/stubValidator/stubs.php:27::doFoo() has invalid type StubValidator\\Foooooooo.",
"line": 30,
"ignorable": false
}
Expand Down
49 changes: 49 additions & 0 deletions tests/PHPStan/Reflection/AnonymousClassReflectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,55 @@ public function testReflection(): void
]),
9,
],
[
implode("\n", [
'name: AnonymousClass1d622e3ff3a656e68d55eafbd25eaef1',
'display name: AnonymousClassReflectionTest\A@anonymous/tests/PHPStan/Reflection/data/anonymous-classes.php:17:1',
]),
17,
],
[
implode("\n", [
'name: AnonymousClass6e1acc8e948827c8d0439a2225fdbdd0',
'display name: AnonymousClassReflectionTest\A@anonymous/tests/PHPStan/Reflection/data/anonymous-classes.php:17:2',
]),
17,
],
[
implode("\n", [
'name: AnonymousClass2a49db3d44479dddd8beaea4ea8131fb',
'display name: AnonymousClassReflectionTest\A@anonymous/tests/PHPStan/Reflection/data/anonymous-classes.php:19:1',
]),
19,
],
[
implode("\n", [
'name: AnonymousClass337463cf86ee25e526f445630960b336',
'display name: AnonymousClassReflectionTest\A@anonymous/tests/PHPStan/Reflection/data/anonymous-classes.php:19:2',
]),
19,
],
[
implode("\n", [
'name: AnonymousClassda3e79cc45f826d60295f848abab37e7',
'display name: AnonymousClassReflectionTest\U@anonymous/tests/PHPStan/Reflection/data/anonymous-classes.php:29',
]),
29,
],
[
implode("\n", [
'name: AnonymousClassc06612bf3776bbe5e50870a8c3151186',
'display name: AnonymousClassReflectionTest\U@anonymous/tests/PHPStan/Reflection/data/anonymous-classes.php:31',
]),
31,
],
[
implode("\n", [
'name: AnonymousClassbee6eba8c721d73d649fcc9d361f5902',
'display name: AnonymousClassReflectionTest\V@anonymous/tests/PHPStan/Reflection/data/anonymous-classes.php:33',
]),
33,
],
]);
}

Expand Down
20 changes: 20 additions & 0 deletions tests/PHPStan/Reflection/data/anonymous-classes.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,23 @@ public function __construct(object $object)
{
}
};

class A {}

new class extends A {}; new class extends A {};

new class (new class extends A {}) extends A {
public function __construct(object $object)
{
}
};

interface U {}

interface V {}

new class implements U {};

new class implements U, V {};

new class implements V, U {};
2 changes: 1 addition & 1 deletion tests/PHPStan/Rules/Classes/RequireImplementsRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function testRule(): void
137,
],
[
'Trait IncompatibleRequireImplements\ValidPsalmTrait requires using class to implement IncompatibleRequireImplements\RequiredInterface2, but class@anonymous/tests/PHPStan/Rules/PhpDoc/data/incompatible-require-implements.php:164 does not.',
'Trait IncompatibleRequireImplements\ValidPsalmTrait requires using class to implement IncompatibleRequireImplements\RequiredInterface2, but IncompatibleRequireImplements\RequiredInterface@anonymous/tests/PHPStan/Rules/PhpDoc/data/incompatible-require-implements.php:164 does not.',
164,
],
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function testRule(): void
24,
],
[
'Non-abstract class class@anonymous/tests/PHPStan/Rules/Methods/data/missing-method-impl.php:41 contains abstract method doFoo() from interface MissingMethodImpl\Foo.',
'Non-abstract class MissingMethodImpl\Foo@anonymous/tests/PHPStan/Rules/Methods/data/missing-method-impl.php:41 contains abstract method doFoo() from interface MissingMethodImpl\Foo.',
41,
],
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ public function testRedeclaredReadonlyProperties(): void
70,
],
[
'Readonly property class@anonymous/tests/PHPStan/Rules/Properties/data/redeclare-readonly-property.php:117::$myProp is already assigned.',
'Readonly property RedeclareReadonlyProperty\A@anonymous/tests/PHPStan/Rules/Properties/data/redeclare-readonly-property.php:117::$myProp is already assigned.',
121,
],
[
Expand Down
Loading