Skip to content

Commit 83c8668

Browse files
API class/interfaces should still require DocBlocks for methods
Adding in code to check the namespace of the class/interfaces to see if it is API. Magento's API code requires method Doc Blocks because it doesn't use Reflection for types. https://developer.adobe.com/commerce/php/development/components/web-api/services/
1 parent ee3ddb3 commit 83c8668

File tree

1 file changed

+52
-18
lines changed

1 file changed

+52
-18
lines changed

Magento2/Sniffs/Annotation/MethodArgumentsSniff.php

+52-18
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)