@descent-vtt/spec-guard 0.10.1 → 0.10.3
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 +124 -0
- package/README.md +101 -19
- package/dist/comments.d.ts +40 -3
- package/dist/comments.d.ts.map +1 -1
- package/dist/comments.js +169 -20
- package/dist/comments.js.map +1 -1
- package/dist/imports.d.ts +29 -0
- package/dist/imports.d.ts.map +1 -1
- package/dist/imports.js +32 -1
- package/dist/imports.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/layers.d.ts +27 -7
- package/dist/layers.d.ts.map +1 -1
- package/dist/layers.js +40 -13
- package/dist/layers.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +9 -1
- package/dist/parser.js.map +1 -1
- package/dist/polyglot.d.ts +17 -1
- package/dist/polyglot.d.ts.map +1 -1
- package/dist/polyglot.js +95 -16
- package/dist/polyglot.js.map +1 -1
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +36 -11
- package/dist/runner.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,130 @@ All notable changes to this project are documented here. Versions follow
|
|
|
5
5
|
may change in a minor release — each such change is listed under **Changed**
|
|
6
6
|
with the flag that restores the previous behaviour.
|
|
7
7
|
|
|
8
|
+
## 0.10.3
|
|
9
|
+
|
|
10
|
+
Fixes from running 0.10.2 over a Rust and .NET monorepo, where an import rule
|
|
11
|
+
missed five `use` declarations in one crate and said nothing, and from probing
|
|
12
|
+
every other language profile for the same mistake.
|
|
13
|
+
[ADR-0006](docs/adr/0006-comment-classification.md),
|
|
14
|
+
[ADR-0008](docs/adr/0008-polyglot-imports.md).
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **A Rust lifetime hid the code after it.** Every `'` opened a character
|
|
19
|
+
literal, and a lifetime - `&'static str`, `<'_>`, `'a`, `where 'a: 'b` - has
|
|
20
|
+
no closing quote, so the literal ran on to the next quote in the file: often
|
|
21
|
+
an apostrophe in a comment (`// don't`). Every `use` in between went unread
|
|
22
|
+
without a note, because the literal did close; with no second quote, every
|
|
23
|
+
`use` after it went unread with one. For a text rule the rest of that comment
|
|
24
|
+
became code, and a `/*` in it hid code as a comment. Quotes are now read as
|
|
25
|
+
`rustc_lexer` reads them: a quote and an identifier with no closing quote is a
|
|
26
|
+
lifetime or a label, and `'a'`, `'\''` and `'"'` are character literals.
|
|
27
|
+
- **A Rust raw string with two or more hashes lost the scan.** `r##"…"##` read
|
|
28
|
+
as an ordinary string that closed at its first inner quote. Any number of
|
|
29
|
+
hashes is read now, in byte and C strings too (`br##"…"##`, `cr#"…"#`), and
|
|
30
|
+
`r#type` stays a raw identifier. `literalValue` strips any number of them.
|
|
31
|
+
- **A `#` inside a word in a shell script or YAML file hid the rest of the
|
|
32
|
+
line**, as in `${path##*/}`, `${#items[@]}`, `$#` and
|
|
33
|
+
`url: https://example.com/#top`. `.sh`, `.bash`, `.zsh`, `.yaml` and `.yml`
|
|
34
|
+
have a profile of their own, `shell-like`, in which `#` opens a comment only
|
|
35
|
+
at the start of a line or after a space or a tab, as both languages define
|
|
36
|
+
it. Their quotes follow their specifications as well: `'C:\'` is a complete
|
|
37
|
+
string, and `$'it\'s'` is one string.
|
|
38
|
+
- **A C++ digit separator opened a string.** `100'000` read its quote as the
|
|
39
|
+
start of a character literal, which paired with the next quote in the file.
|
|
40
|
+
In `.c`, `.cpp` and the rest of the C profile, a quote after a word that
|
|
41
|
+
begins with a digit is now part of the number; `u8'a'` is still a
|
|
42
|
+
character.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- **A Rust character literal ends at the end of its line.** None can hold a
|
|
47
|
+
line break, and rustc stops reading an unclosed one there, so a quote misread
|
|
48
|
+
in future costs at most the rest of its line. Such a file is still reported
|
|
49
|
+
as unreadable, and the note now reads `a string or comment was never closed,
|
|
50
|
+
so its imports are not trustworthy` - it used to say the literal ran to the
|
|
51
|
+
end of the file.
|
|
52
|
+
|
|
53
|
+
JavaScript and TypeScript are read exactly as before: across 7,954 files, the
|
|
54
|
+
new lexer's ranges match 0.10.2's on every one. What it still misreads there - a
|
|
55
|
+
regular expression literal holding a quote, `/["']/` - is recorded in ADR-0006.
|
|
56
|
+
|
|
57
|
+
## 0.10.2
|
|
58
|
+
|
|
59
|
+
Fixes from running 0.10.1 over a .NET solution, where a layer rule passed while
|
|
60
|
+
the domain imported the application, and from reading C# as it is written in
|
|
61
|
+
2026 while fixing that.
|
|
62
|
+
[ADR-0011](docs/adr/0011-layers-and-cycles.md),
|
|
63
|
+
[ADR-0008](docs/adr/0008-polyglot-imports.md).
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
- **A dotted module pattern did not cover what sits beneath it.**
|
|
68
|
+
`module="Shop.Application"` missed `using Shop.Application.Catalog;`, while
|
|
69
|
+
`module="Shop/Application"` caught it. A layer named `Shop.Application` had
|
|
70
|
+
the same gap, so `order="Shop.Domain, Shop.Application"` passed over a domain
|
|
71
|
+
that imported the application. Each reference in C#, Python and Rust now also
|
|
72
|
+
goes by every module it sits under, in its own notation, so `Shop.Application`
|
|
73
|
+
covers `Shop.Application.Catalog` and not `Shop.ApplicationServices`,
|
|
74
|
+
`app.db` covers `app.db.client`, and `crate::db` covers `crate::db::pool`.
|
|
75
|
+
An `@assert-import-count` over those languages can count more files than
|
|
76
|
+
before, and each is a file that depends on the module.
|
|
77
|
+
- **Three kinds of C# using were read under a name no pattern matched.**
|
|
78
|
+
- `using global::Shop.Application;` read as `global.Shop.Application`, and
|
|
79
|
+
`using Legacy::Shop.Application;` (an extern alias) as
|
|
80
|
+
`Legacy.Shop.Application`. The qualifier is now left off.
|
|
81
|
+
- A using inside a namespace may be relative to it: in `namespace
|
|
82
|
+
Shop.Domain`, `using Application.Catalog;` can be
|
|
83
|
+
`Shop.Application.Catalog`. It now counts under each name it can resolve to
|
|
84
|
+
there.
|
|
85
|
+
- **Two kinds of C# string lost the scan.** A raw string literal (C# 11) that
|
|
86
|
+
held a quote, or that opened with four quotes to hold three, and an
|
|
87
|
+
interpolated verbatim string written `@$"C:\"`, were misread. Every using after
|
|
88
|
+
one could go unread, and a text rule could count a comment as code. Both are
|
|
89
|
+
now read as strings.
|
|
90
|
+
- **A backslash in a directive attribute was dropped.** Every backslash escaped
|
|
91
|
+
the character after it, so `symbol="Shop\.(Application|Web)\b" regex="true"`
|
|
92
|
+
searched for `Shop.(Application|Web)b`, matched nothing and passed, and
|
|
93
|
+
`exclude="src\gen"` excluded `srcgen`. Only `\"`, `\'` and `\\` are escapes
|
|
94
|
+
now; any other backslash is kept. Found by running this release's README
|
|
95
|
+
example against a project file. A pattern written with doubled backslashes to
|
|
96
|
+
get past the old behaviour, `\\b`, still reads as `\b`.
|
|
97
|
+
- **`.csproj`, `.fsproj`, `.vbproj`, `.props`, `.targets`, `.slnx`, `.nuspec`,
|
|
98
|
+
`.resx` and `.xaml` were unclassified,** so a text rule over a project file
|
|
99
|
+
counted a `<ProjectReference>` inside `<!-- -->`. They are now read as XML.
|
|
100
|
+
|
|
101
|
+
### Changed
|
|
102
|
+
|
|
103
|
+
- **A layer rule that could not have failed now fails** (`allow-empty="true"`,
|
|
104
|
+
or `--allow-empty-scope`, makes each a warning again):
|
|
105
|
+
- **A layer no C# using can reach.** A layer named by its folder,
|
|
106
|
+
`src/Shop.Application`, holds the right files, but a using names a
|
|
107
|
+
namespace, never a path. When a layer after the first matches none of the
|
|
108
|
+
namespaces its own files declare, the rule fails:
|
|
109
|
+
`no C# using can reach layer "src/Shop.Application": it matches none of the
|
|
110
|
+
namespaces its files declare, such as Shop.Application.Catalog, so a
|
|
111
|
+
dependency on it is never seen`. Name a C# layer by its namespace,
|
|
112
|
+
`Shop.Application`, which matches the folder as well.
|
|
113
|
+
- **A scope in which no import reaches another layer.** Such a rule would
|
|
114
|
+
pass with its layers in any order: `no import in scope reaches a layer other
|
|
115
|
+
than its own file's, so these layers would pass in any order`. This is how
|
|
116
|
+
a layer named in a way no reference can match shows up in every language.
|
|
117
|
+
- **The files an import rule could not read are named by kind**, as in
|
|
118
|
+
`analysed 5 of 7 files; 2 are in a language whose imports spec-guard cannot
|
|
119
|
+
read (.csproj, .razor)`. In a .NET project, the count alone hid the Razor
|
|
120
|
+
page among project files, and a Razor page can hold an `@using`.
|
|
121
|
+
- **README:** a section on C# and .NET solutions - layers by namespace, what an
|
|
122
|
+
import rule cannot see and the text rule for each, and the `exclude` list for
|
|
123
|
+
build output (`bin`, `obj`, `artifacts`, `TestResults`, `.vs`).
|
|
124
|
+
- **API:**
|
|
125
|
+
- `ModuleReference` has an optional `namespace`, the namespace a C# using sits
|
|
126
|
+
in.
|
|
127
|
+
- `FileImports` and `LayerInput` have an optional `namespaces`, those a C#
|
|
128
|
+
file declares.
|
|
129
|
+
- `LayerReport` has `crossed` and `unreachable`.
|
|
130
|
+
- New: `moduleNames` and `enclosingModules`.
|
|
131
|
+
|
|
8
132
|
## 0.10.1
|
|
9
133
|
|
|
10
134
|
Fixes from running 0.10.0 over a large monorepo, and from testing each exclude
|
package/README.md
CHANGED
|
@@ -107,7 +107,9 @@ Exit code 1. The ADR is now a test.
|
|
|
107
107
|
## Directives
|
|
108
108
|
|
|
109
109
|
Every directive is an HTML comment. It may span multiple lines. Attribute values
|
|
110
|
-
may use double or single quotes, and a bare attribute means `="true"`.
|
|
110
|
+
may use double or single quotes, and a bare attribute means `="true"`. Inside a
|
|
111
|
+
value, `\"`, `\'` and `\\` are escapes and any other backslash is kept, so a
|
|
112
|
+
regular expression is written as it reads: `symbol="\bTODO\b" regex="true"`.
|
|
111
113
|
|
|
112
114
|
### `@assert-absence` - this symbol is gone
|
|
113
115
|
|
|
@@ -204,10 +206,13 @@ touching code, a run that passed this way says so:
|
|
|
204
206
|
✔ every spec assertion holds
|
|
205
207
|
```
|
|
206
208
|
|
|
207
|
-
Comment syntax is known for around
|
|
208
|
-
C#, Rust, Go, Python-style `#`, SQL-style `--`, markup
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
Comment syntax is known for around 68 extensions across 10 families (JS/TS, C,
|
|
210
|
+
C#, Rust, Go, Python-style `#`, shell and YAML `#`, SQL-style `--`, markup -
|
|
211
|
+
MSBuild project files included - and formats with no comments at all). Strings
|
|
212
|
+
are tracked too, because `//` inside a URL is not a comment and reading it as
|
|
213
|
+
one would hide real code. So is what only looks like either: a Rust lifetime
|
|
214
|
+
(`&'static str`), a C++ digit separator (`100'000`) and a `#` inside a shell
|
|
215
|
+
word (`${#items[@]}`) open nothing. Where spec-guard is unsure —
|
|
211
216
|
an unknown extension, an unterminated literal — the text counts as code, and the
|
|
212
217
|
report says which files it could not classify. A match wrongly kept is a visible
|
|
213
218
|
failure you can argue with; a match wrongly dropped is a lie.
|
|
@@ -302,7 +307,7 @@ These read the dependency rather than the text, in **five languages**:
|
|
|
302
307
|
| Python | `.py .pyi` | `import a.b`, `from .rel import x`, `importlib.import_module("x")` |
|
|
303
308
|
| Go | `.go` | `import "x"` and grouped `import ( ... )`, including aliases and `_` |
|
|
304
309
|
| Rust | `.rs` | `use a::{b, c}` with nested groups, `pub use`, `extern crate` |
|
|
305
|
-
| C# | `.cs .csx` | `using`, `using static`, `global using`, `using X = A.B` |
|
|
310
|
+
| C# | `.cs .csx` | `using`, `using static`, `global using`, `using X = A.B`, `global::` and extern-alias qualifiers, and a using relative to its namespace |
|
|
306
311
|
|
|
307
312
|
No parser and no new dependency. JavaScript gets a full tokenizer because a
|
|
308
313
|
module reference can appear anywhere in an expression; the other four are read
|
|
@@ -315,9 +320,12 @@ this does not.
|
|
|
315
320
|
|
|
316
321
|
Module patterns are matched against the resolved `/`-separated path *and*
|
|
317
322
|
against the specifier as written, so `module="System.Text.Json"` and
|
|
318
|
-
`module="System/Text/Json"` both work.
|
|
319
|
-
|
|
320
|
-
`
|
|
323
|
+
`module="System/Text/Json"` both work. Either form covers what sits beneath it,
|
|
324
|
+
as `module="lodash"` covers `lodash/fp`: `module="Shop.Application"` matches
|
|
325
|
+
`using Shop.Application.Catalog;` and not `using Shop.ApplicationServices;`,
|
|
326
|
+
`module="app.db"` matches `import app.db.client`, and `module="crate::db"`
|
|
327
|
+
matches `use crate::db::pool`. Matching is case-sensitive, so a rule spanning C#
|
|
328
|
+
and Go needs both conventions: `module="app/db/** App/Db/**"`.
|
|
321
329
|
|
|
322
330
|
The unit counted is **files** that depend on the module. For JavaScript and
|
|
323
331
|
TypeScript it understands:
|
|
@@ -354,7 +362,7 @@ stops it being mistaken for a complete answer. A passing rule prints it without
|
|
|
354
362
|
`--verbose` too, since a green run is when it would otherwise go unread.
|
|
355
363
|
`--strict` turns those warnings into failures. Files in scope that are not JavaScript or TypeScript are counted
|
|
356
364
|
and reported too, so a rule pointed at the wrong tree says "analysed 2 of 3
|
|
357
|
-
files" rather than quietly passing - and if *none* of them can be read, the
|
|
365
|
+
files; 1 is in a language whose imports spec-guard cannot read (.razor)" rather than quietly passing - and if *none* of them can be read, the
|
|
358
366
|
assertion fails rather than passing on an empty analysis.
|
|
359
367
|
|
|
360
368
|
[ADR-0005](docs/adr/0005-import-assertions.md) has the measurements and the
|
|
@@ -387,15 +395,89 @@ why this works in all five languages above: `src/domain` is anchored at the
|
|
|
387
395
|
root, and a bare `domain` matches that segment anywhere - in `src/domain/user.ts`,
|
|
388
396
|
in Python's `app.domain.user`, in Rust's `crate::domain::user`. A layer may also
|
|
389
397
|
be a single file; `order="src/parser.ts, src/cli.ts"` understands that
|
|
390
|
-
`./parser.js` is `src/parser.ts`.
|
|
398
|
+
`./parser.js` is `src/parser.ts`. C# is layered by namespace, and has
|
|
399
|
+
[a section of its own](#c-and-net-solutions).
|
|
391
400
|
|
|
392
401
|
The unit is files, and `max`, `types`, `exclude` and `baseline` mean what they
|
|
393
|
-
mean on `@assert-import-absence`.
|
|
394
|
-
each is a rule that would otherwise check less than it says:
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
402
|
+
mean on `@assert-import-absence`. Five things fail rather than pass, because
|
|
403
|
+
each is a rule that would otherwise check less than it says:
|
|
404
|
+
|
|
405
|
+
- a layer that matches no file (`order="domain, aplication"`);
|
|
406
|
+
- a file two layers both claim;
|
|
407
|
+
- a target that does not exist;
|
|
408
|
+
- a layer no C# `using` can reach, because it matches none of the namespaces its
|
|
409
|
+
own files declare - `src/Shop.Application` rather than `Shop.Application`;
|
|
410
|
+
- a scope in which no import reaches a layer other than its own file's, since
|
|
411
|
+
that rule passes whatever order its layers are listed in:
|
|
412
|
+
|
|
413
|
+
```text
|
|
414
|
+
✖ docs/architecture.md:12 @assert-layers
|
|
415
|
+
src must keep its layers in order, src/domain < src/application < src/infrastructure
|
|
416
|
+
no import in scope reaches a layer other than its own file's, so these layers would pass in any order (add allow-empty="true" if that is expected)
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
`allow-empty="true"` turns the first and the last two into warnings. Files that
|
|
420
|
+
no layer claims are left alone and counted, so a directory nobody assigned shows
|
|
421
|
+
up as a number rather than as silence.
|
|
422
|
+
|
|
423
|
+
### C# and .NET solutions
|
|
424
|
+
|
|
425
|
+
A .NET project has three names: its folder, its project file and its root
|
|
426
|
+
namespace. `dotnet new` gives all three the same one, and that is what lets a
|
|
427
|
+
single pattern do both halves of a layer rule - hold the files under
|
|
428
|
+
`src/Shop.Domain`, and reach `using Shop.Domain.Orders;` from anywhere else:
|
|
429
|
+
|
|
430
|
+
```md
|
|
431
|
+
<!-- @assert-layers target="src" order="Shop.Domain, Shop.Application, Shop.Infrastructure, Shop.Web" reason="dependencies point inward" -->
|
|
432
|
+
<!-- @assert-import-absence target="src/Shop.Application" module="Microsoft.EntityFrameworkCore" reason="persistence is infrastructure's" -->
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
- **Name a C# layer by its namespace.** `Shop.Domain` matches the folder as a
|
|
436
|
+
path segment, and the namespace with everything under it - `Shop.Domain.Orders`,
|
|
437
|
+
but not `Shop.DomainEvents`. A folder path such as `src/Shop.Domain` holds the
|
|
438
|
+
right files, but a using names a namespace, never a path, so nothing can reach
|
|
439
|
+
it: such a rule fails, and names a namespace the layer's files declare. Where
|
|
440
|
+
folders and namespaces differ, as when `src/Domain` holds
|
|
441
|
+
`Acme.Clean.Domain.Entities`, the name they share - `Domain` - does both.
|
|
442
|
+
- **`module=` is a namespace too**, as above: `module="Shop.Infrastructure"`
|
|
443
|
+
covers `using Shop.Infrastructure.Persistence;`.
|
|
444
|
+
- **What is read**: `using`, `global using`, `using static` and aliases, with
|
|
445
|
+
any `global::` or extern-alias qualifier left off the name. A using inside a
|
|
446
|
+
namespace may be relative to it, so `using Application.Orders;` inside
|
|
447
|
+
`namespace Shop.Domain` also counts as `Shop.Application.Orders`. Nothing in a
|
|
448
|
+
comment, a verbatim string or a raw string literal is read.
|
|
449
|
+
|
|
450
|
+
What it cannot see, and the text rule that covers each - a text rule reads a
|
|
451
|
+
name wherever it is written:
|
|
452
|
+
|
|
453
|
+
| Not seen by an import rule | Held by |
|
|
454
|
+
| --- | --- |
|
|
455
|
+
| A fully qualified name with no using: `new Shop.Infrastructure.Db()` | `@assert-absence target="src/Shop.Domain" glob="*.cs" symbol="Shop.Infrastructure" word="true"` |
|
|
456
|
+
| A `<ProjectReference>`, or a `<Using Include>` in a project file | the same rule with `glob="*.csproj,*.props"` |
|
|
457
|
+
| `@using` in `.razor` and `.cshtml`, which import rules count as files they could not read | the same rule with `glob="*.razor,*.cshtml"` |
|
|
458
|
+
| Code a source generator writes | nothing: it is not in the tree |
|
|
459
|
+
|
|
460
|
+
In a solution of projects, the project references are the layering the
|
|
461
|
+
compiler enforces - a using of a project that is not referenced does not build -
|
|
462
|
+
so a rule over the project files is worth having beside the layer rule:
|
|
463
|
+
|
|
464
|
+
```md
|
|
465
|
+
<!-- @assert-absence target="src/Shop.Domain" glob="*.csproj" regex="true" symbol="Shop\.(Application|Infrastructure|Web)\b" reason="the domain references no outer project" -->
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Keep build output out of every rule in `.spec-guard.json`:
|
|
469
|
+
|
|
470
|
+
```json
|
|
471
|
+
{
|
|
472
|
+
"specs": ["docs/**/*.md"],
|
|
473
|
+
"exclude": ["bin", "obj", "artifacts", "TestResults", ".vs"]
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
`bin` and `obj` are MSBuild's output, `artifacts` is where the output goes with
|
|
478
|
+
`UseArtifactsOutput` (.NET 8 and later), `TestResults` is where `dotnet test`
|
|
479
|
+
writes, and `.vs` holds Visual Studio's caches. A front end in the same tree
|
|
480
|
+
adds its own, such as Nuxt's `.output`; `node_modules` is skipped already.
|
|
399
481
|
|
|
400
482
|
### `@assert-import-cycle` - no file depends on itself
|
|
401
483
|
|
|
@@ -573,7 +655,7 @@ Passes when every listed path exists relative to `--root`. Directories count.
|
|
|
573
655
|
| `partner` | structure | Partner templates, any one of which must exist: `[name].test.[ext]` |
|
|
574
656
|
| `types` | import assertions, layers, cycles | `include` (default) or `ignore` for `import type` |
|
|
575
657
|
| `dynamic` | cycles | `include` (default) or `ignore` for `import('x')` |
|
|
576
|
-
| `allow-empty` | all but present | Tolerate a scope that holds no files, a layer that matches none, or no chosen directories. Off by default - see below |
|
|
658
|
+
| `allow-empty` | all but present | Tolerate a scope that holds no files, a layer that matches none, a layer no C# using can reach, layers no import crosses between, or no chosen directories. Off by default - see below |
|
|
577
659
|
| `baseline` | absence, import-absence, layers, structure | Known violations that do not count: `path` or `path:count` |
|
|
578
660
|
| `ratchet` | absence, import-absence, layers, structure | `two-sided` (default) or `one-way` - see below |
|
|
579
661
|
| `reason` | all | Human-readable justification, printed on failure |
|
|
@@ -1285,7 +1367,7 @@ prebuilt binary and is never a runtime dependency.
|
|
|
1285
1367
|
|
|
1286
1368
|
Coverage says a line ran. It does not say an assertion would notice if the line
|
|
1287
1369
|
behaved differently. This repository measures the difference: line coverage is
|
|
1288
|
-
**100%**, and **
|
|
1370
|
+
**100%**, and **99.00%** of 8,420 mutants are killed in CI, with 81 survivors and
|
|
1289
1371
|
no file below 95%. The second number is the one worth reading, and what was done
|
|
1290
1372
|
about the survivors matters more than the score. At 0.5.1 every surviving mutant
|
|
1291
1373
|
was checked individually, and the 101 left then produced byte-identical output.
|
package/dist/comments.d.ts
CHANGED
|
@@ -31,6 +31,25 @@ interface StringRule {
|
|
|
31
31
|
close: string;
|
|
32
32
|
/** Backslash escapes apply inside. */
|
|
33
33
|
escape: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* The opener is a run of its character at least `open` long, and only a run
|
|
36
|
+
* of the same length closes it: C#'s raw strings, which take `"""` or as many
|
|
37
|
+
* more quotes as their text needs to hold a `"""` of its own.
|
|
38
|
+
*/
|
|
39
|
+
run?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Rust's raw strings: `open`, any number of `#` and a quote, closed only by a
|
|
42
|
+
* quote and as many `#` - `r"…"`, `r#"…"#`, `r##"…"##`, as many as the text
|
|
43
|
+
* needs to hold a `"#` of its own. Without the quote it is no string at all:
|
|
44
|
+
* `r#match` is a raw identifier, and the `r` in `for` is a letter.
|
|
45
|
+
*/
|
|
46
|
+
hashes?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* The literal cannot hold a line break, so reaching one means it was never
|
|
49
|
+
* closed. A Rust character literal holds a single character, and rustc stops
|
|
50
|
+
* reading one at the end of its line.
|
|
51
|
+
*/
|
|
52
|
+
singleLine?: boolean;
|
|
34
53
|
}
|
|
35
54
|
export interface CommentSyntax {
|
|
36
55
|
name: string;
|
|
@@ -40,6 +59,22 @@ export interface CommentSyntax {
|
|
|
40
59
|
block: ReadonlyArray<readonly [string, string]>;
|
|
41
60
|
/** Block comments nest, as in Rust. */
|
|
42
61
|
nested: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* A quote before an identifier that no quote closes is a lifetime or a loop
|
|
64
|
+
* label, as in Rust - `'a`, `'static`, `'_`, `'outer` - and is code.
|
|
65
|
+
*/
|
|
66
|
+
lifetimes: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* A quote straight after a number is part of it: C++14 and C23 separate
|
|
69
|
+
* digits with one, `100'000`.
|
|
70
|
+
*/
|
|
71
|
+
digitSeparators: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* A line comment opens only where a word could start - at the start of a
|
|
74
|
+
* line, or after a space or a tab - as in a shell, where `${#items[@]}` and
|
|
75
|
+
* `$#` are code, and in YAML, where `a#b` is text.
|
|
76
|
+
*/
|
|
77
|
+
wordComments: boolean;
|
|
43
78
|
/** Literal forms that may contain comment-looking text. */
|
|
44
79
|
strings: readonly StringRule[];
|
|
45
80
|
}
|
|
@@ -55,10 +90,12 @@ export interface LexResult {
|
|
|
55
90
|
/** Half-open ranges of string literals, delimiters included. */
|
|
56
91
|
strings: CommentRange[];
|
|
57
92
|
/**
|
|
58
|
-
* True when a
|
|
93
|
+
* True when a literal or block comment was never closed: it ran off the end
|
|
94
|
+
* of the file, or - for a literal that cannot hold a line break - off the end
|
|
95
|
+
* of its line.
|
|
59
96
|
*
|
|
60
|
-
* The ranges are still returned - reading an unterminated literal to
|
|
61
|
-
* what a compiler does - but everything after the opening delimiter was
|
|
97
|
+
* The ranges are still returned - reading an unterminated literal to its end
|
|
98
|
+
* is what a compiler does - but everything after the opening delimiter was
|
|
62
99
|
* swallowed by it, so anything derived from this scan is missing whatever
|
|
63
100
|
* lived in there. Callers that draw conclusions from absence must say so.
|
|
64
101
|
*/
|
package/dist/comments.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../src/comments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,MAAM,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../src/comments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,0CAA0C;IAC1C,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,uCAAuC;IACvC,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;CAChC;AAgOD,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAEhE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAE9D;AAED,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAuGrD,oFAAoF;AACpF,MAAM,WAAW,SAAS;IACxB,4DAA4D;IAC5D,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gEAAgE;IAChE,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB;;;;;;;;;OASG;IACH,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,SAAS,CAkD1E;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,YAAY,EAAE,CAEnF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CACpC;AAQD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAqB/E"}
|