phpstan-mcp-mx 0.22.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +142 -19
- package/dist/baseline.d.ts +10 -0
- package/dist/baseline.js +36 -14
- package/dist/baseline.js.map +1 -1
- package/dist/changed.d.ts +17 -0
- package/dist/changed.js +56 -29
- package/dist/changed.js.map +1 -1
- package/dist/compare.js +12 -6
- package/dist/compare.js.map +1 -1
- package/dist/composer.js +43 -21
- package/dist/composer.js.map +1 -1
- package/dist/config.js +12 -6
- package/dist/config.js.map +1 -1
- package/dist/defaults.js +2 -1
- package/dist/defaults.js.map +1 -1
- package/dist/dumptype.js +16 -8
- package/dist/dumptype.js.map +1 -1
- package/dist/failure.d.ts +1 -1
- package/dist/failure.js.map +1 -1
- package/dist/history.d.ts +61 -0
- package/dist/history.js +275 -0
- package/dist/history.js.map +1 -0
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/php.js +10 -5
- package/dist/php.js.map +1 -1
- package/dist/phpstan/error.js.map +1 -1
- package/dist/phpstan/output.js +12 -6
- package/dist/phpstan/output.js.map +1 -1
- package/dist/phpstan/parameters.js.map +1 -1
- package/dist/phpstan/process.d.ts +10 -0
- package/dist/phpstan/process.js +35 -9
- package/dist/phpstan/process.js.map +1 -1
- package/dist/phpstan/queue.js +4 -2
- package/dist/phpstan/queue.js.map +1 -1
- package/dist/phpstan.d.ts +14 -0
- package/dist/phpstan.js +94 -25
- package/dist/phpstan.js.map +1 -1
- package/dist/project.d.ts +6 -2
- package/dist/project.js +57 -18
- package/dist/project.js.map +1 -1
- package/dist/prune.d.ts +92 -0
- package/dist/prune.js +387 -0
- package/dist/prune.js.map +1 -0
- package/dist/report.js +38 -19
- package/dist/report.js.map +1 -1
- package/dist/root-source.d.ts +43 -0
- package/dist/root-source.js +124 -0
- package/dist/root-source.js.map +1 -0
- package/dist/roots.d.ts +12 -0
- package/dist/roots.js +23 -6
- package/dist/roots.js.map +1 -1
- package/dist/runner.js +14 -7
- package/dist/runner.js.map +1 -1
- package/dist/runs.js +6 -3
- package/dist/runs.js.map +1 -1
- package/dist/schema-dialect.js +6 -3
- package/dist/schema-dialect.js.map +1 -1
- package/dist/server.d.ts +3 -2
- package/dist/server.js +9 -5
- package/dist/server.js.map +1 -1
- package/dist/tmpdir.js +6 -3
- package/dist/tmpdir.js.map +1 -1
- package/dist/tools/analysis.d.ts +4 -4
- package/dist/tools/analysis.js +4 -2
- package/dist/tools/analysis.js.map +1 -1
- package/dist/tools/inspect.d.ts +9 -7
- package/dist/tools/inspect.js +158 -37
- package/dist/tools/inspect.js.map +1 -1
- package/dist/tools/prompts.d.ts +3 -3
- package/dist/tools/prompts.js +16 -8
- package/dist/tools/prompts.js.map +1 -1
- package/dist/tools/shared.d.ts +2 -2
- package/dist/tools/shared.js +7 -5
- package/dist/tools/shared.js.map +1 -1
- package/dist/tools/writes.d.ts +8 -3
- package/dist/tools/writes.js +73 -3
- package/dist/tools/writes.js.map +1 -1
- package/dist/tools.d.ts +2 -2
- package/dist/tools.js +6 -3
- package/dist/tools.js.map +1 -1
- package/dist/unmatched.d.ts +66 -0
- package/dist/unmatched.js +194 -44
- package/dist/unmatched.js.map +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
package/dist/prune.js
ADDED
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import { existsSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, normalize, resolve } from 'node:path';
|
|
3
|
+
import { BaselineError, includedBaselineFiles, unquote } from './baseline.js';
|
|
4
|
+
import { PhpstanError } from './phpstan.js';
|
|
5
|
+
import { analyseUnmatched, readStaleInline, readStaleRule, unmatchedGeneralPattern } from './unmatched.js';
|
|
6
|
+
/** Tekens die van een pad een fnmatch-patroon maken; zo'n pad bestaat nooit letterlijk. */
|
|
7
|
+
const GLOB = /[*?[\]]/;
|
|
8
|
+
/**
|
|
9
|
+
* Snoeit de baselines die de config includeert: entries die niets meer matchen gaan eruit,
|
|
10
|
+
* een te hoge `count` gaat omlaag naar wat nog voorkomt. Er komt nooit iets bij.
|
|
11
|
+
*
|
|
12
|
+
* Dat is het verschil met `generate_baseline`: die ruimt ook op, maar zet alles wat nu
|
|
13
|
+
* gemeld wordt erbij, en dan verdwijnt het uit elke volgende analyse. Opruimen en verstoppen
|
|
14
|
+
* horen twee handelingen te zijn.
|
|
15
|
+
*
|
|
16
|
+
* Geen verse baseline naast de oude leggen: zolang de oude geïncludeerd is, negeert PHPStan
|
|
17
|
+
* die fouten al, en een verse baseline zou dan bijna leeg zijn. PHPStans eigen
|
|
18
|
+
* `reportUnmatchedIgnoredErrors` zegt per entry wat er niet meer klopt; dat is dezelfde run
|
|
19
|
+
* als `unmatched_ignores`.
|
|
20
|
+
*
|
|
21
|
+
* Alles wat niet eenduidig terug te vinden is, blijft staan. Een fout in het koppelen laat
|
|
22
|
+
* dus hooguit een verouderde entry achter, en haalt nooit een entry weg die nog iets doet.
|
|
23
|
+
*/
|
|
24
|
+
export async function pruneBaseline(project, options = {}, analyse = analyseUnmatched) {
|
|
25
|
+
const files = includedBaselineFiles(project);
|
|
26
|
+
// Zonder config includeert includedBaselineFiles niets; dit dekt dus ook dat geval.
|
|
27
|
+
if (project.config === null || files.length === 0) {
|
|
28
|
+
return nothingIncluded(project, noBaselineReason(project));
|
|
29
|
+
}
|
|
30
|
+
const before = new Map(files.map((file) => [file, readParsed(project, file)]));
|
|
31
|
+
// Eerst de entries voor een bestand dat er niet meer is. Met reportUnmatchedIgnoredErrors
|
|
32
|
+
// aan weigert PHPStan de héle run op zo'n pad ("is neither a directory, nor a file path"),
|
|
33
|
+
// dus dit moet vóór de analyse op schijf staan. Een bestand dat er niet is, kan geen fout
|
|
34
|
+
// hebben: weghalen verbergt niets.
|
|
35
|
+
const missing = new Map();
|
|
36
|
+
for (const file of files) {
|
|
37
|
+
const parsed = before.get(file);
|
|
38
|
+
const dead = parsed.blocks.filter((block) => block.known && block.path !== null && !GLOB.test(block.path) && !existsSync(resolve(project.path, dirname(file), block.path)));
|
|
39
|
+
if (dead.length > 0) {
|
|
40
|
+
writeBaseline(project, file, applyEdits(parsed, new Set(dead), new Map()));
|
|
41
|
+
missing.set(file, dead.length);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
let result;
|
|
45
|
+
try {
|
|
46
|
+
result = await analyse(project, project.config, options);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
throw withMissingNotice(error, missing);
|
|
50
|
+
}
|
|
51
|
+
requireComplete(result, missing);
|
|
52
|
+
const rules = [];
|
|
53
|
+
let currentFindings = 0;
|
|
54
|
+
let inline = 0;
|
|
55
|
+
for (const finding of result.findings) {
|
|
56
|
+
// Een inline ignore die niets meer doet, staat in de code: dat is niet aan deze tool, en
|
|
57
|
+
// ook geen huidige bevinding die de baseline zou kunnen verstoppen.
|
|
58
|
+
if (readStaleInline(finding) !== null) {
|
|
59
|
+
inline++;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const rule = readStaleRule(finding, project.path);
|
|
63
|
+
// Een count die te laag is, is geen verouderde regel: de fout komt vaker voor, en die
|
|
64
|
+
// extra keer is een bevinding. Verhogen zou hem verstoppen.
|
|
65
|
+
if (rule === null || rule.kind === 'countTooLow') {
|
|
66
|
+
currentFindings++;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
rules.push(rule);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const general = result.generalErrors.filter((error) => unmatchedGeneralPattern(error) !== null).length;
|
|
73
|
+
const perFile = [];
|
|
74
|
+
const claimed = new Set();
|
|
75
|
+
let unknownCount = 0;
|
|
76
|
+
// Opnieuw inlezen: het bestand kan hierboven al gesnoeid zijn, en de regelnummers van
|
|
77
|
+
// toen kloppen dan niet meer.
|
|
78
|
+
const current = new Map(files.map((file) => [file, readParsed(project, file)]));
|
|
79
|
+
const edits = new Map(files.map((file) => [file, { remove: new Set(), lower: new Map() }]));
|
|
80
|
+
for (const rule of rules) {
|
|
81
|
+
const found = findBlock(project, current, rule, claimed);
|
|
82
|
+
if (found === null) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
claimed.add(found.block);
|
|
86
|
+
const edit = edits.get(found.file);
|
|
87
|
+
// Alleen omlaag, en alleen naar een getal dat PHPStan zelf noemde.
|
|
88
|
+
if (rule.kind === 'unmatched') {
|
|
89
|
+
edit.remove.add(found.block);
|
|
90
|
+
}
|
|
91
|
+
else if (rule.occurred === null || found.block.countLine === null || rule.occurred >= found.block.count) {
|
|
92
|
+
unknownCount++;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
edit.lower.set(found.block, rule.occurred);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
for (const file of files) {
|
|
99
|
+
const parsed = current.get(file);
|
|
100
|
+
const edit = edits.get(file);
|
|
101
|
+
if (edit.remove.size > 0 || edit.lower.size > 0) {
|
|
102
|
+
writeBaseline(project, file, applyEdits(parsed, edit.remove, edit.lower));
|
|
103
|
+
}
|
|
104
|
+
const original = before.get(file);
|
|
105
|
+
const errorsAfter = errorsIn(parsed) - sumCounts(edit.remove) - [...edit.lower].reduce((sum, [block, count]) => sum + block.count - count, 0);
|
|
106
|
+
perFile.push({
|
|
107
|
+
file,
|
|
108
|
+
removed: edit.remove.size + (missing.get(file) ?? 0),
|
|
109
|
+
lowered: edit.lower.size,
|
|
110
|
+
errorsBefore: errorsIn(original),
|
|
111
|
+
errorsAfter,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
project: project.path,
|
|
116
|
+
files: perFile,
|
|
117
|
+
totals: {
|
|
118
|
+
removed: perFile.reduce((sum, file) => sum + file.removed, 0),
|
|
119
|
+
lowered: perFile.reduce((sum, file) => sum + file.lowered, 0),
|
|
120
|
+
missingFiles: [...missing.values()].reduce((sum, count) => sum + count, 0),
|
|
121
|
+
errorsBefore: perFile.reduce((sum, file) => sum + file.errorsBefore, 0),
|
|
122
|
+
errorsAfter: perFile.reduce((sum, file) => sum + file.errorsAfter, 0),
|
|
123
|
+
},
|
|
124
|
+
left: { outsideBaseline: rules.length - claimed.size, general, unknownCount, inline },
|
|
125
|
+
currentFindings,
|
|
126
|
+
notices: [],
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Leest een baseline in blokken, met regelnummers, zodat een wijziging alleen die blokken
|
|
131
|
+
* raakt en de rest van het bestand byte voor byte blijft staan. Regelgericht, net als
|
|
132
|
+
* `parseBaseline`: PHPStan genereert dit bestand, dus de vorm ligt vast.
|
|
133
|
+
*/
|
|
134
|
+
export function parseBaselineBlocks(content) {
|
|
135
|
+
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
136
|
+
const lines = content.split(/\r?\n/);
|
|
137
|
+
const listLine = lines.findIndex((line) => /^\s*ignoreErrors:\s*$/.test(line));
|
|
138
|
+
if (listLine === -1) {
|
|
139
|
+
return { lines, eol, listLine: null, blocks: [] };
|
|
140
|
+
}
|
|
141
|
+
const listIndent = indentOf(lines[listLine] ?? '');
|
|
142
|
+
const blocks = [];
|
|
143
|
+
let itemIndent = null;
|
|
144
|
+
let open = null;
|
|
145
|
+
let index = listLine + 1;
|
|
146
|
+
const close = (end) => {
|
|
147
|
+
if (open !== null) {
|
|
148
|
+
blocks.push(toBlock(open.start, end, open.known, open.fields));
|
|
149
|
+
}
|
|
150
|
+
open = null;
|
|
151
|
+
};
|
|
152
|
+
for (; index < lines.length; index++) {
|
|
153
|
+
const line = lines[index] ?? '';
|
|
154
|
+
const trimmed = line.trim();
|
|
155
|
+
if (trimmed === '') {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
const indent = indentOf(line);
|
|
159
|
+
if (indent <= listIndent) {
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
// Een nieuw lijstitem op dezelfde diepte als het eerste. `- message: …` op één regel
|
|
163
|
+
// maakt PHPStan niet; zo'n blok is een grens, maar wordt niet gelezen of aangeraakt.
|
|
164
|
+
if (trimmed.startsWith('-') && (itemIndent === null || indent === itemIndent)) {
|
|
165
|
+
itemIndent ??= indent;
|
|
166
|
+
close(index);
|
|
167
|
+
open = { start: index, known: trimmed === '-', fields: new Map() };
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const field = /^(identifier|path|count|message|rawMessage):\s*(.*)$/.exec(trimmed);
|
|
171
|
+
if (open !== null && field?.[1] !== undefined) {
|
|
172
|
+
open.fields.set(field[1], { value: (field[2] ?? '').trim(), line: index });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
close(index);
|
|
176
|
+
return { lines, eol, listLine, blocks };
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Past de wijzigingen toe en geeft de nieuwe inhoud. Weghalen gaat per blok inclusief de
|
|
180
|
+
* lege regels erna; een lagere count vervangt alleen het getal op zijn eigen regel.
|
|
181
|
+
*/
|
|
182
|
+
export function applyEdits(parsed, remove, lower) {
|
|
183
|
+
const lines = [...parsed.lines];
|
|
184
|
+
for (const [block, count] of lower) {
|
|
185
|
+
if (block.countLine !== null) {
|
|
186
|
+
lines[block.countLine] = (lines[block.countLine] ?? '').replace(/count:\s*\d+/, `count: ${String(count)}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const dropped = new Set();
|
|
190
|
+
for (const block of remove) {
|
|
191
|
+
for (let line = block.start; line < block.end; line++) {
|
|
192
|
+
dropped.add(line);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// De laatste regel is leeg als het bestand op een regeleinde eindigt; die hoort bij het
|
|
196
|
+
// bestand en niet bij het laatste blok.
|
|
197
|
+
const last = lines.length - 1;
|
|
198
|
+
if (lines[last] === '') {
|
|
199
|
+
dropped.delete(last);
|
|
200
|
+
}
|
|
201
|
+
const kept = lines.filter((_, index) => !dropped.has(index));
|
|
202
|
+
// Alles weg: `ignoreErrors:` zonder lijst eronder is in NEON null, en daar valt PHPStan
|
|
203
|
+
// over. Een lege lijst is wat er dan bedoeld wordt.
|
|
204
|
+
if (parsed.listLine !== null && remove.size === parsed.blocks.length) {
|
|
205
|
+
const at = kept.indexOf(parsed.lines[parsed.listLine] ?? '');
|
|
206
|
+
if (at !== -1) {
|
|
207
|
+
kept[at] = (kept[at] ?? '').replace(/ignoreErrors:\s*$/, 'ignoreErrors: []');
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return kept.join(parsed.eol);
|
|
211
|
+
}
|
|
212
|
+
/** Schrijft een overzicht van wat er gedaan is, als tekst voor het model. */
|
|
213
|
+
export function renderPruned(result) {
|
|
214
|
+
const lines = [];
|
|
215
|
+
if (result.notices.length > 0) {
|
|
216
|
+
lines.push(...result.notices.map((notice) => `Note: ${notice}`), '');
|
|
217
|
+
}
|
|
218
|
+
const changed = result.files.filter((file) => file.removed > 0 || file.lowered > 0);
|
|
219
|
+
if (changed.length === 0) {
|
|
220
|
+
lines.push(result.files.length === 0
|
|
221
|
+
? 'Nothing to prune.'
|
|
222
|
+
: `Nothing to prune: every entry in ${result.files.map((file) => file.file).join(', ')} still matches.`);
|
|
223
|
+
}
|
|
224
|
+
for (const file of changed) {
|
|
225
|
+
const delen = [`removed ${file.removed} ${file.removed === 1 ? 'entry' : 'entries'}`];
|
|
226
|
+
if (file.lowered > 0) {
|
|
227
|
+
delen.push(`lowered the count of ${file.lowered}`);
|
|
228
|
+
}
|
|
229
|
+
lines.push(`${file.file}: ${delen.join(', ')}; ${file.errorsBefore} → ${file.errorsAfter} ignored error(s).`);
|
|
230
|
+
}
|
|
231
|
+
if (result.totals.missingFiles > 0) {
|
|
232
|
+
lines.push(`${result.totals.missingFiles} of the removed entries named a file that no longer exists.`);
|
|
233
|
+
}
|
|
234
|
+
lines.push('', result.currentFindings > 0
|
|
235
|
+
? `Nothing was added: the ${result.currentFindings} current finding(s) are still reported. Fix them at the ` +
|
|
236
|
+
'source; generate_baseline would hide them in the baseline.'
|
|
237
|
+
: 'Nothing was added, and there are no current findings.');
|
|
238
|
+
const { left } = result;
|
|
239
|
+
if (left.outsideBaseline + left.general + left.unknownCount + left.inline > 0) {
|
|
240
|
+
lines.push('', 'Left alone:');
|
|
241
|
+
if (left.outsideBaseline > 0) {
|
|
242
|
+
lines.push(`- ${left.outsideBaseline} stale rule(s) with a path that are not in an included baseline: they are in ignoreErrors of the config. Edit that yourself.`);
|
|
243
|
+
}
|
|
244
|
+
if (left.general > 0) {
|
|
245
|
+
lines.push(`- ${left.general} pattern(s) without a path: from ignoreErrors of a config, often one a package ships. A baseline change does nothing about them.`);
|
|
246
|
+
}
|
|
247
|
+
if (left.unknownCount > 0) {
|
|
248
|
+
lines.push(`- ${left.unknownCount} count(s) that are too high, where PHPStan did not say how often the error still occurs.`);
|
|
249
|
+
}
|
|
250
|
+
if (left.inline > 0) {
|
|
251
|
+
lines.push(`- ${left.inline} inline @phpstan-ignore comment(s) that no longer suppress anything: those are in the code. unmatched_ignores lists them.`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return lines.join('\n');
|
|
255
|
+
}
|
|
256
|
+
function toBlock(start, end, known, fields) {
|
|
257
|
+
const value = (key) => {
|
|
258
|
+
const field = fields.get(key);
|
|
259
|
+
return field === undefined ? null : unquote(field.value);
|
|
260
|
+
};
|
|
261
|
+
const message = value('message');
|
|
262
|
+
const raw = value('rawMessage');
|
|
263
|
+
const count = fields.get('count');
|
|
264
|
+
return {
|
|
265
|
+
start,
|
|
266
|
+
end,
|
|
267
|
+
known,
|
|
268
|
+
path: value('path'),
|
|
269
|
+
identifier: value('identifier'),
|
|
270
|
+
// Zoals PHPStans IgnoredError::stringifyPattern het schrijft: `rawMessage` tussen dubbele
|
|
271
|
+
// quotes, zodat hij te koppelen is aan de melding over een verouderde regel.
|
|
272
|
+
pattern: message ?? (raw === null ? null : `"${raw}"`),
|
|
273
|
+
count: count === undefined ? 1 : Number.parseInt(count.value, 10) || 1,
|
|
274
|
+
countLine: count?.line ?? null,
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Het blok dat bij een verouderde regel hoort, of null als het niet eenduidig te vinden is.
|
|
279
|
+
* Een blok wordt maar één keer gebruikt: twee gelijke entries leveren twee meldingen op.
|
|
280
|
+
*/
|
|
281
|
+
function findBlock(project, baselines, rule, claimed) {
|
|
282
|
+
for (const [file, parsed] of baselines) {
|
|
283
|
+
for (const block of parsed.blocks) {
|
|
284
|
+
if (!claimed.has(block) && matches(project, file, block, rule)) {
|
|
285
|
+
return { file, block };
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
function matches(project, file, block, rule) {
|
|
292
|
+
if (!block.known || block.path === null || !samePath(resolve(project.path, dirname(file), block.path), rule.file)) {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
// Een regel met alleen een identifier noemt PHPStan bij die identifier, zonder haakjes.
|
|
296
|
+
if (block.pattern === null) {
|
|
297
|
+
return rule.identifier === null && rule.pattern === block.identifier;
|
|
298
|
+
}
|
|
299
|
+
return rule.pattern === block.pattern && rule.identifier === block.identifier;
|
|
300
|
+
}
|
|
301
|
+
function samePath(a, b) {
|
|
302
|
+
// Windows vergelijkt zonder hoofdletters, en PHPStan schrijft het pad zoals het die kreeg.
|
|
303
|
+
return process.platform === 'win32' ? normalize(a).toLowerCase() === normalize(b).toLowerCase() : normalize(a) === normalize(b);
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Een onvolledige analyse laat entries verouderd lijken die dat niet zijn. Dan wordt er
|
|
307
|
+
* niets geschreven: liever niets snoeien dan een baseline half leeghalen omdat PHPStan
|
|
308
|
+
* halverwege klapte.
|
|
309
|
+
*/
|
|
310
|
+
function requireComplete(result, missing) {
|
|
311
|
+
const incomplete = result.warnings.find((warning) => /Result is incomplete/i.test(warning));
|
|
312
|
+
const errors = result.generalErrors.filter((error) => unmatchedGeneralPattern(error) === null);
|
|
313
|
+
if (incomplete === undefined && errors.length === 0) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const reason = incomplete ?? errors.slice(0, 3).join('\n');
|
|
317
|
+
throw withMissingNotice(new PhpstanError(`The analysis did not cover the whole project, so the baseline was not pruned: an entry can look stale ` +
|
|
318
|
+
`when PHPStan simply did not get that far.\n\n${reason}`, 'phpstan_failed'), missing);
|
|
319
|
+
}
|
|
320
|
+
/** Een fout na het weghalen van entries voor verdwenen bestanden: dat is dan wél gebeurd. */
|
|
321
|
+
function withMissingNotice(error, missing) {
|
|
322
|
+
if (missing.size === 0 || !(error instanceof PhpstanError)) {
|
|
323
|
+
return error;
|
|
324
|
+
}
|
|
325
|
+
const wat = [...missing].map(([file, count]) => `${count} from ${file}`).join(', ');
|
|
326
|
+
return new PhpstanError(`${error.message}\n\nAlready removed before the analysis: the entries for files that no longer exist (${wat}).`, error.reason, error.details);
|
|
327
|
+
}
|
|
328
|
+
function readParsed(project, file) {
|
|
329
|
+
let content;
|
|
330
|
+
try {
|
|
331
|
+
content = readFileSync(join(project.path, file), 'utf8');
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
throw new BaselineError(`${file} cannot be read: ${error instanceof Error ? error.message : String(error)}.`);
|
|
335
|
+
}
|
|
336
|
+
const parsed = parseBaselineBlocks(content);
|
|
337
|
+
// Hetzelfde onderscheid als bij baseline_summary: ignoreErrors noemen en niets opleveren is
|
|
338
|
+
// een vorm die we niet kennen, en daar wordt niet in geschreven.
|
|
339
|
+
if (parsed.blocks.filter((block) => block.known).length === 0 && parsed.blocks.length > 0) {
|
|
340
|
+
throw new BaselineError(`${file} contains ignoreErrors, but not a single entry could be read from it; it was not changed.`);
|
|
341
|
+
}
|
|
342
|
+
return parsed;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Via een tijdelijk bestand naast het origineel en een rename: een analyse die tegelijk
|
|
346
|
+
* leest, ziet het oude of het nieuwe bestand en nooit een half.
|
|
347
|
+
*/
|
|
348
|
+
function writeBaseline(project, file, content) {
|
|
349
|
+
const target = join(project.path, file);
|
|
350
|
+
const tmp = `${target}.phpstan-mcp-${String(process.pid)}`;
|
|
351
|
+
try {
|
|
352
|
+
writeFileSync(tmp, content);
|
|
353
|
+
renameSync(tmp, target);
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
throw new BaselineError(`${file} could not be written: ${error instanceof Error ? error.message : String(error)}.`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
function nothingIncluded(project, notice) {
|
|
360
|
+
return {
|
|
361
|
+
project: project.path,
|
|
362
|
+
files: [],
|
|
363
|
+
totals: { removed: 0, lowered: 0, missingFiles: 0, errorsBefore: 0, errorsAfter: 0 },
|
|
364
|
+
left: { outsideBaseline: 0, general: 0, unknownCount: 0, inline: 0 },
|
|
365
|
+
currentFindings: 0,
|
|
366
|
+
notices: [notice],
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function noBaselineReason(project) {
|
|
370
|
+
return project.config === null
|
|
371
|
+
? `${project.path} has no phpstan.neon(.dist), so no baseline is included.`
|
|
372
|
+
: `The config of ${project.path} includes no phpstan-baseline*.neon from the project root; there is nothing to prune.`;
|
|
373
|
+
}
|
|
374
|
+
function errorsIn(parsed) {
|
|
375
|
+
return parsed.blocks.reduce((sum, block) => sum + block.count, 0);
|
|
376
|
+
}
|
|
377
|
+
function sumCounts(blocks) {
|
|
378
|
+
let sum = 0;
|
|
379
|
+
for (const block of blocks) {
|
|
380
|
+
sum += block.count;
|
|
381
|
+
}
|
|
382
|
+
return sum;
|
|
383
|
+
}
|
|
384
|
+
function indentOf(line) {
|
|
385
|
+
return /^\s*/.exec(line)?.[0].length ?? 0;
|
|
386
|
+
}
|
|
387
|
+
//# sourceMappingURL=prune.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune.js","sourceRoot":"","sources":["../src/prune.ts"],"names":[],"mappings":"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"}
|
package/dist/report.js
CHANGED
|
@@ -79,8 +79,9 @@ export function buildReport(result, window = {}, notices = [], onChangedLine, co
|
|
|
79
79
|
}
|
|
80
80
|
/** Lege of alleen-witruimte-waarden vallen weg; blijft er niets over, dan is er geen filter. */
|
|
81
81
|
function normaliseFilter(identifiers) {
|
|
82
|
-
if (identifiers === undefined)
|
|
82
|
+
if (identifiers === undefined) {
|
|
83
83
|
return null;
|
|
84
|
+
}
|
|
84
85
|
const cleaned = [...new Set(identifiers.map((value) => value.trim()).filter((value) => value !== ''))];
|
|
85
86
|
return cleaned.length === 0 ? null : cleaned;
|
|
86
87
|
}
|
|
@@ -91,8 +92,9 @@ function normaliseFilter(identifiers) {
|
|
|
91
92
|
* zijn. Blijft er niets over, dan is er geen filter, net als bij identifiers.
|
|
92
93
|
*/
|
|
93
94
|
function normalisePlaces(project, places) {
|
|
94
|
-
if (places === undefined)
|
|
95
|
+
if (places === undefined) {
|
|
95
96
|
return null;
|
|
97
|
+
}
|
|
96
98
|
const cleaned = [
|
|
97
99
|
...new Set(places
|
|
98
100
|
.map((place) => place.trim())
|
|
@@ -117,8 +119,9 @@ function isIn(file, places) {
|
|
|
117
119
|
* containment-check op paden.
|
|
118
120
|
*/
|
|
119
121
|
function matches(finding, filter) {
|
|
120
|
-
if (finding.identifier === null)
|
|
122
|
+
if (finding.identifier === null) {
|
|
121
123
|
return false;
|
|
124
|
+
}
|
|
122
125
|
const identifier = finding.identifier;
|
|
123
126
|
return filter.some((value) => identifier === value || identifier.startsWith(`${value}.`));
|
|
124
127
|
}
|
|
@@ -131,22 +134,26 @@ export function renderReport(report, runId) {
|
|
|
131
134
|
// Bovenaan, vóór de fouten: dit bepaalt of je de uitslag hieronder mag vertrouwen.
|
|
132
135
|
if (report.warnings.length > 0) {
|
|
133
136
|
lines.push('WARNING PHPStan reported this alongside the result:');
|
|
134
|
-
for (const warning of report.warnings)
|
|
137
|
+
for (const warning of report.warnings) {
|
|
135
138
|
lines.push(`- ${warning}`);
|
|
136
|
-
|
|
139
|
+
}
|
|
140
|
+
if (report.omitted.warnings > 0) {
|
|
137
141
|
lines.push(`- (${report.omitted.warnings} more message(s) not shown)`);
|
|
142
|
+
}
|
|
138
143
|
lines.push('');
|
|
139
144
|
}
|
|
140
145
|
if (report.notices.length > 0) {
|
|
141
146
|
lines.push('Note:');
|
|
142
|
-
for (const notice of report.notices)
|
|
147
|
+
for (const notice of report.notices) {
|
|
143
148
|
lines.push(`- ${notice}`);
|
|
149
|
+
}
|
|
144
150
|
lines.push('');
|
|
145
151
|
}
|
|
146
152
|
if (report.generalErrors.length > 0) {
|
|
147
153
|
lines.push('Errors not tied to a file:');
|
|
148
|
-
for (const error of report.generalErrors)
|
|
154
|
+
for (const error of report.generalErrors) {
|
|
149
155
|
lines.push(`- ${error}`);
|
|
156
|
+
}
|
|
150
157
|
if (report.omitted.generalErrors > 0) {
|
|
151
158
|
lines.push(`- (${report.omitted.generalErrors} more error(s) not shown)`);
|
|
152
159
|
}
|
|
@@ -154,16 +161,18 @@ export function renderReport(report, runId) {
|
|
|
154
161
|
}
|
|
155
162
|
// Vóór de vroege uitgang bij nul bevindingen: "alles opgelost" is juist het geval
|
|
156
163
|
// waarin de vergelijking het meest zegt.
|
|
157
|
-
if (report.comparison !== null)
|
|
164
|
+
if (report.comparison !== null) {
|
|
158
165
|
lines.push(...describeComparison(report.comparison), '');
|
|
166
|
+
}
|
|
159
167
|
const filters = describeFilters(report);
|
|
160
168
|
const changes = report.changedLines === null ? null : describeChangedLines(report.changedLines, report.comparison?.basis === 'base');
|
|
161
169
|
if (report.page.total === 0) {
|
|
162
170
|
if (filters !== null && report.totals.fileErrors > 0) {
|
|
163
171
|
lines.push(`No findings ${filters}, ` +
|
|
164
172
|
`but there are ${report.totals.fileErrors} other finding(s).`);
|
|
165
|
-
if (changes !== null)
|
|
173
|
+
if (changes !== null) {
|
|
166
174
|
lines.push(changes);
|
|
175
|
+
}
|
|
167
176
|
return lines.join('\n');
|
|
168
177
|
}
|
|
169
178
|
const zonderContext = report.generalErrors.length === 0 && report.warnings.length === 0 && report.notices.length === 0;
|
|
@@ -173,8 +182,9 @@ export function renderReport(report, runId) {
|
|
|
173
182
|
lines.push(filters === null
|
|
174
183
|
? `${report.page.total} finding(s) in ${report.summary.filesWithFindings} file(s).`
|
|
175
184
|
: `${report.page.total} finding(s) ${filters}, of ${report.totals.fileErrors} in total.`);
|
|
176
|
-
if (changes !== null)
|
|
185
|
+
if (changes !== null) {
|
|
177
186
|
lines.push(changes);
|
|
187
|
+
}
|
|
178
188
|
lines.push('', filters === null
|
|
179
189
|
? 'Most common:'
|
|
180
190
|
: 'Most common (across all findings, including filtered ones):', ...report.summary.byIdentifier.map((row) => ` ${pad(row.count)} ${row.identifier}`),
|
|
@@ -204,13 +214,15 @@ export function renderReport(report, runId) {
|
|
|
204
214
|
const mark = marked ? (finding.onChangedLine === true ? '+ ' : ' ') : '';
|
|
205
215
|
const where = finding.line === null ? ' ?' : String(finding.line).padStart(4);
|
|
206
216
|
lines.push(`${mark}${where} ${finding.identifier ?? '-'} ${finding.message}`);
|
|
207
|
-
if (finding.tip !== null)
|
|
217
|
+
if (finding.tip !== null) {
|
|
208
218
|
lines.push(`${marked ? ' ' : ''} tip: ${finding.tip}`);
|
|
219
|
+
}
|
|
209
220
|
}
|
|
210
221
|
if (report.instructions.length > 0) {
|
|
211
222
|
lines.push('', 'PHPStan adds:');
|
|
212
|
-
for (const regel of report.instructions)
|
|
223
|
+
for (const regel of report.instructions) {
|
|
213
224
|
lines.push(` ${regel}`);
|
|
225
|
+
}
|
|
214
226
|
}
|
|
215
227
|
if (report.page.hasMore) {
|
|
216
228
|
lines.push('', runId === undefined
|
|
@@ -225,12 +237,15 @@ export function renderReport(report, runId) {
|
|
|
225
237
|
/** Waarop de pagina beperkt is, als bijzin ("with identifier x on a changed line"), of null. */
|
|
226
238
|
function describeFilters(report) {
|
|
227
239
|
const parts = [];
|
|
228
|
-
if (report.filter !== null)
|
|
240
|
+
if (report.filter !== null) {
|
|
229
241
|
parts.push(`with identifier ${report.filter.join(', ')}`);
|
|
230
|
-
|
|
242
|
+
}
|
|
243
|
+
if (report.onlyIn !== null) {
|
|
231
244
|
parts.push(`in ${report.onlyIn.join(', ')}`);
|
|
232
|
-
|
|
245
|
+
}
|
|
246
|
+
if (report.changedLines?.onlyChangedLines === true) {
|
|
233
247
|
parts.push('on a changed line');
|
|
248
|
+
}
|
|
234
249
|
return parts.length === 0 ? null : parts.join(' ');
|
|
235
250
|
}
|
|
236
251
|
/**
|
|
@@ -243,8 +258,9 @@ function describeChangedLines(changes, comparedWithBase = false) {
|
|
|
243
258
|
const zin = `${changes.onChangedLine} on a line you changed (marked with +), ` +
|
|
244
259
|
`${changes.elsewhere} elsewhere in the changed files, ${changes.otherFiles} in files you did not change.`;
|
|
245
260
|
// Met het "vóór" is het voorbehoud niet meer nodig: de vergelijking erboven zegt het.
|
|
246
|
-
if (comparedWithBase)
|
|
261
|
+
if (comparedWithBase) {
|
|
247
262
|
return `${zin} The comparison above says which of them your change introduced.`;
|
|
263
|
+
}
|
|
248
264
|
// Het voorbehoud is hier nog zwaarder: in een project zonder baseline staan alle oude
|
|
249
265
|
// fouten onder "not changed". Welke door de wijziging komen, zegt één analyse niet.
|
|
250
266
|
return changes.otherFiles === 0 && changes.elsewhere === 0
|
|
@@ -277,13 +293,15 @@ function describeComparison(comparison) {
|
|
|
277
293
|
];
|
|
278
294
|
if (comparison.fixedFindings.length > 0) {
|
|
279
295
|
lines.push(comparison.basis === 'base' ? 'Fixed (line numbers from before your change):' : 'Fixed (line numbers from that analysis):', ...comparison.fixedFindings.map(comparedLine));
|
|
280
|
-
if (comparison.omitted.fixed > 0)
|
|
296
|
+
if (comparison.omitted.fixed > 0) {
|
|
281
297
|
lines.push(` (and ${String(comparison.omitted.fixed)} more)`);
|
|
298
|
+
}
|
|
282
299
|
}
|
|
283
300
|
if (comparison.newFindings.length > 0) {
|
|
284
301
|
lines.push('New:', ...comparison.newFindings.map(comparedLine));
|
|
285
|
-
if (comparison.omitted.new > 0)
|
|
302
|
+
if (comparison.omitted.new > 0) {
|
|
286
303
|
lines.push(` (and ${String(comparison.omitted.new)} more)`);
|
|
304
|
+
}
|
|
287
305
|
}
|
|
288
306
|
if (comparison.notCompared.findings > 0) {
|
|
289
307
|
lines.push(`${String(comparison.notCompared.findings)} finding(s) are in files that only one of the two analyses ` +
|
|
@@ -388,8 +406,9 @@ function topRows(counts) {
|
|
|
388
406
|
*/
|
|
389
407
|
export function displayPath(project, file) {
|
|
390
408
|
const rel = relative(project, file);
|
|
391
|
-
if (rel === '' || rel.startsWith('..') || isAbsolute(rel))
|
|
409
|
+
if (rel === '' || rel.startsWith('..') || isAbsolute(rel)) {
|
|
392
410
|
return file;
|
|
411
|
+
}
|
|
393
412
|
return rel;
|
|
394
413
|
}
|
|
395
414
|
function clamp(value, low, high) {
|