diff --git a/BigBiteDocs/Docs/Commenting/FunctionCommentStandard.xml b/BigBiteDocs/Docs/Commenting/FunctionCommentStandard.xml
new file mode 100644
index 0000000..975e01c
--- /dev/null
+++ b/BigBiteDocs/Docs/Commenting/FunctionCommentStandard.xml
@@ -0,0 +1,296 @@
+
+
+
+
+
+
+ /**
+ * Short description here.
+ *
+ * @return void
+ */
+function foo()
+{
+}
+ ]]>
+
+
+
+
+
+
+
+ Short description here.
+ *
+ * @return void
+ */
+function foo()
+{
+}
+ ]]>
+
+
+
+ * Short description here.
+ *
+ * @return void
+ */
+function foo()
+{
+}
+ ]]>
+
+
+
+
+
+ * Long description here.
+ *
+ * @return void
+ */
+function foo()
+{
+}
+ ]]>
+
+
+
+ *
+ * Long description here.
+ *
+ *
+ * @return void
+ */
+function foo()
+{
+}
+ ]]>
+
+
+
+
+
+ * @return void
+ */
+function foo()
+{
+}
+ ]]>
+
+
+
+ *
+ * @return void
+ */
+function foo()
+{
+}
+ ]]>
+
+
+
+
+ When something goes wrong with foo.
+ */
+function foo()
+{
+}
+ ]]>
+
+
+ @throws
+ */
+function foo()
+{
+}
+ ]]>
+
+
+
+
+ @return void
+ */
+function foo()
+{
+}
+ ]]>
+
+
+
+
+
+
+
+ $foo Foo parameter.
+ * @param string $bar Bar parameter.
+ * @return void
+ */
+function foo($foo, $bar)
+{
+}
+ ]]>
+
+
+ $qux Bar parameter.
+ * @return void
+ */
+function foo($foo, $bar)
+{
+}
+ ]]>
+
+
+
+
+ $foo Foo parameter.
+ * @param string $bar Bar parameter.
+ * @return void
+ */
+function foo($foo, $bar)
+{
+}
+ ]]>
+
+
+ $bar Bar parameter.
+ * @param string $foo Foo parameter.
+ * @return void
+ */
+function foo($foo, $bar)
+{
+}
+ ]]>
+
+
+
+
+ Foo parameter.
+ * @param string $bar Bar parameter.
+ * @return void
+ */
+function foo($foo, $bar)
+{
+}
+ ]]>
+
+
+ foo parameter.
+ * @param string $bar bar parameter.
+ * @return void
+ */
+function foo($foo, $bar)
+{
+}
+ ]]>
+
+
+
+
+ .
+ * @param string $bar Bar parameter.
+ * @return void
+ */
+function foo($foo, $bar)
+{
+}
+ ]]>
+
+
+
+ * @param string $bar bar parameter
+ * @return void
+ */
+function foo($foo, $bar)
+{
+}
+ ]]>
+
+
+
diff --git a/BigBiteDocs/Sniffs/Commenting/FunctionCommentSniff.php b/BigBiteDocs/Sniffs/Commenting/FunctionCommentSniff.php
new file mode 100644
index 0000000..52be848
--- /dev/null
+++ b/BigBiteDocs/Sniffs/Commenting/FunctionCommentSniff.php
@@ -0,0 +1,806 @@
+
+ */
+ protected static $allowedTypes = array(
+ 'array',
+ 'bool',
+ 'float',
+ 'int',
+ 'mixed',
+ 'object',
+ 'string',
+ 'resource',
+ 'callable',
+ );
+
+ /**
+ * The current PHP version.
+ *
+ * @var int|string|null
+ */
+ private $phpVersion = null;
+
+ /**
+ * Process the return comment of this function comment.
+ *
+ * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ * @param int $commentStart The position in the stack where the comment started.
+ *
+ * @return void
+ */
+ protected function processReturn( File $phpcsFile, $stackPtr, $commentStart ) {
+ $tokens = $phpcsFile->getTokens();
+ $return = null;
+
+ if ( true === $this->skipIfInheritdoc ) {
+ if ( true === $this->checkInheritdoc( $phpcsFile, $stackPtr, $commentStart ) ) {
+ return;
+ }
+ }
+
+ foreach ( $tokens[ $commentStart ]['comment_tags'] as $tag ) {
+ if ( '@return' === $tokens[ $tag ]['content'] ) {
+ if ( null !== $return ) {
+ $error = 'Only 1 @return tag is allowed in a function comment';
+ $phpcsFile->addError( $error, $tag, 'DuplicateReturn' );
+ return;
+ }
+
+ $return = $tag;
+ }
+ }
+
+ // Skip constructor and destructor.
+ $methodName = $phpcsFile->getDeclarationName( $stackPtr );
+ $isSpecialMethod = in_array( $methodName, $this->specialMethods, true );
+
+ if ( null !== $return ) {
+ $content = $tokens[ ( $return + 2 ) ]['content'];
+ if ( empty( $content ) === true || T_DOC_COMMENT_STRING !== $tokens[ ( $return + 2 ) ]['code'] ) {
+ $error = 'Return type missing for @return tag in function comment';
+ $phpcsFile->addError( $error, $return, 'MissingReturnType' );
+ } else {
+ // Support both a return type and a description.
+ preg_match( '`^((?:\|?(?:array\([^\)]*\)|[\\\\a-z0-9\[\]]+))*)( .*)?`i', $content, $returnParts );
+ if ( isset( $returnParts[1] ) === false ) {
+ return;
+ }
+
+ $returnType = $returnParts[1];
+
+ // Check return type (can be multiple, separated by '|').
+ $typeNames = explode( '|', $returnType );
+ $suggestedNames = array();
+ foreach ( $typeNames as $typeName ) {
+ $suggestedName = $this->suggestType( $typeName );
+ if ( in_array( $suggestedName, $suggestedNames, true ) === false ) {
+ $suggestedNames[] = $suggestedName;
+ }
+ }
+
+ $suggestedType = implode( '|', $suggestedNames );
+ if ( $returnType !== $suggestedType ) {
+ $error = 'Expected "%s" but found "%s" for function return type';
+ $data = array(
+ $suggestedType,
+ $returnType,
+ );
+
+ $fix = $phpcsFile->addFixableError( $error, $return, 'InvalidReturn', $data );
+
+ if ( true === $fix ) {
+ $replacement = $suggestedType;
+ if ( empty( $returnParts[2] ) === false ) {
+ $replacement .= $returnParts[2];
+ }
+
+ $phpcsFile->fixer->replaceToken( ( $return + 2 ), $replacement );
+ unset( $replacement );
+ }
+ }
+
+ // If the return type is void, make sure there is
+ // no return statement in the function.
+ if ( 'void' === $returnType ) {
+ if ( isset( $tokens[ $stackPtr ]['scope_closer'] ) === true ) {
+ $endToken = $tokens[ $stackPtr ]['scope_closer'];
+ for ( $returnToken = $stackPtr; $returnToken < $endToken; $returnToken++ ) {
+ if ( T_CLOSURE === $tokens[ $returnToken ]['code']
+ || T_ANON_CLASS === $tokens[ $returnToken ]['code']
+ ) {
+ $returnToken = $tokens[ $returnToken ]['scope_closer'];
+ continue;
+ }
+
+ if ( T_RETURN === $tokens[ $returnToken ]['code']
+ || T_YIELD === $tokens[ $returnToken ]['code']
+ || T_YIELD_FROM === $tokens[ $returnToken ]['code']
+ ) {
+ break;
+ }
+ }
+
+ if ( $returnToken !== $endToken ) {
+ // If the function is not returning anything, just
+ // exiting, then there is no problem.
+ $semicolon = $phpcsFile->findNext( T_WHITESPACE, ( $returnToken + 1 ), null, true );
+ if ( T_SEMICOLON !== $tokens[ $semicolon ]['code'] ) {
+ $error = 'Function return type is void, but function contains return statement';
+ $phpcsFile->addError( $error, $return, 'InvalidReturnVoid' );
+ }
+ }
+ }
+ } elseif ( 'mixed' !== $returnType
+ && 'never' !== $returnType
+ && in_array( 'void', $typeNames, true ) === false
+ ) {
+ // If return type is not void, never, or mixed, there needs to be a
+ // return statement somewhere in the function that returns something.
+ if ( isset( $tokens[ $stackPtr ]['scope_closer'] ) === true ) {
+ $endToken = $tokens[ $stackPtr ]['scope_closer'];
+ for ( $returnToken = $stackPtr; $returnToken < $endToken; $returnToken++ ) {
+ if ( T_CLOSURE === $tokens[ $returnToken ]['code']
+ || T_ANON_CLASS === $tokens[ $returnToken ]['code']
+ ) {
+ $returnToken = $tokens[ $returnToken ]['scope_closer'];
+ continue;
+ }
+
+ if ( T_RETURN === $tokens[ $returnToken ]['code']
+ || T_YIELD === $tokens[ $returnToken ]['code']
+ || T_YIELD_FROM === $tokens[ $returnToken ]['code']
+ ) {
+ break;
+ }
+ }
+
+ if ( $returnToken === $endToken ) {
+ $error = 'Function return type is not void, but function has no return statement';
+ $phpcsFile->addError( $error, $return, 'InvalidNoReturn' );
+ } else {
+ $semicolon = $phpcsFile->findNext( T_WHITESPACE, ( $returnToken + 1 ), null, true );
+ if ( T_SEMICOLON === $tokens[ $semicolon ]['code'] ) {
+ $error = 'Function return type is not void, but function is returning void here';
+ $phpcsFile->addError( $error, $returnToken, 'InvalidReturnNotVoid' );
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if ( true === $isSpecialMethod ) {
+ return;
+ }
+
+ $error = 'Missing @return tag in function comment';
+ $phpcsFile->addError( $error, $tokens[ $commentStart ]['comment_closer'], 'MissingReturn' );
+ }
+ }
+
+ /**
+ * Process any throw tags that this function comment has.
+ *
+ * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ * @param int $commentStart The position in the stack where the comment started.
+ *
+ * @return void
+ */
+ protected function processThrows( File $phpcsFile, $stackPtr, $commentStart ) {
+ $tokens = $phpcsFile->getTokens();
+
+ if ( true === $this->skipIfInheritdoc ) {
+ if ( true === $this->checkInheritdoc( $phpcsFile, $stackPtr, $commentStart ) ) {
+ return;
+ }
+ }
+
+ foreach ( $tokens[ $commentStart ]['comment_tags'] as $pos => $tag ) {
+ if ( '@throws' !== $tokens[ $tag ]['content'] ) {
+ continue;
+ }
+
+ $exception = null;
+ $comment = null;
+ if ( T_DOC_COMMENT_STRING === $tokens[ ( $tag + 2 ) ]['code'] ) {
+ $matches = array();
+ preg_match( '/([^\s]+)(?:\s+(.*))?/', $tokens[ ( $tag + 2 ) ]['content'], $matches );
+ $exception = $matches[1];
+ if ( true === isset( $matches[2] ) && '' !== trim( $matches[2] ) ) {
+ $comment = $matches[2];
+ }
+ }
+
+ if ( null === $exception ) {
+ $error = 'Exception type and comment missing for @throws tag in function comment';
+ $phpcsFile->addError( $error, $tag, 'InvalidThrows' );
+ } elseif ( null === $comment ) {
+ $error = 'Comment missing for @throws tag in function comment';
+ $phpcsFile->addError( $error, $tag, 'EmptyThrows' );
+ } else {
+ // Any strings until the next tag belong to this comment.
+ if ( true === isset( $tokens[ $commentStart ]['comment_tags'][ ( $pos + 1 ) ] ) ) {
+ $end = $tokens[ $commentStart ]['comment_tags'][ ( $pos + 1 ) ];
+ } else {
+ $end = $tokens[ $commentStart ]['comment_closer'];
+ }
+
+ for ( $i = ( $tag + 3 ); $i < $end; $i++ ) {
+ if ( T_DOC_COMMENT_STRING === $tokens[ $i ]['code'] ) {
+ $comment .= ' ' . $tokens[ $i ]['content'];
+ }
+ }
+
+ $comment = trim( $comment );
+
+ // Starts with a capital letter and ends with a fullstop.
+ $firstChar = $comment[0];
+ if ( strtoupper( $firstChar ) !== $firstChar ) {
+ $error = '@throws tag comment must start with a capital letter';
+ $fix = $phpcsFile->addFixableError( $error, ( $tag + 2 ), 'ThrowsNotCapital' );
+
+ if ( true === $fix ) {
+ $oldContent = $comment;
+ $newContent = ucfirst( $oldContent );
+ $replacement = str_replace( $oldContent, $newContent, $tokens[ ( $tag + 2 ) ]['content'] );
+
+ $phpcsFile->fixer->beginChangeset();
+ $phpcsFile->fixer->replaceToken( ( $tag + 2 ), $replacement );
+ $phpcsFile->fixer->endChangeset();
+ return;
+ }
+ }
+
+ $lastChar = substr( $comment, -1 );
+ if ( '.' !== $lastChar ) {
+ $error = '@throws tag comment must end with a full stop';
+ $fix = $phpcsFile->addFixableError( $error, ( $tag + 2 ), 'ThrowsNoFullStop' );
+
+ if ( true === $fix ) {
+ $phpcsFile->fixer->beginChangeset();
+ $phpcsFile->fixer->addContent( ( $tag + 2 ), '.' );
+ $phpcsFile->fixer->endChangeset();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Process the function parameter comments.
+ *
+ * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token
+ * in the stack passed in $tokens.
+ * @param int $commentStart The position in the stack where the comment started.
+ *
+ * @return void
+ */
+ protected function processParams( File $phpcsFile, $stackPtr, $commentStart ) {
+ if ( null === $this->phpVersion ) {
+ $this->phpVersion = Config::getConfigData( 'php_version' );
+
+ if ( null === $this->phpVersion ) {
+ $this->phpVersion = PHP_VERSION_ID;
+ }
+ }
+
+ $tokens = $phpcsFile->getTokens();
+
+ if ( true === $this->skipIfInheritdoc ) {
+ if ( true === $this->checkInheritdoc( $phpcsFile, $stackPtr, $commentStart ) ) {
+ return;
+ }
+ }
+
+ $params = array();
+ $maxType = 0;
+ $maxVar = 0;
+
+ foreach ( $tokens[ $commentStart ]['comment_tags'] as $pos => $tag ) {
+ if ( '@param' !== $tokens[ $tag ]['content'] ) {
+ continue;
+ }
+
+ $type = '';
+ $typeSpace = 0;
+ $var = '';
+ $varSpace = 0;
+ $comment = '';
+ $commentLines = array();
+ if ( T_DOC_COMMENT_STRING === $tokens[ ( $tag + 2 ) ]['code'] ) {
+ $matches = array();
+ preg_match( '/([^$&.]+)(?:((?:\.\.\.)?(?:\$|&)[^\s]+)(?:(\s+)(.*))?)?/', $tokens[ ( $tag + 2 ) ]['content'], $matches );
+
+ if ( empty( $matches ) === false ) {
+ $typeLen = strlen( $matches[1] );
+ $type = trim( $matches[1] );
+ $typeSpace = ( $typeLen - strlen( $type ) );
+ $typeLen = strlen( $type );
+ if ( $typeLen > $maxType ) {
+ $maxType = $typeLen;
+ }
+ }
+
+ if ( isset( $matches[2] ) === true ) {
+ $var = $matches[2];
+ $varLen = strlen( $var );
+ if ( $varLen > $maxVar ) {
+ $maxVar = $varLen;
+ }
+
+ if ( isset( $matches[4] ) === true ) {
+ $varSpace = strlen( $matches[3] );
+ $comment = $matches[4];
+ $commentLines[] = array(
+ 'comment' => $comment,
+ 'token' => ( $tag + 2 ),
+ 'indent' => $varSpace,
+ );
+
+ // Any strings until the next tag belong to this comment.
+ if ( isset( $tokens[ $commentStart ]['comment_tags'][ ( $pos + 1 ) ] ) === true ) {
+ $end = $tokens[ $commentStart ]['comment_tags'][ ( $pos + 1 ) ];
+ } else {
+ $end = $tokens[ $commentStart ]['comment_closer'];
+ }
+
+ for ( $i = ( $tag + 3 ); $i < $end; $i++ ) {
+ if ( T_DOC_COMMENT_STRING === $tokens[ $i ]['code'] ) {
+ $indent = 0;
+ if ( T_DOC_COMMENT_WHITESPACE === $tokens[ ( $i - 1 ) ]['code'] ) {
+ $indent = $tokens[ ( $i - 1 ) ]['length'];
+ }
+
+ $comment .= ' ' . $tokens[ $i ]['content'];
+ $commentLines[] = array(
+ 'comment' => $tokens[ $i ]['content'],
+ 'token' => $i,
+ 'indent' => $indent,
+ );
+ }
+ }
+ } else {
+ $error = 'Missing parameter comment';
+ $phpcsFile->addError( $error, $tag, 'MissingParamComment' );
+ $commentLines[] = array( 'comment' => '' );
+ }
+ } elseif ( '$' === $tokens[ ( $tag + 2 ) ]['content'][0] ) {
+ $error = 'Missing parameter type';
+ $phpcsFile->addError( $error, $tag, 'MissingParamType' );
+ } else {
+ $error = 'Missing parameter name';
+ $phpcsFile->addError( $error, $tag, 'MissingParamName' );
+ }
+ } else {
+ $error = 'Missing parameter type';
+ $phpcsFile->addError( $error, $tag, 'MissingParamType' );
+ }
+
+ $params[] = array(
+ 'tag' => $tag,
+ 'type' => $type,
+ 'var' => $var,
+ 'comment' => $comment,
+ 'commentLines' => $commentLines,
+ 'type_space' => $typeSpace,
+ 'var_space' => $varSpace,
+ );
+ }
+
+ $realParams = $phpcsFile->getMethodParameters( $stackPtr );
+ $foundParams = array();
+
+ // We want to use ... for all variable length arguments, so added
+ // this prefix to the variable name so comparisons are easier.
+ foreach ( $realParams as $pos => $param ) {
+ if ( true === $param['variable_length'] ) {
+ $realParams[ $pos ]['name'] = '...' . $realParams[ $pos ]['name'];
+ }
+ }
+
+ foreach ( $params as $pos => $param ) {
+ // If the type is empty, the whole line is empty.
+ if ( '' === $param['type'] ) {
+ continue;
+ }
+
+ // Check the param type value.
+ $typeNames = explode( '|', $param['type'] );
+ $suggestedTypeNames = array();
+
+ foreach ( $typeNames as $typeName ) {
+ if ( '' === $typeName ) {
+ continue;
+ }
+
+ // Strip nullable operator.
+ if ( '?' === $typeName[0] ) {
+ $typeName = substr( $typeName, 1 );
+ }
+
+ $suggestedName = $this->suggestType( $typeName );
+ $suggestedTypeNames[] = $suggestedName;
+
+ if ( count( $typeNames ) > 1 ) {
+ continue;
+ }
+
+ // Check type hint for array and custom type.
+ $suggestedTypeHint = '';
+ if ( false !== strpos( $suggestedName, 'array' ) || '[]' === substr( $suggestedName, -2 ) ) {
+ $suggestedTypeHint = 'array';
+ } elseif ( false !== strpos( $suggestedName, 'callable' ) ) {
+ $suggestedTypeHint = 'callable';
+ } elseif ( false !== strpos( $suggestedName, 'callback' ) ) {
+ $suggestedTypeHint = 'callable';
+ } elseif ( false === in_array( $suggestedName, $this::$allowedTypes, true ) ) {
+ $suggestedTypeHint = $suggestedName;
+ }
+
+ if ( $this->phpVersion >= 70000 ) {
+ if ( 'string' === $suggestedName ) {
+ $suggestedTypeHint = 'string';
+ } elseif ( 'int' === $suggestedName || 'integer' === $suggestedName ) {
+ $suggestedTypeHint = 'int';
+ } elseif ( 'float' === $suggestedName ) {
+ $suggestedTypeHint = 'float';
+ } elseif ( 'bool' === $suggestedName || 'boolean' === $suggestedName ) {
+ $suggestedTypeHint = 'bool';
+ }
+ }
+
+ if ( $this->phpVersion >= 70200 ) {
+ if ( 'object' === $suggestedName ) {
+ $suggestedTypeHint = 'object';
+ }
+ }
+
+ if ( $this->phpVersion >= 80000 ) {
+ if ( 'mixed' === $suggestedName ) {
+ $suggestedTypeHint = 'mixed';
+ }
+ }
+
+ if ( '' !== $suggestedTypeHint && true === isset( $realParams[ $pos ] ) && '' !== $param['var'] ) {
+ $typeHint = $realParams[ $pos ]['type_hint'];
+
+ // Remove namespace prefixes when comparing.
+ $compareTypeHint = substr( $suggestedTypeHint, ( strlen( $typeHint ) * -1 ) );
+
+ if ( '' === $typeHint ) {
+ $error = 'Type hint "%s" missing for %s';
+ $data = array(
+ $suggestedTypeHint,
+ $param['var'],
+ );
+
+ $errorCode = 'TypeHintMissing';
+ if ( 'string' === $suggestedTypeHint
+ || 'int' === $suggestedTypeHint
+ || 'float' === $suggestedTypeHint
+ || 'bool' === $suggestedTypeHint
+ ) {
+ $errorCode = 'Scalar' . $errorCode;
+ }
+
+ $phpcsFile->addError( $error, $stackPtr, $errorCode, $data );
+ } elseif ( $typeHint !== $compareTypeHint && '?' !== $typeHint . $compareTypeHint ) {
+ $error = 'Expected type hint "%s"; found "%s" for %s';
+ $data = array(
+ $suggestedTypeHint,
+ $typeHint,
+ $param['var'],
+ );
+ $phpcsFile->addError( $error, $stackPtr, 'IncorrectTypeHint', $data );
+ }
+ } elseif ( '' === $suggestedTypeHint && true === isset( $realParams[ $pos ] ) ) {
+ $typeHint = $realParams[ $pos ]['type_hint'];
+ if ( '' !== $typeHint ) {
+ $error = 'Unknown type hint "%s" found for %s';
+ $data = array(
+ $typeHint,
+ $param['var'],
+ );
+ $phpcsFile->addError( $error, $stackPtr, 'InvalidTypeHint', $data );
+ }
+ }
+ }
+
+ $suggestedType = implode( '|', $suggestedTypeNames );
+ if ( $param['type'] !== $suggestedType ) {
+ $error = 'Expected "%s" but found "%s" for parameter type';
+ $data = array(
+ $suggestedType,
+ $param['type'],
+ );
+
+ $fix = $phpcsFile->addFixableError( $error, $param['tag'], 'IncorrectParamVarName', $data );
+ if ( true === $fix ) {
+ $phpcsFile->fixer->beginChangeset();
+
+ $content = $suggestedType;
+ $content .= str_repeat( ' ', $param['type_space'] );
+ $content .= $param['var'];
+ $content .= str_repeat( ' ', $param['var_space'] );
+ if ( isset( $param['commentLines'][0] ) === true ) {
+ $content .= $param['commentLines'][0]['comment'];
+ }
+
+ $phpcsFile->fixer->replaceToken( ( $param['tag'] + 2 ), $content );
+
+ // Fix up the indent of additional comment lines.
+ foreach ( $param['commentLines'] as $lineNum => $line ) {
+ if ( 0 === $lineNum || 0 === $param['commentLines'][ $lineNum ]['indent'] ) {
+ continue;
+ }
+
+ $diff = ( strlen( $param['type'] ) - strlen( $suggestedType ) );
+ $newIndent = ( $param['commentLines'][ $lineNum ]['indent'] - $diff );
+
+ $phpcsFile->fixer->replaceToken(
+ ( $param['commentLines'][ $lineNum ]['token'] - 1 ),
+ str_repeat( ' ', $newIndent )
+ );
+ }
+
+ $phpcsFile->fixer->endChangeset();
+ }
+ }
+
+ if ( '' === $param['var'] ) {
+ continue;
+ }
+
+ $foundParams[] = $param['var'];
+
+ // Check number of spaces after the type.
+ $this->checkSpacingAfterParamType( $phpcsFile, $param, $maxType );
+
+ // Make sure the param name is correct.
+ if ( true === isset( $realParams[ $pos ] ) ) {
+ $realName = $realParams[ $pos ]['name'];
+ $paramVarName = $param['var'];
+
+ if ( '&' === $param['var'][0] ) {
+ // Even when passed by reference, the variable name in $realParams does not have
+ // a leading '&'. This sniff will accept both '&$var' and '$var' in these cases.
+ $paramVarName = substr( $param['var'], 1 );
+
+ // This makes sure that the 'MissingParamTag' check won't throw a false positive.
+ $foundParams[ ( count( $foundParams ) - 1 ) ] = $paramVarName;
+
+ if ( true !== $realParams[ $pos ]['pass_by_reference'] && $realName === $paramVarName ) {
+ // Don't complain about this unless the param name is otherwise correct.
+ $error = 'Doc comment for parameter %s is prefixed with "&" but parameter is not passed by reference';
+ $code = 'ParamNameUnexpectedAmpersandPrefix';
+ $data = array( $paramVarName );
+
+ // We're not offering an auto-fix here because we can't tell if the docblock
+ // is wrong, or the parameter should be passed by reference.
+ $phpcsFile->addError( $error, $param['tag'], $code, $data );
+ }
+ }
+
+ if ( $realName !== $paramVarName ) {
+ $code = 'ParamNameNoMatch';
+ $data = array(
+ $paramVarName,
+ $realName,
+ );
+
+ $error = 'Doc comment for parameter %s does not match ';
+ if ( strtolower( $paramVarName ) === strtolower( $realName ) ) {
+ $error .= 'case of ';
+ $code = 'ParamNameNoCaseMatch';
+ }
+
+ $error .= 'actual variable name %s';
+
+ $phpcsFile->addError( $error, $param['tag'], $code, $data );
+ }
+ } elseif ( substr( $param['var'], -4 ) !== ',...' ) {
+ // We must have an extra parameter comment.
+ $error = 'Superfluous parameter comment';
+ $phpcsFile->addError( $error, $param['tag'], 'ExtraParamComment' );
+ }
+
+ if ( '' === $param['comment'] ) {
+ continue;
+ }
+
+ // Check number of spaces after the var name.
+ $this->checkSpacingAfterParamName( $phpcsFile, $param, $maxVar );
+
+ // Param comments must start with a capital letter and end with a full stop.
+ if ( 1 === preg_match( '/^(\p{Ll}|\P{L})/u', $param['comment'] ) ) {
+ $error = 'Parameter comment must start with a capital letter';
+
+ $firstCharOrd = ord( $param['comment'][0] );
+
+ // Char is lowercase ASCII letter - we can fix it.
+ if ( $firstCharOrd >= 97 && $firstCharOrd <= 122 ) {
+ $fix = $phpcsFile->addFixableError( $error, $param['tag'], 'ParamCommentNotCapital', array(), 0 );
+
+ if ( true === $fix ) {
+ $tokenToFix = ( $param['tag'] + 2 );
+ $oldContent = $param['commentLines'][0]['comment'];
+ $newContent = ucfirst( $oldContent );
+ $replacement = str_replace( $oldContent, $newContent, $tokens[ $tokenToFix ]['content'] );
+
+ $phpcsFile->fixer->beginChangeset();
+ $phpcsFile->fixer->replaceToken( $tokenToFix, $replacement );
+ $phpcsFile->fixer->endChangeset();
+ }
+ } else {
+ // Char is not lowercase ASCII letter - user must manually fix.
+ $phpcsFile->addError( $error, $param['tag'], 'ParamCommentNotCapital', array(), 0 );
+ }
+ }
+
+ $lastChar = substr( $param['comment'], -1 );
+ if ( '.' !== $lastChar ) {
+ $error = 'Parameter comment must end with a full stop';
+ $fix = $phpcsFile->addFixableError( $error, $param['tag'], 'ParamCommentFullStop', array(), 0 );
+
+ if ( true === $fix ) {
+ $lineCount = count( $param['commentLines'] );
+
+ if ( 1 === $lineCount ) {
+ $phpcsFile->fixer->beginChangeset();
+ $phpcsFile->fixer->addContent( ( $param['tag'] + 2 ), '.' );
+ $phpcsFile->fixer->endChangeset();
+ } else {
+ $phpcsFile->fixer->beginChangeset();
+ $phpcsFile->fixer->addContent( $param['commentLines'][ ( $lineCount - 1 ) ]['token'], '.' );
+ $phpcsFile->fixer->endChangeset();
+ }
+ }
+ }
+ }
+
+ $realNames = array();
+ foreach ( $realParams as $realParam ) {
+ $realNames[] = $realParam['name'];
+ }
+
+ // Report missing comments.
+ $diff = array_diff( $realNames, $foundParams );
+ foreach ( $diff as $neededParam ) {
+ $error = 'Doc comment for parameter "%s" missing';
+ $data = array( $neededParam );
+ $phpcsFile->addError( $error, $commentStart, 'MissingParamTag', $data );
+ }
+ }
+
+ /**
+ * Returns a valid variable type for param/var tags.
+ *
+ * If type is not one of the standard types, it must be a custom type.
+ * Returns the correct type name suggestion if type name is invalid.
+ *
+ * @param string $varType The variable type to process.
+ *
+ * @return string
+ */
+ protected function suggestType( $varType ) {
+ if ( '' === $varType ) {
+ return '';
+ }
+
+ // A valid type.
+ if ( in_array( $varType, self::$allowedTypes, true ) === true ) {
+ return $varType;
+ }
+
+ $lowerVarType = strtolower( $varType );
+ switch ( $lowerVarType ) {
+ case 'bool':
+ case 'boolean':
+ return 'bool';
+ case 'double':
+ case 'real':
+ case 'float':
+ return 'float';
+ case 'int':
+ case 'integer':
+ return 'int';
+ case 'array()':
+ case 'array':
+ return 'array';
+ }
+
+ // A valid type, but not lower cased.
+ if ( in_array( $lowerVarType, self::$allowedTypes, true ) === true ) {
+ return $lowerVarType;
+ }
+
+ // Old-style array declaration.
+ if ( strpos( $lowerVarType, 'array(' ) !== false ) {
+ // Valid array declaration:
+ // array, array, array.
+ $matches = array();
+ $pattern = '/^array\(\s*([^\s^=^>]*)(\s*=>\s*(.*))?\s*\)/i';
+
+ if ( preg_match( $pattern, $varType, $matches ) !== 0 ) {
+ $type1 = '';
+ if ( isset( $matches[1] ) === true ) {
+ $type1 = $matches[1];
+ }
+
+ $type2 = '';
+ if ( isset( $matches[3] ) === true ) {
+ $type2 = $matches[3];
+ }
+
+ $type1 = $this->suggestType( $type1 );
+ $type2 = $this->suggestType( $type2 );
+ if ( '' !== $type2 ) {
+ $type2 = ',' . $type2;
+ }
+
+ return "array<$type1$type2>";
+ }
+
+ return 'array';
+ }
+
+ // New style array declaration.
+ if ( strpos( $lowerVarType, 'array<' ) !== false ) {
+ // Valid array declaration:
+ // array, array, array.
+ $matches = array();
+ $pattern = '/^array\<\s*([^\s^,]*)(\s*,\s*(.*))?\s*\>/i';
+
+ if ( preg_match( $pattern, $varType, $matches ) !== 0 ) {
+ $type1 = '';
+ if ( isset( $matches[1] ) === true ) {
+ $type1 = $matches[1];
+ }
+
+ $type2 = '';
+ if ( isset( $matches[3] ) === true ) {
+ $type2 = $matches[3];
+ }
+
+ $type1 = $this->suggestType( $type1 );
+ $type2 = $this->suggestType( $type2 );
+ if ( '' !== $type2 ) {
+ $type2 = ',' . $type2;
+ }
+
+ return "array<$type1$type2>";
+ }
+
+ return 'array';
+ }
+
+ // Must be a custom type name.
+ return $varType;
+ }
+}
diff --git a/BigBiteDocs/Tests/Commenting/FunctionCommentUnitTest.inc b/BigBiteDocs/Tests/Commenting/FunctionCommentUnitTest.inc
new file mode 100644
index 0000000..cca1a4d
--- /dev/null
+++ b/BigBiteDocs/Tests/Commenting/FunctionCommentUnitTest.inc
@@ -0,0 +1,1160 @@
+MyClass)
+ */
+public function caseSensitive($a1, $a2, $a3, arRay $a4, $a5, $a6, myclas $a7)
+{
+
+}//end caseSensitive()
+
+
+/**
+ * More type hint check for custom type and array.
+ *
+ * @param array $a1 Comment here.
+ * @param array $a2 Comment here.
+ * @param MyClass $a3 Comment here.
+ * @param MyClass $a4 Comment here.
+ *
+ * @return array(int => MyClass)
+ */
+public function typeHint(MyClass $a1, $a2, myclass $a3, $a4)
+{
+ return (3 => 'myclass obj');
+
+}//end typeHint()
+
+
+/**
+ * Mixed variable type separated by a '|'.
+ *
+ * @param array|string $a1 Comment here.
+ * @param mixed $a2 Comment here.
+ * @param string|array $a3 Comment here.
+ * @param MyClass|integer $a4 Comment here.
+ *
+ * @return boolean
+ */
+public function mixedType($a1, $a2, $a3, $a4)
+{
+ return true;
+
+}//end mixedType()
+
+
+/**
+ * Array type.
+ *
+ * @param array(MyClass) $a1 OK.
+ * @param array() $a2 Invalid type.
+ * @param array( $a3 Typo.
+ * @param array(integer) $a4 Use 'array' instead.
+ * @param array(integer => integer) $a5 Use 'array' instead.
+ * @param array(integer => bool) $a6 Use 'array' instead.
+ * @param aRRay $a7 Use 'array' instead.
+ * @param string $a8 String with unknown type hint.
+ *
+ * @return integer
+ */
+public function mixedArrayType($a1, $a2, array $a3, $a4, $a5, $a6, $a7, unknownTypeHint $a8)
+{
+ return 1;
+
+}//end mixedArrayType()
+
+
+/**
+ */
+function empty1()
+{
+}//end empty1()
+
+
+/**
+ *
+ */
+function empty2()
+{
+}//end empty2()
+
+
+/**
+ *
+ *
+ *
+ */
+function empty3()
+{
+}//end empty3
+
+
+/**
+ * @return boolean
+ */
+public function missingShortDescriptionInFunctionComment()
+{
+ return true;
+
+}//end missingShortDescriptionInFunctionComment()
+
+
+class Another_Class
+{
+
+ /**
+ * Destructor should not include a return tag.
+ *
+ * @return void
+ */
+ function __destruct()
+ {
+ return;
+ }
+
+ /**
+ * Constructor should not include a return tag.
+ *
+ * @return void
+ */
+ function __construct()
+ {
+ return;
+ }
+
+}//end class
+
+
+/**
+ * Comment param alignment test.
+ *
+ * @param string $varrr1 Comment1..
+ * @param string $vr2 Comment2.
+ * @param string $var3 Comment3..
+ *
+ * @return void
+ */
+public static function paramAlign($varrr1, $vr2, $var3)
+{
+
+}//end paramAlign()
+
+
+/**
+ * Comment.
+ *
+ * @param string $id Comment.
+ * @param array $design Comment.
+ *
+ * @return void
+ */
+public static function paint($id, array $design)
+{
+
+}//end paint()
+
+
+/**
+ * Adds specified class name to class attribute of this widget.
+ *
+ * @since 4.0.0
+ * @return string
+ */
+public function myFunction()
+{
+ if ($condition === FALSE) {
+ echo 'hi';
+ }
+
+}//end myFunction()
+
+
+/**
+ * Adds specified class name to class attribute of this widget.
+ *
+ * @return string
+ */
+public function myFunction()
+{
+ if ($condition === FALSE) {
+ echo 'hi';
+ return;
+ }
+
+ return 'blah';
+
+}//end myFunction()
+
+
+/**
+ * Adds specified class name to class attribute of this widget.
+ *
+ * @return string
+ */
+public function myFunction()
+{
+ if ($condition === FALSE) {
+ echo 'hi';
+ }
+
+ return 'blah';
+
+}//end myFunction()
+
+/**
+ * Test function.
+ *
+ * @param string $arg1 An argument
+ *
+ * @access public
+ * @return bool
+ */
+
+echo $blah;
+
+function myFunction($arg1) {}
+
+class MyClass() {
+ /**
+ * An abstract function.
+ *
+ * @return string[]
+ */
+ abstract final protected function myFunction();
+}
+
+/**
+ * Comment.
+ *
+ * @param mixed $test An argument.
+ *
+ * @return mixed
+ */
+function test($test)
+{
+ if ($test === TRUE) {
+ return;
+ }
+
+ return $test;
+
+}//end test()
+
+
+/** Comment.
+ *
+ * @return mixed
+ *
+ */
+function test()
+{
+
+}//end test()
+
+/**
+ * Comment.
+ *
+ * @param \other\ns\item $test An argument.
+ *
+ * @return mixed
+ */
+function test(\other\ns\item $test)
+{
+ return $test;
+
+}//end test()
+
+/**
+ * Comment.
+ *
+ * @param item $test An argument.
+ *
+ * @return mixed
+ */
+function test(\other\ns\item $test)
+{
+ return $test;
+
+}//end test()
+
+/**
+ * Comment.
+ *
+ * @param \first\ns\item $test An argument.
+ *
+ * @return mixed
+ */
+function test(\first\ns\item $test = \second\ns::CONSTANT)
+{
+ return $test;
+
+}//end test()
+
+/**
+ * Comment.
+ *
+ * @param \first\item $test An argument.
+ *
+ * @return mixed
+ */
+function test(\first\ns\item $test = \second\ns::CONSTANT)
+{
+ return $test;
+
+}//end test()
+
+// Closures should be ignored.
+preg_replace_callback(
+ '~-([a-z])~',
+ function ($match) {
+ return strtoupper($match[1]);
+ },
+ 'hello-world'
+);
+
+$callback = function ($bar) use ($foo)
+ {
+ $bar += $foo;
+ };
+
+/**
+ * Comment should end with '*', not '**' before the slash.
+ **/
+function test123() {
+
+}
+
+/**
+ * Cant use resource for type hint.
+ *
+ * @param resource $test An argument.
+ *
+ * @return mixed
+ */
+function test($test)
+{
+ return $test;
+
+}//end test()
+
+/**
+ * Variable number of args.
+ *
+ * @param string $a1 Comment here.
+ * @param string $a2 Comment here.
+ * @param string $a2,... Comment here.
+ *
+ * @return boolean
+ */
+public function variableArgs($a1, $a2)
+{
+ return true;
+
+}//end variableArgs()
+
+/**
+ * Contains closure.
+ *
+ * @return void
+ */
+public function containsClosure()
+{
+ function ($e) {
+ return new Event($e);
+ },
+
+}//end containsClosure()
+
+/**
+ * 这是一条测试评论.
+ *
+ * @return void
+ */
+public function test()
+{
+
+}//end variableArgs()
+
+/**
+ * Uses callable.
+ *
+ * @param callable $cb Test parameter.
+ *
+ * @return void
+ */
+public function usesCallable(callable $cb) {
+ $cb();
+}//end usesCallable()
+
+/**
+ * Creates a map of tokens => line numbers for each token.
+ *
+ * @param array $tokens The array of tokens to process.
+ * @param object $tokenizer The tokenizer being used to process this file.
+ * @param string $eolChar The EOL character
+ * to use for splitting strings.
+ *
+ * @return void
+ * @throws Exception If something really bad
+ * happens while doing foo.
+ */
+public function foo(array &$tokens, $tokenizer, $eolChar)
+{
+
+}//end foo()
+
+/**
+ * Some description.
+ *
+ * @param \Vendor\Package\SomeClass $someclass Some class.
+ * @param \OtherVendor\Package\SomeClass2 $someclass2 Some class.
+ * @param \OtherVendor\Package\SomeClass2 $someclass3 Some class.
+ *
+ * @return void
+ */
+public function foo(SomeClass $someclass, \OtherVendor\Package\SomeClass2 $someclass2, SomeClass3 $someclass3)
+{
+}
+
+/**
+ * Gettext.
+ *
+ * @return string
+ */
+public function _() {
+ return $foo;
+}
+
+class Baz {
+ /**
+ * The PHP5 constructor
+ *
+ * No return tag
+ */
+ public function __construct() {
+
+ }
+}
+
+/**
+ * Test
+ *
+ * @return void
+ * @throws E
+ */
+function myFunction() {}
+
+/**
+ * Yield test
+ *
+ * @return int
+ */
+function yieldTest()
+{
+ for ($i = 0; $i < 5; $i++) {
+ yield $i;
+ }
+}
+
+/**
+ * Yield test
+ *
+ * @return void
+ */
+function yieldTest()
+{
+ for ($i = 0; $i < 5; $i++) {
+ yield $i;
+ }
+}
+
+/**
+ * Using "array" as a type hint should satisfy a specified array parameter type.
+ *
+ * @param MyClass[] $values An array of MyClass objects.
+ *
+ * @return void
+ */
+public function specifiedArray(array $values) {
+
+}// end specifiedArray()
+
+/**
+ * Using "callable" as a type hint should satisfy a "callback" parameter type.
+ *
+ * @param callback $cb A callback.
+ *
+ * @return void
+ */
+public function callableCallback(callable $cb) {
+
+}// end callableCallback()
+
+/**
+ * PHP7 type hints.
+ *
+ * @param string $name1 Comment.
+ * @param int $name2 Comment.
+ * @param float $name3 Comment.
+ * @param boolean $name4 Comment.
+ *
+ * @return void
+ */
+public function myFunction (string $name1, int $name2, float $name3, bool $name4) {
+}
+
+/**
+ * Variadic function.
+ *
+ * @param string $name1 Comment.
+ * @param string ...$name2 Comment.
+ *
+ * @return void
+ */
+public function myFunction(string $name1, string ...$name2) {
+}
+
+
+/**
+ * Variadic function.
+ *
+ * @param string $name1 Comment.
+ * @param string $name2 Comment.
+ *
+ * @return void
+ */
+public function myFunction(string $name1, string ...$name2) {
+}
+
+/**
+ * Return description function + correct type.
+ *
+ * @return int This is a description.
+ */
+public function myFunction() {
+ return 5;
+}
+
+/**
+ * Return description function + incorrect type.
+ *
+ * @return integer This is a description.
+ */
+public function myFunction() {
+ return 5;
+}
+
+/**
+ * Return description function + no return.
+ *
+ * @return void This is a description.
+ */
+public function myFunction() {
+}
+
+/**
+ * Return description function + mixed return.
+ *
+ * @return mixed This is a description.
+ */
+public function myFunction() {
+}
+
+/**
+ * Function comment.
+ *
+ * @param $bar
+ * Comment here.
+ * @param ...
+ * Additional arguments here.
+ *
+ * @return
+ * Return value
+ *
+ */
+function foo($bar) {
+}
+
+/**
+ * Do something.
+ *
+ * @return void
+ */
+public function someFunc(): void
+{
+ $class = new class
+ {
+ /**
+ * Do something.
+ *
+ * @return string
+ */
+ public function getString(): string
+ {
+ return 'some string';
+ }
+ };
+}
+
+/**
+ * Return description function + mixed return types.
+ *
+ * @return boolean|integer This is a description.
+ */
+function returnTypeWithDescriptionA()
+{
+ return 5;
+
+}//end returnTypeWithDescriptionA()
+
+
+/**
+ * Return description function + mixed return types.
+ *
+ * @return real|bool This is a description.
+ */
+function returnTypeWithDescriptionB()
+{
+ return 5;
+
+}//end returnTypeWithDescriptionB()
+
+
+/**
+ * Return description function + lots of different mixed return types.
+ *
+ * @return int|object|string[]|real|double|float|bool|array(int=>MyClass)|callable And here we have a description
+ */
+function returnTypeWithDescriptionC()
+{
+ return 5;
+
+}//end returnTypeWithDescriptionC()
+
+
+/**
+ * Return description function + lots of different mixed return types.
+ *
+ * @return array(int=>bool)|\OtherVendor\Package\SomeClass2|MyClass[]|void And here we have a description
+ */
+function returnTypeWithDescriptionD()
+{
+
+}//end returnTypeWithDescriptionD()
+
+/**
+ * Yield from test
+ *
+ * @return int[]
+ */
+function yieldFromTest()
+{
+ yield from foo();
+}
+
+/**
+ * Audio
+ *
+ * Generates an audio element to embed sounds
+ *
+ * @param mixed $src Either a source string or
+ * an array of sources.
+ * @param mixed $unsupportedMessage The message to display
+ * if the media tag is not supported by the browser.
+ * @param mixed $attributes HTML attributes.
+ * @return string
+ */
+function audio(
+ $src,
+ $unsupportedMessage = '',
+ $attributes = '',
+)
+{
+ return 'test';
+}
+
+/**
+ * Test function
+ *
+ * @return array
+ */
+function returnArrayWithClosure()
+{
+ function () {
+ return;
+ };
+
+ return [];
+}
+
+/**
+ * Test function
+ *
+ * @return array
+ */
+function returnArrayWithAnonymousClass()
+{
+ new class {
+ /**
+ * @return void
+ */
+ public function test() {
+ return;
+ }
+ };
+
+ return [];
+}
+
+/**
+ * @return void
+ */
+function returnVoidWithClosure()
+{
+ function () {
+ return 1;
+ };
+}
+
+/**
+ * @return void
+ */
+function returnVoidWithAnonymousClass()
+{
+ new class {
+ /**
+ * @return int
+ */
+ public function test()
+ {
+ return 1;
+ }
+ };
+}
+
+class TestReturnVoid
+{
+ /**
+ * @return void
+ */
+ public function test()
+ {
+ function () {
+ return 4;
+ };
+ }
+}
+
+/**
+ * Comment here.
+ *
+ * @param int $a This is A.
+ * @param ?array $b This is B.
+ *
+ * @return void
+ */
+public static function foo(?int $a, ?array $b) {}
+
+/**
+ * Comment here.
+ *
+ * @param object $a This is A.
+ * @param object $b This is B.
+ *
+ * @return void
+ */
+public function foo(object $a, ?object $b) {}
+
+/**
+ * Prepares given PHP class method for later code building.
+ *
+ * @param int $foo Comment.
+ * - Additional comment.
+ *
+ * @return void
+ */
+function foo($foo) {}
+
+/**
+ * {@inheritDoc}
+ */
+public function foo($a, $b) {}
+
+// phpcs:set BigBiteDocs.Commenting.FunctionComment skipIfInheritdoc true
+
+/**
+ * {@inheritDoc}
+ */
+public function foo($a, $b) {}
+
+/**
+ * Foo.
+ *
+ * @param mixed $a Comment.
+ *
+ * @return mixed
+ */
+public function foo(mixed $a): mixed {}
+
+// phpcs:set BigBiteDocs.Commenting.FunctionComment specialMethods[]
+class Bar {
+ /**
+ * The PHP5 constructor
+ */
+ public function __construct() {
+
+ }
+}
+
+// phpcs:set BigBiteDocs.Commenting.FunctionComment specialMethods[] ignored
+/**
+ * Should be ok
+ */
+public function ignored() {
+
+}
+
+// phpcs:set BigBiteDocs.Commenting.FunctionComment specialMethods[] __construct,__destruct
+
+/**
+ * @return void
+ * @throws Exception If any other error occurs. */
+function throwCommentOneLine() {}
+
+/**
+ * When two adjacent pipe symbols are used (by mistake), the sniff should not throw a PHP Fatal error
+ *
+ * @param stdClass||null $object While invalid, this should not throw a PHP Fatal error.
+ * @return void
+ */
+function doublePipeFatalError(?stdClass $object) {}
+
+/**
+ * Test for passing variables by reference
+ *
+ * This sniff treats the '&' as optional for parameters passed by reference, but
+ * forbidden for parameters which are not passed by reference.
+ *
+ * Because mismatches may be in either direction, we cannot auto-fix these.
+ *
+ * @param string $foo A string passed in by reference.
+ * @param string &$bar A string passed in by reference.
+ * @param string $baz A string NOT passed in by reference.
+ * @param string &$qux A string NOT passed in by reference.
+ * @param string &$case1 A string passed in by reference with a case mismatch.
+ * @param string &$CASE2 A string NOT passed in by reference, also with a case mismatch.
+ *
+ * @return void
+ */
+public function variablesPassedByReference(&$foo, &$bar, $baz, $qux, &$CASE1, $case2)
+{
+ return;
+}
+
+/**
+ * Test for param tag containing ref, but param in declaration not being by ref.
+ *
+ * @param string &$foo This should be flagged as (only) ParamNameUnexpectedAmpersandPrefix.
+ * @param string &$bar This should be flagged as (only) ParamNameNoMatch.
+ * @param string &$baz This should be flagged as (only) ParamNameNoCaseMatch.
+ *
+ * @return void
+ */
+function passedByRefMismatch($foo, $bra, $BAZ) {
+ return;
+}
+
+/**
+ * Test variable case
+ *
+ * @param string $foo This parameter is lowercase.
+ * @param string $BAR This parameter is UPPERCASE.
+ * @param string $BazQux This parameter is TitleCase.
+ * @param string $corgeGrault This parameter is camelCase.
+ * @param string $GARPLY This parameter should be in lowercase.
+ * @param string $waldo This parameter should be in TitleCase.
+ * @param string $freD This parameter should be in UPPERCASE.
+ * @param string $PLUGH This parameter should be in TitleCase.
+ *
+ * @return void
+ */
+public function variableCaseTest(
+ $foo,
+ $BAR,
+ $BazQux,
+ $corgeGrault,
+ $garply,
+ $Waldo,
+ $FRED,
+ $PluGh
+) {
+ return;
+}
+
+/**
+ * Test variable order mismatch
+ *
+ * @param string $foo This is the third parameter.
+ * @param string $bar This is the first parameter.
+ * @param string $baz This is the second parameter.
+ *
+ * @return void
+ */
+public function variableOrderMismatch($bar, $baz, $foo) {
+ return;
+}
+
+/**
+ * @return never
+ */
+function foo() {}
+
+/**
+ * @param $noTypeNoComment
+ * @return void
+ */
+function paramVariation1($noTypeNoComment): void {}
+
+/**
+ * @param $noTypeWithComment This parameter has no type specified.
+ * @return void
+ */
+function paramVariation2($noTypeWithComment): void {}
+
+/**
+ * @param int $hasTypeNoComment
+ * @return void
+ */
+function paramVariation3($hasTypeNoComment): void {}
+
+/**
+ * @param int $hasTypehasComment This parameter has type.
+ * @return void
+ */
+function paramVariation4($hasTypehasComment): void {}
diff --git a/BigBiteDocs/Tests/Commenting/FunctionCommentUnitTest.inc.fixed b/BigBiteDocs/Tests/Commenting/FunctionCommentUnitTest.inc.fixed
new file mode 100644
index 0000000..f60caf2
--- /dev/null
+++ b/BigBiteDocs/Tests/Commenting/FunctionCommentUnitTest.inc.fixed
@@ -0,0 +1,1160 @@
+
+ */
+public function caseSensitive($a1, $a2, $a3, arRay $a4, $a5, $a6, myclas $a7)
+{
+
+}//end caseSensitive()
+
+
+/**
+ * More type hint check for custom type and array.
+ *
+ * @param array $a1 Comment here.
+ * @param array $a2 Comment here.
+ * @param MyClass $a3 Comment here.
+ * @param MyClass $a4 Comment here.
+ *
+ * @return array
+ */
+public function typeHint(MyClass $a1, $a2, myclass $a3, $a4)
+{
+ return (3 => 'myclass obj');
+
+}//end typeHint()
+
+
+/**
+ * Mixed variable type separated by a '|'.
+ *
+ * @param array|string $a1 Comment here.
+ * @param mixed $a2 Comment here.
+ * @param string|array $a3 Comment here.
+ * @param MyClass|int $a4 Comment here.
+ *
+ * @return bool
+ */
+public function mixedType($a1, $a2, $a3, $a4)
+{
+ return true;
+
+}//end mixedType()
+
+
+/**
+ * Array type.
+ *
+ * @param array $a1 OK.
+ * @param array $a2 Invalid type.
+ * @param array $a3 Typo.
+ * @param array $a4 Use 'array' instead.
+ * @param array $a5 Use 'array' instead.
+ * @param array $a6 Use 'array' instead.
+ * @param array $a7 Use 'array' instead.
+ * @param string $a8 String with unknown type hint.
+ *
+ * @return int
+ */
+public function mixedArrayType($a1, $a2, array $a3, $a4, $a5, $a6, $a7, unknownTypeHint $a8)
+{
+ return 1;
+
+}//end mixedArrayType()
+
+
+/**
+ */
+function empty1()
+{
+}//end empty1()
+
+
+/**
+ *
+ */
+function empty2()
+{
+}//end empty2()
+
+
+/**
+ *
+ *
+ *
+ */
+function empty3()
+{
+}//end empty3
+
+
+/**
+ * @return bool
+ */
+public function missingShortDescriptionInFunctionComment()
+{
+ return true;
+
+}//end missingShortDescriptionInFunctionComment()
+
+
+class Another_Class
+{
+
+ /**
+ * Destructor should not include a return tag.
+ *
+ * @return void
+ */
+ function __destruct()
+ {
+ return;
+ }
+
+ /**
+ * Constructor should not include a return tag.
+ *
+ * @return void
+ */
+ function __construct()
+ {
+ return;
+ }
+
+}//end class
+
+
+/**
+ * Comment param alignment test.
+ *
+ * @param string $varrr1 Comment1..
+ * @param string $vr2 Comment2.
+ * @param string $var3 Comment3..
+ *
+ * @return void
+ */
+public static function paramAlign($varrr1, $vr2, $var3)
+{
+
+}//end paramAlign()
+
+
+/**
+ * Comment.
+ *
+ * @param string $id Comment.
+ * @param array $design Comment.
+ *
+ * @return void
+ */
+public static function paint($id, array $design)
+{
+
+}//end paint()
+
+
+/**
+ * Adds specified class name to class attribute of this widget.
+ *
+ * @since 4.0.0
+ * @return string
+ */
+public function myFunction()
+{
+ if ($condition === FALSE) {
+ echo 'hi';
+ }
+
+}//end myFunction()
+
+
+/**
+ * Adds specified class name to class attribute of this widget.
+ *
+ * @return string
+ */
+public function myFunction()
+{
+ if ($condition === FALSE) {
+ echo 'hi';
+ return;
+ }
+
+ return 'blah';
+
+}//end myFunction()
+
+
+/**
+ * Adds specified class name to class attribute of this widget.
+ *
+ * @return string
+ */
+public function myFunction()
+{
+ if ($condition === FALSE) {
+ echo 'hi';
+ }
+
+ return 'blah';
+
+}//end myFunction()
+
+/**
+ * Test function.
+ *
+ * @param string $arg1 An argument
+ *
+ * @access public
+ * @return bool
+ */
+
+echo $blah;
+
+function myFunction($arg1) {}
+
+class MyClass() {
+ /**
+ * An abstract function.
+ *
+ * @return string[]
+ */
+ abstract final protected function myFunction();
+}
+
+/**
+ * Comment.
+ *
+ * @param mixed $test An argument.
+ *
+ * @return mixed
+ */
+function test($test)
+{
+ if ($test === TRUE) {
+ return;
+ }
+
+ return $test;
+
+}//end test()
+
+
+/** Comment.
+ *
+ * @return mixed
+ *
+ */
+function test()
+{
+
+}//end test()
+
+/**
+ * Comment.
+ *
+ * @param \other\ns\item $test An argument.
+ *
+ * @return mixed
+ */
+function test(\other\ns\item $test)
+{
+ return $test;
+
+}//end test()
+
+/**
+ * Comment.
+ *
+ * @param item $test An argument.
+ *
+ * @return mixed
+ */
+function test(\other\ns\item $test)
+{
+ return $test;
+
+}//end test()
+
+/**
+ * Comment.
+ *
+ * @param \first\ns\item $test An argument.
+ *
+ * @return mixed
+ */
+function test(\first\ns\item $test = \second\ns::CONSTANT)
+{
+ return $test;
+
+}//end test()
+
+/**
+ * Comment.
+ *
+ * @param \first\item $test An argument.
+ *
+ * @return mixed
+ */
+function test(\first\ns\item $test = \second\ns::CONSTANT)
+{
+ return $test;
+
+}//end test()
+
+// Closures should be ignored.
+preg_replace_callback(
+ '~-([a-z])~',
+ function ($match) {
+ return strtoupper($match[1]);
+ },
+ 'hello-world'
+);
+
+$callback = function ($bar) use ($foo)
+ {
+ $bar += $foo;
+ };
+
+/**
+ * Comment should end with '*', not '**' before the slash.
+ **/
+function test123() {
+
+}
+
+/**
+ * Cant use resource for type hint.
+ *
+ * @param resource $test An argument.
+ *
+ * @return mixed
+ */
+function test($test)
+{
+ return $test;
+
+}//end test()
+
+/**
+ * Variable number of args.
+ *
+ * @param string $a1 Comment here.
+ * @param string $a2 Comment here.
+ * @param string $a2,... Comment here.
+ *
+ * @return bool
+ */
+public function variableArgs($a1, $a2)
+{
+ return true;
+
+}//end variableArgs()
+
+/**
+ * Contains closure.
+ *
+ * @return void
+ */
+public function containsClosure()
+{
+ function ($e) {
+ return new Event($e);
+ },
+
+}//end containsClosure()
+
+/**
+ * 这是一条测试评论.
+ *
+ * @return void
+ */
+public function test()
+{
+
+}//end variableArgs()
+
+/**
+ * Uses callable.
+ *
+ * @param callable $cb Test parameter.
+ *
+ * @return void
+ */
+public function usesCallable(callable $cb) {
+ $cb();
+}//end usesCallable()
+
+/**
+ * Creates a map of tokens => line numbers for each token.
+ *
+ * @param array $tokens The array of tokens to process.
+ * @param object $tokenizer The tokenizer being used to process this file.
+ * @param string $eolChar The EOL character
+ * to use for splitting strings.
+ *
+ * @return void
+ * @throws Exception If something really bad
+ * happens while doing foo.
+ */
+public function foo(array &$tokens, $tokenizer, $eolChar)
+{
+
+}//end foo()
+
+/**
+ * Some description.
+ *
+ * @param \Vendor\Package\SomeClass $someclass Some class.
+ * @param \OtherVendor\Package\SomeClass2 $someclass2 Some class.
+ * @param \OtherVendor\Package\SomeClass2 $someclass3 Some class.
+ *
+ * @return void
+ */
+public function foo(SomeClass $someclass, \OtherVendor\Package\SomeClass2 $someclass2, SomeClass3 $someclass3)
+{
+}
+
+/**
+ * Gettext.
+ *
+ * @return string
+ */
+public function _() {
+ return $foo;
+}
+
+class Baz {
+ /**
+ * The PHP5 constructor
+ *
+ * No return tag
+ */
+ public function __construct() {
+
+ }
+}
+
+/**
+ * Test
+ *
+ * @return void
+ * @throws E
+ */
+function myFunction() {}
+
+/**
+ * Yield test
+ *
+ * @return int
+ */
+function yieldTest()
+{
+ for ($i = 0; $i < 5; $i++) {
+ yield $i;
+ }
+}
+
+/**
+ * Yield test
+ *
+ * @return void
+ */
+function yieldTest()
+{
+ for ($i = 0; $i < 5; $i++) {
+ yield $i;
+ }
+}
+
+/**
+ * Using "array" as a type hint should satisfy a specified array parameter type.
+ *
+ * @param MyClass[] $values An array of MyClass objects.
+ *
+ * @return void
+ */
+public function specifiedArray(array $values) {
+
+}// end specifiedArray()
+
+/**
+ * Using "callable" as a type hint should satisfy a "callback" parameter type.
+ *
+ * @param callback $cb A callback.
+ *
+ * @return void
+ */
+public function callableCallback(callable $cb) {
+
+}// end callableCallback()
+
+/**
+ * PHP7 type hints.
+ *
+ * @param string $name1 Comment.
+ * @param int $name2 Comment.
+ * @param float $name3 Comment.
+ * @param bool $name4 Comment.
+ *
+ * @return void
+ */
+public function myFunction (string $name1, int $name2, float $name3, bool $name4) {
+}
+
+/**
+ * Variadic function.
+ *
+ * @param string $name1 Comment.
+ * @param string ...$name2 Comment.
+ *
+ * @return void
+ */
+public function myFunction(string $name1, string ...$name2) {
+}
+
+
+/**
+ * Variadic function.
+ *
+ * @param string $name1 Comment.
+ * @param string $name2 Comment.
+ *
+ * @return void
+ */
+public function myFunction(string $name1, string ...$name2) {
+}
+
+/**
+ * Return description function + correct type.
+ *
+ * @return int This is a description.
+ */
+public function myFunction() {
+ return 5;
+}
+
+/**
+ * Return description function + incorrect type.
+ *
+ * @return int This is a description.
+ */
+public function myFunction() {
+ return 5;
+}
+
+/**
+ * Return description function + no return.
+ *
+ * @return void This is a description.
+ */
+public function myFunction() {
+}
+
+/**
+ * Return description function + mixed return.
+ *
+ * @return mixed This is a description.
+ */
+public function myFunction() {
+}
+
+/**
+ * Function comment.
+ *
+ * @param $bar
+ * Comment here.
+ * @param ...
+ * Additional arguments here.
+ *
+ * @return
+ * Return value
+ *
+ */
+function foo($bar) {
+}
+
+/**
+ * Do something.
+ *
+ * @return void
+ */
+public function someFunc(): void
+{
+ $class = new class
+ {
+ /**
+ * Do something.
+ *
+ * @return string
+ */
+ public function getString(): string
+ {
+ return 'some string';
+ }
+ };
+}
+
+/**
+ * Return description function + mixed return types.
+ *
+ * @return bool|int This is a description.
+ */
+function returnTypeWithDescriptionA()
+{
+ return 5;
+
+}//end returnTypeWithDescriptionA()
+
+
+/**
+ * Return description function + mixed return types.
+ *
+ * @return float|bool This is a description.
+ */
+function returnTypeWithDescriptionB()
+{
+ return 5;
+
+}//end returnTypeWithDescriptionB()
+
+
+/**
+ * Return description function + lots of different mixed return types.
+ *
+ * @return int|object|string[]|float|bool|array|callable And here we have a description
+ */
+function returnTypeWithDescriptionC()
+{
+ return 5;
+
+}//end returnTypeWithDescriptionC()
+
+
+/**
+ * Return description function + lots of different mixed return types.
+ *
+ * @return array|\OtherVendor\Package\SomeClass2|MyClass[]|void And here we have a description
+ */
+function returnTypeWithDescriptionD()
+{
+
+}//end returnTypeWithDescriptionD()
+
+/**
+ * Yield from test
+ *
+ * @return int[]
+ */
+function yieldFromTest()
+{
+ yield from foo();
+}
+
+/**
+ * Audio
+ *
+ * Generates an audio element to embed sounds
+ *
+ * @param mixed $src Either a source string or
+ * an array of sources.
+ * @param mixed $unsupportedMessage The message to display
+ * if the media tag is not supported by the browser.
+ * @param mixed $attributes HTML attributes.
+ * @return string
+ */
+function audio(
+ $src,
+ $unsupportedMessage = '',
+ $attributes = '',
+)
+{
+ return 'test';
+}
+
+/**
+ * Test function
+ *
+ * @return array
+ */
+function returnArrayWithClosure()
+{
+ function () {
+ return;
+ };
+
+ return [];
+}
+
+/**
+ * Test function
+ *
+ * @return array
+ */
+function returnArrayWithAnonymousClass()
+{
+ new class {
+ /**
+ * @return void
+ */
+ public function test() {
+ return;
+ }
+ };
+
+ return [];
+}
+
+/**
+ * @return void
+ */
+function returnVoidWithClosure()
+{
+ function () {
+ return 1;
+ };
+}
+
+/**
+ * @return void
+ */
+function returnVoidWithAnonymousClass()
+{
+ new class {
+ /**
+ * @return int
+ */
+ public function test()
+ {
+ return 1;
+ }
+ };
+}
+
+class TestReturnVoid
+{
+ /**
+ * @return void
+ */
+ public function test()
+ {
+ function () {
+ return 4;
+ };
+ }
+}
+
+/**
+ * Comment here.
+ *
+ * @param int $a This is A.
+ * @param array $b This is B.
+ *
+ * @return void
+ */
+public static function foo(?int $a, ?array $b) {}
+
+/**
+ * Comment here.
+ *
+ * @param object $a This is A.
+ * @param object $b This is B.
+ *
+ * @return void
+ */
+public function foo(object $a, ?object $b) {}
+
+/**
+ * Prepares given PHP class method for later code building.
+ *
+ * @param int $foo Comment.
+ * - Additional comment.
+ *
+ * @return void
+ */
+function foo($foo) {}
+
+/**
+ * {@inheritDoc}
+ */
+public function foo($a, $b) {}
+
+// phpcs:set BigBiteDocs.Commenting.FunctionComment skipIfInheritdoc true
+
+/**
+ * {@inheritDoc}
+ */
+public function foo($a, $b) {}
+
+/**
+ * Foo.
+ *
+ * @param mixed $a Comment.
+ *
+ * @return mixed
+ */
+public function foo(mixed $a): mixed {}
+
+// phpcs:set BigBiteDocs.Commenting.FunctionComment specialMethods[]
+class Bar {
+ /**
+ * The PHP5 constructor
+ */
+ public function __construct() {
+
+ }
+}
+
+// phpcs:set BigBiteDocs.Commenting.FunctionComment specialMethods[] ignored
+/**
+ * Should be ok
+ */
+public function ignored() {
+
+}
+
+// phpcs:set BigBiteDocs.Commenting.FunctionComment specialMethods[] __construct,__destruct
+
+/**
+ * @return void
+ * @throws Exception If any other error occurs. */
+function throwCommentOneLine() {}
+
+/**
+ * When two adjacent pipe symbols are used (by mistake), the sniff should not throw a PHP Fatal error
+ *
+ * @param stdClass|null $object While invalid, this should not throw a PHP Fatal error.
+ * @return void
+ */
+function doublePipeFatalError(?stdClass $object) {}
+
+/**
+ * Test for passing variables by reference
+ *
+ * This sniff treats the '&' as optional for parameters passed by reference, but
+ * forbidden for parameters which are not passed by reference.
+ *
+ * Because mismatches may be in either direction, we cannot auto-fix these.
+ *
+ * @param string $foo A string passed in by reference.
+ * @param string &$bar A string passed in by reference.
+ * @param string $baz A string NOT passed in by reference.
+ * @param string &$qux A string NOT passed in by reference.
+ * @param string &$case1 A string passed in by reference with a case mismatch.
+ * @param string &$CASE2 A string NOT passed in by reference, also with a case mismatch.
+ *
+ * @return void
+ */
+public function variablesPassedByReference(&$foo, &$bar, $baz, $qux, &$CASE1, $case2)
+{
+ return;
+}
+
+/**
+ * Test for param tag containing ref, but param in declaration not being by ref.
+ *
+ * @param string &$foo This should be flagged as (only) ParamNameUnexpectedAmpersandPrefix.
+ * @param string &$bar This should be flagged as (only) ParamNameNoMatch.
+ * @param string &$baz This should be flagged as (only) ParamNameNoCaseMatch.
+ *
+ * @return void
+ */
+function passedByRefMismatch($foo, $bra, $BAZ) {
+ return;
+}
+
+/**
+ * Test variable case
+ *
+ * @param string $foo This parameter is lowercase.
+ * @param string $BAR This parameter is UPPERCASE.
+ * @param string $BazQux This parameter is TitleCase.
+ * @param string $corgeGrault This parameter is camelCase.
+ * @param string $GARPLY This parameter should be in lowercase.
+ * @param string $waldo This parameter should be in TitleCase.
+ * @param string $freD This parameter should be in UPPERCASE.
+ * @param string $PLUGH This parameter should be in TitleCase.
+ *
+ * @return void
+ */
+public function variableCaseTest(
+ $foo,
+ $BAR,
+ $BazQux,
+ $corgeGrault,
+ $garply,
+ $Waldo,
+ $FRED,
+ $PluGh
+) {
+ return;
+}
+
+/**
+ * Test variable order mismatch
+ *
+ * @param string $foo This is the third parameter.
+ * @param string $bar This is the first parameter.
+ * @param string $baz This is the second parameter.
+ *
+ * @return void
+ */
+public function variableOrderMismatch($bar, $baz, $foo) {
+ return;
+}
+
+/**
+ * @return never
+ */
+function foo() {}
+
+/**
+ * @param $noTypeNoComment
+ * @return void
+ */
+function paramVariation1($noTypeNoComment): void {}
+
+/**
+ * @param $noTypeWithComment This parameter has no type specified.
+ * @return void
+ */
+function paramVariation2($noTypeWithComment): void {}
+
+/**
+ * @param int $hasTypeNoComment
+ * @return void
+ */
+function paramVariation3($hasTypeNoComment): void {}
+
+/**
+ * @param int $hasTypehasComment This parameter has type.
+ * @return void
+ */
+function paramVariation4($hasTypehasComment): void {}
diff --git a/BigBiteDocs/Tests/Commenting/FunctionCommentUnitTest.php b/BigBiteDocs/Tests/Commenting/FunctionCommentUnitTest.php
new file mode 100644
index 0000000..3c9bb20
--- /dev/null
+++ b/BigBiteDocs/Tests/Commenting/FunctionCommentUnitTest.php
@@ -0,0 +1,206 @@
+
+ */
+ public function getErrorList( $testFile = '' ) {
+ $errors = array(
+ 5 => 1,
+ 10 => 2,
+ 12 => 1,
+ 13 => 3,
+ 14 => 1,
+ 15 => 1,
+ 28 => 1,
+ 43 => 1,
+ 76 => 1,
+ 87 => 1,
+ 103 => 1,
+ 109 => 1,
+ 112 => 1,
+ 122 => 1,
+ 123 => 2,
+ 124 => 3,
+ 125 => 1,
+ 126 => 1,
+ 137 => 2,
+ 138 => 2,
+ 139 => 2,
+ 143 => 2,
+ 155 => 1,
+ 159 => 1,
+ 166 => 1,
+ 173 => 1,
+ 183 => 1,
+ 190 => 2,
+ 193 => 2,
+ 196 => 1,
+ 199 => 2,
+ 210 => 1,
+ 211 => 1,
+ 222 => 1,
+ 223 => 1,
+ 224 => 1,
+ 225 => 1,
+ 226 => 1,
+ 227 => 1,
+ 230 => 2,
+ 232 => 2,
+ 246 => 1,
+ 248 => 4,
+ 261 => 1,
+ 263 => 1,
+ 275 => 1,
+ 276 => 1,
+ 277 => 1,
+ 278 => 1,
+ 279 => 1,
+ 280 => 1,
+ 281 => 1,
+ 284 => 1,
+ 286 => 7,
+ 294 => 1,
+ 302 => 1,
+ 312 => 1,
+ 319 => 1,
+ 358 => 1,
+ 359 => 2,
+ 372 => 1,
+ 373 => 1,
+ 387 => 1,
+ 407 => 1,
+ 441 => 1,
+ 500 => 1,
+ 526 => 1,
+ 548 => 1,
+ 573 => 1,
+ 641 => 1,
+ 669 => 1,
+ 688 => 1,
+ 725 => 1,
+ 744 => 1,
+ 748 => 1,
+ 767 => 1,
+ 789 => 1,
+ 792 => 1,
+ 794 => 1,
+ 797 => 1,
+ 828 => 1,
+ 840 => 1,
+ 852 => 1,
+ 864 => 1,
+ 886 => 1,
+ 888 => 1,
+ 890 => 1,
+ 978 => 1,
+ 982 => 2,
+ 992 => 1,
+ 997 => 1,
+ 1004 => 2,
+ 1006 => 1,
+ 1029 => 1,
+ 1053 => 1,
+ 1058 => 2,
+ 1069 => 1,
+ 1070 => 1,
+ 1071 => 1,
+ 1080 => 2,
+ 1083 => 1,
+ 1084 => 1,
+ 1085 => 1,
+ 1093 => 4,
+ 1100 => 1,
+ 1101 => 1,
+ 1102 => 1,
+ 1103 => 1,
+ 1123 => 1,
+ 1124 => 1,
+ 1125 => 1,
+ 1138 => 1,
+ 1139 => 1,
+ 1144 => 1,
+ 1145 => 1,
+ 1151 => 1,
+ );
+
+ // Scalar type hints only work from PHP 7 onwards.
+ if ( PHP_VERSION_ID >= 70000 ) {
+ $errors[17] = 3;
+ $errors[128] = 1;
+ $errors[143] = 3;
+ $errors[161] = 2;
+ $errors[201] = 1;
+ $errors[232] = 7;
+ $errors[363] = 3;
+ $errors[377] = 1;
+ $errors[575] = 2;
+ $errors[627] = 1;
+ $errors[1002] = 1;
+ $errors[1075] = 6;
+ $errors[1089] = 3;
+ $errors[1107] = 8;
+ $errors[1129] = 3;
+ $errors[1154] = 1;
+ $errors[1160] = 1;
+ } else {
+ $errors[729] = 4;
+ $errors[740] = 2;
+ $errors[752] = 2;
+ $errors[982] = 1;
+ }
+
+ // Object type hints only work from PHP 7.2 onwards.
+ if ( PHP_VERSION_ID >= 70200 ) {
+ $errors[627] = 2;
+ } else {
+ $errors[992] = 2;
+ }
+
+ // Mixed type hints only work from PHP 8.0 onwards.
+ if ( PHP_VERSION_ID >= 80000 ) {
+ $errors[265] = 1;
+ $errors[459] = 1;
+ $errors[893] = 3;
+ } else {
+ $errors[1023] = 1;
+ }
+
+ return $errors;
+ }
+
+ /**
+ * Returns the lines where warnings should occur.
+ *
+ * The key of the array should represent the line number and the value
+ * should represent the number of warnings that should occur on that line.
+ *
+ * @return array
+ */
+ public function getWarningList() {
+ return array();
+ }
+}
diff --git a/BigBiteDocs/ruleset.xml b/BigBiteDocs/ruleset.xml
index 76746fc..cd91056 100644
--- a/BigBiteDocs/ruleset.xml
+++ b/BigBiteDocs/ruleset.xml
@@ -29,16 +29,6 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/composer.json b/composer.json
index ac477e2..c51c9b0 100644
--- a/composer.json
+++ b/composer.json
@@ -76,8 +76,7 @@
"@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf ."
],
"test": [
- "@php ./vendor/bin/phpunit --filter BigBite ./vendor/squizlabs/php_codesniffer/tests/AllTests.php",
- "@php ./vendor/bin/phpunit --filter BigBiteDocs ./vendor/squizlabs/php_codesniffer/tests/AllTests.php"
+ "@php ./vendor/bin/phpunit --filter BigBite ./vendor/squizlabs/php_codesniffer/tests/AllTests.php"
],
"analyse": [
"./vendor/bin/phpstan"