/** * Process the return comment of this function comment. * * @param int $commentStart The position in the stack where the comment started. * @param int $commentEnd The position in the stack where the comment ended. * * @return void */ protected function processReturn($commentStart, $commentEnd) { // Skip constructor and destructor. $className = ''; if ($this->_classToken !== null) { $className = $this->currentFile->getDeclarationName($this->_classToken); $className = strtolower(ltrim($className, '_')); } $methodName = strtolower(ltrim($this->_methodName, '_')); $isSpecialMethod = $this->_methodName === '__construct' || $this->_methodName === '__destruct'; if ($isSpecialMethod === false && $methodName !== $className) { // Report missing return tag. if ($this->commentParser->getReturn() === null) { $error = 'Missing @return tag in function comment'; $this->currentFile->addError($error, $commentEnd, 'MissingReturn'); } else { if (trim($this->commentParser->getReturn()->getRawContent()) === '') { $error = '@return tag is empty in function comment'; $errorPos = $commentStart + $this->commentParser->getReturn()->getLine(); $this->currentFile->addError($error, $errorPos, 'EmptyReturn'); } else { if (substr_count($this->commentParser->getReturn()->getWhitespaceAfter(), $this->currentFile->eolChar) !== 2) { $error = 'Return comment requires a blank newline after it'; $errorPos = $this->commentParser->getReturn()->getLine() + $commentStart; $this->currentFile->addError($error, $errorPos, 'SpacingAfterReturn'); } } } } }
/** * Process the return comment of this function comment. * * @param int $commentStart The position in the stack where the comment started. * @param int $commentEnd The position in the stack where the comment ended. * * @return void */ protected function processReturn($commentStart, $commentEnd) { // Skip constructor and destructor. $className = ''; if ($this->_classToken !== null) { $className = $this->currentFile->getDeclarationName($this->_classToken); $className = strtolower(ltrim($className, '_')); } $methodName = strtolower(ltrim($this->_methodName, '_')); if ($methodName === '') { $methodName = $this->_methodName; } $isSpecialMethod = $this->_methodName === '__construct' || $this->_methodName === '__destruct'; if ($isSpecialMethod === false && $methodName !== $className) { // Report missing return tag. if ($this->commentParser->getReturn() === null) { $error = 'Missing @return tag in function comment'; $this->currentFile->addError($error, $commentEnd, 'MissingReturn'); } else { if (trim($this->commentParser->getReturn()->getRawContent()) === '') { $error = '@return tag is empty in function comment'; $errorPos = $commentStart + $this->commentParser->getReturn()->getLine(); $this->currentFile->addError($error, $errorPos, 'EmptyReturn'); } } } }
/** * Process the return comment of this function comment. * * @param int $commentStart The position in the stack where the comment started. * @param int $commentEnd The position in the stack where the comment ended. * * @return void */ protected function processReturn($commentStart, $commentEnd) { // Skip constructor and destructor. if ($this->_methodName === '__construct' || $this->_methodName === '__destruct') { if ($this->commentParser->getReturn() != null) { $error = 'Constructor and destructor comments must not have a @return tag'; $errorPos = $this->commentParser->getReturn()->getLine() + $commentStart; $this->currentFile->addError($error, $errorPos, 'UselessReturn'); } } else { // Report missing return tag. if ($this->commentParser->getReturn() === null) { $error = 'Missing @return tag in function comment'; $this->currentFile->addError($error, $commentEnd, 'MissingReturn'); } else { if (trim($this->commentParser->getReturn()->getRawContent()) === '') { $error = '@return tag is empty in function comment'; $errorPos = $commentStart + $this->commentParser->getReturn()->getLine(); $this->currentFile->addError($error, $errorPos, 'EmptyReturn'); } else { if (substr_count($this->commentParser->getReturn()->getWhitespaceAfter(), $this->currentFile->eolChar) !== 2) { $error = 'Return comment requires a blank newline after it'; $errorPos = $this->commentParser->getReturn()->getLine() + $commentStart; $this->currentFile->addError($error, $errorPos, 'SpacingAfterReturn'); } } } } }
/** * Process the return comment of this function comment. * * @return void */ protected function getValueOfReturnTag() { $returnContent = $tmpContent = null; $pairElement = $this->commentParser->getReturn(); if ($pairElement instanceof PHP_CodeSniffer_CommentParser_AbstractDocElement) { $tmpContent = trim($this->commentParser->getReturn()->getRawContent()); } if ($tmpContent !== null) { $returnContent = $tmpContent; } return $returnContent; }
/** * Process the return comment of this function comment * * @param integer $commentStart The position in the stack where the comment started * @param integer $commentEnd The position in the stack where the comment ended * @return void */ protected function _processReturn($commentStart, $commentEnd) { // Skip constructor and destructor $className = ''; if ($this->_classToken !== null) { $className = $this->_currentFile->getDeclarationName($this->_classToken); $className = strtolower(ltrim($className, '_')); } $methodName = strtolower(ltrim($this->_methodName, '_')); $isSpecialMethod = ($this->_methodName === '__construct' or $this->_methodName === '__destruct'); $return = $this->_commentParser->getReturn(); if ($methodName === $className or $isSpecialMethod !== false) { // No return tag for constructor and destructor if ($return !== null) { $errorPos = $commentStart + $return->getLine(); $error = '@return tag is not required for constructor and destructor'; $this->_currentFile->addError($error, $errorPos); } return; } if ($return === null) { $error = 'Missing @return tag in function comment'; $this->_currentFile->addError($error, $commentEnd); return; } $tagOrder = $this->_commentParser->getTagOrders(); $index = array_keys($tagOrder, 'return'); $errorPos = $commentStart + $return->getLine(); $content = trim($return->getRawContent()); if (count($index) > 1) { $error = 'Only 1 @return tag is allowed in function comment'; $this->_currentFile->addError($error, $errorPos); return; } $since = array_keys($tagOrder, 'since'); if (count($since) === 1 and $this->_tagIndex !== 0) { $this->_tagIndex++; if ($index[0] !== $this->_tagIndex) { $error = 'The @return tag is in the wrong order; the tag follows @see (if used) or @since'; $this->_currentFile->addError($error, $errorPos); } } if (empty($content) === true) { $error = 'Return type missing for @return tag in function comment'; $this->_currentFile->addError($error, $errorPos); } else { // Check return type (can be multiple, separated by '|') $typeNames = explode('|', $content); $suggestedNames = array(); foreach ($typeNames as $i => $typeName) { $suggestedName = PHP_CodeSniffer::suggestType($typeName); if (in_array($suggestedName, $suggestedNames) === false) { $suggestedNames[] = $suggestedName; } } $suggestedType = implode('|', $suggestedNames); if ($content !== $suggestedType) { $error = "Function return type \"{$content}\" is invalid"; $this->_currentFile->addError($error, $errorPos); } $tokens = $this->_currentFile->getTokens(); // If the return type is void, make sure there is // no return statement in the function if ($content === 'void') { if (isset($tokens[$this->_functionToken]['scope_closer']) === true) { $endToken = $tokens[$this->_functionToken]['scope_closer']; $return = $this->_currentFile->findNext(T_RETURN, $this->_functionToken, $endToken); if ($return !== false) { // If the function is not returning anything, just // exiting, then there is no problem $semicolon = $this->_currentFile->findNext(T_WHITESPACE, $return + 1, null, true); if ($tokens[$semicolon]['code'] !== T_SEMICOLON) { $error = 'Function return type is void, but function contains return statement'; $this->_currentFile->addError($error, $errorPos); } } } } else { // If return type is not void, there needs to be a // returns statement somewhere in the function that // returns something if (isset($tokens[$this->_functionToken]['scope_closer']) === true) { $endToken = $tokens[$this->_functionToken]['scope_closer']; $return = $this->_currentFile->findNext(T_RETURN, $this->_functionToken, $endToken); if ($return === false) { $error = 'Function return type is not void, but function has no return statement'; $this->_currentFile->addError($error, $errorPos); } else { $semicolon = $this->_currentFile->findNext(T_WHITESPACE, $return + 1, null, true); if ($tokens[$semicolon]['code'] === T_SEMICOLON) { $error = 'Function return type is not void, but function is returning void here'; $this->_currentFile->addError($error, $return); } } } } } }
/** * Process the return comment of this function comment. * * @param int $commentStart The position in the stack where the comment started. * @param int $commentEnd The position in the stack where the comment ended. * * @return void */ protected function processReturn($commentStart, $commentEnd) { // Skip constructor and destructor. $className = ''; if ($this->_classToken !== null) { $className = $this->currentFile->getDeclarationName($this->_classToken); $className = strtolower(ltrim($className, '_')); } $methodName = strtolower(ltrim($this->_methodName, '_')); $isSpecialMethod = $this->_methodName === '__construct' || $this->_methodName === '__destruct'; $return = $this->commentParser->getReturn(); if ($isSpecialMethod === false && $methodName !== $className) { if ($return !== null) { $tagOrder = $this->commentParser->getTagOrders(); $index = array_keys($tagOrder, 'return'); $errorPos = $commentStart + $return->getLine(); $content = trim($return->getRawContent()); if (count($index) > 1) { $error = 'Only 1 @return tag is allowed in function comment'; $this->currentFile->addError($error, $errorPos, 'DuplicateReturn'); return; } $since = array_keys($tagOrder, 'since'); if (count($since) === 1 && $this->_tagIndex !== 0) { $this->_tagIndex++; if ($index[0] !== $this->_tagIndex) { $error = 'The @return tag is in the wrong order; the tag follows @see (if used)'; $this->currentFile->addError($error, $errorPos, 'ReturnOrder'); } } if (empty($content) === true) { $error = 'Return type missing for @return tag in function comment'; $this->currentFile->addError($error, $errorPos, 'MissingReturnType'); } else { // Check return type (can be multiple, separated by '|'). $typeNames = explode('|', $content); $suggestedNames = array(); foreach ($typeNames as $i => $typeName) { $suggestedName = PHP_CodeSniffer::suggestType($typeName); if (in_array($suggestedName, $suggestedNames) === false) { $suggestedNames[] = $suggestedName; } } $suggestedType = implode('|', $suggestedNames); if ($content !== $suggestedType) { $error = 'Function return type "%s" is invalid'; $data = array($content); $this->currentFile->addError($error, $errorPos, 'InvalidReturn', $data); } $tokens = $this->currentFile->getTokens(); // If the return type is void, make sure there is // no return statement in the function. if ($content === 'void') { if (isset($tokens[$this->_functionToken]['scope_closer']) === true) { $endToken = $tokens[$this->_functionToken]['scope_closer']; $returnToken = $this->currentFile->findNext(T_RETURN, $this->_functionToken, $endToken); if ($returnToken !== false) { // If the function is not returning anything, just // exiting, then there is no problem. $semicolon = $this->currentFile->findNext(T_WHITESPACE, $returnToken + 1, null, true); if ($tokens[$semicolon]['code'] !== T_SEMICOLON) { $error = 'Function return type is void, but function contains return statement'; $this->currentFile->addError($error, $errorPos, 'InvalidReturnVoid'); } } } } else { if ($content !== 'mixed') { // If return type is not void, there needs to be a // returns statement somewhere in the function that // returns something. if (isset($tokens[$this->_functionToken]['scope_closer']) === true) { $endToken = $tokens[$this->_functionToken]['scope_closer']; $returnToken = $this->currentFile->findNext(T_RETURN, $this->_functionToken, $endToken); if ($returnToken === false) { $error = 'Function return type is not void, but function has no return statement'; $this->currentFile->addError($error, $errorPos, 'InvalidNoReturn'); } else { $semicolon = $this->currentFile->findNext(T_WHITESPACE, $returnToken + 1, null, true); if ($tokens[$semicolon]['code'] === T_SEMICOLON) { $error = 'Function return type is not void, but function is returning void here'; $this->currentFile->addError($error, $returnToken, 'InvalidReturnNotVoid'); } } } } } //end if $spacing = substr_count($return->getWhitespaceBeforeValue(), ' '); if ($spacing !== 1) { $error = '@return tag indented incorrectly; expected 1 space but found %s'; $data = array($spacing); $this->currentFile->addError($error, $errorPos, 'ReturnIndent', $data); } } //end if } else { $error = 'Missing @return tag in function comment'; $this->currentFile->addError($error, $commentEnd, 'MissingReturn'); } //end if } else { // No return tag for constructor and destructor. if ($return !== null) { $errorPos = $commentStart + $return->getLine(); $error = '@return tag is not required for constructor and destructor'; $this->currentFile->addError($error, $errorPos, 'ReturnNotRequired'); } } //end if }
/** * Process the return comment of this function comment. * * @param int $commentStart The position in the stack where the comment started. * @param int $commentEnd The position in the stack where the comment ended. * * @return void */ private function _processReturn($commentStart, $commentEnd) { // Skip constructor and destructor. $className = ''; if ($this->_classToken !== null) { $className = $this->currentFile->getDeclarationName($this->_classToken); $className = strtolower(ltrim($className, '_')); } $methodName = strtolower(ltrim($this->_methodName, '_')); $isSpecialMethod = $this->_methodName === '__construct' || $this->_methodName === '__destruct'; $return = $this->commentParser->getReturn(); if ($isSpecialMethod === false && $methodName !== $className) { if ($return !== null) { $tagOrder = $this->commentParser->getTagOrders(); $index = array_keys($tagOrder, 'return'); $errorPos = $commentStart + $return->getLine(); $content = trim($return->getRawContent()); if (count($index) > 1) { $error = 'Only 1 @return tag is allowed in function comment'; $this->currentFile->addError($error, $errorPos); return; } $since = array_keys($tagOrder, 'since'); if (count($since) === 1 && $this->_tagIndex !== 0) { $this->_tagIndex++; if ($index[0] !== $this->_tagIndex) { $error = 'The order of @return tag is wrong in function comment'; $this->currentFile->addError($error, $errorPos); } } if (empty($content) === true) { $error = 'Return type missing for @return tag in function comment'; $this->currentFile->addError($error, $errorPos); } else { // Check return type (can be multiple, separated by '|'). $typeNames = explode('|', $content); $suggestedNames = array(); foreach ($typeNames as $i => $typeName) { $suggestedName = PHP_CodeSniffer::suggestType($typeName); if (in_array($suggestedName, $suggestedNames) === false) { $suggestedNames[] = $suggestedName; } } $suggestedType = implode('|', $suggestedNames); if ($content !== $suggestedType) { $error = "Function return type \"{$content}\" is invalid"; $this->currentFile->addError($error, $errorPos); } } } else { $error = 'Missing @return tag in function comment'; $this->currentFile->addError($error, $commentEnd); } //end if } else { // No return tag for constructor and destructor. if ($return !== null) { $errorPos = $commentStart + $return->getLine(); $error = "@return tag is not required for constructor and destructor"; $this->currentFile->addError($error, $errorPos); } } //end if }