Skip to content

Commit c539adc

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 c539adc

128 files changed

Lines changed: 1937 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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\Identifier;
56
use PHPStan\Php\PhpVersion;
67
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
78
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -19,6 +20,7 @@
1920
use PHPStan\Type\IntersectionType;
2021
use PHPStan\Type\IsSuperTypeOfResult;
2122
use PHPStan\Type\MixedType;
23+
use PHPStan\Type\NativeTypePosition;
2224
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
2325
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
2426
use PHPStan\Type\Traits\NonGenericTypeTrait;
@@ -579,6 +581,11 @@ public function toPhpDocNode(): TypeNode
579581
return new IdentifierTypeNode('list');
580582
}
581583

584+
public function toNativePhpTypeNode(NativeTypePosition $position)
585+
{
586+
return $position->isArrayAllowed() ? new Identifier('array') : null;
587+
}
588+
582589
public function hasTemplateOrLateResolvableType(): bool
583590
{
584591
return false;

‎src/Type/Accessory/AccessoryDecimalIntegerStringType.php‎

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

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\Identifier;
56
use PHPStan\Php\PhpVersion;
67
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
78
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -24,6 +25,7 @@
2425
use PHPStan\Type\IntegerType;
2526
use PHPStan\Type\IntersectionType;
2627
use PHPStan\Type\IsSuperTypeOfResult;
28+
use PHPStan\Type\NativeTypePosition;
2729
use PHPStan\Type\StringType;
2830
use PHPStan\Type\Traits\NonArrayTypeTrait;
2931
use PHPStan\Type\Traits\NonGenericTypeTrait;
@@ -480,6 +482,11 @@ public function toPhpDocNode(): TypeNode
480482
return new IdentifierTypeNode($this->inverse ? 'non-decimal-int-string' : 'decimal-int-string');
481483
}
482484

485+
public function toNativePhpTypeNode(NativeTypePosition $position)
486+
{
487+
return $position->isScalarAllowed() ? new Identifier('string') : null;
488+
}
489+
483490
public function hasTemplateOrLateResolvableType(): bool
484491
{
485492
return false;

‎src/Type/Accessory/AccessoryLiteralStringType.php‎

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

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\Identifier;
56
use PHPStan\Php\PhpVersion;
67
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
78
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -21,6 +22,7 @@
2122
use PHPStan\Type\IntersectionType;
2223
use PHPStan\Type\IsSuperTypeOfResult;
2324
use PHPStan\Type\MixedType;
25+
use PHPStan\Type\NativeTypePosition;
2426
use PHPStan\Type\ObjectWithoutClassType;
2527
use PHPStan\Type\StringType;
2628
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
@@ -401,6 +403,11 @@ public function toPhpDocNode(): TypeNode
401403
return new IdentifierTypeNode('literal-string');
402404
}
403405

406+
public function toNativePhpTypeNode(NativeTypePosition $position)
407+
{
408+
return $position->isScalarAllowed() ? new Identifier('string') : null;
409+
}
410+
404411
public function hasTemplateOrLateResolvableType(): bool
405412
{
406413
return false;

‎src/Type/Accessory/AccessoryLowercaseStringType.php‎

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

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\Identifier;
56
use PHPStan\Php\PhpVersion;
67
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
78
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -21,6 +22,7 @@
2122
use PHPStan\Type\IntegerType;
2223
use PHPStan\Type\IntersectionType;
2324
use PHPStan\Type\IsSuperTypeOfResult;
25+
use PHPStan\Type\NativeTypePosition;
2426
use PHPStan\Type\ObjectWithoutClassType;
2527
use PHPStan\Type\StringType;
2628
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
@@ -406,6 +408,11 @@ public function toPhpDocNode(): TypeNode
406408
return new IdentifierTypeNode('lowercase-string');
407409
}
408410

411+
public function toNativePhpTypeNode(NativeTypePosition $position)
412+
{
413+
return $position->isScalarAllowed() ? new Identifier('string') : null;
414+
}
415+
409416
public function hasTemplateOrLateResolvableType(): bool
410417
{
411418
return false;

‎src/Type/Accessory/AccessoryNonEmptyStringType.php‎

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

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\Identifier;
56
use PHPStan\Php\PhpVersion;
67
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
78
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -22,6 +23,7 @@
2223
use PHPStan\Type\IntegerType;
2324
use PHPStan\Type\IntersectionType;
2425
use PHPStan\Type\IsSuperTypeOfResult;
26+
use PHPStan\Type\NativeTypePosition;
2527
use PHPStan\Type\ObjectWithoutClassType;
2628
use PHPStan\Type\StringType;
2729
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
@@ -410,6 +412,11 @@ public function toPhpDocNode(): TypeNode
410412
return new IdentifierTypeNode('non-empty-string');
411413
}
412414

