@mark1russell7/ste-lint 0.0.0-bootstrap.0 → 0.1.1
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/README.md +224 -1
- package/dist/.tsbuildinfo +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +9 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +103 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +251 -0
- package/dist/config.js.map +1 -0
- package/dist/dictionary.d.ts +74 -0
- package/dist/dictionary.d.ts.map +1 -0
- package/dist/dictionary.js +169 -0
- package/dist/dictionary.js.map +1 -0
- package/dist/files.d.ts +35 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +181 -0
- package/dist/files.js.map +1 -0
- package/dist/format.d.ts +21 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +61 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/lexicon.d.ts +33 -0
- package/dist/lexicon.d.ts.map +1 -0
- package/dist/lexicon.js +71 -0
- package/dist/lexicon.js.map +1 -0
- package/dist/lint.d.ts +28 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +132 -0
- package/dist/lint.js.map +1 -0
- package/dist/rules/about-quantity.d.ts +3 -0
- package/dist/rules/about-quantity.d.ts.map +1 -0
- package/dist/rules/about-quantity.js +34 -0
- package/dist/rules/about-quantity.js.map +1 -0
- package/dist/rules/index.d.ts +8 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +35 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/ing-verb.d.ts +9 -0
- package/dist/rules/ing-verb.d.ts.map +1 -0
- package/dist/rules/ing-verb.js +60 -0
- package/dist/rules/ing-verb.js.map +1 -0
- package/dist/rules/latin-abbreviation.d.ts +3 -0
- package/dist/rules/latin-abbreviation.d.ts.map +1 -0
- package/dist/rules/latin-abbreviation.js +48 -0
- package/dist/rules/latin-abbreviation.js.map +1 -0
- package/dist/rules/missing-subject.d.ts +16 -0
- package/dist/rules/missing-subject.d.ts.map +1 -0
- package/dist/rules/missing-subject.js +138 -0
- package/dist/rules/missing-subject.js.map +1 -0
- package/dist/rules/modal-verb.d.ts +3 -0
- package/dist/rules/modal-verb.d.ts.map +1 -0
- package/dist/rules/modal-verb.js +72 -0
- package/dist/rules/modal-verb.js.map +1 -0
- package/dist/rules/noun-cluster.d.ts +17 -0
- package/dist/rules/noun-cluster.d.ts.map +1 -0
- package/dist/rules/noun-cluster.js +83 -0
- package/dist/rules/noun-cluster.js.map +1 -0
- package/dist/rules/paragraph-length.d.ts +3 -0
- package/dist/rules/paragraph-length.d.ts.map +1 -0
- package/dist/rules/paragraph-length.js +19 -0
- package/dist/rules/paragraph-length.js.map +1 -0
- package/dist/rules/passive-instruction.d.ts +15 -0
- package/dist/rules/passive-instruction.d.ts.map +1 -0
- package/dist/rules/passive-instruction.js +38 -0
- package/dist/rules/passive-instruction.js.map +1 -0
- package/dist/rules/pronouns.d.ts +4 -0
- package/dist/rules/pronouns.d.ts.map +1 -0
- package/dist/rules/pronouns.js +57 -0
- package/dist/rules/pronouns.js.map +1 -0
- package/dist/rules/rule.d.ts +46 -0
- package/dist/rules/rule.d.ts.map +1 -0
- package/dist/rules/rule.js +31 -0
- package/dist/rules/rule.js.map +1 -0
- package/dist/rules/semicolon.d.ts +3 -0
- package/dist/rules/semicolon.d.ts.map +1 -0
- package/dist/rules/semicolon.js +20 -0
- package/dist/rules/semicolon.js.map +1 -0
- package/dist/rules/sentence-length.d.ts +3 -0
- package/dist/rules/sentence-length.d.ts.map +1 -0
- package/dist/rules/sentence-length.js +31 -0
- package/dist/rules/sentence-length.js.map +1 -0
- package/dist/rules/unknown-word.d.ts +9 -0
- package/dist/rules/unknown-word.d.ts.map +1 -0
- package/dist/rules/unknown-word.js +49 -0
- package/dist/rules/unknown-word.js.map +1 -0
- package/dist/rules/word-list-matcher.d.ts +25 -0
- package/dist/rules/word-list-matcher.d.ts.map +1 -0
- package/dist/rules/word-list-matcher.js +60 -0
- package/dist/rules/word-list-matcher.js.map +1 -0
- package/dist/rules/word-list.d.ts +3 -0
- package/dist/rules/word-list.d.ts.map +1 -0
- package/dist/rules/word-list.js +26 -0
- package/dist/rules/word-list.js.map +1 -0
- package/dist/run-cli.d.ts +27 -0
- package/dist/run-cli.d.ts.map +1 -0
- package/dist/run-cli.js +176 -0
- package/dist/run-cli.js.map +1 -0
- package/dist/source/blocks.d.ts +55 -0
- package/dist/source/blocks.d.ts.map +1 -0
- package/dist/source/blocks.js +464 -0
- package/dist/source/blocks.js.map +1 -0
- package/dist/source/inline.d.ts +42 -0
- package/dist/source/inline.d.ts.map +1 -0
- package/dist/source/inline.js +396 -0
- package/dist/source/inline.js.map +1 -0
- package/dist/source/jsx.d.ts +18 -0
- package/dist/source/jsx.d.ts.map +1 -0
- package/dist/source/jsx.js +137 -0
- package/dist/source/jsx.js.map +1 -0
- package/dist/source/lines.d.ts +34 -0
- package/dist/source/lines.d.ts.map +1 -0
- package/dist/source/lines.js +83 -0
- package/dist/source/lines.js.map +1 -0
- package/dist/source/markdown.d.ts +23 -0
- package/dist/source/markdown.d.ts.map +1 -0
- package/dist/source/markdown.js +42 -0
- package/dist/source/markdown.js.map +1 -0
- package/dist/source/suppressions.d.ts +38 -0
- package/dist/source/suppressions.d.ts.map +1 -0
- package/dist/source/suppressions.js +69 -0
- package/dist/source/suppressions.js.map +1 -0
- package/dist/source/tsdoc.d.ts +40 -0
- package/dist/source/tsdoc.d.ts.map +1 -0
- package/dist/source/tsdoc.js +176 -0
- package/dist/source/tsdoc.js.map +1 -0
- package/dist/text/grammar.d.ts +91 -0
- package/dist/text/grammar.d.ts.map +1 -0
- package/dist/text/grammar.js +289 -0
- package/dist/text/grammar.js.map +1 -0
- package/dist/text/phrases.d.ts +30 -0
- package/dist/text/phrases.d.ts.map +1 -0
- package/dist/text/phrases.js +65 -0
- package/dist/text/phrases.js.map +1 -0
- package/dist/text/sentences.d.ts +45 -0
- package/dist/text/sentences.d.ts.map +1 -0
- package/dist/text/sentences.js +141 -0
- package/dist/text/sentences.js.map +1 -0
- package/dist/text/tokens.d.ts +35 -0
- package/dist/text/tokens.d.ts.map +1 -0
- package/dist/text/tokens.js +113 -0
- package/dist/text/tokens.js.map +1 -0
- package/dist/text/words.d.ts +58 -0
- package/dist/text/words.d.ts.map +1 -0
- package/dist/text/words.js +159 -0
- package/dist/text/words.js.map +1 -0
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +20 -0
- package/dist/types.js.map +1 -0
- package/dist/units.d.ts +47 -0
- package/dist/units.d.ts.map +1 -0
- package/dist/units.js +42 -0
- package/dist/units.js.map +1 -0
- package/dist/word-list.d.ts +34 -0
- package/dist/word-list.d.ts.map +1 -0
- package/dist/word-list.js +90 -0
- package/dist/word-list.js.map +1 -0
- package/package.json +41 -4
- package/src/cli.ts +9 -0
- package/src/config.test.ts +188 -0
- package/src/config.ts +318 -0
- package/src/dictionary.test.ts +82 -0
- package/src/dictionary.ts +177 -0
- package/src/files.test.ts +107 -0
- package/src/files.ts +191 -0
- package/src/format.ts +78 -0
- package/src/index.test.ts +28 -0
- package/src/index.ts +34 -0
- package/src/lexicon.ts +92 -0
- package/src/lint.test.ts +182 -0
- package/src/lint.ts +135 -0
- package/src/rules/about-quantity.ts +33 -0
- package/src/rules/index.ts +40 -0
- package/src/rules/ing-verb.test.ts +48 -0
- package/src/rules/ing-verb.ts +54 -0
- package/src/rules/latin-abbreviation.ts +46 -0
- package/src/rules/missing-subject.test.ts +53 -0
- package/src/rules/missing-subject.ts +129 -0
- package/src/rules/modal-verb.test.ts +45 -0
- package/src/rules/modal-verb.ts +72 -0
- package/src/rules/noun-cluster.test.ts +49 -0
- package/src/rules/noun-cluster.ts +82 -0
- package/src/rules/paragraph-length.test.ts +30 -0
- package/src/rules/paragraph-length.ts +19 -0
- package/src/rules/passive-instruction.test.ts +38 -0
- package/src/rules/passive-instruction.ts +37 -0
- package/src/rules/pronouns.test.ts +38 -0
- package/src/rules/pronouns.ts +54 -0
- package/src/rules/punctuation.test.ts +59 -0
- package/src/rules/rule.ts +73 -0
- package/src/rules/semicolon.ts +19 -0
- package/src/rules/sentence-length.test.ts +52 -0
- package/src/rules/sentence-length.ts +32 -0
- package/src/rules/unknown-word.test.ts +81 -0
- package/src/rules/unknown-word.ts +43 -0
- package/src/rules/word-list-matcher.ts +68 -0
- package/src/rules/word-list.test.ts +110 -0
- package/src/rules/word-list.ts +25 -0
- package/src/run-cli.test.ts +189 -0
- package/src/run-cli.ts +193 -0
- package/src/source/blocks.ts +534 -0
- package/src/source/inline.test.ts +92 -0
- package/src/source/inline.ts +416 -0
- package/src/source/jsx.test.ts +46 -0
- package/src/source/jsx.ts +147 -0
- package/src/source/lines.test.ts +51 -0
- package/src/source/lines.ts +91 -0
- package/src/source/markdown.test.ts +210 -0
- package/src/source/markdown.ts +49 -0
- package/src/source/suppressions.ts +79 -0
- package/src/source/tsdoc.test.ts +137 -0
- package/src/source/tsdoc.ts +189 -0
- package/src/text/grammar.ts +304 -0
- package/src/text/phrases.ts +72 -0
- package/src/text/sentences.ts +148 -0
- package/src/text/text.test.ts +262 -0
- package/src/text/tokens.ts +135 -0
- package/src/text/words.ts +183 -0
- package/src/types.ts +39 -0
- package/src/units.ts +86 -0
- package/src/word-list.ts +128 -0
- package/ste.config.schema.json +87 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This function divides `text` into lines. The offset of each line starts at
|
|
3
|
+
* `base`. A `\r` before a `\n` is not part of the line text.
|
|
4
|
+
*/
|
|
5
|
+
export function splitLines(text, base = 0) {
|
|
6
|
+
const lines = [];
|
|
7
|
+
let start = 0;
|
|
8
|
+
for (let i = 0; i <= text.length; i++) {
|
|
9
|
+
if (i === text.length || text[i] === "\n") {
|
|
10
|
+
let end = i;
|
|
11
|
+
if (end > start && text[end - 1] === "\r")
|
|
12
|
+
end--;
|
|
13
|
+
lines.push({ text: text.slice(start, end), offset: base + start });
|
|
14
|
+
start = i + 1;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return lines;
|
|
18
|
+
}
|
|
19
|
+
/** This index changes file offsets into 1-based line and column numbers. */
|
|
20
|
+
export class LineIndex {
|
|
21
|
+
starts = [0];
|
|
22
|
+
constructor(text) {
|
|
23
|
+
for (let i = 0; i < text.length; i++) {
|
|
24
|
+
if (text[i] === "\n")
|
|
25
|
+
this.starts.push(i + 1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** The line and column of `offset`. */
|
|
29
|
+
position(offset) {
|
|
30
|
+
let low = 0;
|
|
31
|
+
let high = this.starts.length - 1;
|
|
32
|
+
while (low < high) {
|
|
33
|
+
const middle = (low + high + 1) >> 1;
|
|
34
|
+
if (this.starts[middle] <= offset)
|
|
35
|
+
low = middle;
|
|
36
|
+
else
|
|
37
|
+
high = middle - 1;
|
|
38
|
+
}
|
|
39
|
+
return { line: low + 1, column: offset - this.starts[low] + 1 };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** The number of columns of indentation at the start of `text`. A tab moves to the next multiple of 4. */
|
|
43
|
+
export function indentWidth(text) {
|
|
44
|
+
let width = 0;
|
|
45
|
+
for (const char of text) {
|
|
46
|
+
if (char === " ")
|
|
47
|
+
width++;
|
|
48
|
+
else if (char === "\t")
|
|
49
|
+
width += 4 - (width % 4);
|
|
50
|
+
else
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
return width;
|
|
54
|
+
}
|
|
55
|
+
/** The part of `line` after the first `count` characters. The offset moves with the text. */
|
|
56
|
+
export function sliceLine(line, count) {
|
|
57
|
+
const n = Math.min(Math.max(count, 0), line.text.length);
|
|
58
|
+
return { text: line.text.slice(n), offset: line.offset + n };
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The part of `line` after `columns` columns of indentation. The function
|
|
62
|
+
* removes fewer characters when the line has less indentation.
|
|
63
|
+
*/
|
|
64
|
+
export function stripIndent(line, columns) {
|
|
65
|
+
let width = 0;
|
|
66
|
+
let i = 0;
|
|
67
|
+
while (i < line.text.length && width < columns) {
|
|
68
|
+
const char = line.text[i];
|
|
69
|
+
if (char === " ")
|
|
70
|
+
width++;
|
|
71
|
+
else if (char === "\t")
|
|
72
|
+
width += 4 - (width % 4);
|
|
73
|
+
else
|
|
74
|
+
break;
|
|
75
|
+
i++;
|
|
76
|
+
}
|
|
77
|
+
return sliceLine(line, i);
|
|
78
|
+
}
|
|
79
|
+
/** True when the line has only white space. */
|
|
80
|
+
export function isBlank(text) {
|
|
81
|
+
return text.trim().length === 0;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.js","sourceRoot":"","sources":["../../src/source/lines.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prose extraction from Markdown and MDX files.
|
|
3
|
+
*/
|
|
4
|
+
import type { ExtractedBlock } from "../units.js";
|
|
5
|
+
import { type ProseBlock } from "./blocks.js";
|
|
6
|
+
import { type Line } from "./lines.js";
|
|
7
|
+
import { type Suppression } from "./suppressions.js";
|
|
8
|
+
export type Extraction = {
|
|
9
|
+
readonly blocks: readonly ExtractedBlock[];
|
|
10
|
+
readonly suppressions: readonly Suppression[];
|
|
11
|
+
};
|
|
12
|
+
/** This function removes YAML (`---`) or TOML (`+++`) front matter at the start of the file. */
|
|
13
|
+
export declare function stripFrontMatter(lines: readonly Line[]): readonly Line[];
|
|
14
|
+
/** The file offsets of the first and the last character of a block. */
|
|
15
|
+
export declare function blockRange(block: ProseBlock): {
|
|
16
|
+
start: number;
|
|
17
|
+
end: number;
|
|
18
|
+
};
|
|
19
|
+
/** This function extracts the prose blocks and the suppressions of a Markdown or MDX file. */
|
|
20
|
+
export declare function extractMarkdown(text: string, options: {
|
|
21
|
+
readonly mdx: boolean;
|
|
22
|
+
}): Extraction;
|
|
23
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/source/markdown.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAc,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAwB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG;IACrB,QAAQ,CAAC,MAAM,EAAG,SAAS,cAAc,EAAE,CAAC;IAC5C,QAAQ,CAAC,YAAY,EAAG,SAAS,WAAW,EAAE,CAAC;CAClD,CAAC;AAEF,gGAAgG;AAChG,wBAAgB,gBAAgB,CAAC,KAAK,EAAG,SAAS,IAAI,EAAE,GAAI,SAAS,IAAI,EAAE,CAQ1E;AAED,uEAAuE;AACvE,wBAAgB,UAAU,CAAC,KAAK,EAAG,UAAU,GAAI;IAAE,KAAK,EAAG,MAAM,CAAC;IAAC,GAAG,EAAG,MAAM,CAAA;CAAE,CAIhF;AAED,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,IAAI,EAAG,MAAM,EAAE,OAAO,EAAG;IAAE,QAAQ,CAAC,GAAG,EAAG,OAAO,CAAA;CAAE,GAAI,UAAU,CAehG"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prose extraction from Markdown and MDX files.
|
|
3
|
+
*/
|
|
4
|
+
import { parseBlocks } from "./blocks.js";
|
|
5
|
+
import { splitLines } from "./lines.js";
|
|
6
|
+
import { SuppressionCollector } from "./suppressions.js";
|
|
7
|
+
/** This function removes YAML (`---`) or TOML (`+++`) front matter at the start of the file. */
|
|
8
|
+
export function stripFrontMatter(lines) {
|
|
9
|
+
const first = lines[0]?.text.trimEnd();
|
|
10
|
+
if (first !== "---" && first !== "+++")
|
|
11
|
+
return lines;
|
|
12
|
+
for (let i = 1; i < lines.length; i++) {
|
|
13
|
+
const text = lines[i].text.trimEnd();
|
|
14
|
+
if (text === first || (first === "---" && text === "..."))
|
|
15
|
+
return lines.slice(i + 1);
|
|
16
|
+
}
|
|
17
|
+
return lines;
|
|
18
|
+
}
|
|
19
|
+
/** The file offsets of the first and the last character of a block. */
|
|
20
|
+
export function blockRange(block) {
|
|
21
|
+
const first = block.lines[0];
|
|
22
|
+
const last = block.lines[block.lines.length - 1];
|
|
23
|
+
return { start: first.offset, end: last.offset + last.text.length };
|
|
24
|
+
}
|
|
25
|
+
/** This function extracts the prose blocks and the suppressions of a Markdown or MDX file. */
|
|
26
|
+
export function extractMarkdown(text, options) {
|
|
27
|
+
const lines = stripFrontMatter(splitLines(text));
|
|
28
|
+
const collector = new SuppressionCollector();
|
|
29
|
+
const blocks = [];
|
|
30
|
+
const origin = { source: options.mdx ? "mdx" : "markdown", tsdocSection: null, tsdocTag: null };
|
|
31
|
+
for (const block of parseBlocks(lines, options)) {
|
|
32
|
+
if (block.kind === "directive") {
|
|
33
|
+
collector.directive(block);
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const range = blockRange(block);
|
|
37
|
+
collector.block(range.start, range.end);
|
|
38
|
+
blocks.push({ block, origin });
|
|
39
|
+
}
|
|
40
|
+
return { blocks, suppressions: collector.finish(text.length) };
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/source/markdown.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,WAAW,EAAmB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAoB,MAAM,mBAAmB,CAAC;AAO3E,gGAAgG;AAChG,MAAM,UAAU,gBAAgB,CAAC,KAAuB;IACpD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IACvC,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACrD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACtC,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,UAAU,CAAC,KAAkB;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;IAClD,OAAO,EAAE,KAAK,EAAG,KAAK,CAAC,MAAM,EAAE,GAAG,EAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;AAC1E,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,eAAe,CAAC,IAAa,EAAE,OAAoC;IAC/E,MAAM,KAAK,GAAG,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,MAAM,MAAM,GAAG,EAAE,MAAM,EAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAc,CAAC,CAAC,CAAC,UAAmB,EAAE,YAAY,EAAG,IAAI,EAAE,QAAQ,EAAG,IAAI,EAAE,CAAC;IACrH,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;QAC9C,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7B,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC3B,SAAS;QACb,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAChC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Directive } from "./blocks.js";
|
|
2
|
+
/** A range of the file in which some rules (or all rules) do not report findings. */
|
|
3
|
+
export type Suppression = {
|
|
4
|
+
readonly start: number;
|
|
5
|
+
readonly end: number;
|
|
6
|
+
/** The rule IDs, or null for all rules. */
|
|
7
|
+
readonly rules: ReadonlySet<string> | null;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* This class collects suppressions from directive comments:
|
|
11
|
+
*
|
|
12
|
+
* - `ste-disable [rules]` starts a range. `ste-enable [rules]` stops it.
|
|
13
|
+
* Without an `ste-enable`, the range continues to the end of the file.
|
|
14
|
+
* - `ste-disable-next [rules]` applies to the next block only: the next
|
|
15
|
+
* paragraph, heading, list item or table row in Markdown, or the next doc
|
|
16
|
+
* comment in TypeScript.
|
|
17
|
+
*
|
|
18
|
+
* Without rule IDs, a directive applies to all rules.
|
|
19
|
+
*/
|
|
20
|
+
export declare class SuppressionCollector {
|
|
21
|
+
private readonly ranges;
|
|
22
|
+
private readonly open;
|
|
23
|
+
private pending;
|
|
24
|
+
directive(directive: Directive): void;
|
|
25
|
+
/**
|
|
26
|
+
* A plain `ste-enable` stops all open ranges. An `ste-enable` with rule
|
|
27
|
+
* IDs stops those rules only. A range for all rules stops only at a
|
|
28
|
+
* plain `ste-enable`.
|
|
29
|
+
*/
|
|
30
|
+
private enable;
|
|
31
|
+
/** This method tells the collector about the next block, so that a pending `ste-disable-next` applies to it. */
|
|
32
|
+
block(start: number, end: number): void;
|
|
33
|
+
/** The suppressions. Open ranges stop at `fileEnd`. */
|
|
34
|
+
finish(fileEnd: number): Suppression[];
|
|
35
|
+
}
|
|
36
|
+
/** True when a suppression covers a finding of `rule` at `offset`. */
|
|
37
|
+
export declare function isSuppressed(suppressions: readonly Suppression[], rule: string, offset: number): boolean;
|
|
38
|
+
//# sourceMappingURL=suppressions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppressions.d.ts","sourceRoot":"","sources":["../../src/source/suppressions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,qFAAqF;AACrF,MAAM,MAAM,WAAW,GAAG;IACtB,QAAQ,CAAC,KAAK,EAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAG,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,EAAG,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;CAC/C,CAAC;AAIF;;;;;;;;;;GAUG;AACH,qBAAa,oBAAoB;IAC7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAoB;IACzC,OAAO,CAAC,OAAO,CAA8C;IAE7D,SAAS,CAAC,SAAS,EAAG,SAAS,GAAI,IAAI;IAWvC;;;;OAIG;IACH,OAAO,CAAC,MAAM;IAkBd,gHAAgH;IAChH,KAAK,CAAC,KAAK,EAAG,MAAM,EAAE,GAAG,EAAG,MAAM,GAAI,IAAI;IAM1C,uDAAuD;IACvD,MAAM,CAAC,OAAO,EAAG,MAAM,GAAI,WAAW,EAAE;CAG3C;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,YAAY,EAAG,SAAS,WAAW,EAAE,EAAE,IAAI,EAAG,MAAM,EAAE,MAAM,EAAG,MAAM,GAAI,OAAO,CAE5G"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This class collects suppressions from directive comments:
|
|
3
|
+
*
|
|
4
|
+
* - `ste-disable [rules]` starts a range. `ste-enable [rules]` stops it.
|
|
5
|
+
* Without an `ste-enable`, the range continues to the end of the file.
|
|
6
|
+
* - `ste-disable-next [rules]` applies to the next block only: the next
|
|
7
|
+
* paragraph, heading, list item or table row in Markdown, or the next doc
|
|
8
|
+
* comment in TypeScript.
|
|
9
|
+
*
|
|
10
|
+
* Without rule IDs, a directive applies to all rules.
|
|
11
|
+
*/
|
|
12
|
+
export class SuppressionCollector {
|
|
13
|
+
ranges = [];
|
|
14
|
+
open = [];
|
|
15
|
+
pending = undefined;
|
|
16
|
+
directive(directive) {
|
|
17
|
+
const rules = directive.rules.length === 0 ? null : new Set(directive.rules);
|
|
18
|
+
if (directive.command === "disable-next") {
|
|
19
|
+
this.pending = rules;
|
|
20
|
+
}
|
|
21
|
+
else if (directive.command === "disable") {
|
|
22
|
+
this.open.push({ start: directive.offset, rules });
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
this.enable(directive.offset, rules);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A plain `ste-enable` stops all open ranges. An `ste-enable` with rule
|
|
30
|
+
* IDs stops those rules only. A range for all rules stops only at a
|
|
31
|
+
* plain `ste-enable`.
|
|
32
|
+
*/
|
|
33
|
+
enable(offset, rules) {
|
|
34
|
+
for (let i = this.open.length - 1; i >= 0; i--) {
|
|
35
|
+
const range = this.open[i];
|
|
36
|
+
if (rules === null) {
|
|
37
|
+
this.ranges.push({ start: range.start, end: offset, rules: range.rules });
|
|
38
|
+
this.open.splice(i, 1);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (range.rules === null)
|
|
42
|
+
continue;
|
|
43
|
+
const closing = [...range.rules].filter((rule) => rules.has(rule));
|
|
44
|
+
if (closing.length === 0)
|
|
45
|
+
continue;
|
|
46
|
+
this.ranges.push({ start: range.start, end: offset, rules: new Set(closing) });
|
|
47
|
+
this.open.splice(i, 1);
|
|
48
|
+
const remaining = [...range.rules].filter((rule) => !rules.has(rule));
|
|
49
|
+
if (remaining.length > 0)
|
|
50
|
+
this.open.push({ start: range.start, rules: new Set(remaining) });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** This method tells the collector about the next block, so that a pending `ste-disable-next` applies to it. */
|
|
54
|
+
block(start, end) {
|
|
55
|
+
if (this.pending === undefined)
|
|
56
|
+
return;
|
|
57
|
+
this.ranges.push({ start, end, rules: this.pending });
|
|
58
|
+
this.pending = undefined;
|
|
59
|
+
}
|
|
60
|
+
/** The suppressions. Open ranges stop at `fileEnd`. */
|
|
61
|
+
finish(fileEnd) {
|
|
62
|
+
return [...this.ranges, ...this.open.map((range) => ({ start: range.start, end: fileEnd, rules: range.rules }))];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** True when a suppression covers a finding of `rule` at `offset`. */
|
|
66
|
+
export function isSuppressed(suppressions, rule, offset) {
|
|
67
|
+
return suppressions.some((range) => offset >= range.start && offset <= range.end && (range.rules === null || range.rules.has(rule)));
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=suppressions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppressions.js","sourceRoot":"","sources":["../../src/source/suppressions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prose extraction from the doc comments (`/** ... *\/`) of TypeScript and
|
|
3
|
+
* JavaScript files.
|
|
4
|
+
*
|
|
5
|
+
* The TypeScript compiler parses the file. The extractor then examines only
|
|
6
|
+
* the trivia between tokens. Thus, text in strings, template literals,
|
|
7
|
+
* regular expressions and JSX does not become a comment.
|
|
8
|
+
*/
|
|
9
|
+
import type { TsdocSection } from "../units.js";
|
|
10
|
+
import { type Line } from "./lines.js";
|
|
11
|
+
import type { Extraction } from "./markdown.js";
|
|
12
|
+
export type CommentKind = "line" | "block" | "doc";
|
|
13
|
+
export type CommentRange = {
|
|
14
|
+
readonly kind: CommentKind;
|
|
15
|
+
/** The file offset of the first `/`. */
|
|
16
|
+
readonly pos: number;
|
|
17
|
+
/** The file offset after the comment. */
|
|
18
|
+
readonly end: number;
|
|
19
|
+
};
|
|
20
|
+
/** This function finds all comments in a file. The comments come in file order. */
|
|
21
|
+
export declare function collectComments(text: string, fileName: string): CommentRange[];
|
|
22
|
+
/**
|
|
23
|
+
* This function removes the comment syntax from the lines of a doc comment:
|
|
24
|
+
*
|
|
25
|
+
* - `/**` on the first line
|
|
26
|
+
* - `*\/` on the last line
|
|
27
|
+
* - The `*` and one space at the start of the other lines.
|
|
28
|
+
*/
|
|
29
|
+
export declare function docCommentLines(text: string, comment: CommentRange): Line[];
|
|
30
|
+
type Section = {
|
|
31
|
+
readonly section: TsdocSection;
|
|
32
|
+
readonly tag: string | null;
|
|
33
|
+
readonly lines: Line[];
|
|
34
|
+
};
|
|
35
|
+
/** This function divides the lines of a doc comment into the summary and the block tag sections. */
|
|
36
|
+
export declare function splitSections(lines: readonly Line[]): Section[];
|
|
37
|
+
/** This function extracts the prose blocks of the doc comments of a file, and the suppressions. */
|
|
38
|
+
export declare function extractTsdoc(text: string, fileName: string): Extraction;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=tsdoc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsdoc.d.ts","sourceRoot":"","sources":["../../src/source/tsdoc.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAA+B,YAAY,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,EAAyB,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAEnD,MAAM,MAAM,YAAY,GAAG;IACvB,QAAQ,CAAC,IAAI,EAAG,WAAW,CAAC;IAC5B,wCAAwC;IACxC,QAAQ,CAAC,GAAG,EAAG,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,GAAG,EAAG,MAAM,CAAC;CACzB,CAAC;AA8BF,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,IAAI,EAAG,MAAM,EAAE,QAAQ,EAAG,MAAM,GAAI,YAAY,EAAE,CAsCjF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAG,MAAM,EAAE,OAAO,EAAG,YAAY,GAAI,IAAI,EAAE,CAQ9E;AAED,KAAK,OAAO,GAAG;IACX,QAAQ,CAAC,OAAO,EAAG,YAAY,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAG,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAG,IAAI,EAAE,CAAC;CAC3B,CAAC;AAaF,oGAAoG;AACpG,wBAAgB,aAAa,CAAC,KAAK,EAAG,SAAS,IAAI,EAAE,GAAI,OAAO,EAAE,CAgCjE;AAED,mGAAmG;AACnG,wBAAgB,YAAY,CAAC,IAAI,EAAG,MAAM,EAAE,QAAQ,EAAG,MAAM,GAAI,UAAU,CAuB1E"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prose extraction from the doc comments (`/** ... *\/`) of TypeScript and
|
|
3
|
+
* JavaScript files.
|
|
4
|
+
*
|
|
5
|
+
* The TypeScript compiler parses the file. The extractor then examines only
|
|
6
|
+
* the trivia between tokens. Thus, text in strings, template literals,
|
|
7
|
+
* regular expressions and JSX does not become a comment.
|
|
8
|
+
*/
|
|
9
|
+
import ts from "typescript";
|
|
10
|
+
import { parseBlocks, parseDirective } from "./blocks.js";
|
|
11
|
+
import { sliceLine, splitLines } from "./lines.js";
|
|
12
|
+
import { SuppressionCollector } from "./suppressions.js";
|
|
13
|
+
/** Tags whose content is not prose: code, values, names and other data. */
|
|
14
|
+
const SKIPPED_TAGS = new Set([
|
|
15
|
+
"example", "default", "defaultvalue", "since", "version", "author", "license", "module", "category",
|
|
16
|
+
"group", "file", "fileoverview", "overview", "typedef", "type", "callback", "enum", "class", "constructor",
|
|
17
|
+
"extends", "augments", "implements", "satisfies", "overload", "import", "link", "linkcode", "linkplain",
|
|
18
|
+
"jsx", "jsxfrag", "jsximportsource", "jsxruntime", "ts-check", "ts-nocheck", "ts-ignore", "ts-expect-error",
|
|
19
|
+
"vitest-environment", "jest-environment", "eslint-disable", "copyright", "summary-only",
|
|
20
|
+
]);
|
|
21
|
+
/** Tags whose content is the same type of text as the summary. */
|
|
22
|
+
const REMARKS_TAGS = new Set(["remarks", "privateremarks", "description", "summary", "classdesc"]);
|
|
23
|
+
/** Tags that have a name before their text: `@param name - text`. */
|
|
24
|
+
const NAMED_TAGS = new Set(["param", "typeparam", "template", "property", "prop", "arg", "argument"]);
|
|
25
|
+
/** Tags that can have a type before their text: `@throws {Error} text`. */
|
|
26
|
+
const TYPED_TAGS = new Set(["returns", "return", "throws", "exception", "yields", "yield"]);
|
|
27
|
+
const TAG_LINE = /^[ \t]*@([A-Za-z][\w-]*)(?=[\s{]|$)/;
|
|
28
|
+
function scriptKind(fileName) {
|
|
29
|
+
const lower = fileName.toLowerCase();
|
|
30
|
+
if (lower.endsWith(".tsx"))
|
|
31
|
+
return ts.ScriptKind.TSX;
|
|
32
|
+
if (lower.endsWith(".jsx"))
|
|
33
|
+
return ts.ScriptKind.JSX;
|
|
34
|
+
if (/\.[mc]?js$/.test(lower))
|
|
35
|
+
return ts.ScriptKind.JS;
|
|
36
|
+
return ts.ScriptKind.TS;
|
|
37
|
+
}
|
|
38
|
+
/** This function finds all comments in a file. The comments come in file order. */
|
|
39
|
+
export function collectComments(text, fileName) {
|
|
40
|
+
const sourceFile = ts.createSourceFile(fileName, text, ts.ScriptTarget.Latest, true, scriptKind(fileName));
|
|
41
|
+
const comments = [];
|
|
42
|
+
const scanTrivia = (from, to) => {
|
|
43
|
+
let i = from;
|
|
44
|
+
if (i === 0 && text.startsWith("#!")) {
|
|
45
|
+
const lineEnd = text.indexOf("\n");
|
|
46
|
+
i = lineEnd === -1 ? to : lineEnd;
|
|
47
|
+
}
|
|
48
|
+
while (i < to) {
|
|
49
|
+
if (text[i] === "/" && text[i + 1] === "/") {
|
|
50
|
+
const lineEnd = text.indexOf("\n", i);
|
|
51
|
+
const end = lineEnd === -1 || lineEnd > to ? to : lineEnd;
|
|
52
|
+
comments.push({ kind: "line", pos: i, end });
|
|
53
|
+
i = end;
|
|
54
|
+
}
|
|
55
|
+
else if (text[i] === "/" && text[i + 1] === "*") {
|
|
56
|
+
const close = text.indexOf("*/", i + 2);
|
|
57
|
+
const end = close === -1 ? to : Math.min(close + 2, to);
|
|
58
|
+
const isDoc = text.startsWith("/**", i) && !text.startsWith("/**/", i);
|
|
59
|
+
comments.push({ kind: isDoc ? "doc" : "block", pos: i, end });
|
|
60
|
+
i = end;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
i++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const isJsDoc = (node) => node.kind >= ts.SyntaxKind.FirstJSDocNode && node.kind <= ts.SyntaxKind.LastJSDocNode;
|
|
68
|
+
const visit = (node) => {
|
|
69
|
+
// A token can have a JSDoc child, for example the end-of-file token after a final doc comment. It is still a token.
|
|
70
|
+
const children = node.getChildren(sourceFile).filter((child) => !isJsDoc(child));
|
|
71
|
+
if (children.length === 0) {
|
|
72
|
+
scanTrivia(node.getFullStart(), node.getStart(sourceFile));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
for (const child of children)
|
|
76
|
+
visit(child);
|
|
77
|
+
};
|
|
78
|
+
visit(sourceFile);
|
|
79
|
+
return comments;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* This function removes the comment syntax from the lines of a doc comment:
|
|
83
|
+
*
|
|
84
|
+
* - `/**` on the first line
|
|
85
|
+
* - `*\/` on the last line
|
|
86
|
+
* - The `*` and one space at the start of the other lines.
|
|
87
|
+
*/
|
|
88
|
+
export function docCommentLines(text, comment) {
|
|
89
|
+
const inner = text.slice(comment.pos + 3, Math.max(comment.pos + 3, comment.end - 2));
|
|
90
|
+
return splitLines(inner, comment.pos + 3).map((line, index) => {
|
|
91
|
+
if (index === 0)
|
|
92
|
+
return line;
|
|
93
|
+
const prefix = /^[ \t]*\*(?!\/)[ \t]?/.exec(line.text);
|
|
94
|
+
if (prefix)
|
|
95
|
+
return sliceLine(line, prefix[0].length);
|
|
96
|
+
return sliceLine(line, line.text.length - line.text.trimStart().length);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/** This function removes the tag, and the type and the name after the tag, from the first line of a block tag. */
|
|
100
|
+
function tagContent(line, tag, tagEnd) {
|
|
101
|
+
const rest = sliceLine(line, tagEnd);
|
|
102
|
+
const lower = tag.toLowerCase();
|
|
103
|
+
let prefix;
|
|
104
|
+
if (NAMED_TAGS.has(lower))
|
|
105
|
+
prefix = /^\s*(?:\{[^}]*\}\s*)?(?:\[[^\]]*\]|[\w$.]+)?\s*(?:-\s+|-$)?/;
|
|
106
|
+
else if (TYPED_TAGS.has(lower))
|
|
107
|
+
prefix = /^\s*(?:\{[^}]*\}\s*)?(?:-\s+)?/;
|
|
108
|
+
else
|
|
109
|
+
prefix = /^\s*(?:-\s+)?/;
|
|
110
|
+
return sliceLine(rest, prefix.exec(rest.text)[0].length);
|
|
111
|
+
}
|
|
112
|
+
/** This function divides the lines of a doc comment into the summary and the block tag sections. */
|
|
113
|
+
export function splitSections(lines) {
|
|
114
|
+
const sections = [];
|
|
115
|
+
let current = { section: "summary", tag: null, lines: [] };
|
|
116
|
+
let fence = null;
|
|
117
|
+
for (const line of lines) {
|
|
118
|
+
const fenceMatch = /^[ \t]*(`{3,}|~{3,})/.exec(line.text);
|
|
119
|
+
if (fence !== null) {
|
|
120
|
+
if (fenceMatch && fenceMatch[1][0] === fence[0] && fenceMatch[1].length >= fence.length)
|
|
121
|
+
fence = null;
|
|
122
|
+
current?.lines.push(line);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (fenceMatch)
|
|
126
|
+
fence = fenceMatch[1];
|
|
127
|
+
const tag = fence === null ? TAG_LINE.exec(line.text) : null;
|
|
128
|
+
if (tag === null) {
|
|
129
|
+
current?.lines.push(line);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (current !== null)
|
|
133
|
+
sections.push(current);
|
|
134
|
+
const name = tag[1];
|
|
135
|
+
const lower = name.toLowerCase();
|
|
136
|
+
if (SKIPPED_TAGS.has(lower)) {
|
|
137
|
+
current = null;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
current = {
|
|
141
|
+
section: REMARKS_TAGS.has(lower) ? "remarks" : "tag",
|
|
142
|
+
tag: name,
|
|
143
|
+
lines: [tagContent(line, name, tag[0].length)],
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (current !== null)
|
|
147
|
+
sections.push(current);
|
|
148
|
+
return sections.filter((section) => section.lines.length > 0);
|
|
149
|
+
}
|
|
150
|
+
/** This function extracts the prose blocks of the doc comments of a file, and the suppressions. */
|
|
151
|
+
export function extractTsdoc(text, fileName) {
|
|
152
|
+
const collector = new SuppressionCollector();
|
|
153
|
+
const blocks = [];
|
|
154
|
+
for (const comment of collectComments(text, fileName)) {
|
|
155
|
+
if (comment.kind !== "doc") {
|
|
156
|
+
const body = comment.kind === "line" ? text.slice(comment.pos + 2, comment.end) : text.slice(comment.pos + 2, comment.end - 2);
|
|
157
|
+
const directive = parseDirective(body, comment.pos);
|
|
158
|
+
if (directive !== null)
|
|
159
|
+
collector.directive(directive);
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
collector.block(comment.pos, comment.end);
|
|
163
|
+
for (const section of splitSections(docCommentLines(text, comment))) {
|
|
164
|
+
const origin = { source: "tsdoc", tsdocSection: section.section, tsdocTag: section.tag };
|
|
165
|
+
for (const block of parseBlocks(section.lines, { mdx: false })) {
|
|
166
|
+
if (block.kind === "directive") {
|
|
167
|
+
collector.directive(block);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
blocks.push({ block, origin });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return { blocks, suppressions: collector.finish(text.length) };
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=tsdoc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsdoc.js","sourceRoot":"","sources":["../../src/source/tsdoc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grammar heuristics. The linter has no part-of-speech tagger. These
|
|
3
|
+
* functions look at the words near a word to guess its function. Each
|
|
4
|
+
* heuristic prefers to miss a problem than to report a false one.
|
|
5
|
+
*/
|
|
6
|
+
import { type Token } from "./tokens.js";
|
|
7
|
+
/**
|
|
8
|
+
* The possible base forms of a word: the word itself, and the word without
|
|
9
|
+
* the endings -s, -es, -ies, -ed, -d, -ied and -ing. The list can contain
|
|
10
|
+
* forms that are not words. The callers look up each form in a word list.
|
|
11
|
+
*/
|
|
12
|
+
export declare function lemmas(word: string): string[];
|
|
13
|
+
/** True when one of the base forms of `word` is in `words`. */
|
|
14
|
+
export declare function hasLemmaIn(word: string, words: ReadonlySet<string>): boolean;
|
|
15
|
+
/** True when `word` can be a past participle: an irregular participle, or a word that ends in -ed. */
|
|
16
|
+
export declare function isParticiple(word: string): boolean;
|
|
17
|
+
/** True for a word that is an auxiliary verb: a form of "be", "have" or "do", or a modal verb. */
|
|
18
|
+
export declare function isAuxiliary(token: Token | undefined): boolean;
|
|
19
|
+
/** The index of the next token that is a word or a placeholder, or -1. */
|
|
20
|
+
export declare function nextCounted(tokens: readonly Token[], from: number): number;
|
|
21
|
+
/** True when the token can start the object of a verb: a determiner, a pronoun, a number, a placeholder or an adverb. */
|
|
22
|
+
export declare function startsObject(token: Token | undefined): boolean;
|
|
23
|
+
export type ImperativeOptions = {
|
|
24
|
+
/** Base forms of verbs, for example the common verbs and the technical verbs of the glossary. */
|
|
25
|
+
readonly verbs: ReadonlySet<string>;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* True when the sentence is an instruction (imperative). The heuristic:
|
|
29
|
+
*
|
|
30
|
+
* 1. Skip the adverbs at the start, for example "then", "first" and "please".
|
|
31
|
+
* 2. If the sentence starts with a condition or purpose clause ("If ...,",
|
|
32
|
+
* "To ...,", "When ...,"), continue after the first comma.
|
|
33
|
+
* 3. "Do not", "Never", "Make sure" and "Be sure" start an instruction.
|
|
34
|
+
* 4. Otherwise, the first word must be the base form of a known verb. The
|
|
35
|
+
* next words must not show that the first word is a noun subject. Thus,
|
|
36
|
+
* the next word is not an auxiliary verb or "of". Also, the next two
|
|
37
|
+
* words are not a plural noun and a verb ("Test runs take 5 s").
|
|
38
|
+
*/
|
|
39
|
+
export declare function isInstruction(tokens: readonly Token[], options: ImperativeOptions): boolean;
|
|
40
|
+
export type VerbUseOptions = {
|
|
41
|
+
readonly verbs: ReadonlySet<string>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* True when the word at `index` is likely a verb, not a noun or an
|
|
45
|
+
* adjective. The heuristic is conservative. It is true only when the words
|
|
46
|
+
* near the word show a verb. It looks at these words:
|
|
47
|
+
*
|
|
48
|
+
* - The word before. These words show a verb: "to", a modal verb, a form
|
|
49
|
+
* of "do", a subject pronoun, a form of "be" or "have" (for participles).
|
|
50
|
+
* - The start of the sentence, for an imperative
|
|
51
|
+
* - The word after, for an -s form: an object, for example "the", a
|
|
52
|
+
* pronoun, code or a number
|
|
53
|
+
* - A determiner before the word, which shows a noun ("the call", "a run").
|
|
54
|
+
*/
|
|
55
|
+
export declare function isVerbUse(tokens: readonly Token[], index: number, options: VerbUseOptions): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* True when the -ing word at `index` is a verb. The heuristic finds four
|
|
58
|
+
* uses:
|
|
59
|
+
*
|
|
60
|
+
* - After a form of "be": "is running", "is still running"
|
|
61
|
+
* - After a preposition, with an object: "by calling `stop()`", "after
|
|
62
|
+
* waiting for the worker"
|
|
63
|
+
* - At the start of a clause, with an object: "Using the worker, ..."
|
|
64
|
+
* - After a word that is not a determiner, with an object (a reduced
|
|
65
|
+
* clause): "a timer firing every 5 ms".
|
|
66
|
+
*
|
|
67
|
+
* A noun ("the timing") or an adjective before a noun ("existing code")
|
|
68
|
+
* is not a verb use.
|
|
69
|
+
*/
|
|
70
|
+
export declare function isIngVerbUse(tokens: readonly Token[], index: number): boolean;
|
|
71
|
+
/** True when the token is the first word of the sentence or the first word after a comma, colon or opening parenthesis. */
|
|
72
|
+
export declare function isClauseStart(tokens: readonly Token[], index: number): boolean;
|
|
73
|
+
export type Passive = {
|
|
74
|
+
/** The index of the first word of the construction: the modal verb, "has" in "has to be", or the form of "be". */
|
|
75
|
+
readonly start: number;
|
|
76
|
+
/** The index of the form of "be" or "get". */
|
|
77
|
+
readonly auxiliary: number;
|
|
78
|
+
/** The index of the past participle. */
|
|
79
|
+
readonly participle: number;
|
|
80
|
+
/** True when a modal verb or "has to", "needs to" or "is to" shows an obligation: "must be set". */
|
|
81
|
+
readonly obligation: boolean;
|
|
82
|
+
/** True when a modal verb or "to" comes before "be": "can be set", "to be set". */
|
|
83
|
+
readonly modal: boolean;
|
|
84
|
+
/** True when "by" comes after the participle. */
|
|
85
|
+
readonly agent: boolean;
|
|
86
|
+
/** True when a condition word ("if", "when", "make sure that") comes before, in the same clause. */
|
|
87
|
+
readonly inCondition: boolean;
|
|
88
|
+
};
|
|
89
|
+
/** This function finds the passive constructions in a sentence: a form of "be" or "get" and a past participle. */
|
|
90
|
+
export declare function findPassives(tokens: readonly Token[]): Passive[];
|
|
91
|
+
//# sourceMappingURL=grammar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../../src/text/grammar.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAA+B,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAqBtE;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAG,MAAM,GAAI,MAAM,EAAE,CAwB/C;AAED,+DAA+D;AAC/D,wBAAgB,UAAU,CAAC,IAAI,EAAG,MAAM,EAAE,KAAK,EAAG,WAAW,CAAC,MAAM,CAAC,GAAI,OAAO,CAE/E;AAED,sGAAsG;AACtG,wBAAgB,YAAY,CAAC,IAAI,EAAG,MAAM,GAAI,OAAO,CAGpD;AAED,kGAAkG;AAClG,wBAAgB,WAAW,CAAC,KAAK,EAAG,KAAK,GAAG,SAAS,GAAI,OAAO,CAE/D;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,MAAM,EAAG,SAAS,KAAK,EAAE,EAAE,IAAI,EAAG,MAAM,GAAI,MAAM,CAG7E;AAOD,yHAAyH;AACzH,wBAAgB,YAAY,CAAC,KAAK,EAAG,KAAK,GAAG,SAAS,GAAI,OAAO,CAShE;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC5B,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAG,WAAW,CAAC,MAAM,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAG,SAAS,KAAK,EAAE,EAAE,OAAO,EAAG,iBAAiB,GAAI,OAAO,CA6B9F;AAED,MAAM,MAAM,cAAc,GAAG;IACzB,QAAQ,CAAC,KAAK,EAAG,WAAW,CAAC,MAAM,CAAC,CAAC;CACxC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAG,SAAS,KAAK,EAAE,EAAE,KAAK,EAAG,MAAM,EAAE,OAAO,EAAG,cAAc,GAAI,OAAO,CAyCvG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAG,SAAS,KAAK,EAAE,EAAE,KAAK,EAAG,MAAM,GAAI,OAAO,CAahF;AAED,2HAA2H;AAC3H,wBAAgB,aAAa,CAAC,MAAM,EAAG,SAAS,KAAK,EAAE,EAAE,KAAK,EAAG,MAAM,GAAI,OAAO,CAOjF;AAED,MAAM,MAAM,OAAO,GAAG;IAClB,kHAAkH;IAClH,QAAQ,CAAC,KAAK,EAAG,MAAM,CAAC;IACxB,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAG,MAAM,CAAC;IAC5B,wCAAwC;IACxC,QAAQ,CAAC,UAAU,EAAG,MAAM,CAAC;IAC7B,oGAAoG;IACpG,QAAQ,CAAC,UAAU,EAAG,OAAO,CAAC;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAG,OAAO,CAAC;IACzB,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAG,OAAO,CAAC;IACzB,oGAAoG;IACpG,QAAQ,CAAC,WAAW,EAAG,OAAO,CAAC;CAClC,CAAC;AAIF,kHAAkH;AAClH,wBAAgB,YAAY,CAAC,MAAM,EAAG,SAAS,KAAK,EAAE,GAAI,OAAO,EAAE,CA+BlE"}
|