1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.collectSpellingDiagnostics = void 0;
|
4 | const utils_1 = require("../utils");
|
5 | const ruleId = 'spelling';
|
6 |
|
7 | const matchers = [
|
8 | {
|
9 | pattern: /\*this\* object/gu,
|
10 | message: 'prefer "*this* value"',
|
11 | },
|
12 | {
|
13 | pattern: /1's complement/gu,
|
14 | message: 'prefer "one\'s complement"',
|
15 | },
|
16 | {
|
17 | pattern: /2's complement/gu,
|
18 | message: 'prefer "two\'s complement"',
|
19 | },
|
20 | {
|
21 | pattern: /\*0\*(?!<sub>ℤ<\/sub>)/gu,
|
22 | message: 'the Number value 0 should be written "*+0*", to unambiguously exclude "*-0*"',
|
23 | },
|
24 | {
|
25 | pattern: /[+-]?(?:&[a-z]+;|0x[0-9A-Fa-f]+|[0-9]+(?:\.[0-9]+)?)<sub>𝔽<\/sub>/gu,
|
26 | message: 'literal Number values should be bolded',
|
27 | },
|
28 | {
|
29 | pattern: /[+-]?[0-9]+<sub>ℤ<\/sub>/gu,
|
30 | message: 'literal BigInt values should be bolded',
|
31 | },
|
32 | {
|
33 | pattern: /\*[+-]?(?:&[a-z]+;|0x[0-9A-Fa-f]+|[0-9]+(?:\.[0-9]+)?)\*(?!<sub>[𝔽ℤ]<\/sub>)/gu,
|
34 | message: 'literal Number or BigInt values should be followed by <sub>𝔽</sub> or <sub>ℤ</sub> respectively',
|
35 | },
|
36 | {
|
37 | pattern: /(?<=\*)\+(?:0x[1-9A-Fa-f]|[1-9])/gu,
|
38 | message: 'positive numeric values other than 0 should not have a leading plus sign (+)',
|
39 | },
|
40 | {
|
41 |
|
42 |
|
43 |
|
44 | pattern: /(?<=^|\s)\+[0-9](?![0-9]*[-:])/gu,
|
45 | message: 'positive real numbers should not have a leading plus sign (+)',
|
46 | },
|
47 | {
|
48 | pattern: /(?<![+-])∞/gu,
|
49 | message: '∞ should always be written with a leading + or -',
|
50 | },
|
51 | {
|
52 | pattern: /(?<= )[+-]\*(?:&[a-z]+;|0x[0-9A-Fa-f]+|[0-9]+(?:\.[0-9]+)?)\*/gu,
|
53 | message: 'the sign character for a numeric literal should be within the `*`s',
|
54 | },
|
55 | {
|
56 | pattern: /(?<=\bmathematical value )for\b/gu,
|
57 | message: 'the mathematical value "of", not "for"',
|
58 | },
|
59 | {
|
60 | pattern: /(?<=\b[Nn]umber value )of\b/gu,
|
61 | message: 'the Number value "for", not "of"',
|
62 | },
|
63 | {
|
64 | pattern: /\bnumber value\b/gu,
|
65 | message: '"Number value", not "number value"',
|
66 | },
|
67 | {
|
68 |
|
69 |
|
70 |
|
71 | pattern: /\b(?:[Bb]ehaviors?|[Ff]lavors?|[Hh]arbors?|[Hh]onors?|[Hh]umors?|[Ll]abors?|[Nn]eighbors?|[Rr]umors?|[Ss]plendors?)\b/gu,
|
72 | message: 'ECMA-262 uses Oxford spelling ("behaviour", etc.)',
|
73 | },
|
74 | {
|
75 | pattern: /[Ii]ndexes/gu,
|
76 | message: 'prefer "indices"',
|
77 | },
|
78 | {
|
79 | pattern: /\b[Nn]onnegative\b/gu,
|
80 | message: 'prefer "non-negative"',
|
81 | },
|
82 | {
|
83 | pattern: /\b[Nn]onzero\b/gu,
|
84 | message: 'prefer "non-zero"',
|
85 | },
|
86 | {
|
87 | pattern: /[Tt]he empty string/gu,
|
88 | message: 'prefer "the empty String"',
|
89 | },
|
90 | {
|
91 | pattern: /[ \t]+\n/gu,
|
92 | message: 'trailing spaces are not allowed',
|
93 | },
|
94 | {
|
95 | pattern: /(?<=(^|[^\n])\n\n)\n+/gu,
|
96 | message: 'no more than one blank line is allowed',
|
97 | },
|
98 | {
|
99 | pattern: /(?<=<emu-clause.*>\n)\n\s*<h1>/gu,
|
100 | message: "there should not be a blank line between a clause's opening tag and its header",
|
101 | },
|
102 | {
|
103 | pattern: /(?<=(^|[^\n])\n)\n+[ \t]*<\/emu-clause>/gu,
|
104 | message: 'there should not be a blank line between the last line of a clause and its closing tag',
|
105 | },
|
106 | {
|
107 | pattern: /\r/gu,
|
108 | message: 'only Unix-style (LF) linebreaks are allowed',
|
109 | },
|
110 | {
|
111 | pattern: /(?<=\b[Ss]teps? )\d/gu,
|
112 | message: 'prefer using labeled steps and <emu-xref> tags over hardcoding step numbers',
|
113 | },
|
114 | {
|
115 | pattern: /(?<=\b[Cc]lauses? )\d/gu,
|
116 | message: 'clauses should be referenced using <emu-xref> tags rather than hardcoding clause numbers',
|
117 | },
|
118 | {
|
119 | pattern: /(?<=\S) +(?! |<\/(td|th|dd|dt)>)/gu,
|
120 | message: 'multiple consecutive spaces are not allowed',
|
121 | },
|
122 | {
|
123 | pattern: /(?<=<[a-z]+( [a-z]+(="[^"\n]+")?)*>)(?<!(td|th|dd|dt|ins|del)>) /gu,
|
124 | message: 'tags should not contain leading whitespace',
|
125 | },
|
126 | {
|
127 | pattern: /(?<=[^ \n]) +<\/(?!td|th|dd|dt|ins|del)/gu,
|
128 | message: 'tags should not contain trailing whitespace',
|
129 | },
|
130 | {
|
131 | pattern: /(?<=< ?\*)\+0\*/gu,
|
132 | message: '"less than" comparisons against floating-point zero should use negative zero',
|
133 | },
|
134 | {
|
135 | pattern: /(?<=> ?\*)-0\*/gu,
|
136 | message: '"greater than" comparisons against floating-point zero should use positive zero',
|
137 | },
|
138 | {
|
139 | pattern: /(?<=&[lg]e; ?\*)[+-]0\*/gu,
|
140 | message: 'comparisons against floating-point zero should use strict comparisons (< or >); guard the equals case with "is"',
|
141 | },
|
142 | {
|
143 | pattern: /(÷|÷)/gu,
|
144 | message: 'division should be written as "/", not "÷", per ISO 80000-2',
|
145 | },
|
146 | ];
|
147 | function collectSpellingDiagnostics(report, mainSource, imports) {
|
148 | const composed = new RegExp(matchers.map(m => `(?:${m.pattern.source})`).join('|'), 'u');
|
149 | const toTest = [{ source: mainSource }].concat(imports);
|
150 | for (const { source, importLocation } of toTest) {
|
151 |
|
152 |
|
153 | if (composed.test(source)) {
|
154 | let reported = false;
|
155 | for (const { pattern, message } of matchers) {
|
156 | let match = pattern.exec(source);
|
157 | while (match !== null) {
|
158 | reported = true;
|
159 | const { line, column } = (0, utils_1.offsetToLineAndColumn)(source, match.index);
|
160 | report({
|
161 | type: 'raw',
|
162 | ruleId,
|
163 | line,
|
164 | column,
|
165 | message,
|
166 | source,
|
167 | file: importLocation,
|
168 | });
|
169 | match = pattern.exec(source);
|
170 | }
|
171 | }
|
172 | if (!reported) {
|
173 | throw new Error('Ecmarkup has a bug: the spell checker reported an error, but could not find one. Please report this at https://github.com/tc39/ecmarkup/issues/new.');
|
174 | }
|
175 | }
|
176 | }
|
177 | }
|
178 | exports.collectSpellingDiagnostics = collectSpellingDiagnostics;
|