415+
public function toNativePhpTypeNode(NativeTypePosition $position)
416+
{
417+
return $position->isScalarAllowed() ? new Identifier('string') : null;
418+
}
419+
413420
public function hasTemplateOrLateResolvableType(): bool
414421
{
415422
return false;

‎src/Type/Accessory/AccessoryNonFalsyStringType.php‎

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

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\Identifier;
56
use PHPStan\Php\PhpVersion;
67
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
78
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -22,6 +23,7 @@
2223
use PHPStan\Type\IntegerType;
2324
use PHPStan\Type\IntersectionType;
2425
use PHPStan\Type\IsSuperTypeOfResult;
26+
use PHPStan\Type\NativeTypePosition;
2527
use PHPStan\Type\NullType;
2628
use PHPStan\Type\ObjectWithoutClassType;
2729
use PHPStan\Type\StringType;
@@ -407,6 +409,11 @@ public function toPhpDocNode(): TypeNode
407409
return new IdentifierTypeNode('non-falsy-string');
408410
}
409411

412+
public function toNativePhpTypeNode(NativeTypePosition $position)
413+
{
414+
return $position->isScalarAllowed() ? new Identifier('string') : null;
415+
}
416+
410417
public function hasTemplateOrLateResolvableType(): bool
411418
{
412419
return false;

‎src/Type/Accessory/AccessoryNumericStringType.php‎

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

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\Identifier;
56
use PHPStan\DependencyInjection\ReportUnsafeArrayStringKeyCastingToggle;
67
use PHPStan\Php\PhpVersion;
78
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
@@ -23,6 +24,7 @@
2324
use PHPStan\Type\IntegerType;
2425
use PHPStan\Type\IntersectionType;
2526
use PHPStan\Type\IsSuperTypeOfResult;
27+
use PHPStan\Type\NativeTypePosition;
2628
use PHPStan\Type\StringType;
2729
use PHPStan\Type\Traits\NonArrayTypeTrait;
2830
use PHPStan\Type\Traits\NonCallableTypeTrait;
@@ -419,6 +421,11 @@ public function toPhpDocNode(): TypeNode
419421
return new IdentifierTypeNode('numeric-string');
420422
}
421423

424+
public function toNativePhpTypeNode(NativeTypePosition $position)
425+
{
426+
return $position->isScalarAllowed() ? new Identifier('string') : null;
427+
}
428+
422429
public function hasTemplateOrLateResolvableType(): bool
423430
{
424431
return false;

‎src/Type/Accessory/AccessoryUppercaseStringType.php‎

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

33
namespace PHPStan\Type\Accessory;
44

5+
use PhpParser\Node\Identifier;
56
use PHPStan\Php\PhpVersion;
67
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
78
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -21,6 +22,7 @@
2122
use PHPStan\Type\IntegerType;
2223
use PHPStan\Type\IntersectionType;
2324
use PHPStan\Type\IsSuperTypeOfResult;
25+
use PHPStan\Type\NativeTypePosition;
2426
use PHPStan\Type\ObjectWithoutClassType;
2527
use PHPStan\Type\StringType;
2628
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
@@ -406,6 +408,11 @@ public function toPhpDocNode(): TypeNode
406408
return new IdentifierTypeNode('uppercase-string');
407409
}
408410

411+
public function toNativePhpTypeNode(NativeTypePosition $position)
412+
{
413+
return $position->isScalarAllowed() ? new Identifier('string') : null;
414+
}
415+
409416
public function hasTemplateOrLateResolvableType(): bool
410417
{
411418
return false;

‎src/Type/Accessory/HasMethodType.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use PHPStan\Type\IntersectionType;
2424
use PHPStan\Type\IsSuperTypeOfResult;
2525
use PHPStan\Type\MixedType;
26+
use PHPStan\Type\NativeTypePosition;
2627
use PHPStan\Type\ObjectType;
2728
use PHPStan\Type\ObjectWithoutClassType;
2829
use PHPStan\Type\StringType;
@@ -345,6 +346,12 @@ public function toPhpDocNode(): TypeNode
345346
return new IdentifierTypeNode(''); // no PHPDoc representation
346347
}
347348

349+
public function toNativePhpTypeNode(NativeTypePosition $position)
350+
{
351+
// not certainly an object on its own, object&hasMethod(foo) maps to object through the intersection
352+
return null;
353+
}
354+
348355
public function hasTemplateOrLateResolvableType(): bool
349356
{
350357
return false;

‎src/Type/Accessory/HasOffsetType.php‎

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

55
use ArrayAccess;
6+
use PhpParser\Node\Identifier;
67
use PHPStan\Php\PhpVersion;
78
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
89
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -21,6 +22,7 @@
2122
use PHPStan\Type\IntersectionType;
2223
use PHPStan\Type\IsSuperTypeOfResult;
2324
use PHPStan\Type\MixedType;
25+
use PHPStan\Type\NativeTypePosition;
2426
use PHPStan\Type\ObjectType;
2527
use PHPStan\Type\ObjectWithoutClassType;
2628
use PHPStan\Type\Traits\MaybeArrayTypeTrait;
@@ -474,6 +476,11 @@ public function toPhpDocNode(): TypeNode
474476
return new IdentifierTypeNode(''); // no PHPDoc representation
475477
}
476478

479+
public function toNativePhpTypeNode(NativeTypePosition $position)
480+
{
481+
return $position->isArrayAllowed() ? new Identifier('array') : null;
482+
}
483+
477484
public function hasTemplateOrLateResolvableType(): bool
478485
{
479486
return $this->offsetType->hasTemplateOrLateResolvableType();

0 commit comments

Comments
 (0)