Skip to content

Commit f1d95cf

Browse files
committed
Add Type::toNativePhpTypeNode() and NativeTypePosition
Exports a type as a native PHP type declaration node (Identifier, Name or ComplexType), or null when the type cannot be expressed in the given position. NativeTypePosition is a value object like VerbosityLevel. It carries the PHP version and answers feature questions (isCallableAllowed(), isIntersectionAllowed(), isNullableAllowed(), ...) rather than naming the position. UnionType hands its members a derived position, so an intersection inside a union is only emitted from PHP 8.2 (DNF) while a standalone intersection is emitted from PHP 8.1. Foo|null is preferred as ?Foo wherever the nullable syntax is allowed. The compound halves live in NativePhpTypeNodeHelper so the turbo extension calls the same code; the other shadowed types implement the method natively. Amp-Thread-ID: https://ampcode.com/threads/T-01a179f2-995f-7745-8d8c-4c174ba5c0ce
1 parent 0d32f8b commit f1d95cf

128 files changed

Lines changed: 2067 additions & 452 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎src/Type/Accessory/AccessoryArrayListType.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\ComplexType;
6+
use PhpParser\Node\Identifier;
7+
use PhpParser\Node\Name;
58
use PHPStan\Php\PhpVersion;
69
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
710
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -19,6 +22,7 @@
1922
use PHPStan\Type\IntersectionType;
2023
use PHPStan\Type\IsSuperTypeOfResult;
2124
use PHPStan\Type\MixedType;
25+
use PHPStan\Type\NativeTypePosition;
2226
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
2327
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
2428
use PHPStan\Type\Traits\NonGenericTypeTrait;
@@ -579,6 +583,12 @@ public function toPhpDocNode(): TypeNode
579583
return new IdentifierTypeNode('list');
580584
}
581585

586+
/** @return Identifier|Name|ComplexType|null */
587+
public function toNativePhpTypeNode(NativeTypePosition $position)
588+
{
589+
return $position->isArrayAllowed() ? new Identifier('array') : null;
590+
}
591+
582592
public function hasTemplateOrLateResolvableType(): bool
583593
{
584594
return false;

‎src/Type/Accessory/AccessoryDecimalIntegerStringType.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\ComplexType;
6+
use PhpParser\Node\Identifier;
7+
use PhpParser\Node\Name;
58
use PHPStan\Php\PhpVersion;
69
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
710
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -24,6 +27,7 @@
2427
use PHPStan\Type\IntegerType;
2528
use PHPStan\Type\IntersectionType;
2629
use PHPStan\Type\IsSuperTypeOfResult;
30+
use PHPStan\Type\NativeTypePosition;
2731
use PHPStan\Type\StringType;
2832
use PHPStan\Type\Traits\NonArrayTypeTrait;
2933
use PHPStan\Type\Traits\NonGenericTypeTrait;
@@ -480,6 +484,12 @@ public function toPhpDocNode(): TypeNode
480484
return new IdentifierTypeNode($this->inverse ? 'non-decimal-int-string' : 'decimal-int-string');
481485
}
482486

487+
/** @return Identifier|Name|ComplexType|null */
488+
public function toNativePhpTypeNode(NativeTypePosition $position)
489+
{
490+
return $position->isScalarAllowed() ? new Identifier('string') : null;
491+
}
492+
483493
public function hasTemplateOrLateResolvableType(): bool
484494
{
485495
return false;

‎src/Type/Accessory/AccessoryLiteralStringType.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\ComplexType;
6+
use PhpParser\Node\Identifier;
7+
use PhpParser\Node\Name;
58
use PHPStan\Php\PhpVersion;
69
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
710
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -21,6 +24,7 @@
2124
use PHPStan\Type\IntersectionType;
2225
use PHPStan\Type\IsSuperTypeOfResult;
2326
use PHPStan\Type\MixedType;
27+
use PHPStan\Type\NativeTypePosition;
2428
use PHPStan\Type\ObjectWithoutClassType;
2529
use PHPStan\Type\StringType;
2630
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
@@ -401,6 +405,12 @@ public function toPhpDocNode(): TypeNode
401405
return new IdentifierTypeNode('literal-string');
402406
}
403407

