Skip to content

Commit 05ec182

Browse files
bkdotcomkukulich
authored andcommitted
Added SlevomatCodingStandard.Files.FileLength
1 parent c047258 commit 05ec182

File tree

5 files changed

+125
-3
lines changed

5 files changed

+125
-3
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,14 @@ Sniff provides the following settings:
781781

782782
However, if you prefer Yoda conditions, you can use `RequireYodaComparisonSniff`.
783783

784+
#### SlevomatCodingStandard.Files.FileLength
785+
786+
Disallows long files. This sniff provides the following settings:
787+
788+
* `includeComments`: should comments be included in the count (default value is false).
789+
* `includeWhitespace`: shoud empty lines be included in the count (default value is false).
790+
* `maxLinesLength`: specifies max allowed function lines length (default value is 250).
791+
784792
#### SlevomatCodingStandard.Files.LineLength
785793

786794
Enforces maximum length of a single line of code.

SlevomatCodingStandard/Helpers/FunctionHelper.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,15 +468,19 @@ public static function getFunctionLengthInLines(File $file, int $functionPositio
468468
if (self::isAbstract($file, $functionPosition)) {
469469
return 0;
470470
}
471+
return self::getLineCount($file, $functionPosition, $flags);
472+
}
471473

474+
public static function getLineCount(File $file, int $tokenPosition, int $flags = 0): int
475+
{
472476
$includeWhitespace = ($flags & self::LINE_INCLUDE_WHITESPACE) === self::LINE_INCLUDE_WHITESPACE;
473477
$includeComments = ($flags & self::LINE_INCLUDE_COMMENT) === self::LINE_INCLUDE_COMMENT;
474478

475479
$tokens = $file->getTokens();
476-
$token = $tokens[$functionPosition];
480+
$token = $tokens[$tokenPosition];
477481

478-
$tokenOpenerPosition = $token['scope_opener'];
479-
$tokenCloserPosition = $token['scope_closer'];
482+
$tokenOpenerPosition = $token['scope_opener'] ?? $tokenPosition;
483+
$tokenCloserPosition = $token['scope_closer'] ?? $file->numTokens - 1;
480484
$tokenOpenerLine = $tokens[$tokenOpenerPosition]['line'];
481485
$tokenCloserLine = $tokens[$tokenCloserPosition]['line'];
482486

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace SlevomatCodingStandard\Sniffs\Files;
4+
5+
use PHP_CodeSniffer\Files\File;
6+
use PHP_CodeSniffer\Sniffs\Sniff;
7+
use SlevomatCodingStandard\Helpers\FunctionHelper;
8+
use SlevomatCodingStandard\Helpers\SniffSettingsHelper;
9+
use function array_filter;
10+
use function array_keys;
11+
use function array_reduce;
12+
use function sprintf;
13+
use const T_OPEN_TAG;
14+
15+
class FileLengthSniff implements Sniff
16+
{
17+
18+
public const CODE_FILE_TOO_LONG = 'FileTooLong';
19+
20+
/** @var int */
21+
public $maxLinesLength = 250;
22+
23+
/** @var bool */
24+
public $includeComments = false;
25+
26+
/** @var bool */
27+
public $includeWhitespace = false;
28+
29+
/**
30+
* @return array<int, (int|string)>
31+
*/
32+
public function register(): array
33+
{
34+
return [T_OPEN_TAG];
35+
}
36+
37+
/**
38+
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
39+
* @param int $pointer
40+
*/
41+
public function process(File $phpcsFile, $pointer): void
42+
{
43+
$this->maxLinesLength = SniffSettingsHelper::normalizeInteger($this->maxLinesLength);
44+
$flags = array_keys(array_filter([
45+
FunctionHelper::LINE_INCLUDE_COMMENT => $this->includeComments,
46+
FunctionHelper::LINE_INCLUDE_WHITESPACE => $this->includeWhitespace,
47+
]));
48+
$flags = array_reduce($flags, static function ($carry, $flag): int {
49+
return $carry | $flag;
50+
}, 0);
51+
52+
$length = FunctionHelper::getLineCount($phpcsFile, $pointer, $flags);
53+
54+
if ($length <= $this->maxLinesLength) {
55+
return;
56+
}
57+
58+
$errorMessage = sprintf('Your file is too long. Currently using %d lines. Can be up to %d lines.', $length, $this->maxLinesLength);
59+
60+
$phpcsFile->addError($errorMessage, $pointer, self::CODE_FILE_TOO_LONG);
61+
}
62+
63+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace SlevomatCodingStandard\Sniffs\Files;
4+
5+
use SlevomatCodingStandard\Sniffs\TestCase;
6+
7+
class FileLengthSniffTest extends TestCase
8+
{
9+
10+
public function testNoErrors(): void
11+
{
12+
$report = self::checkFile(__DIR__ . '/data/fileLength.php');
13+
self::assertNoSniffErrorInFile($report);
14+
}
15+
16+
public function testErrors(): void
17+
{
18+
$report = self::checkFile(__DIR__ . '/data/fileLength.php', [
19+
'maxLinesLength' => 5,
20+
'includeComments' => true,
21+
]);
22+
23+
self::assertSame(1, $report->getErrorCount());
24+
25+
self::assertSniffError(
26+
$report,
27+
1,
28+
FileLengthSniff::CODE_FILE_TOO_LONG,
29+
'Your file is too long. Currently using 12 lines. Can be up to 5 lines.'
30+
);
31+
}
32+
33+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Foo\Bar;
4+
5+
class FileLineCountSniffTest
6+
{
7+
/**
8+
*
9+
*/
10+
public function someMethod() : string
11+
{
12+
return 'foo bar';
13+
}
14+
}

0 commit comments

Comments
 (0)