1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Analyser;
4:
5: use PhpParser\Node;
6: use PHPStan\Turbo\ShadowedByTurboExtension;
7: use PHPStan\Type\ObjectType;
8: use PHPStan\Type\Type;
9: use PHPStan\Type\TypeCombinator;
10: use Throwable;
11:
12: /**
13: * @api
14: */
15: #[ShadowedByTurboExtension(implementation: __DIR__ . '/../../turbo-ext/src/ThrowPoint.cpp')]
16: final class ThrowPoint
17: {
18:
19: /**
20: * @param Node\Expr|Node\Stmt $node
21: */
22: private function __construct(
23: private Scope $scope,
24: private Type $type,
25: private Node $node,
26: private bool $explicit,
27: private bool $canContainAnyThrowable,
28: private bool $fromThrowExpr = false,
29: )
30: {
31: }
32:
33: /**
34: * @param Node\Expr|Node\Stmt $node
35: */
36: public static function createExplicit(Scope $scope, Type $type, Node $node, bool $canContainAnyThrowable, bool $fromThrowExpr = false): self
37: {
38: return new self($scope, $type, $node, true, $canContainAnyThrowable, $fromThrowExpr);
39: }
40:
41: /**
42: * @param Node\Expr|Node\Stmt $node
43: */
44: public static function createImplicit(Scope $scope, Node $node, ?Type $type = null): self
45: {
46: return new self($scope, $type ?? new ObjectType(Throwable::class), $node, explicit: false, canContainAnyThrowable: true);
47: }
48:
49: public function getScope(): Scope
50: {
51: return $this->scope;
52: }
53:
54: public function getType(): Type
55: {
56: return $this->type;
57: }
58:
59: /**
60: * @return Node\Expr|Node\Stmt
61: */
62: public function getNode()
63: {
64: return $this->node;
65: }
66:
67: public function isExplicit(): bool
68: {
69: return $this->explicit;
70: }
71:
72: public function canContainAnyThrowable(): bool
73: {
74: return $this->canContainAnyThrowable;
75: }
76:
77: /**
78: * Whether the throw point comes from a `throw` written in the analysed code,
79: * as opposed to a throw inferred from what a called function or an operation
80: * can throw.
81: */
82: public function isFromThrowExpr(): bool
83: {
84: return $this->fromThrowExpr;
85: }
86:
87: public function subtractCatchType(Type $catchType): self
88: {
89: return new self($this->scope, TypeCombinator::remove($this->type, $catchType), $this->node, $this->explicit, $this->canContainAnyThrowable, $this->fromThrowExpr);
90: }
91:
92: }
93: