|
33 | 33 | use PHPStan\DependencyInjection\AutowiredParameter; |
34 | 34 | use PHPStan\DependencyInjection\AutowiredService; |
35 | 35 | use PHPStan\DependencyInjection\Type\OperatorTypeSpecifyingExtensionRegistryProvider; |
| 36 | +use PHPStan\DependencyInjection\Type\UnaryOperatorTypeSpecifyingExtensionRegistryProvider; |
36 | 37 | use PHPStan\Node\Expr\TypeExpr; |
37 | 38 | use PHPStan\Php\PhpVersion; |
38 | 39 | use PHPStan\PhpDoc\Tag\TemplateTag; |
@@ -136,6 +137,7 @@ public function __construct( |
136 | 137 | private ReflectionProviderProvider $reflectionProviderProvider, |
137 | 138 | private PhpVersion $phpVersion, |
138 | 139 | private OperatorTypeSpecifyingExtensionRegistryProvider $operatorTypeSpecifyingExtensionRegistryProvider, |
| 140 | + private UnaryOperatorTypeSpecifyingExtensionRegistryProvider $unaryOperatorTypeSpecifyingExtensionRegistryProvider, |
139 | 141 | private OversizedArrayBuilder $oversizedArrayBuilder, |
140 | 142 | #[AutowiredParameter] |
141 | 143 | private bool $usePathConstantsAsConstantString, |
@@ -270,7 +272,7 @@ public function getType(Expr $expr, InitializerExprContext $context): Type |
270 | 272 | return $this->getClassConstFetchType($expr->class, $expr->name->toString(), $context->getClassName(), fn (Expr $expr): Type => $this->getType($expr, $context)); |
271 | 273 | } |
272 | 274 | if ($expr instanceof Expr\UnaryPlus) { |
273 | | - return $this->getType($expr->expr, $context)->toNumber(); |
| 275 | + return $this->getUnaryPlusType($expr->expr, fn (Expr $expr): Type => $this->getType($expr, $context)); |
274 | 276 | } |
275 | 277 | if ($expr instanceof Expr\UnaryMinus) { |
276 | 278 | return $this->getUnaryMinusType($expr->expr, fn (Expr $expr): Type => $this->getType($expr, $context)); |
@@ -2604,13 +2606,35 @@ public function getClassConstFetchType(Name|Expr $class, string $constantName, ? |
2604 | 2606 | return $this->getClassConstFetchTypeByReflection($class, $constantName, $classReflection, $getTypeCallback); |
2605 | 2607 | } |
2606 | 2608 |
|
| 2609 | + /** |
| 2610 | + * @param callable(Expr): Type $getTypeCallback |
| 2611 | + */ |
| 2612 | + public function getUnaryPlusType(Expr $expr, callable $getTypeCallback): Type |
| 2613 | + { |
| 2614 | + $type = $getTypeCallback($expr); |
| 2615 | + |
| 2616 | + $specifiedTypes = $this->unaryOperatorTypeSpecifyingExtensionRegistryProvider->getRegistry() |
| 2617 | + ->callUnaryOperatorTypeSpecifyingExtensions('+', $type); |
| 2618 | + if ($specifiedTypes !== null) { |
| 2619 | + return $specifiedTypes; |
| 2620 | + } |
| 2621 | + |
| 2622 | + return $type->toNumber(); |
| 2623 | + } |
| 2624 | + |
2607 | 2625 | /** |
2608 | 2626 | * @param callable(Expr): Type $getTypeCallback |
2609 | 2627 | */ |
2610 | 2628 | public function getUnaryMinusType(Expr $expr, callable $getTypeCallback): Type |
2611 | 2629 | { |
2612 | 2630 | $type = $getTypeCallback($expr); |
2613 | 2631 |
|
| 2632 | + $specifiedTypes = $this->unaryOperatorTypeSpecifyingExtensionRegistryProvider->getRegistry() |
| 2633 | + ->callUnaryOperatorTypeSpecifyingExtensions('-', $type); |
| 2634 | + if ($specifiedTypes !== null) { |
| 2635 | + return $specifiedTypes; |
| 2636 | + } |
| 2637 | + |
2614 | 2638 | $type = $this->getUnaryMinusTypeFromType($expr, $type); |
2615 | 2639 | if ($type instanceof IntegerRangeType) { |
2616 | 2640 | return $getTypeCallback(new Expr\BinaryOp\Mul($expr, new Int_(-1))); |
@@ -2652,6 +2676,12 @@ public function getBitwiseNotType(Expr $expr, callable $getTypeCallback): Type |
2652 | 2676 | { |
2653 | 2677 | $exprType = $getTypeCallback($expr); |
2654 | 2678 |
|
| 2679 | + $specifiedTypes = $this->unaryOperatorTypeSpecifyingExtensionRegistryProvider->getRegistry() |
| 2680 | + ->callUnaryOperatorTypeSpecifyingExtensions('~', $exprType); |
| 2681 | + if ($specifiedTypes !== null) { |
| 2682 | + return $specifiedTypes; |
| 2683 | + } |
| 2684 | + |
2655 | 2685 | return $this->getBitwiseNotTypeFromType($exprType); |
2656 | 2686 | } |
2657 | 2687 |
|
|
0 commit comments