Skip to content

Commit

Permalink
Adds SlevomatCodingStandard.Classes.ClassLength sniff
Browse files Browse the repository at this point in the history
  • Loading branch information
bkdotcom authored and kukulich committed Jul 16, 2022
1 parent fd5336f commit 3e6b61a
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,14 @@ Sniff provides the following settings:
* `spacesCountBeforeColon`: the number of spaces before `:`.
* `spacesCountBeforeType`: the number of spaces before type.

#### SlevomatCodingStandard.Classes.ClassLength

Disallows long classes. This sniff provides the following settings:

* `includeComments`: should comments be included in the count (default value is false).
* `includeWhitespace`: shoud empty lines be included in the count (default value is false).
* `maxLinesLength`: specifies max allowed function lines length (default value is 250).

#### SlevomatCodingStandard.Classes.ClassMemberSpacing 🔧

Checks lines count between different class members, eg. between last property and first method.
Expand Down
64 changes: 64 additions & 0 deletions SlevomatCodingStandard/Sniffs/Classes/ClassLengthSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php declare(strict_types = 1);

namespace SlevomatCodingStandard\Sniffs\Classes;

use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use PHP_CodeSniffer\Util\Tokens;
use SlevomatCodingStandard\Helpers\FunctionHelper;
use SlevomatCodingStandard\Helpers\SniffSettingsHelper;
use function array_filter;
use function array_keys;
use function array_reduce;
use function array_values;
use function sprintf;

class ClassLengthSniff implements Sniff
{

public const CODE_CLASS_TOO_LONG = 'ClassTooLong';

/** @var int */
public $maxLinesLength = 250;

/** @var bool */
public $includeComments = false;

/** @var bool */
public $includeWhitespace = false;

/**
* @return array<int, (int|string)>
*/
public function register(): array
{
return array_values(Tokens::$ooScopeTokens);
}

/**
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
* @param int $pointer
*/
public function process(File $phpcsFile, $pointer): void
{
$this->maxLinesLength = SniffSettingsHelper::normalizeInteger($this->maxLinesLength);
$flags = array_keys(array_filter([
FunctionHelper::LINE_INCLUDE_COMMENT => $this->includeComments,
FunctionHelper::LINE_INCLUDE_WHITESPACE => $this->includeWhitespace,
]));
$flags = array_reduce($flags, static function ($carry, $flag): int {
return $carry | $flag;
}, 0);

$length = FunctionHelper::getLineCount($phpcsFile, $pointer, $flags);

if ($length <= $this->maxLinesLength) {
return;
}

$errorMessage = sprintf('Your class is too long. Currently using %d lines. Can be up to %d lines.', $length, $this->maxLinesLength);

$phpcsFile->addError($errorMessage, $pointer, self::CODE_CLASS_TOO_LONG);
}

}
33 changes: 33 additions & 0 deletions tests/Sniffs/Classes/ClassLengthSniffTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php declare(strict_types = 1);

namespace SlevomatCodingStandard\Sniffs\Classes;

use SlevomatCodingStandard\Sniffs\TestCase;

class ClassLengthSniffTest extends TestCase
{

public function testNoErrors(): void
{
$report = self::checkFile(__DIR__ . '/data/classLength.php');
self::assertNoSniffErrorInFile($report);
}

public function testErrors(): void
{
$report = self::checkFile(__DIR__ . '/data/classLength.php', [
'maxLinesLength' => 5,
'includeComments' => true,
]);

self::assertSame(1, $report->getErrorCount());

self::assertSniffError(
$report,
5,
ClassLengthSniff::CODE_CLASS_TOO_LONG,
'Your class is too long. Currently using 13 lines. Can be up to 5 lines.'
);
}

}
22 changes: 22 additions & 0 deletions tests/Sniffs/Classes/data/classLength.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Foo\Bar;

class ClassLineCountSniffTest
{
public function __construct()
{
}

public function __get($name)
{
}

/**
*
*/
public function someMethod() : string
{
return 'foo bar';
}
}

0 comments on commit 3e6b61a

Please sign in to comment.