408+
/** @return Identifier|Name|ComplexType|null */
409+
public function toNativePhpTypeNode(NativeTypePosition $position)
410+
{
411+
return $position->isScalarAllowed() ? new Identifier('string') : null;
412+
}
413+
404414
public function hasTemplateOrLateResolvableType(): bool
405415
{
406416
return false;

‎src/Type/Accessory/AccessoryLowercaseStringType.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\ComplexType;
6+
use PhpParser\Node\Identifier;
7+
use PhpParser\Node\Name;
58
use PHPStan\Php\PhpVersion;
69
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
710
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -21,6 +24,7 @@
2124
use PHPStan\Type\IntegerType;
2225
use PHPStan\Type\IntersectionType;
2326
use PHPStan\Type\IsSuperTypeOfResult;
27+
use PHPStan\Type\NativeTypePosition;
2428
use PHPStan\Type\ObjectWithoutClassType;
2529
use PHPStan\Type\StringType;
2630
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
@@ -406,6 +410,12 @@ public function toPhpDocNode(): TypeNode
406410
return new IdentifierTypeNode('lowercase-string');
407411
}
408412

413+
/** @return Identifier|Name|ComplexType|null */
414+
public function toNativePhpTypeNode(NativeTypePosition $position)
415+
{
416+
return $position->isScalarAllowed() ? new Identifier('string') : null;
417+
}
418+
409419
public function hasTemplateOrLateResolvableType(): bool
410420
{
411421
return false;

‎src/Type/Accessory/AccessoryNonEmptyStringType.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\ComplexType;
6+
use PhpParser\Node\Identifier;
7+
use PhpParser\Node\Name;
58
use PHPStan\Php\PhpVersion;
69
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
710
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -22,6 +25,7 @@
2225
use PHPStan\Type\IntegerType;
2326
use PHPStan\Type\IntersectionType;
2427
use PHPStan\Type\IsSuperTypeOfResult;
28+
use PHPStan\Type\NativeTypePosition;
2529
use PHPStan\Type\ObjectWithoutClassType;
2630
use PHPStan\Type\StringType;
2731
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
@@ -410,6 +414,12 @@ public function toPhpDocNode(): TypeNode
410414
return new IdentifierTypeNode('non-empty-string');
411415
}
412416

417+
/** @return Identifier|Name|ComplexType|null */
418+
public function toNativePhpTypeNode(NativeTypePosition $position)
419+
{
420+
return $position->isScalarAllowed() ? new Identifier('string') : null;
421+
}
422+
413423
public function hasTemplateOrLateResolvableType(): bool
414424
{
415425
return false;

‎src/Type/Accessory/AccessoryNonFalsyStringType.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\ComplexType;
6+
use PhpParser\Node\Identifier;
7+
use PhpParser\Node\Name;
58
use PHPStan\Php\PhpVersion;
69
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
710
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -22,6 +25,7 @@
2225
use PHPStan\Type\IntegerType;
2326
use PHPStan\Type\IntersectionType;
2427
use PHPStan\Type\IsSuperTypeOfResult;
28+
use PHPStan\Type\NativeTypePosition;
2529
use PHPStan\Type\NullType;
2630
use PHPStan\Type\ObjectWithoutClassType;
2731
use PHPStan\Type\StringType;
@@ -407,6 +411,12 @@ public function toPhpDocNode(): TypeNode
407411
return new IdentifierTypeNode('non-falsy-string');
408412
}
409413

414+
/** @return Identifier|Name|ComplexType|null */
415+
public function toNativePhpTypeNode(NativeTypePosition $position)
416+
{
417+
return $position->isScalarAllowed() ? new Identifier('string') : null;
418+
}
419+
410420
public function hasTemplateOrLateResolvableType(): bool
411421
{
412422
return false;

‎src/Type/Accessory/AccessoryNumericStringType.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\ComplexType;
6+
use PhpParser\Node\Identifier;
7+
use PhpParser\Node\Name;
58
use PHPStan\DependencyInjection\ReportUnsafeArrayStringKeyCastingToggle;
69
use PHPStan\Php\PhpVersion;
710
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
@@ -23,6 +26,7 @@
2326
use PHPStan\Type\IntegerType;
2427
use PHPStan\Type\IntersectionType;
2528
use PHPStan\Type\IsSuperTypeOfResult;
29+
use PHPStan\Type\NativeTypePosition;
2630
use PHPStan\Type\StringType;
2731
use PHPStan\Type\Traits\NonArrayTypeTrait;
2832
use PHPStan\Type\Traits\NonCallableTypeTrait;
@@ -419,6 +423,12 @@ public function toPhpDocNode(): TypeNode
419423
return new IdentifierTypeNode('numeric-string');
420424
}
421425

