@@ -568,24 +568,8 @@ public function process(File $phpcsFile, $stackPtr)
568568 $ previousCommentClosePtr = $ phpcsFile ->findPrevious (T_DOC_COMMENT_CLOSE_TAG , $ stackPtr - 1 , 0 );
569569 if ($ previousCommentClosePtr && $ previousCommentOpenPtr ) {
570570 if (!$ this ->validateCommentBlockExists ($ phpcsFile , $ previousCommentClosePtr , $ stackPtr )) {
571- $ foundAllParameterTypes = true ;
572- $ methodParameters = $ phpcsFile ->getMethodParameters ($ stackPtr );
573- foreach ($ methodParameters as $ parameter ) {
574- if (!$ parameter ['type_hint ' ]) {
575- $ foundAllParameterTypes = false ;
576- break ;
577- }
578- }
579- if ($ foundAllParameterTypes ) {
580- $ methodProperties = $ phpcsFile ->getMethodProperties ($ stackPtr );
581- $ foundReturnType = !!$ methodProperties ['return_type ' ];
582- if ($ foundReturnType ) {
583- return ; // We don't need comment if all parameters and return value are typed
584- }
585- $ methodName = $ phpcsFile ->getDeclarationName ($ stackPtr );
586- if ('__construct ' == $ methodName || '__destruct ' == $ methodName ) {
587- return ; // __construct and __destruct can't have return types, so they don't need comment
588- }
571+ if (!$ this ->checkIfMethodNeedsDocBlock ($ phpcsFile , $ stackPtr )) {
572+ return ;
589573 }
590574 $ phpcsFile ->addError ('Comment block is missing ' , $ stackPtr , 'NoCommentBlock ' );
591575 return ;
@@ -636,6 +620,56 @@ public function process(File $phpcsFile, $stackPtr)
636620 );
637621 }
638622
623+ /**
624+ * Check method if it has defined return & parameter types, then it doesn't need DocBlock
625+ *
626+ * @param File $phpcsFile
627+ * @param int $stackPtr
628+ * @return bool
629+ */
630+ private function checkIfMethodNeedsDocBlock (File $ phpcsFile , $ stackPtr ) : bool
631+ {
632+ if ($ this ->checkIfNamespaceContainsApi ($ phpcsFile )) {
633+ // Note: API classes MUST have DocBlock because it uses them instead of reflection for types
634+ return true ;
635+ }
636+ $ foundAllParameterTypes = true ;
637+ $ methodParameters = $ phpcsFile ->getMethodParameters ($ stackPtr );
638+ foreach ($ methodParameters as $ parameter ) {
639+ if (!$ parameter ['type_hint ' ]) {
640+ return true ; // doesn't have type hint
641+ }
642+ }
643+ $ methodProperties = $ phpcsFile ->getMethodProperties ($ stackPtr );
644+ $ foundReturnType = !!$ methodProperties ['return_type ' ];
645+ if (!$ foundReturnType ) {
646+ $ methodName = $ phpcsFile ->getDeclarationName ($ stackPtr );
647+ // Note: __construct and __destruct can't have return types
648+ if ('__construct ' !== $ methodName && '__destruct ' !== $ methodName ) {
649+ return true ;
650+ }
651+ }
652+ return false ;
653+ }
654+
655+ /**
656+ * Check if namespace contains API
657+ *
658+ * @param File $phpcsFile
659+ * @return bool
660+ */
661+ private function checkIfNamespaceContainsApi (File $ phpcsFile ) : bool
662+ {
663+ $ namespaceStackPtr = $ phpcsFile ->findNext (T_NAMESPACE , 0 );
664+ $ tokens = $ phpcsFile ->getTokens ();
665+ for ($ index = $ namespaceStackPtr ; 'T_SEMICOLON ' !== $ tokens [$ index ]['type ' ]; $ index ++) {
666+ if ('T_STRING ' === $ tokens [$ index ]['type ' ] && 'Api ' === $ tokens [$ index ]['content ' ]) {
667+ return true ;
668+ }
669+ }
670+ return false ;
671+ }
672+
639673 /**
640674 * Validates function params format consistency.
641675 *
0 commit comments