88namespace OpenAPIExtractor ;
99
1010use PhpParser \Node \Stmt \ClassMethod ;
11+ use PhpParser \Node \Stmt \Return_ ;
1112use PHPStan \PhpDocParser \Ast \PhpDoc \DeprecatedTagValueNode ;
1213use PHPStan \PhpDocParser \Ast \PhpDoc \GenericTagValueNode ;
1314use PHPStan \PhpDocParser \Ast \PhpDoc \ParamTagValueNode ;
@@ -30,7 +31,6 @@ class ControllerMethod {
3031 public function __construct (
3132 public array $ parameters ,
3233 public array $ responses ,
33- public array $ returns ,
3434 public array $ responseDescription ,
3535 public array $ description ,
3636 public ?string $ summary ,
@@ -46,18 +46,20 @@ public static function parse(string $context,
4646 bool $ isPasswordConfirmation ,
4747 bool $ isCORS ,
4848 ): ControllerMethod {
49- global $ phpDocParser , $ lexer , $ allowMissingDocs ;
49+ global $ phpDocParser , $ lexer , $ nodeFinder , $ allowMissingDocs ;
5050
5151 $ parameters = [];
5252 $ responses = [];
5353 $ responseDescriptions = [];
54- $ returns = [];
5554
5655 $ methodDescription = [];
5756 $ methodSummary = null ;
5857 $ methodParameters = $ method ->getParams ();
5958 $ docParameters = [];
6059
60+ $ returnStmtCount = count ($ nodeFinder ->findInstanceOf ($ method ->getStmts (), Return_::class));
61+ $ returnTagCount = 0 ;
62+
6163 $ doc = $ method ->getDocComment ()?->getText();
6264 if ($ doc !== null ) {
6365 $ docNodes = $ phpDocParser ->parse (new TokenIterator ($ lexer ->tokenize ($ doc )))->children ;
@@ -111,6 +113,8 @@ public static function parse(string $context,
111113 }
112114
113115 if ($ docNode ->value instanceof ReturnTagValueNode) {
116+ $ returnTagCount ++;
117+
114118 $ type = $ docNode ->value ->type ;
115119
116120 $ responses = array_merge ($ responses , ResponseType::resolve ($ context . ': @return ' , $ type ));
@@ -138,6 +142,10 @@ public static function parse(string $context,
138142 }
139143 }
140144
145+ if ($ returnStmtCount !== 0 && $ returnTagCount === 0 ) {
146+ Logger::error ($ context , 'Missing @return annotation ' );
147+ }
148+
141149 if (!$ allowMissingDocs ) {
142150 foreach (array_unique (array_map (fn (ControllerMethodResponse $ response ): int => $ response ->statusCode , array_filter ($ responses , fn (?ControllerMethodResponse $ response ): bool => $ response != null ))) as $ statusCode ) {
143151 if ($ statusCode < 500 && (!array_key_exists ($ statusCode , $ responseDescriptions ) || $ responseDescriptions [$ statusCode ] === '' )) {
@@ -266,7 +274,7 @@ public static function parse(string $context,
266274 Logger::warning ($ context , 'Summary ends with a punctuation mark ' );
267275 }
268276
269- return new ControllerMethod ($ parameters , $ responses , $ returns , $ responseDescriptions , $ methodDescription , $ methodSummary , $ isDeprecated );
277+ return new ControllerMethod ($ parameters , $ responses , $ responseDescriptions , $ methodDescription , $ methodSummary , $ isDeprecated );
270278 }
271279
272280}
0 commit comments