Skip to content

Commit d94ba38

Browse files
committed
Add excludedCallPatterns option to RequireMultiLineCallSniff
1 parent 9bba0ac commit d94ba38

File tree

4 files changed

+108
-0
lines changed

4 files changed

+108
-0
lines changed

SlevomatCodingStandard/Sniffs/Functions/RequireMultiLineCallSniff.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace SlevomatCodingStandard\Sniffs\Functions;
44

5+
use Exception;
56
use PHP_CodeSniffer\Files\File;
67
use SlevomatCodingStandard\Helpers\FixerHelper;
78
use SlevomatCodingStandard\Helpers\IndentationHelper;
@@ -12,6 +13,7 @@
1213
use function count;
1314
use function in_array;
1415
use function ltrim;
16+
use function preg_match;
1517
use function sprintf;
1618
use function strlen;
1719
use function trim;
@@ -34,6 +36,12 @@ class RequireMultiLineCallSniff extends AbstractLineCall
3436

3537
public ?int $minParametersCount = null;
3638

39+
/** @var list<string> */
40+
public array $excludedCallPatterns = [];
41+
42+
/** @var list<string>|null */
43+
public ?array $excludedCallNormalizedPatterns = null;
44+
3745
public function process(File $phpcsFile, int $stringPointer): void
3846
{
3947
$this->minLineLength = SniffSettingsHelper::normalizeNullableInteger($this->minLineLength);
@@ -139,6 +147,13 @@ public function process(File $phpcsFile, int $stringPointer): void
139147

140148
$name = ltrim($tokens[$stringPointer]['content'], '\\');
141149

150+
if (
151+
count($this->excludedCallPatterns) !== 0
152+
&& $this->isCallNameInPatterns($name, $this->getExcludedCallNormalizedPatterns())
153+
) {
154+
return;
155+
}
156+
142157
if (in_array($tokens[$previousPointer]['code'], [T_OBJECT_OPERATOR, T_DOUBLE_COLON], true)) {
143158
$error = sprintf('Call of method %s() should be split to more lines.', $name);
144159
} elseif ($tokens[$previousPointer]['code'] === T_NEW) {
@@ -257,4 +272,31 @@ private function shouldReportError(
257272
return strlen(trim($lineStart) . trim($lineEnd)) > $indentationLength;
258273
}
259274

275+
/**
276+
* @param list<string> $normalizedPatterns
277+
*/
278+
private function isCallNameInPatterns(string $callName, array $normalizedPatterns): bool
279+
{
280+
foreach ($normalizedPatterns as $pattern) {
281+
if (!SniffSettingsHelper::isValidRegularExpression($pattern)) {
282+
throw new Exception(sprintf('%s is not valid PCRE pattern.', $pattern));
283+
}
284+
285+
if (preg_match($pattern, $callName) !== 0) {
286+
return true;
287+
}
288+
}
289+
290+
return false;
291+
}
292+
293+
/**
294+
* @return list<string>
295+
*/
296+
private function getExcludedCallNormalizedPatterns(): array
297+
{
298+
$this->excludedCallNormalizedPatterns ??= SniffSettingsHelper::normalizeArray($this->excludedCallPatterns);
299+
return $this->excludedCallNormalizedPatterns;
300+
}
301+
260302
}

tests/Sniffs/Functions/RequireMultiLineCallSniffTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,34 @@ public function testErrorsBasedOnParamCount(): void
162162
self::assertAllFixedInFile($report);
163163
}
164164

165+
public function testThrowExceptionForInvalidPattern(): void
166+
{
167+
$this->expectException(Throwable::class);
168+
169+
self::checkFile(
170+
__DIR__ . '/data/requireMultiLineCallErrors.php',
171+
['includedCallPatterns' => ['invalidPattern']],
172+
);
173+
174+
self::checkFile(
175+
__DIR__ . '/data/requireMultiLineCallErrors.php',
176+
['excludedCallPatterns' => ['invalidPattern']],
177+
);
178+
}
179+
180+
public function testExcludedCallPatterns(): void
181+
{
182+
$report = self::checkFile(__DIR__ . '/data/requireMultiLineCallExcludedCallsErrors.php', [
183+
'minLineLength' => 0,
184+
'excludedCallPatterns' => ['/dontReportError/'],
185+
], [RequireMultiLineCallSniff::CODE_REQUIRED_MULTI_LINE_CALL]);
186+
187+
self::assertSame(2, $report->getErrorCount());
188+
189+
self::assertSniffError($report, 7, RequireMultiLineCallSniff::CODE_REQUIRED_MULTI_LINE_CALL);
190+
self::assertSniffError($report, 13, RequireMultiLineCallSniff::CODE_REQUIRED_MULTI_LINE_CALL);
191+
192+
self::assertAllFixedInFile($report);
193+
}
194+
165195
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
class Whatever
4+
{
5+
public function __construct()
6+
{
7+
$this->reportError(
8+
'false',
9+
true
10+
);
11+
$this->dontReportError('true', false);
12+
}
13+
}
14+
15+
function () {
16+
reportError(
17+
'false',
18+
true
19+
);
20+
dontReportError('true', false);
21+
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
class Whatever
4+
{
5+
public function __construct()
6+
{
7+
$this->reportError('false', true);
8+
$this->dontReportError('true', false);
9+
}
10+
}
11+
12+
function () {
13+
reportError('false', true);
14+
dontReportError('true', false);
15+
};

0 commit comments

Comments
 (0)