Skip to content

Commit 9f8c741

Browse files
Update describe
1 parent 213fb95 commit 9f8c741

File tree

6 files changed

+40
-43
lines changed

6 files changed

+40
-43
lines changed

src/Type/MixedType.php

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
use PHPStan\Type\Generic\TemplateType;
3737
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
3838
use PHPStan\Type\Traits\NonGenericTypeTrait;
39+
use PHPStan\Type\Traits\SubstractableTypeTrait;
3940
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
4041
use function get_class;
4142
use function sprintf;
@@ -47,6 +48,7 @@ class MixedType implements CompoundType, SubtractableType
4748
use NonGenericTypeTrait;
4849
use UndecidedComparisonCompoundTypeTrait;
4950
use NonGeneralizableTypeTrait;
51+
use SubstractableTypeTrait;
5052

5153
private ?Type $subtractedType;
5254

@@ -471,23 +473,9 @@ public function describe(VerbosityLevel $level): string
471473
return $level->handle(
472474
static fn (): string => 'mixed',
473475
static fn (): string => 'mixed',
476+
fn (): string => 'mixed'.$this->describeSubstractedType($this->subtractedType, $level),
474477
function () use ($level): string {
475-
$description = 'mixed';
476-
if ($this->subtractedType !== null) {
477-
$description .= $this->subtractedType instanceof UnionType
478-
? sprintf('~(%s)', $this->subtractedType->describe($level))
479-
: sprintf('~%s', $this->subtractedType->describe($level));
480-
}
481-
482-
return $description;
483-
},
484-
function () use ($level): string {
485-
$description = 'mixed';
486-
if ($this->subtractedType !== null) {
487-
$description .= $this->subtractedType instanceof UnionType
488-
? sprintf('~(%s)', $this->subtractedType->describe($level))
489-
: sprintf('~%s', $this->subtractedType->describe($level));
490-
}
478+
$description = 'mixed'.$this->describeSubstractedType($this->subtractedType, $level);
491479

492480
if ($this->isExplicitMixed) {
493481
$description .= '=explicit';

src/Type/ObjectType.php

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
use PHPStan\Type\Traits\NonArrayTypeTrait;
4747
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
4848
use PHPStan\Type\Traits\NonGenericTypeTrait;
49+
use PHPStan\Type\Traits\SubstractableTypeTrait;
4950
use PHPStan\Type\Traits\UndecidedComparisonTypeTrait;
5051
use Stringable;
5152
use Throwable;
@@ -68,6 +69,7 @@ class ObjectType implements TypeWithClassName, SubtractableType
6869
use NonGenericTypeTrait;
6970
use UndecidedComparisonTypeTrait;
7071
use NonGeneralizableTypeTrait;
72+
use SubstractableTypeTrait;
7173

7274
private const EXTRA_OFFSET_CLASSES = [
7375
'DOMNamedNodeMap', // Only read and existence
@@ -504,16 +506,7 @@ public function describe(VerbosityLevel $level): string
504506
return $reflectionProvider->getClassName($this->className);
505507
};
506508

507-
$preciseWithSubtracted = function () use ($level): string {
508-
$description = $this->className;
509-
if ($this->subtractedType !== null) {
510-
$description .= $this->subtractedType instanceof UnionType
511-
? sprintf('~(%s)', $this->subtractedType->describe($level))
512-
: sprintf('~%s', $this->subtractedType->describe($level));
513-
}
514-
515-
return $description;
516-
};
509+
$preciseWithSubtracted = fn (): string => $this->className.$this->describeSubstractedType($this->subtractedType, $level);
517510

518511
return $level->handle(
519512
$preciseNameCallback,
@@ -559,11 +552,7 @@ private function describeCache(): string
559552
$description .= '<' . implode(', ', $typeDescriptions) . '>';
560553
}
561554

562-
if ($this->subtractedType !== null) {
563-
$description .= $this->subtractedType instanceof UnionType
564-
? sprintf('~(%s)', $this->subtractedType->describe(VerbosityLevel::cache()))
565-
: sprintf('~%s', $this->subtractedType->describe(VerbosityLevel::cache()));
566-
}
555+
$description .= $this->describeSubstractedType($this->subtractedType, VerbosityLevel::cache());
567556

568557
$reflection = $this->classReflection;
569558
if ($reflection !== null) {

src/Type/ObjectWithoutClassType.php

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
88
use PHPStan\Type\Traits\NonGenericTypeTrait;
99
use PHPStan\Type\Traits\ObjectTypeTrait;
10+
use PHPStan\Type\Traits\SubstractableTypeTrait;
1011
use PHPStan\Type\Traits\UndecidedComparisonTypeTrait;
1112
use function sprintf;
1213

@@ -18,6 +19,7 @@ class ObjectWithoutClassType implements SubtractableType
1819
use NonGenericTypeTrait;
1920
use UndecidedComparisonTypeTrait;
2021
use NonGeneralizableTypeTrait;
22+
use SubstractableTypeTrait;
2123

2224
private ?Type $subtractedType;
2325

@@ -120,16 +122,7 @@ public function describe(VerbosityLevel $level): string
120122
return $level->handle(
121123
static fn (): string => 'object',
122124
static fn (): string => 'object',
123-
function () use ($level): string {
124-
$description = 'object';
125-
if ($this->subtractedType !== null) {
126-
$description .= $this->subtractedType instanceof UnionType
127-
? sprintf('~(%s)', $this->subtractedType->describe($level))
128-
: sprintf('~%s', $this->subtractedType->describe($level));
129-
}
130-
131-
return $description;
132-
},
125+
fn (): string => 'object'.$this->describeSubstractedType($this->subtractedType, $level),
133126
);
134127
}
135128

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace PHPStan\Type\Traits;
4+
5+
use PHPStan\Type\SubtractableType;
6+
use PHPStan\Type\Type;
7+
use PHPStan\Type\UnionType;
8+
use PHPStan\Type\VerbosityLevel;
9+
10+
trait SubstractableTypeTrait
11+
{
12+
public function describeSubstractedType(?Type $subtractedType, VerbosityLevel $level): string
13+
{
14+
if (null === $subtractedType) {
15+
return '';
16+
}
17+
18+
if (
19+
$subtractedType instanceof UnionType
20+
|| ($subtractedType instanceof SubtractableType && null !== $subtractedType->getSubtractedType())
21+
) {
22+
return sprintf('~(%s)', $subtractedType->describe($level));
23+
}
24+
25+
return sprintf('~%s', $subtractedType->describe($level));
26+
}
27+
}

tests/PHPStan/Analyser/nsrt/subtracted.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function sayHello($date, $foo): void
2121
if ($foo) {
2222
$date = new \stdClass();
2323
}
24-
assertType('mixed~object~stdClass', $date);
24+
assertType('mixed~(object~stdClass)', $date);
2525

2626
if (is_object($date)) {
2727
assertType('stdClass', $date);

tests/PHPStan/Type/TypeCombinatorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1140,7 +1140,7 @@ public static function dataUnion(): iterable
11401140
new ObjectType('InvalidArgumentException'),
11411141
],
11421142
MixedType::class,
1143-
'mixed~Exception~InvalidArgumentException=implicit',
1143+
'mixed~(Exception~InvalidArgumentException)=implicit',
11441144
],
11451145
[
11461146
[

0 commit comments

Comments
 (0)