|
134 | 134 | use PHPStan\Reflection\ExtendedParameterReflection; |
135 | 135 | use PHPStan\Reflection\ExtendedParametersAcceptor; |
136 | 136 | use PHPStan\Reflection\FunctionReflection; |
| 137 | +use PHPStan\Reflection\InitializerExprContext; |
137 | 138 | use PHPStan\Reflection\InitializerExprTypeResolver; |
138 | 139 | use PHPStan\Reflection\MethodReflection; |
139 | 140 | use PHPStan\Reflection\Native\NativeMethodReflection; |
@@ -525,6 +526,10 @@ private function processStmtNode( |
525 | 526 | $nodeCallback($stmt->returnType, $scope); |
526 | 527 | } |
527 | 528 |
|
| 529 | + if (!$isDeprecated) { |
| 530 | + [$isDeprecated, $deprecatedDescription] = $this->getDeprecatedAttribute($scope, $stmt); |
| 531 | + } |
| 532 | + |
528 | 533 | $functionScope = $scope->enterFunction( |
529 | 534 | $stmt, |
530 | 535 | $templateTypeMap, |
@@ -609,6 +614,10 @@ private function processStmtNode( |
609 | 614 | $nodeCallback($stmt->returnType, $scope); |
610 | 615 | } |
611 | 616 |
|
| 617 | + if (!$isDeprecated) { |
| 618 | + [$isDeprecated, $deprecatedDescription] = $this->getDeprecatedAttribute($scope, $stmt); |
| 619 | + } |
| 620 | + |
612 | 621 | $methodScope = $scope->enterClassMethod( |
613 | 622 | $stmt, |
614 | 623 | $templateTypeMap, |
@@ -1933,6 +1942,57 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void { |
1933 | 1942 | return new StatementResult($scope, $hasYield, false, [], $throwPoints, $impurePoints); |
1934 | 1943 | } |
1935 | 1944 |
|
| 1945 | + /** |
| 1946 | + * @return array{bool, string|null} |
| 1947 | + */ |
| 1948 | + private function getDeprecatedAttribute(Scope $scope, Node\Stmt\Function_|Node\Stmt\ClassMethod $stmt): array |
| 1949 | + { |
| 1950 | + $initializerExprContext = InitializerExprContext::fromStubParameter( |
| 1951 | + null, |
| 1952 | + $scope->getFile(), |
| 1953 | + $stmt, |
| 1954 | + ); |
| 1955 | + $isDeprecated = false; |
| 1956 | + $deprecatedDescription = null; |
| 1957 | + $deprecatedDescriptionType = null; |
| 1958 | + foreach ($stmt->attrGroups as $attrGroup) { |
| 1959 | + foreach ($attrGroup->attrs as $attr) { |
| 1960 | + if ($attr->name->toString() !== 'Deprecated') { |
| 1961 | + continue; |
| 1962 | + } |
| 1963 | + $isDeprecated = true; |
| 1964 | + $arguments = $attr->args; |
| 1965 | + foreach ($arguments as $i => $arg) { |
| 1966 | + $argName = $arg->name; |
| 1967 | + if ($argName === null) { |
| 1968 | + if ($i !== 0) { |
| 1969 | + continue; |
| 1970 | + } |
| 1971 | + |
| 1972 | + $deprecatedDescriptionType = $this->initializerExprTypeResolver->getType($arg->value, $initializerExprContext); |
| 1973 | + break; |
| 1974 | + } |
| 1975 | + |
| 1976 | + if ($argName->toString() !== 'message') { |
| 1977 | + continue; |
| 1978 | + } |
| 1979 | + |
| 1980 | + $deprecatedDescriptionType = $this->initializerExprTypeResolver->getType($arg->value, $initializerExprContext); |
| 1981 | + break; |
| 1982 | + } |
| 1983 | + } |
| 1984 | + } |
| 1985 | + |
| 1986 | + if ($deprecatedDescriptionType !== null) { |
| 1987 | + $constantStrings = $deprecatedDescriptionType->getConstantStrings(); |
| 1988 | + if (count($constantStrings) === 1) { |
| 1989 | + $deprecatedDescription = $constantStrings[0]->getValue(); |
| 1990 | + } |
| 1991 | + } |
| 1992 | + |
| 1993 | + return [$isDeprecated, $deprecatedDescription]; |
| 1994 | + } |
| 1995 | + |
1936 | 1996 | /** |
1937 | 1997 | * @return ThrowPoint[]|null |
1938 | 1998 | */ |
|
0 commit comments