Skip to content

Commit 1c5cc0a

Browse files
authored
Support error identfiers and rawMessage (#194)
1 parent 600d455 commit 1c5cc0a

File tree

8 files changed

+90
-28
lines changed

8 files changed

+90
-28
lines changed

lib/Baseline.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
final class Baseline {
1010
/**
11-
* @var array{parameters?: array{ignoreErrors?: list<array{message: string, count: int, path: string}>}}
11+
* @var array{parameters?: array{ignoreErrors?: list<array{message: ?string, count: int, path: ?string, identifier: ?string, rawMessage: ?string}>}}
1212
*/
1313
private $content;
1414

@@ -32,7 +32,7 @@ static public function forFile(string $filePath):self {
3232
}
3333

3434
$baseline = new self();
35-
$baseline->content = $decoded;
35+
$baseline->content = $decoded; // @phpstan-ignore assign.propertyType
3636
$baseline->filePath = $filePath;
3737
return $baseline;
3838
}
@@ -41,18 +41,20 @@ static public function forFile(string $filePath):self {
4141
* @return Iterator<BaselineError>
4242
*/
4343
public function getIgnoreErrors(): Iterator {
44+
// @phpstan-ignore function.alreadyNarrowedType
4445
if (!array_key_exists('parameters', $this->content) || !is_array($this->content['parameters'])) {
4546
throw new RuntimeException(sprintf('missing parameters from baseline %s', $this->filePath));
4647
}
4748
$parameters = $this->content['parameters'];
4849

50+
// @phpstan-ignore function.alreadyNarrowedType
4951
if (!array_key_exists('ignoreErrors', $parameters) || !is_array($parameters['ignoreErrors'])) {
5052
throw new RuntimeException(sprintf('missing ignoreErrors from baseline %s', $this->filePath));
5153
}
5254
$ignoreErrors = $parameters['ignoreErrors'];
5355

5456
foreach($ignoreErrors as $error) {
55-
yield new BaselineError($error['count'], $error['message'], $error['path']);
57+
yield new BaselineError($error['count'], $error['message'] ?? null, $error['path'] ?? null, $error['identifier'] ?? null, $error['rawMessage'] ?? null);
5658
}
5759
}
5860

lib/BaselineError.php

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,36 @@ final class BaselineError
99
{
1010
public int $count;
1111

12-
public string $message;
12+
public ?string $message;
1313

14-
public string $path;
14+
public ?string $rawMessage;
1515

16-
public function __construct(int $count, string $message, string $path)
16+
public ?string $path;
17+
18+
public ?string $identifier;
19+
20+
public function __construct(int $count, ?string $message, ?string $path, ?string $identifier, ?string $rawMessage)
1721
{
1822
$this->count = $count;
1923
$this->message = $message;
24+
$this->rawMessage = $rawMessage;
2025
$this->path = $path;
26+
$this->identifier = $identifier;
2127
}
2228

2329
/**
2430
* Returns the baseline error message, without regex delimiters.
2531
* Note: the message may still contain escaped regex meta characters.
2632
*/
2733
public function unwrapMessage(): string {
34+
if ($this->rawMessage !== null) {
35+
return $this->rawMessage;
36+
}
37+
38+
if ($this->message === null) {
39+
return '';
40+
}
41+
2842
$msg = $this->message;
2943
$msg = str_replace(['\\-', '\\.', '%%'], ['-', '.', '%'], $msg);
3044
$msg = trim($msg, '#^$');
@@ -33,10 +47,12 @@ public function unwrapMessage(): string {
3347

3448
public function isDeprecationError(): bool
3549
{
36-
return str_contains($this->message, ' deprecated class ')
37-
|| str_contains($this->message, ' deprecated method ')
38-
|| str_contains($this->message, ' deprecated function ')
39-
|| str_contains($this->message, ' deprecated property ');
50+
$message = $this->unwrapMessage();
51+
52+
return str_contains($message, ' deprecated class ')
53+
|| str_contains($message, ' deprecated method ')
54+
|| str_contains($message, ' deprecated function ')
55+
|| str_contains($message, ' deprecated property ');
4056
}
4157

4258
public function isComplexityError(): bool
@@ -46,24 +62,26 @@ public function isComplexityError(): bool
4662

4763
public function isInvalidPhpDocError(): bool
4864
{
49-
return str_contains($this->message, 'PHPDoc tag ');
65+
return str_contains($this->unwrapMessage(), 'PHPDoc tag ');
5066
}
5167

5268
public function isUnknownTypeError(): bool
5369
{
54-
return preg_match('/Instantiated class .+ not found/', $this->message, $matches) === 1
55-
|| str_contains($this->message, 'on an unknown class')
56-
|| str_contains($this->message, 'has invalid type unknown')
57-
|| str_contains($this->message, 'unknown_type as its type');
70+
$message = $this->unwrapMessage();
71+
72+
return preg_match('/Instantiated class .+ not found/', $message, $matches) === 1
73+
|| str_contains($message, 'on an unknown class')
74+
|| str_contains($message, 'has invalid type unknown')
75+
|| str_contains($message, 'unknown_type as its type');
5876
}
5977

6078
public function isAnonymousVariableError(): bool
6179
{
62-
return str_contains($this->message, 'Anonymous variable');
80+
return str_contains($this->unwrapMessage(), 'Anonymous variable');
6381
}
6482

6583
public function isUnusedSymbolError(): bool
6684
{
67-
return str_ends_with($this->message, 'is never used$#');
85+
return str_ends_with($this->unwrapMessage(), 'is never used');
6886
}
6987
}

lib/FilterApplication.php

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,25 @@ private function printResult(array $errors): void
6161
{
6262
$ignoreErrors = [];
6363
foreach ($errors as $error) {
64-
$ignoreErrors[] = [
65-
'message' => $error->message,
66-
'count' => $error->count,
67-
'path' => $error->path,
68-
];
64+
$ignoreError = [];
65+
66+
if ($error->message !== null) {
67+
$ignoreError['message'] = $error->message;
68+
}
69+
70+
$ignoreError['count'] = $error->count;
71+
72+
if ($error->path !== null) {
73+
$ignoreError['path'] = $error->path;
74+
}
75+
if ($error->identifier !== null) {
76+
$ignoreError['identifier'] = $error->identifier;
77+
}
78+
if ($error->rawMessage !== null) {
79+
$ignoreError['rawMessage'] = $error->rawMessage;
80+
}
81+
82+
$ignoreErrors[] = $ignoreError;
6983

7084
}
7185

tests/AnalyzeApplicationTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function testTextPrinting():void
2121
$expected = <<<PHP
2222
Analyzing /fixtures/all-in.neon
2323
Date: {$expectedDate}
24-
Overall-Errors: 41
24+
Overall-Errors: 43
2525
Classes-Cognitive-Complexity: 70
2626
Deprecations: 2
2727
Invalid-Phpdocs: 5
@@ -30,7 +30,7 @@ function testTextPrinting():void
3030
Native-Property-Type-Coverage: 1
3131
Native-Param-Type-Coverage: 27
3232
Native-Return-Type-Coverage: 4
33-
Unused-Symbols: 3
33+
Unused-Symbols: 4
3434
3535
PHP;
3636

@@ -50,7 +50,7 @@ function testJsonPrinting():void
5050

5151
$expectedDate = date(ResultPrinter::DATE_FORMAT);
5252
$expected = <<<PHP
53-
[{"\/fixtures\/all-in.neon":{"Date":"{$expectedDate}","Overall-Errors":41,"Classes-Cognitive-Complexity":70,"Deprecations":2,"Invalid-Phpdocs":5,"Unknown-Types":1,"Anonymous-Variables":4,"Native-Property-Type-Coverage":1,"Native-Param-Type-Coverage":27,"Native-Return-Type-Coverage":4,"Unused-Symbols":3}}]
53+
[{"\/fixtures\/all-in.neon":{"Date":"{$expectedDate}","Overall-Errors":43,"Classes-Cognitive-Complexity":70,"Deprecations":2,"Invalid-Phpdocs":5,"Unknown-Types":1,"Anonymous-Variables":4,"Native-Property-Type-Coverage":1,"Native-Param-Type-Coverage":27,"Native-Return-Type-Coverage":4,"Unused-Symbols":4}}]
5454
PHP;
5555

5656
$this->assertSame($expected, $rendered);

tests/BaselineAnalyzerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ function testNeverUsed():void
205205

206206
private function allInAssertions(AnalyzerResult $result): void
207207
{
208-
$this->assertSame(41, $result->overallErrors);
208+
$this->assertSame(43, $result->overallErrors);
209209
$this->assertSame(70, $result->classesComplexity);
210210
$this->assertSame(2, $result->deprecations);
211211
$this->assertSame(5, $result->invalidPhpdocs);
@@ -214,7 +214,7 @@ private function allInAssertions(AnalyzerResult $result): void
214214
$this->assertSame(1, $result->propertyTypeCoverage);
215215
$this->assertSame(27, $result->paramTypeCoverage);
216216
$this->assertSame(4, $result->returnTypeCoverage);
217-
$this->assertSame(3, $result->unusedSymbols);
217+
$this->assertSame(4, $result->unusedSymbols);
218218
}
219219

220220
}

tests/FilterApplicationTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ function testMultiInclude():void
6767
count: 1
6868
path: scripts/portal/SearchExport.php
6969
70+
-
71+
count: 1
72+
path: scripts/portal/SearchExport.php
73+
rawMessage: Public constant "SearchExport::OTHER_PATH" is never used
74+
7075
PHP;
7176

7277
$this->assertSame($expected, $rendered);
@@ -102,6 +107,11 @@ function testUnusedTypes():void
102107
count: 1
103108
path: scripts/portal/SearchExport.php
104109
110+
-
111+
count: 1
112+
path: scripts/portal/SearchExport.php
113+
rawMessage: Public constant "SearchExport::OTHER_PATH" is never used
114+
105115
PHP;
106116

107117
$this->assertSame($expected, $rendered);

tests/fixtures/all-in.neon

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,13 @@ parameters:
118118
-
119119
message: "#^Public constant \"SearchExport\\:\\:TMP_PATH\" is never used$#"
120120
count: 1
121-
path: scripts/portal/SearchExport.php
121+
path: scripts/portal/SearchExport.php
122+
123+
-
124+
rawMessage: "Public constant \"SearchExport::OTHER_PATH\" is never used"
125+
count: 1
126+
path: scripts/portal/SearchExport.php
127+
128+
-
129+
identifier: myident.test
130+
count: 1

tests/fixtures/all-in.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,14 @@
121121
'count' => 1,
122122
'path' => 'scripts/portal/SearchExport.php',
123123
];
124+
$ignoreErrors[] = [
125+
'rawMessage' => 'Public constant "SearchExport::TMP_PATH" is never used',
126+
'count' => 1,
127+
'path' => 'scripts/portal/SearchExport.php',
128+
];
129+
$ignoreErrors[] = [
130+
'identifier' => 'myident.test',
131+
'count' => 1,
132+
];
124133

125134
return ['parameters' => ['ignoreErrors' => $ignoreErrors]];

0 commit comments

Comments
 (0)