426+
/** @return Identifier|Name|ComplexType|null */
427+
public function toNativePhpTypeNode(NativeTypePosition $position)
428+
{
429+
return $position->isScalarAllowed() ? new Identifier('string') : null;
430+
}
431+
422432
public function hasTemplateOrLateResolvableType(): bool
423433
{
424434
return false;

‎src/Type/Accessory/AccessoryUppercaseStringType.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\ComplexType;
6+
use PhpParser\Node\Identifier;
7+
use PhpParser\Node\Name;
58
use PHPStan\Php\PhpVersion;
69
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
710
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -21,6 +24,7 @@
2124
use PHPStan\Type\IntegerType;
2225
use PHPStan\Type\IntersectionType;
2326
use PHPStan\Type\IsSuperTypeOfResult;
27+
use PHPStan\Type\NativeTypePosition;
2428
use PHPStan\Type\ObjectWithoutClassType;
2529
use PHPStan\Type\StringType;
2630
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
@@ -406,6 +410,12 @@ public function toPhpDocNode(): TypeNode
406410
return new IdentifierTypeNode('uppercase-string');
407411
}
408412

413+
/** @return Identifier|Name|ComplexType|null */
414+
public function toNativePhpTypeNode(NativeTypePosition $position)
415+
{
416+
return $position->isScalarAllowed() ? new Identifier('string') : null;
417+
}
418+
409419
public function hasTemplateOrLateResolvableType(): bool
410420
{
411421
return false;

‎src/Type/Accessory/HasMethodType.php‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
namespace PHPStan\Type\Accessory;
44

55
use Closure;
6+
use PhpParser\Node\ComplexType;
7+
use PhpParser\Node\Identifier;
8+
use PhpParser\Node\Name;
69
use PHPStan\Php\PhpVersion;
710
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
811
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -23,6 +26,7 @@
2326
use PHPStan\Type\IntersectionType;
2427
use PHPStan\Type\IsSuperTypeOfResult;
2528
use PHPStan\Type\MixedType;
29+
use PHPStan\Type\NativeTypePosition;
2630
use PHPStan\Type\ObjectType;
2731
use PHPStan\Type\ObjectWithoutClassType;
2832
use PHPStan\Type\StringType;
@@ -345,6 +349,13 @@ public function toPhpDocNode(): TypeNode
345349
return new IdentifierTypeNode(''); // no PHPDoc representation
346350
}
347351

352+
/** @return Identifier|Name|ComplexType|null */
353+
public function toNativePhpTypeNode(NativeTypePosition $position)
354+
{
355+
// not certainly an object on its own, object&hasMethod(foo) maps to object through the intersection
356+
return null;
357+
}
358+
348359
public function hasTemplateOrLateResolvableType(): bool
349360
{
350361
return false;

‎src/Type/Accessory/HasOffsetType.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
namespace PHPStan\Type\Accessory;
44

55
use ArrayAccess;
6+
use PhpParser\Node\ComplexType;
7+
use PhpParser\Node\Identifier;
8+
use PhpParser\Node\Name;
69
use PHPStan\Php\PhpVersion;
710
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
811
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -21,6 +24,7 @@
2124
use PHPStan\Type\IntersectionType;
2225
use PHPStan\Type\IsSuperTypeOfResult;
2326
use PHPStan\Type\MixedType;
27+
use PHPStan\Type\NativeTypePosition;
2428
use PHPStan\Type\ObjectType;
2529
use PHPStan\Type\ObjectWithoutClassType;
2630
use PHPStan\Type\Traits\MaybeArrayTypeTrait;
@@ -474,6 +478,12 @@ public function toPhpDocNode(): TypeNode
474478
return new IdentifierTypeNode(''); // no PHPDoc representation
475479
}
476480

481+
/** @return Identifier|Name|ComplexType|null */
482+
public function toNativePhpTypeNode(NativeTypePosition $position)
483+
{
484+
return $position->isArrayAllowed() ? new Identifier('array') : null;
485+
}
486+
477487
public function hasTemplateOrLateResolvableType(): bool
478488
{
479489
return $this->offsetType->hasTemplateOrLateResolvableType();

0 commit comments

Comments
 (0)