Skip to content

Commit 2e57a65

Browse files
Fixing MaxLineLength Rule (#22)
1 parent e99c8c4 commit 2e57a65

File tree

4 files changed

+166
-5
lines changed

4 files changed

+166
-5
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use Some\Very\Long\Namespace\That\Definitely\Exceeds\Eighty\Characters\SomeVeryLongClassName;
6+
use Another\Very\Long\Namespace\That\Also\Exceeds\The\Maximum\Line\Length\Limit\AnotherClass;
7+
use YetAnother\Very\Long\Namespace\Path\That\Goes\On\And\On\Until\It\Exceeds\EightyCharacters;
8+
9+
class MaxLineLengthLongUseStatementsClass
10+
{
11+
public function shortMethod(): void
12+
{
13+
$variable = 'short';
14+
}
15+
16+
public function methodWithVeryLongLineInsideThatDefinitelyExceedsTheEightyCharacterMaximumLineLengthLimit(): void
17+
{
18+
$thisVariableNameIsAlsoExtremelyLongAndWillDefinitelyExceedTheMaximumLineLengthLimitOf80Characters = true;
19+
}
20+
}
21+

src/CleanCode/MaxLineLengthRule.php

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ class MaxLineLengthRule implements Rule
4646
*/
4747
private array $processedLines = [];
4848

49+
/**
50+
* @var array<string, array<int, bool>>
51+
* Cache of which lines contain use statements per file
52+
*/
53+
private array $useStatementLines = [];
54+
4955
/**
5056
* @param string[] $excludePatterns
5157
*/
@@ -76,14 +82,24 @@ public function processNode(Node $node, Scope $scope): array
7682
return [];
7783
}
7884

79-
// Skip use statements if configured to ignore them
80-
if ($this->ignoreUseStatements && $node instanceof Use_) {
81-
return [];
82-
}
83-
8485
$filePath = $scope->getFile();
8586
$lineNumber = $node->getLine();
8687

88+
// Track use statement lines for this file
89+
if ($node instanceof Use_) {
90+
$this->markLineAsUseStatement($filePath, $lineNumber);
91+
92+
// If ignoring use statements, skip processing this node
93+
if ($this->ignoreUseStatements) {
94+
return [];
95+
}
96+
}
97+
98+
// Skip if this line is a use statement and we're ignoring them
99+
if ($this->ignoreUseStatements && $this->isUseStatementLine($filePath, $lineNumber)) {
100+
return [];
101+
}
102+
87103
// Skip if we've already processed this line
88104
if ($this->isLineProcessed($filePath, $lineNumber)) {
89105
return [];
@@ -137,6 +153,20 @@ private function markLineAsProcessed(string $filePath, int $lineNumber): void
137153
$this->processedLines[$filePath][$lineNumber] = true;
138154
}
139155

156+
private function isUseStatementLine(string $filePath, int $lineNumber): bool
157+
{
158+
return isset($this->useStatementLines[$filePath][$lineNumber]);
159+
}
160+
161+
private function markLineAsUseStatement(string $filePath, int $lineNumber): void
162+
{
163+
if (!isset($this->useStatementLines[$filePath])) {
164+
$this->useStatementLines[$filePath] = [];
165+
}
166+
167+
$this->useStatementLines[$filePath][$lineNumber] = true;
168+
}
169+
140170
private function getLineLength(string $filePath, int $lineNumber): int
141171
{
142172
// Cache file line lengths to avoid reading the same file multiple times
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Phauthentic\PHPStanRules\Tests\TestCases\CleanCode;
6+
7+
use Phauthentic\PHPStanRules\CleanCode\MaxLineLengthRule;
8+
use PHPStan\Rules\Rule;
9+
use PHPStan\Testing\RuleTestCase;
10+
11+
/**
12+
* Test that long use statements ARE detected when ignoreUseStatements is false
13+
*
14+
* This complements the regression test to ensure the fix doesn't break
15+
* the default behavior of detecting long use statements.
16+
*
17+
* @extends RuleTestCase<MaxLineLengthRule>
18+
*/
19+
class MaxLineLengthRuleDetectUseLongLinesTest extends RuleTestCase
20+
{
21+
protected function getRule(): Rule
22+
{
23+
// Do NOT ignore use statements (3rd parameter is false/default)
24+
return new MaxLineLengthRule(80, [], false);
25+
}
26+
27+
/**
28+
* Test that long use statements ARE detected when ignoreUseStatements is false
29+
*/
30+
public function testLongUseStatementsAreDetectedWhenNotIgnored(): void
31+
{
32+
// Lines 5, 6, 7 have use statements that exceed 80 characters - should be detected
33+
// Line 16 has a method signature that exceeds 80 characters - should be detected
34+
// Line 18 has a variable assignment that exceeds 80 characters - should be detected
35+
$this->analyse([__DIR__ . '/../../../data/MaxLineLengthLongUseStatementsClass.php'], [
36+
[
37+
'Line 5 exceeds the maximum length of 80 characters (found 93 characters).',
38+
5,
39+
],
40+
[
41+
'Line 6 exceeds the maximum length of 80 characters (found 93 characters).',
42+
6,
43+
],
44+
[
45+
'Line 7 exceeds the maximum length of 80 characters (found 94 characters).',
46+
7,
47+
],
48+
[
49+
'Line 16 exceeds the maximum length of 80 characters (found 117 characters).',
50+
16,
51+
],
52+
[
53+
'Line 18 exceeds the maximum length of 80 characters (found 114 characters).',
54+
18,
55+
],
56+
]);
57+
}
58+
}
59+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Phauthentic\PHPStanRules\Tests\TestCases\CleanCode;
6+
7+
use Phauthentic\PHPStanRules\CleanCode\MaxLineLengthRule;
8+
use PHPStan\Rules\Rule;
9+
use PHPStan\Testing\RuleTestCase;
10+
11+
/**
12+
* Regression test for ignoreUseStatements feature
13+
*
14+
* This test ensures that when use statements exceed the line length limit,
15+
* they are properly ignored when ignoreUseStatements is true.
16+
*
17+
* @extends RuleTestCase<MaxLineLengthRule>
18+
*/
19+
class MaxLineLengthRuleIgnoreUseLongLinesTest extends RuleTestCase
20+
{
21+
protected function getRule(): Rule
22+
{
23+
// Ignore use statements (3rd parameter is true)
24+
return new MaxLineLengthRule(80, [], true);
25+
}
26+
27+
/**
28+
* Test that long use statements are ignored when ignoreUseStatements is true,
29+
* but other long lines are still detected.
30+
*
31+
* This is a regression test for a bug where use statements were not properly
32+
* ignored because the check only looked at the node type, not the line itself.
33+
*/
34+
public function testLongUseStatementsAreIgnoredButOtherLongLinesAreDetected(): void
35+
{
36+
// Lines 5, 6, 7 have use statements that exceed 80 characters - should be ignored
37+
// Line 16 has a method signature that exceeds 80 characters - should be detected
38+
// Line 18 has a variable assignment that exceeds 80 characters - should be detected
39+
$this->analyse([__DIR__ . '/../../../data/MaxLineLengthLongUseStatementsClass.php'], [
40+
[
41+
'Line 16 exceeds the maximum length of 80 characters (found 117 characters).',
42+
16,
43+
],
44+
[
45+
'Line 18 exceeds the maximum length of 80 characters (found 114 characters).',
46+
18,
47+
],
48+
]);
49+
}
50+
}
51+

0 commit comments

Comments
 (0)