Skip to content

Commit 27476be

Browse files
committed
Support multiple anonymous class definitions on the same line
1 parent f7fca4a commit 27476be

File tree

6 files changed

+103
-4
lines changed

6 files changed

+103
-4
lines changed

src/Broker/AnonymousClassNameHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function getAnonymousClassName(
3434

3535
return sprintf(
3636
'AnonymousClass%s',
37-
md5(sprintf('%s:%s', $filename, $classNode->getStartLine())),
37+
md5(sprintf('%s:%s', $filename, $classNode->getStartFilePos())),
3838
);
3939
}
4040

tests/PHPStan/Analyser/AnalyserIntegrationTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,27 @@ public function testBug11297(): void
14161416
$this->assertNoErrors($errors);
14171417
}
14181418

1419+
public function testBug5597(): void
1420+
{
1421+
if (PHP_VERSION_ID < 80000) {
1422+
$this->markTestSkipped('Test requires PHP 8.0.');
1423+
}
1424+
1425+
$errors = $this->runAnalyse(__DIR__ . '/data/bug-5597.php');
1426+
$this->assertNoErrors($errors);
1427+
}
1428+
1429+
public function testBug11511(): void
1430+
{
1431+
if (PHP_VERSION_ID < 80000) {
1432+
$this->markTestSkipped('Test requires PHP 8.0.');
1433+
}
1434+
1435+
$errors = $this->runAnalyse(__DIR__ . '/data/bug-11511.php');
1436+
$this->assertCount(1, $errors);
1437+
$this->assertSame('Access to an undefined property object::$bar.', $errors[0]->getMessage());
1438+
}
1439+
14191440
/**
14201441
* @param string[]|null $allAnalysedFiles
14211442
* @return Error[]

tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8335,12 +8335,12 @@ public function dataAnonymousClass(): array
83358335
{
83368336
return [
83378337
[
8338-
'$this(AnonymousClass3301acd9e9d13ba9bbce9581cdb00699)',
8338+
'$this(AnonymousClass6a0687bc4f876de22e6d370597168d67)',
83398339
'$this',
83408340
"'inside'",
83418341
],
83428342
[
8343-
'AnonymousClass3301acd9e9d13ba9bbce9581cdb00699',
8343+
'AnonymousClass6a0687bc4f876de22e6d370597168d67',
83448344
'$foo',
83458345
"'outside'",
83468346
],
@@ -8388,7 +8388,7 @@ public function dataAnonymousClassInTrait(): array
83888388
{
83898389
return [
83908390
[
8391-
'$this(AnonymousClass3de0a9734314db9dec21ba308363ff9a)',
8391+
'$this(AnonymousClassa90f7ae5a3564e08aca97d6fbb39c2b2)',
83928392
'$this',
83938393
],
83948394
];
@@ -8409,6 +8409,44 @@ public function testAnonymousClassNameInTrait(
84098409
);
84108410
}
84118411

8412+
public function dataAnonymousClassNameSameLine(): array
8413+
{
8414+
return [
8415+
[
8416+
'AnonymousClass6540444db24e3b8821f292cc08bb9b6c',
8417+
'$foo',
8418+
'$bar',
8419+
],
8420+
[
8421+
'AnonymousClass7c37a0e958f6b76cfeb23acfa3259ff8',
8422+
'$bar',
8423+
'$baz',
8424+
],
8425+
[
8426+
'AnonymousClassca84fbe02c775710b2735bfe3cbfbb7e',
8427+
'$baz',
8428+
'die',
8429+
],
8430+
];
8431+
}
8432+
8433+
/**
8434+
* @dataProvider dataAnonymousClassNameSameLine
8435+
*/
8436+
public function testAnonymousClassNameSameLine(
8437+
string $description,
8438+
string $expression,
8439+
string $evaluatedPointExpression,
8440+
): void
8441+
{
8442+
$this->assertTypes(
8443+
__DIR__ . '/data/anonymous-class-name-same-line.php',
8444+
$description,
8445+
$expression,
8446+
$evaluatedPointExpression,
8447+
);
8448+
}
8449+
84128450
public function dataDynamicConstants(): array
84138451
{
84148452
return [
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
namespace AnonymousClassNameSameLine;
4+
5+
$foo = new class {}; $bar = new class {}; $baz = new class {}; die;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php declare(strict_types = 1); // lint >= 8.0
2+
3+
namespace Bug11511;
4+
5+
$myObject = new class (new class { public string $bar = 'test'; }) {
6+
public function __construct(public object $foo)
7+
{
8+
}
9+
};
10+
echo $myObject->foo->bar;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types = 1); // lint >= 8.0
2+
3+
namespace Bug5597;
4+
5+
interface InterfaceA {}
6+
7+
class ClassA implements InterfaceA {}
8+
9+
class ClassB
10+
{
11+
public function __construct(
12+
private InterfaceA $parameterA,
13+
) {
14+
}
15+
16+
public function test() : InterfaceA
17+
{
18+
return $this->parameterA;
19+
}
20+
}
21+
22+
$classA = new class() extends ClassA {};
23+
$thisWorks = new class($classA) extends ClassB {};
24+
25+
$thisFailsWithTwoErrors = new class(new class() extends ClassA {}) extends ClassB {};

0 commit comments

Comments
 (0)