diff --git a/WordPress-Docs/ruleset.xml b/WordPress-Docs/ruleset.xml
index 05f0ec87db..00eed4a0ce 100644
--- a/WordPress-Docs/ruleset.xml
+++ b/WordPress-Docs/ruleset.xml
@@ -116,4 +116,7 @@
+
+
+
diff --git a/WordPress/Sniffs/Commenting/FunctionCommentSniff.php b/WordPress/Sniffs/Commenting/FunctionCommentSniff.php
new file mode 100755
index 0000000000..b8b6389724
--- /dev/null
+++ b/WordPress/Sniffs/Commenting/FunctionCommentSniff.php
@@ -0,0 +1,110 @@
+phpcsFile->findPrevious(
+ array_merge( Tokens::$methodPrefixes, array( T_WHITESPACE ) ),
+ ( $stackPtr - 1 ),
+ null,
+ true
+ );
+
+ if ( T_DOC_COMMENT_CLOSE_TAG !== $this->tokens[ $commentEnd ]['code'] ) {
+ // Invalid function comment. Handled elsewhere.
+ return;
+ }
+
+ $commentStart = $this->tokens[ $commentEnd ]['comment_opener'];
+
+ $this->process_return( $stackPtr, $commentStart );
+ }
+
+ /**
+ * Process this function's return comment.
+ *
+ * @param int $stackPtr The position of the current token in the stack.
+ * @param int $commentStart The position in the stack where the comment started.
+ * @return void
+ */
+ protected function process_return( $stackPtr, $commentStart ) {
+ $returnTag = null;
+
+ foreach ( $this->tokens[ $commentStart ]['comment_tags'] as $tag ) {
+ if ( '@return' === $this->tokens[ $tag ]['content'] ) {
+ $returnTag = $tag;
+ // Multiple return tags are invalid, but flagged elsewhere.
+ break;
+ }
+ }
+
+ if ( ! $returnTag ) {
+ return;
+ }
+
+ $returnCommentPtr = ( $returnTag + 2 );
+ $returnComment = $this->tokens[ $returnCommentPtr ];
+
+ if ( empty( $returnComment['content'] ) || T_DOC_COMMENT_STRING !== $returnComment['code'] ) {
+ // Invalid return comment. Handled elsewhere.
+ return;
+ }
+
+ // Extracted from PHP_CodeSniffer\Standards\Squiz\Sniffs\Commenting\FunctionCommentSniff::processReturn().
+ preg_match( '`^((?:\|?(?:array\([^\)]*\)|[\\\\a-z0-9\[\]]+))*)( .*)?`i', $returnComment['content'], $commentParts );
+
+ if ( empty( $commentParts[1] ) ) {
+ return;
+ }
+
+ $returnTypes = array_unique( explode( '|', $commentParts[1] ) );
+
+ /*
+ * Disallow `@return void`.
+ * See https://make.wordpress.org/core/handbook/best-practices/inline-documentation-standards/php/#phpdoc-tags.
+ */
+ if ( array( 'void' ) === $returnTypes ) {
+ $this->phpcsFile->addError(
+ '`@return void` should not be used. Omit the `@return` tag instead',
+ $returnTag,
+ 'NoReturnVoid'
+ );
+ }
+ }
+
+}
diff --git a/WordPress/Tests/Commenting/FunctionCommentUnitTest.inc b/WordPress/Tests/Commenting/FunctionCommentUnitTest.inc
new file mode 100755
index 0000000000..d90b88cd8f
--- /dev/null
+++ b/WordPress/Tests/Commenting/FunctionCommentUnitTest.inc
@@ -0,0 +1,51 @@
+ =>
+ */
+ public function getErrorList() {
+ return array(
+ 5 => 1,
+ 14 => 1,
+ );
+ }
+
+ /**
+ * Returns the lines where warnings should occur.
+ *
+ * @return array =>
+ */
+ public function getWarningList() {
+ return array();
+ }
+
+} // End class.
diff --git a/bin/phpcs.xml b/bin/phpcs.xml
index 89152ebfee..2a27766e55 100644
--- a/bin/phpcs.xml
+++ b/bin/phpcs.xml
@@ -18,7 +18,10 @@
-
+
+
+
+