@descent-vtt/spec-guard 0.4.0 → 0.5.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.
@@ -0,0 +1,544 @@
1
+ /**
2
+ * Module-reference extraction for Python, Go, Rust and C#.
3
+ *
4
+ * The JavaScript analyser in `imports.ts` is a full tokenizer because it has to
5
+ * be: a module reference can appear anywhere in an expression, `/` is division
6
+ * or a regular expression depending on context, and template literals nest
7
+ * arbitrarily. None of that is true here. In these four languages an import is
8
+ * a statement, its shape is fixed, and the only thing that can disguise one is
9
+ * a comment or a string literal.
10
+ *
11
+ * spec-guard already has something that finds comments and string literals in
12
+ * nine language families, and it is the most adversarially tested code in the
13
+ * project. So this module does not add four more tokenizers. It masks the
14
+ * source with the existing lexer and then reads statements off what is left:
15
+ *
16
+ * source -> lexRanges (comments.ts) -> masked code -> per-language statement reader
17
+ *
18
+ * That is the whole architecture, and it is the reason four languages cost
19
+ * about as much as one.
20
+ *
21
+ * The alternative was Tree-sitter, and the reason it lost is size: its runtime
22
+ * plus grammars for these four languages measures 94 MB unpacked against this
23
+ * package's 0.33 MB. What that buys is real - a parser knows about
24
+ * conditional compilation and macro expansion, and this does not - so the
25
+ * places where it would be more accurate are listed in ADR-0008 rather than
26
+ * waved away. None of them is an import that this misreads; they are imports
27
+ * this cannot see, and every one of them is reported.
28
+ *
29
+ * Which is the invariant from ADR-0005, carried over unchanged: **a reference
30
+ * this module cannot resolve becomes a note, never silence**. A dependency
31
+ * rule that quietly ignores what it did not understand is a rule that passes
32
+ * for the wrong reason.
33
+ */
34
+ import path from 'node:path';
35
+ import { lexRanges, syntaxNamed } from './comments.js';
36
+ import { lineStarts, locate, maskRanges } from './text.js';
37
+ /** Extension to language. The single place a new language is switched on. */
38
+ export const POLYGLOT_EXTENSIONS = new Map([
39
+ ['.py', 'python'],
40
+ ['.pyi', 'python'],
41
+ ['.go', 'go'],
42
+ ['.rs', 'rust'],
43
+ ['.cs', 'csharp'],
44
+ ['.csx', 'csharp'],
45
+ ]);
46
+ /** The language for a path, or null when this module does not read it. */
47
+ export function languageFor(filePath) {
48
+ return POLYGLOT_EXTENSIONS.get(path.extname(filePath).toLowerCase()) ?? null;
49
+ }
50
+ /**
51
+ * Largest number of module paths one statement may expand to.
52
+ *
53
+ * Rust's brace groups nest, and nesting multiplies: `use a::{b::{c,d}, e::{f,g}}`
54
+ * is four paths from twelve characters, and the growth is exponential in depth.
55
+ * A file that nests twenty levels deep is not a file anyone wrote, but it is a
56
+ * file somebody could commit, and the failure mode without a cap is an
57
+ * out-of-memory kill in CI rather than an error message. Hitting the cap is
58
+ * reported as a note, so the statement is never silently half-read.
59
+ */
60
+ export const MAX_EXPANSION = 64;
61
+ /**
62
+ * Which comment profile each language is read with.
63
+ *
64
+ * Keyed by language rather than by extension on purpose: the caller has already
65
+ * decided what this file is, and looking the answer up a second way is how the
66
+ * two answers get to disagree. A test asserts these agree with the
67
+ * extension-based lookup for every extension this module claims.
68
+ */
69
+ export const SYNTAX_NAMES = {
70
+ python: 'hash',
71
+ go: 'go',
72
+ rust: 'rust',
73
+ csharp: 'c#',
74
+ };
75
+ function mask(source, language) {
76
+ const syntax = syntaxNamed(SYNTAX_NAMES[language]);
77
+ /* c8 ignore next -- SYNTAX_NAMES is asserted complete and correct in the tests */
78
+ if (!syntax)
79
+ throw new Error(`no comment syntax for ${language}`);
80
+ const { comments, strings, unterminated } = lexRanges(source, syntax);
81
+ // The opening delimiter is left visible so a reader can see that a literal
82
+ // starts here; everything inside it is blanked so no keyword can hide there.
83
+ const blanks = [...comments, ...strings.map(([start, end]) => [start + 1, end])];
84
+ return { code: maskRanges(source, blanks), strings, source, starts: lineStarts(source), unterminated };
85
+ }
86
+ /** The literal that starts exactly at `offset`, or null. */
87
+ function literalAt(masked, offset) {
88
+ const { strings } = masked;
89
+ let low = 0;
90
+ let high = strings.length - 1;
91
+ while (low <= high) {
92
+ const mid = (low + high) >> 1;
93
+ const [start, end] = strings[mid];
94
+ if (start === offset)
95
+ return literalValue(masked.source.slice(start, end));
96
+ if (start < offset)
97
+ low = mid + 1;
98
+ else
99
+ high = mid - 1;
100
+ }
101
+ return null;
102
+ }
103
+ /** Every literal whose opening delimiter falls inside [from, to). */
104
+ function literalsBetween(masked, from, to) {
105
+ const values = [];
106
+ for (const [start, end] of masked.strings) {
107
+ if (start >= to)
108
+ break;
109
+ if (start >= from)
110
+ values.push(literalValue(masked.source.slice(start, end)));
111
+ }
112
+ return values;
113
+ }
114
+ /** Strips the delimiters off a literal as the lexer captured it. */
115
+ export function literalValue(raw) {
116
+ let text = raw;
117
+ if (text.startsWith('@'))
118
+ text = text.slice(1);
119
+ if (text.startsWith('r#"'))
120
+ return text.slice(3, -2);
121
+ if (text.startsWith('r"'))
122
+ return text.slice(2, -1);
123
+ if (text.startsWith('"""') || text.startsWith("'''"))
124
+ return text.slice(3, -3);
125
+ const quote = text[0];
126
+ if (quote === '"' || quote === "'" || quote === '`')
127
+ return text.slice(1, -1);
128
+ /* c8 ignore next -- every literal the lexer emits starts with one of the above */
129
+ return text;
130
+ }
131
+ /* ------------------------------------------------------------------ reading */
132
+ const IDENTIFIER = /[A-Za-z_][A-Za-z0-9_]*/y;
133
+ /**
134
+ * Whitespace-skipping cursor over masked code.
135
+ *
136
+ * Exported so its edges can be pinned directly. Reaching "what does peek() do
137
+ * at the end of the file" through a C# source string is possible but says
138
+ * nothing about C#.
139
+ */
140
+ export class Reader {
141
+ text;
142
+ index = 0;
143
+ constructor(text) {
144
+ this.text = text;
145
+ }
146
+ skipSpace() {
147
+ // Character codes rather than /\s/: this runs once per whitespace character
148
+ // in the file, and a regular expression test at that frequency is the
149
+ // difference between the reader being free and the reader being the cost.
150
+ while (this.index < this.text.length) {
151
+ const code = this.text.charCodeAt(this.index);
152
+ if (code !== 32 && code !== 9 && code !== 10 && code !== 13)
153
+ return;
154
+ this.index += 1;
155
+ }
156
+ }
157
+ peek() {
158
+ return this.text[this.index] ?? '';
159
+ }
160
+ eat(token) {
161
+ if (!this.text.startsWith(token, this.index))
162
+ return false;
163
+ this.index += token.length;
164
+ return true;
165
+ }
166
+ /**
167
+ * Eats a word only when it really is the whole word.
168
+ *
169
+ * `eat('static')` also matches the first six characters of a namespace called
170
+ * `staticfiles`, and would then read the dependency as `files`.
171
+ */
172
+ keyword(word) {
173
+ if (!this.text.startsWith(word, this.index))
174
+ return false;
175
+ if (/[A-Za-z0-9_]/.test(this.text[this.index + word.length] ?? ''))
176
+ return false;
177
+ this.index += word.length;
178
+ return true;
179
+ }
180
+ identifier() {
181
+ IDENTIFIER.lastIndex = this.index;
182
+ const match = IDENTIFIER.exec(this.text);
183
+ if (!match)
184
+ return '';
185
+ this.index += match[0].length;
186
+ return match[0];
187
+ }
188
+ /** Reads `a.b.c`, treating `::` as a separator too (C# alias qualifiers). */
189
+ dotted() {
190
+ const parts = [];
191
+ for (;;) {
192
+ const part = this.identifier();
193
+ if (!part)
194
+ break;
195
+ parts.push(part);
196
+ if (!this.eat('.') && !this.eat('::'))
197
+ break;
198
+ }
199
+ return parts.join('.');
200
+ }
201
+ /** Skips a balanced `<...>`, so a generic alias target does not end the read. */
202
+ skipGenerics() {
203
+ if (this.peek() !== '<')
204
+ return;
205
+ let depth = 0;
206
+ while (this.index < this.text.length) {
207
+ const char = this.text[this.index];
208
+ if (char === '<')
209
+ depth += 1;
210
+ else if (char === '>') {
211
+ depth -= 1;
212
+ this.index += 1;
213
+ if (depth === 0)
214
+ return;
215
+ continue;
216
+ }
217
+ else if (char === ';' || char === '\n')
218
+ return;
219
+ this.index += 1;
220
+ }
221
+ }
222
+ }
223
+ /** Offset of the matching close, given the depth-tracking characters. */
224
+ export function matchingClose(text, open, opener, closer) {
225
+ let depth = 0;
226
+ for (let index = open; index < text.length; index++) {
227
+ const char = text[index];
228
+ if (char === opener)
229
+ depth += 1;
230
+ else if (char === closer) {
231
+ depth -= 1;
232
+ if (depth === 0)
233
+ return index;
234
+ }
235
+ }
236
+ return text.length;
237
+ }
238
+ function emit(collector, specifier, kind, offset) {
239
+ const trimmed = specifier.trim();
240
+ if (!trimmed)
241
+ return;
242
+ const { line, column } = locate(collector.masked.starts, offset);
243
+ collector.references.push({ specifier: trimmed, kind, typeOnly: false, line, column });
244
+ }
245
+ function note(collector, kind, offset, detail) {
246
+ const { line, column } = locate(collector.masked.starts, offset);
247
+ collector.notes.push({ kind, file: collector.file, line, column, detail });
248
+ }
249
+ /* ------------------------------------------------------------------- python */
250
+ /**
251
+ * Groups physical lines into the logical lines Python actually executes.
252
+ *
253
+ * A statement continues while a bracket is open or the line ends in a
254
+ * backslash, and `from x import (\n a,\n b,\n)` is the shape that matters
255
+ * here. Lines are joined with a space so two tokens cannot fuse into one.
256
+ */
257
+ export function logicalLines(code) {
258
+ const lines = [];
259
+ let text = '';
260
+ let offset = 0;
261
+ let depth = 0;
262
+ let start = 0;
263
+ const flush = () => {
264
+ if (text.trim())
265
+ lines.push({ text, offset });
266
+ text = '';
267
+ };
268
+ for (let index = 0; index <= code.length; index++) {
269
+ if (index < code.length && code[index] !== '\n') {
270
+ const char = code[index];
271
+ if (char === '(' || char === '[' || char === '{')
272
+ depth += 1;
273
+ else if (char === ')' || char === ']' || char === '}')
274
+ depth = Math.max(0, depth - 1);
275
+ continue;
276
+ }
277
+ const physical = code.slice(start, index);
278
+ if (!text)
279
+ offset = start;
280
+ text += (text ? ' ' : '') + physical.replace(/\\$/, ' ');
281
+ if (depth === 0 && !/\\$/.test(physical))
282
+ flush();
283
+ start = index + 1;
284
+ }
285
+ flush();
286
+ return lines;
287
+ }
288
+ /** `import` / `from` at a statement position: line start, or after `;` or `:`. */
289
+ const PYTHON_STATEMENT = /(?:^|[;:])[ \t]*(import|from)[ \t]+/g;
290
+ const PYTHON_FROM = /^(\.*)([A-Za-z_][\w.]*)?[ \t]*import[ \t]+(.*)$/;
291
+ const PYTHON_DYNAMIC = /\b(__import__|import_module)[ \t]*\(/g;
292
+ function readPython(collector) {
293
+ const { code } = collector.masked;
294
+ for (const line of logicalLines(code)) {
295
+ PYTHON_STATEMENT.lastIndex = 0;
296
+ let match;
297
+ while ((match = PYTHON_STATEMENT.exec(line.text)) !== null) {
298
+ const rest = line.text.slice(match.index + match[0].length).split(';')[0];
299
+ if (match[1] === 'import') {
300
+ // `import a.b as x, c.d` - one statement, two dependencies.
301
+ for (const clause of rest.split(',')) {
302
+ const name = clause.trim().split(/\s+/)[0];
303
+ if (name)
304
+ emit(collector, name, 'import', line.offset);
305
+ }
306
+ continue;
307
+ }
308
+ const from = PYTHON_FROM.exec(rest);
309
+ if (!from)
310
+ continue;
311
+ const dots = from[1];
312
+ const module = from[2] ?? '';
313
+ if (module || !dots) {
314
+ emit(collector, `${dots}${module}`, 'import', line.offset);
315
+ continue;
316
+ }
317
+ // `from . import a, b` - here the imported names are themselves modules,
318
+ // which `from .pkg import name` cannot assume.
319
+ const names = from[3].replace(/[()]/g, '');
320
+ for (const clause of names.split(',').slice(0, MAX_EXPANSION)) {
321
+ const name = clause.trim().split(/\s+/)[0];
322
+ if (name && name !== '*')
323
+ emit(collector, `${dots}${name}`, 'import', line.offset);
324
+ }
325
+ }
326
+ }
327
+ PYTHON_DYNAMIC.lastIndex = 0;
328
+ let dynamic;
329
+ while ((dynamic = PYTHON_DYNAMIC.exec(code)) !== null) {
330
+ const reader = new Reader(code);
331
+ reader.index = dynamic.index + dynamic[0].length;
332
+ reader.skipSpace();
333
+ const literal = literalAt(collector.masked, reader.index);
334
+ if (literal !== null)
335
+ emit(collector, literal, 'dynamic-import', dynamic.index);
336
+ else
337
+ note(collector, 'dynamic', dynamic.index, `${dynamic[1]}(...) with a computed name`);
338
+ }
339
+ }
340
+ /* ----------------------------------------------------------------------- go */
341
+ const GO_IMPORT = /\bimport\b/g;
342
+ function readGo(collector) {
343
+ const { code } = collector.masked;
344
+ GO_IMPORT.lastIndex = 0;
345
+ let match;
346
+ while ((match = GO_IMPORT.exec(code)) !== null) {
347
+ const reader = new Reader(code);
348
+ reader.index = match.index + match[0].length;
349
+ reader.skipSpace();
350
+ if (reader.peek() === '(') {
351
+ const close = matchingClose(code, reader.index, '(', ')');
352
+ for (const value of literalsBetween(collector.masked, reader.index, close)) {
353
+ emit(collector, value, 'import', match.index);
354
+ }
355
+ GO_IMPORT.lastIndex = close;
356
+ continue;
357
+ }
358
+ // A single import may carry an alias: `import fmt2 "fmt"`, `import _ "x"`.
359
+ if (reader.peek() === '_' || reader.peek() === '.')
360
+ reader.index += 1;
361
+ else
362
+ reader.identifier();
363
+ reader.skipSpace();
364
+ const literal = literalAt(collector.masked, reader.index);
365
+ if (literal !== null)
366
+ emit(collector, literal, 'import', match.index);
367
+ }
368
+ }
369
+ /* --------------------------------------------------------------------- rust */
370
+ const RUST_USE = /\b(?:use|extern[ \t\r\n]+crate)\b/g;
371
+ /**
372
+ * Expands one `use` path into the module paths it actually names.
373
+ *
374
+ * `a::{b, c::{d, e}}` is three dependencies written as one statement, and a
375
+ * rule about `a::c` has to see them. Returns null when the expansion would
376
+ * exceed MAX_EXPANSION, which the caller reports rather than truncating.
377
+ */
378
+ export function expandUsePath(input) {
379
+ const text = input.trim();
380
+ const open = text.indexOf('{');
381
+ if (open === -1) {
382
+ // `a::b as c` and `a::b;` both name `a::b`.
383
+ const leaf = text.split(/\s+as\s+/)[0];
384
+ const trimmed = leaf.replace(/[;\s]+$/, '').replace(/^::/, '');
385
+ return trimmed ? [trimmed] : [];
386
+ }
387
+ const close = matchingClose(text, open, '{', '}');
388
+ const prefix = text.slice(0, open).replace(/::\s*$/, '').trim();
389
+ const inner = text.slice(open + 1, close);
390
+ const parts = [];
391
+ let depth = 0;
392
+ let current = '';
393
+ for (const char of inner) {
394
+ if (char === '{')
395
+ depth += 1;
396
+ if (char === '}')
397
+ depth -= 1;
398
+ if (char === ',' && depth === 0) {
399
+ parts.push(current);
400
+ current = '';
401
+ continue;
402
+ }
403
+ current += char;
404
+ }
405
+ parts.push(current);
406
+ const results = [];
407
+ for (const part of parts) {
408
+ const expanded = expandUsePath(part);
409
+ if (expanded === null)
410
+ return null;
411
+ for (const item of expanded) {
412
+ // `use a::{self, b}` names `a` itself alongside `a::b`.
413
+ results.push(item === 'self' || !prefix ? prefix || item : `${prefix}::${item}`);
414
+ if (results.length > MAX_EXPANSION)
415
+ return null;
416
+ }
417
+ }
418
+ return results;
419
+ }
420
+ function readRust(collector) {
421
+ const { code } = collector.masked;
422
+ RUST_USE.lastIndex = 0;
423
+ let match;
424
+ while ((match = RUST_USE.exec(code)) !== null) {
425
+ const start = match.index + match[0].length;
426
+ let end = start;
427
+ let depth = 0;
428
+ while (end < code.length) {
429
+ const char = code[end];
430
+ if (char === '{')
431
+ depth += 1;
432
+ else if (char === '}') {
433
+ if (depth === 0)
434
+ break;
435
+ depth -= 1;
436
+ }
437
+ else if (char === ';' && depth === 0)
438
+ break;
439
+ end += 1;
440
+ }
441
+ const expanded = expandUsePath(code.slice(start, end));
442
+ if (expanded === null) {
443
+ note(collector, 'truncated', match.index, `a use declaration expands to more than ${MAX_EXPANSION} module paths`);
444
+ }
445
+ else {
446
+ for (const specifier of expanded)
447
+ emit(collector, specifier, 'use', match.index);
448
+ }
449
+ RUST_USE.lastIndex = end;
450
+ }
451
+ }
452
+ /* -------------------------------------------------------------------- c-sharp */
453
+ const CSHARP_USING = /\busing\b/g;
454
+ function readCsharp(collector) {
455
+ const { code } = collector.masked;
456
+ CSHARP_USING.lastIndex = 0;
457
+ let match;
458
+ while ((match = CSHARP_USING.exec(code)) !== null) {
459
+ const reader = new Reader(code);
460
+ reader.index = match.index + match[0].length;
461
+ reader.skipSpace();
462
+ if (reader.keyword('static'))
463
+ reader.skipSpace();
464
+ let target = reader.dotted();
465
+ reader.skipSpace();
466
+ // `using Alias = System.Text.Json;` - the dependency is the right-hand side.
467
+ if (reader.eat('=')) {
468
+ reader.skipSpace();
469
+ target = reader.dotted();
470
+ reader.skipSpace();
471
+ reader.skipGenerics();
472
+ reader.skipSpace();
473
+ }
474
+ // The whole of what separates a directive from a resource statement, and
475
+ // it is one condition on purpose. `using (var s = ...)` reads no name at
476
+ // all and stops on `(`; `using var s = ...` reads `var` and then finds `s`
477
+ // where a terminator has to be. Earlier versions guarded those two shapes
478
+ // explicitly, and a third time against an empty name - none of the three
479
+ // changed an outcome, which mutation testing established by leaving the
480
+ // tests green with each of them defeated. `emit` refuses an empty
481
+ // specifier, so this line is the only check that has to be right.
482
+ if (reader.peek() !== ';')
483
+ continue;
484
+ emit(collector, target, 'using', match.index);
485
+ }
486
+ }
487
+ /* ----------------------------------------------------------------- normalise */
488
+ /**
489
+ * Rewrites a specifier into the `/`-separated form module patterns match.
490
+ *
491
+ * Every language names modules with its own separator - `a.b.c`, `a::b::c`,
492
+ * `a/b/c` - and a rule author should not have to know which one a given file
493
+ * uses. One notation, and the raw specifier stays matchable too, so a pattern
494
+ * written either way finds the dependency.
495
+ *
496
+ * Python's relative imports resolve against the importing file, the same path
497
+ * arithmetic (and the same refusal to touch the filesystem) as ADR-0005.
498
+ * Rust's `self::` and `super::` deliberately do not: resolving them needs the
499
+ * module tree, the module tree needs to know where inline `mod` blocks are, and
500
+ * that needs a parser. They are matched literally instead, and ADR-0008 says so
501
+ * out loud rather than leaving a rule to quietly miss them.
502
+ */
503
+ export function normalizeModule(specifier, importingFile, language) {
504
+ if (language === 'go')
505
+ return specifier;
506
+ if (language === 'rust')
507
+ return specifier.replace(/::/g, '/');
508
+ if (language === 'csharp')
509
+ return specifier.replace(/\./g, '/');
510
+ if (!specifier.startsWith('.'))
511
+ return specifier.replace(/\./g, '/');
512
+ let level = 0;
513
+ while (specifier[level] === '.')
514
+ level += 1;
515
+ const tail = specifier.slice(level).replace(/\./g, '/');
516
+ let base = path.posix.dirname(importingFile);
517
+ for (let up = 1; up < level; up++)
518
+ base = path.posix.dirname(base);
519
+ return path.posix.normalize(path.posix.join(base, tail));
520
+ }
521
+ /* -------------------------------------------------------------------- entry */
522
+ const READERS = {
523
+ python: readPython,
524
+ go: readGo,
525
+ rust: readRust,
526
+ csharp: readCsharp,
527
+ };
528
+ /** Extracts every module reference from a Python, Go, Rust or C# source file. */
529
+ export function analyzePolyglot(source, file, language) {
530
+ const masked = mask(source, language);
531
+ const collector = { references: [], notes: [], masked, file };
532
+ READERS[language](collector);
533
+ if (masked.unterminated) {
534
+ collector.notes.push({
535
+ kind: 'unreadable',
536
+ file,
537
+ line: 1,
538
+ column: 1,
539
+ detail: 'a string or comment ran to the end of the file, so its imports are not trustworthy',
540
+ });
541
+ }
542
+ return { references: collector.references, notes: collector.notes };
543
+ }
544
+ //# sourceMappingURL=polyglot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polyglot.js","sourceRoot":"","sources":["../src/polyglot.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,48 @@ export declare function shouldUseColor(stream: {
39
39
  export declare function shouldUseAscii(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): boolean;
40
40
  /** Renders the full human-readable report. */
41
41
  export declare function formatReport(report: RunResult, options: ReporterOptions, maxSnippets?: number): string;
42
+ /**
43
+ * The `baseline="..."` attribute that would exempt today's violations.
44
+ *
45
+ * The one machine-written edit spec-guard offers, and it is offered rather than
46
+ * applied. `--fix` is refused for architecture rules on purpose (ADR-0009): the
47
+ * only edits a machine can make to a failing boundary assertion are edits that
48
+ * record the rule no longer holding, and a tool that ships a button turning red
49
+ * into green without changing any code has shipped the wrong button - most of
50
+ * all to an agent in a loop, for which that button is the shortest path to a
51
+ * passing build.
52
+ *
53
+ * Printing is different from applying in the way that matters. The author
54
+ * pastes it into the spec, and the diff shows every exempted file by name, to a
55
+ * reviewer, in the commit that grants the exemption. Adopting a strict rule on
56
+ * a codebase that already violates it is otherwise a hand-transcription job,
57
+ * and the realistic alternative to that is not a clean codebase - it is no
58
+ * rule at all.
59
+ */
60
+ export declare function formatBaselines(report: RunResult): string;
42
61
  /** Machine-readable output for CI consumers. */
43
62
  export declare function formatJson(report: RunResult): string;
63
+ /**
64
+ * The static analysis interchange format, which is how a failure becomes a
65
+ * line-level annotation on a pull request.
66
+ *
67
+ * Chosen over an editor language server for the fast-feedback problem, and the
68
+ * reason is what spec-guard checks rather than how fast it is. Its claims are
69
+ * about a whole repository - "this symbol appears nowhere in src" - and a
70
+ * language server is handed one buffer at a time. Answering a repository-wide
71
+ * question on every keystroke means rescanning the tree on every keystroke; the
72
+ * alternative is answering a different, smaller question and calling it the
73
+ * same one. SARIF needs no daemon, no editor extension per editor and no
74
+ * protocol version matrix, and it puts the failure on the offending line for
75
+ * every reviewer rather than only for the author who has the plugin installed.
76
+ *
77
+ * One result per failing assertion, not per match: the thing that broke is the
78
+ * rule. The primary location is the first offending line so the annotation
79
+ * lands on the code; the directive that was violated is always a related
80
+ * location, because that is where the fix usually goes.
81
+ */
82
+ export declare function formatSarif(report: RunResult, options?: {
83
+ version?: string;
84
+ }): string;
44
85
  export {};
45
86
  //# sourceMappingURL=reporter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAKD,QAAA,MAAM,IAAI;aACR,KAAK;aACL,IAAI;aACJ,GAAG;aACH,GAAG;aACH,KAAK;aACL,MAAM;aACN,IAAI;aACJ,OAAO;aACP,IAAI;aACJ,IAAI;CACI,CAAC;AAEX,KAAK,KAAK,GAAG,MAAM,OAAO,IAAI,CAAC;AAE/B,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,MAAM,CAI1F;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAC3B,IAAI,EAAE,OAAO,GAAG,SAAS,EACzB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAKT;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,QAAQ,kBAAmB,GAAG,OAAO,CAGzG;AAkJD,8CAA8C;AAC9C,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,SAAI,GAAG,MAAM,CA6EjG;AAED,gDAAgD;AAChD,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CA+CpD"}
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,gDAAgD;IAChD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAKD,QAAA,MAAM,IAAI;aACR,KAAK;aACL,IAAI;aACJ,GAAG;aACH,GAAG;aACH,KAAK;aACL,MAAM;aACN,IAAI;aACJ,OAAO;aACP,IAAI;aACJ,IAAI;CACI,CAAC;AAEX,KAAK,KAAK,GAAG,MAAM,OAAO,IAAI,CAAC;AAE/B,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,KAAK,MAAM,CAI1F;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EAC3B,IAAI,EAAE,OAAO,GAAG,SAAS,EACzB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAKT;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,EAAE,QAAQ,kBAAmB,GAAG,OAAO,CAGzG;AA0JD,8CAA8C;AAC9C,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,SAAI,GAAG,MAAM,CA8EjG;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAezD;AAED,gDAAgD;AAChD,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAkDpD;AA2CD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CA0EzF"}