1: | <?php declare(strict_types = 1); |
2: | |
3: | namespace PHPStan\Reflection\Php; |
4: | |
5: | use PhpParser\Node; |
6: | use PhpParser\Node\Stmt\ClassMethod; |
7: | use PHPStan\Reflection\Assertions; |
8: | use PHPStan\Reflection\ClassMemberReflection; |
9: | use PHPStan\Reflection\ClassReflection; |
10: | use PHPStan\Reflection\ExtendedMethodReflection; |
11: | use PHPStan\Reflection\MissingMethodFromReflectionException; |
12: | use PHPStan\TrinaryLogic; |
13: | use PHPStan\Type\ArrayType; |
14: | use PHPStan\Type\BooleanType; |
15: | use PHPStan\Type\Generic\TemplateTypeMap; |
16: | use PHPStan\Type\IntegerType; |
17: | use PHPStan\Type\ObjectWithoutClassType; |
18: | use PHPStan\Type\StringType; |
19: | use PHPStan\Type\Type; |
20: | use PHPStan\Type\TypeCombinator; |
21: | use PHPStan\Type\VoidType; |
22: | use function strtolower; |
23: | |
24: | |
25: | |
26: | |
27: | class PhpMethodFromParserNodeReflection extends PhpFunctionFromParserNodeReflection implements ExtendedMethodReflection |
28: | { |
29: | |
30: | |
31: | |
32: | |
33: | |
34: | |
35: | public function __construct( |
36: | private ClassReflection $declaringClass, |
37: | ClassMethod $classMethod, |
38: | string $fileName, |
39: | TemplateTypeMap $templateTypeMap, |
40: | array $realParameterTypes, |
41: | array $phpDocParameterTypes, |
42: | array $realParameterDefaultValues, |
43: | Type $realReturnType, |
44: | ?Type $phpDocReturnType, |
45: | ?Type $throwType, |
46: | ?string $deprecatedDescription, |
47: | bool $isDeprecated, |
48: | bool $isInternal, |
49: | bool $isFinal, |
50: | ?bool $isPure, |
51: | bool $acceptsNamedArguments, |
52: | Assertions $assertions, |
53: | private ?Type $selfOutType, |
54: | ?string $phpDocComment, |
55: | array $parameterOutTypes, |
56: | ) |
57: | { |
58: | $name = strtolower($classMethod->name->name); |
59: | if ( |
60: | $name === '__construct' |
61: | || $name === '__destruct' |
62: | || $name === '__unset' |
63: | || $name === '__wakeup' |
64: | || $name === '__clone' |
65: | ) { |
66: | $realReturnType = new VoidType(); |
67: | } |
68: | if ($name === '__tostring') { |
69: | $realReturnType = new StringType(); |
70: | } |
71: | if ($name === '__isset') { |
72: | $realReturnType = new BooleanType(); |
73: | } |
74: | if ($name === '__sleep') { |
75: | $realReturnType = new ArrayType(new IntegerType(), new StringType()); |
76: | } |
77: | if ($name === '__set_state') { |
78: | $realReturnType = TypeCombinator::intersect(new ObjectWithoutClassType(), $realReturnType); |
79: | } |
80: | |
81: | parent::__construct( |
82: | $classMethod, |
83: | $fileName, |
84: | $templateTypeMap, |
85: | $realParameterTypes, |
86: | $phpDocParameterTypes, |
87: | $realParameterDefaultValues, |
88: | $realReturnType, |
89: | $phpDocReturnType, |
90: | $throwType, |
91: | $deprecatedDescription, |
92: | $isDeprecated, |
93: | $isInternal, |
94: | $isFinal || $classMethod->isFinal(), |
95: | $isPure, |
96: | $acceptsNamedArguments, |
97: | $assertions, |
98: | $phpDocComment, |
99: | $parameterOutTypes, |
100: | ); |
101: | } |
102: | |
103: | public function getDeclaringClass(): ClassReflection |
104: | { |
105: | return $this->declaringClass; |
106: | } |
107: | |
108: | public function getPrototype(): ClassMemberReflection |
109: | { |
110: | try { |
111: | return $this->declaringClass->getNativeMethod($this->getClassMethod()->name->name)->getPrototype(); |
112: | } catch (MissingMethodFromReflectionException) { |
113: | return $this; |
114: | } |
115: | } |
116: | |
117: | private function getClassMethod(): ClassMethod |
118: | { |
119: | |
120: | $functionLike = $this->getFunctionLike(); |
121: | return $functionLike; |
122: | } |
123: | |
124: | public function isStatic(): bool |
125: | { |
126: | return $this->getClassMethod()->isStatic(); |
127: | } |
128: | |
129: | public function isPrivate(): bool |
130: | { |
131: | return $this->getClassMethod()->isPrivate(); |
132: | } |
133: | |
134: | public function isPublic(): bool |
135: | { |
136: | return $this->getClassMethod()->isPublic(); |
137: | } |
138: | |
139: | public function isBuiltin(): bool |
140: | { |
141: | return false; |
142: | } |
143: | |
144: | public function getSelfOutType(): ?Type |
145: | { |
146: | return $this->selfOutType; |
147: | } |
148: | |
149: | public function returnsByReference(): TrinaryLogic |
150: | { |
151: | return TrinaryLogic::createFromBoolean($this->getClassMethod()->returnsByRef()); |
152: | } |
153: | |
154: | } |
155: | |