57
57
use PHPStan \PhpDocParser \Ast \Type \ObjectShapeItemNode ;
58
58
use PHPStan \PhpDocParser \Ast \Type \ObjectShapeNode ;
59
59
use PHPStan \PhpDocParser \Ast \Type \OffsetAccessTypeNode ;
60
+ use PHPStan \PhpDocParser \Ast \Type \SubtractionTypeNode ;
60
61
use PHPStan \PhpDocParser \Ast \Type \ThisTypeNode ;
61
62
use PHPStan \PhpDocParser \Ast \Type \TypeNode ;
62
63
use PHPStan \PhpDocParser \Ast \Type \UnionTypeNode ;
@@ -129,32 +130,47 @@ final class Printer
129
130
CallableTypeNode::class,
130
131
UnionTypeNode::class,
131
132
IntersectionTypeNode::class,
133
+ SubtractionTypeNode::class,
132
134
],
133
135
ArrayTypeNode::class . '->type ' => [
134
136
CallableTypeNode::class,
135
137
UnionTypeNode::class,
136
138
IntersectionTypeNode::class,
139
+ SubtractionTypeNode::class,
137
140
ConstTypeNode::class,
138
141
NullableTypeNode::class,
139
142
],
140
143
OffsetAccessTypeNode::class . '->type ' => [
141
144
CallableTypeNode::class,
142
145
UnionTypeNode::class,
143
146
IntersectionTypeNode::class,
147
+ SubtractionTypeNode::class,
144
148
NullableTypeNode::class,
145
149
],
150
+ SubtractionTypeNode::class . '->type ' => [
151
+ UnionTypeNode::class,
152
+ IntersectionTypeNode::class,
153
+ SubtractionTypeNode::class,
154
+ ],
155
+ SubtractionTypeNode::class . '->subtractedType ' => [
156
+ UnionTypeNode::class,
157
+ IntersectionTypeNode::class,
158
+ SubtractionTypeNode::class,
159
+ ],
146
160
];
147
161
148
162
/** @var array<string, list<class-string<TypeNode>>> */
149
163
private $ parenthesesListMap = [
150
164
IntersectionTypeNode::class . '->types ' => [
151
165
IntersectionTypeNode::class,
152
166
UnionTypeNode::class,
167
+ SubtractionTypeNode::class,
153
168
NullableTypeNode::class,
154
169
],
155
170
UnionTypeNode::class . '->types ' => [
156
171
IntersectionTypeNode::class,
157
172
UnionTypeNode::class,
173
+ SubtractionTypeNode::class,
158
174
NullableTypeNode::class,
159
175
],
160
176
];
@@ -387,7 +403,12 @@ private function printType(TypeNode $node): string
387
403
return $ this ->printOffsetAccessType ($ node ->type ) . '[] ' ;
388
404
}
389
405
if ($ node instanceof CallableTypeNode) {
390
- if ($ node ->returnType instanceof CallableTypeNode || $ node ->returnType instanceof UnionTypeNode || $ node ->returnType instanceof IntersectionTypeNode) {
406
+ if (
407
+ $ node ->returnType instanceof CallableTypeNode
408
+ || $ node ->returnType instanceof UnionTypeNode
409
+ || $ node ->returnType instanceof IntersectionTypeNode
410
+ || $ node ->returnType instanceof SubtractionTypeNode
411
+ ) {
391
412
$ returnType = $ this ->wrapInParentheses ($ node ->returnType );
392
413
} else {
393
414
$ returnType = $ this ->printType ($ node ->returnType );
@@ -450,6 +471,7 @@ private function printType(TypeNode $node): string
450
471
if (
451
472
$ type instanceof IntersectionTypeNode
452
473
|| $ type instanceof UnionTypeNode
474
+ || $ type instanceof SubtractionTypeNode
453
475
|| $ type instanceof NullableTypeNode
454
476
) {
455
477
$ items [] = $ this ->wrapInParentheses ($ type );
@@ -461,11 +483,14 @@ private function printType(TypeNode $node): string
461
483
462
484
return implode ($ node instanceof IntersectionTypeNode ? '& ' : '| ' , $ items );
463
485
}
486
+ if ($ node instanceof SubtractionTypeNode) {
487
+ return $ this ->printSubtractionType ($ node ->type ) . '~ ' . $ this ->printSubtractionType ($ node ->subtractedType );
488
+ }
464
489
if ($ node instanceof InvalidTypeNode) {
465
490
return (string ) $ node ;
466
491
}
467
492
if ($ node instanceof NullableTypeNode) {
468
- if ($ node ->type instanceof IntersectionTypeNode || $ node ->type instanceof UnionTypeNode) {
493
+ if ($ node ->type instanceof IntersectionTypeNode || $ node ->type instanceof UnionTypeNode || $ node -> type instanceof SubtractionTypeNode ) {
469
494
return '?( ' . $ this ->printType ($ node ->type ) . ') ' ;
470
495
}
471
496
@@ -519,6 +544,15 @@ private function printOffsetAccessType(TypeNode $type): string
519
544
return $ this ->printType ($ type );
520
545
}
521
546
547
+ private function printSubtractionType (TypeNode $ type ): string
548
+ {
549
+ if ($ type instanceof UnionTypeNode || $ type instanceof IntersectionTypeNode) {
550
+ return $ this ->wrapInParentheses ($ type );
551
+ }
552
+
553
+ return $ this ->printType ($ type );
554
+ }
555
+
522
556
private function printConstExpr (ConstExprNode $ node ): string
523
557
{
524
558
// this is fine - ConstExprNode classes do not contain nodes that need smart printer logic
0 commit comments