Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 55 additions & 3 deletions BigBite/Sniffs/Commenting/DocCommentLineLengthSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ final class DocCommentLineLengthSniff implements Sniff {
*/
public $includeIndentation = false;

/**
* Specific comment prefixes to ignore.
*
* @var array<int,string>
*/
public $descriptorsToIgnore = array(
'Plugin Name:',
'Theme Name:',
);

/**
* Returns an array of tokens this test wants to listen for.
*
Expand Down Expand Up @@ -92,21 +102,53 @@ public function process( File $phpcsFile, $stackPtr ) {
return;
}

if ( 1 === preg_match( '/^(Plugin|Theme)\s+Name:/i', $tokens[ $short ]['content'] ) ) {
// It's a WordPress plugin or theme, so disregard line length.
return;
foreach ( $this->descriptorsToIgnore as $descriptor ) {
// It's an ignored comment, so disregard line length.
if ( 0 === strpos( $tokens[ $short ]['content'], $descriptor ) ) {
return;
}
}

for ( $i = ( $commentStart + 1 ); $i < $commentEnd; $i++ ) {
if ( in_array( $tokens[ $i ]['type'], array( 'T_DOC_COMMENT_WHITESPACE', 'T_DOC_COMMENT_STAR' ), true ) ) {
continue;
}

if ( \T_DOC_COMMENT_STRING !== $tokens[ $i ]['code'] ) {
continue;
}

$isAParameterDescription = false;

$lineLength = $tokens[ $i ]['length'];
if ( true === $this->includeIndentation ) {
$lineLength = ( $tokens[ $i ]['column'] + $tokens[ $i ]['length'] - 1 );
}

// The line is over the limit, but it's a param comment.
// See if it's reasonable to split - most of the length could be the type hint, which we should allow.
if ( $lineLength > $this->lineLimit ) {
$parameterToken = $phpcsFile->findPrevious( \T_DOC_COMMENT_TAG, $i );
$itIsAParameter = false !== $parameterToken && $tokens[ $parameterToken ]['line'] === $tokens[ $i ]['line'];
$itMatchesRegex = 1 === preg_match( '/^(.+)\s+(\$[a-zA-Z_]+)\s+(.+)$/', $tokens[ $i ]['content'], $lineContent );

// Split the content into parts.
if ( $itIsAParameter && $itMatchesRegex ) {
list( /* $fullMatch */, /* $typehint */, /* $paramName */, $description ) = $lineContent;

$descriptionLength = strlen( $description );
// We only need to flag it if the description alone is greater than the line limit.
if ( $descriptionLength <= $this->lineLimit ) {
$phpcsFile->recordMetric( $i, 'Line length', "{$this->lineLimit} or less" );
continue;
}

$lineLength = $descriptionLength;

$isAParameterDescription = true;
}
}

// Record metrics.
if ( $lineLength <= $this->lineLimit ) {
$phpcsFile->recordMetric( $i, 'Line length', "{$this->lineLimit} or less" );
Expand Down Expand Up @@ -144,6 +186,11 @@ public function process( File $phpcsFile, $stackPtr ) {
);

$error = 'Line exceeds maximum limit of %s characters; contains %s characters';

if ( $isAParameterDescription ) {
$error = 'Parameter description exceeds maximum limit of %s characters; contains %s characters';
}

$phpcsFile->addError( $error, $i, 'MaxExceeded', $data );
} elseif ( $lineLength > $this->lineLimit ) {
$data = array(
Expand All @@ -152,6 +199,11 @@ public function process( File $phpcsFile, $stackPtr ) {
);

$warning = 'Line exceeds %s characters; contains %s characters';

if ( $isAParameterDescription ) {
$warning = 'Parameter description exceeds %s characters; contains %s characters';
}

$phpcsFile->addWarning( $warning, $i, 'TooLong', $data );
}
}
Expand Down
13 changes: 13 additions & 0 deletions BigBite/Tests/Commenting/DocCommentLineLengthUnitTest.1.inc
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,16 @@
/**
* This is a comment line that should not trigger a warning, nor an error.
*/

/**
* This is a function docblock, and the first line of it is really long, so it should trigger an error.
*
* However, it also includes a really long parameter type hint,
* which should not trigger an error, despite its line length.
* Sometimes type hints are just really long.
*
* @param array<int,array<string,array<int,array<int,int>>>> $reallyLongParamName This is a description of the param.
* @param array<int,string> $anotherParamName This is a description of the param that exceeds the minimum line length even when disregarding the type hint and parameter name from the length calculation.
*
* @return void
*/
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,17 @@
/**
* This is a comment line that should not trigger a warning, nor an error.
*/

/**
* This is a function docblock, and the first line of it is really long, so it should trigger an error.
*
* However, it also includes a really long parameter type hint,
* which should not trigger an error, despite its line length.
* Sometimes type hints are just really long.
*
* @param array<int,array<string,array<int,array<int,int>>>> $reallyLongParamName This is a description of the param.
* @param array<int,string> $anotherParamName This is a description of the param that exceeds the minimum line length even when disregarding the
* type hint and parameter name from the length calculation.
*
* @return void
*/
6 changes: 4 additions & 2 deletions BigBite/Tests/Commenting/DocCommentLineLengthUnitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ public function getErrorList( $testFile = '' ) {
switch ( $testFile ) {
case 'DocCommentLineLengthUnitTest.1.inc':
return array(
8 => 1,
8 => 1,
45 => 1,
);
case 'DocCommentLineLengthUnitTest.2.inc':
return array(
Expand Down Expand Up @@ -73,7 +74,8 @@ public function getWarningList( $testFile = '' ) {
switch ( $testFile ) {
case 'DocCommentLineLengthUnitTest.1.inc':
return array(
4 => 1,
4 => 1,
38 => 1,
);
case 'DocCommentLineLengthUnitTest.2.inc':
return array(
Expand Down