diff --git a/generate-spec.php b/generate-spec.php index 744814b..285c723 100755 --- a/generate-spec.php +++ b/generate-spec.php @@ -520,10 +520,6 @@ } $classMethodInfo = ControllerMethod::parse($routeName, $definitions, $methodFunction, $isAdmin, $isDeprecated, $isPasswordConfirmation, $isCORS); - if ($classMethodInfo->returns !== []) { - Logger::error($routeName, 'Returns an invalid response'); - continue; - } if (count($classMethodInfo->responses) == 0) { Logger::error($routeName, 'Returns no responses'); continue; diff --git a/src/ControllerMethod.php b/src/ControllerMethod.php index d429d00..f1950b3 100644 --- a/src/ControllerMethod.php +++ b/src/ControllerMethod.php @@ -8,6 +8,7 @@ namespace OpenAPIExtractor; use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\Stmt\Return_; use PHPStan\PhpDocParser\Ast\PhpDoc\DeprecatedTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode; @@ -30,7 +31,6 @@ class ControllerMethod { public function __construct( public array $parameters, public array $responses, - public array $returns, public array $responseDescription, public array $description, public ?string $summary, @@ -46,18 +46,20 @@ public static function parse(string $context, bool $isPasswordConfirmation, bool $isCORS, ): ControllerMethod { - global $phpDocParser, $lexer, $allowMissingDocs; + global $phpDocParser, $lexer, $nodeFinder, $allowMissingDocs; $parameters = []; $responses = []; $responseDescriptions = []; - $returns = []; $methodDescription = []; $methodSummary = null; $methodParameters = $method->getParams(); $docParameters = []; + $returnStmtCount = count($nodeFinder->findInstanceOf($method->getStmts(), Return_::class)); + $returnTagCount = 0; + $doc = $method->getDocComment()?->getText(); if ($doc !== null) { $docNodes = $phpDocParser->parse(new TokenIterator($lexer->tokenize($doc)))->children; @@ -111,6 +113,8 @@ public static function parse(string $context, } if ($docNode->value instanceof ReturnTagValueNode) { + $returnTagCount++; + $type = $docNode->value->type; $responses = array_merge($responses, ResponseType::resolve($context . ': @return', $type)); @@ -138,6 +142,10 @@ public static function parse(string $context, } } + if ($returnStmtCount !== 0 && $returnTagCount === 0) { + Logger::error($context, 'Missing @return annotation'); + } + if (!$allowMissingDocs) { foreach (array_unique(array_map(fn (ControllerMethodResponse $response): int => $response->statusCode, array_filter($responses, fn (?ControllerMethodResponse $response): bool => $response != null))) as $statusCode) { if ($statusCode < 500 && (!array_key_exists($statusCode, $responseDescriptions) || $responseDescriptions[$statusCode] === '')) { @@ -266,7 +274,7 @@ public static function parse(string $context, Logger::warning($context, 'Summary ends with a punctuation mark'); } - return new ControllerMethod($parameters, $responses, $returns, $responseDescriptions, $methodDescription, $methodSummary, $isDeprecated); + return new ControllerMethod($parameters, $responses, $responseDescriptions, $methodDescription, $methodSummary, $isDeprecated); } }