@sasjs/lint 5.3.0 → 5.4.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,305 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reflowComments = void 0;
4
+ const LineEndings_1 = require("../types/LineEndings");
5
+ const getDataSectionsDetail_1 = require("../utils/getDataSectionsDetail");
6
+ const getHeaderLinesCount_1 = require("../utils/getHeaderLinesCount");
7
+ const scanLine_1 = require("../utils/scanLine");
8
+ const longLines_1 = require("./longLines");
9
+ const rewrapText_1 = require("./rewrapText");
10
+ /**
11
+ * What begins a new paragraph: any Doxygen tag - so `@param y` never joins the
12
+ * `@param x` above it - an HTML heading, a list marker, a table row and a macro
13
+ * trigger.
14
+ *
15
+ * A run of spaces is not in this list: two spaces after a full stop is ordinary
16
+ * prose, and treating it as structure would leave every sentence-spaced
17
+ * paragraph wrapped one line at a time. A reflow therefore normalises the runs
18
+ * inside the paragraph it rewrites.
19
+ */
20
+ const startsParagraph = /^(?:@|<|[-*+]\s|\d+[.)]\s|\||#|%|`)/i;
21
+ /**
22
+ * What is not prose at all, and so is never reflowed even when it is a
23
+ * paragraph of its own: an `@li` entry - whose continuation line would end the
24
+ * list the header readers parse - a `@sasjslint` object, a heading, a list
25
+ * item, a table row, and a macro trigger.
26
+ */
27
+ const lineOriented = /^(?:@li\b|@sasjslint\b|<|[-*+]\s|\d+[.)]\s|\||#|%|`)/i;
28
+ /** A tag whose body is code rather than prose. */
29
+ const codeTag = /@(?:example|code|verbatim)\b/i;
30
+ /** The heading whose `@li` entries other rules read and rewrite. */
31
+ const macrosHeading = /<h4>\s*SAS Macros\s*<\/h4>/i;
32
+ /** The width of a line's leading whitespace. */
33
+ const indentOf = (text) => /^\s*/.exec(text)[0].length;
34
+ /**
35
+ * Wraps one paragraph's words into lines that fit, or returns `null` when a
36
+ * word is longer than the room its line has - there is no break inside a word,
37
+ * so the paragraph is left as the author wrote it.
38
+ */
39
+ const wrapWords = (content, limit, lead, continuationIndent, trail) => {
40
+ const words = content.split(/\s+/).filter(Boolean);
41
+ const lines = [];
42
+ let line = lead;
43
+ let empty = true;
44
+ for (const word of words) {
45
+ const candidate = empty ? lead + word : line + ' ' + word;
46
+ if (empty || candidate.length <= limit) {
47
+ line = candidate;
48
+ empty = false;
49
+ continue;
50
+ }
51
+ lines.push(line);
52
+ line = continuationIndent + word;
53
+ }
54
+ lines.push(line);
55
+ // The closing marker rides on the last line, so that line has `trail.length`
56
+ // fewer characters to spend: pull words down until the marker fits, and give
57
+ // up when the last line is a single word that cannot move.
58
+ while (lines[lines.length - 1].length + trail.length > limit) {
59
+ const last = lines[lines.length - 1];
60
+ const cut = last.lastIndexOf(' ');
61
+ if (cut < 1 || !last.slice(0, cut).trim())
62
+ return null;
63
+ lines[lines.length - 1] = last.slice(0, cut);
64
+ lines.push(continuationIndent + last.slice(cut + 1));
65
+ }
66
+ lines[lines.length - 1] += trail;
67
+ return lines.every((wrapped) => wrapped.length <= limit) ? lines : null;
68
+ };
69
+ /**
70
+ * Collects the block comments of a file that occupy whole lines, so that a
71
+ * comment sharing a line with code - which a reflow would have to move the code
72
+ * around - is left alone.
73
+ *
74
+ * A block opens on a line with nothing but whitespace before its marker, closes
75
+ * on a line with nothing but whitespace after the closing marker, and covers no
76
+ * line that carries code. Text inside a `datalines` record is data rather than
77
+ * SAS, so a marker there is data and never opens a block.
78
+ *
79
+ * @param {string[]} lines - the file's lines.
80
+ * @param {LintConfig} configuration - the configuration in force.
81
+ * @returns {Block[]} the blocks a reflow may edit.
82
+ */
83
+ const collectBlocks = (lines, configuration) => {
84
+ const blocks = [];
85
+ const dataSections = (0, getDataSectionsDetail_1.getDataSectionsDetail)(lines.join('\n'), configuration);
86
+ let state = (0, scanLine_1.cleanState)();
87
+ let index = 0;
88
+ while (index < lines.length) {
89
+ // A data record is data, so it is not scanned and it closes whatever the
90
+ // line before it left open: a comment marker inside a record would
91
+ // otherwise hide every comment block below it.
92
+ if ((0, getDataSectionsDetail_1.checkIsDataLine)(dataSections, index)) {
93
+ state = (0, scanLine_1.cleanState)();
94
+ index++;
95
+ continue;
96
+ }
97
+ const scanned = (0, scanLine_1.scanLine)(lines[index], state);
98
+ state = scanned.endState;
99
+ const span = scanned.comments[0];
100
+ const opensHere = !!span &&
101
+ scanned.comments.length === 1 &&
102
+ lines[index].slice(0, span.start).trim() === '';
103
+ if (!opensHere) {
104
+ index++;
105
+ continue;
106
+ }
107
+ if (span.end < lines[index].length) {
108
+ if (lines[index].slice(span.end + 2).trim() === '') {
109
+ blocks.push({ open: index, close: index });
110
+ }
111
+ index++;
112
+ continue;
113
+ }
114
+ // The comment continues: walk forward to the line carrying its closer. A
115
+ // block that runs to the end of the file has no closer to re-emit, and one
116
+ // that covers a line of code cannot be edited without moving that code, so
117
+ // both are left to their author.
118
+ let close = index;
119
+ let closed = false;
120
+ let usable = true;
121
+ while (usable && !closed && close < lines.length - 1) {
122
+ close++;
123
+ if ((0, getDataSectionsDetail_1.checkIsDataLine)(dataSections, close)) {
124
+ usable = false;
125
+ break;
126
+ }
127
+ const next = (0, scanLine_1.scanLine)(lines[close], state);
128
+ state = next.endState;
129
+ if (next.code.trim() !== '') {
130
+ usable = false;
131
+ break;
132
+ }
133
+ const closing = next.comments[0];
134
+ if (closing && closing.end < lines[close].length) {
135
+ closed = true;
136
+ usable = lines[close].slice(closing.end + 2).trim() === '';
137
+ }
138
+ }
139
+ if (usable && closed)
140
+ blocks.push({ open: index, close });
141
+ index = close + 1;
142
+ }
143
+ return blocks;
144
+ };
145
+ /**
146
+ * Splits a block into its lines, and works out the indentation its continuation
147
+ * lines use - which is where a reflow puts the text it does not fit on the
148
+ * first line.
149
+ *
150
+ * The opener is a special case in both directions: it carries the marker, so
151
+ * its text starts after `/* `, and a comment written as `/* text` on one line
152
+ * with its body indented below it is one paragraph, not two.
153
+ */
154
+ const readBlock = (lines, block, multiple) => {
155
+ const openLine = lines[block.open];
156
+ const marker = openLine.indexOf('/*');
157
+ // `/**` is one marker, so the second asterisk belongs to the lead.
158
+ const afterMarker = marker + 2 + (openLine[marker + 2] === '*' ? 1 : 0);
159
+ const openRest = openLine.slice(afterMarker);
160
+ const openLead = afterMarker + indentOf(openRest);
161
+ const closer = block.open === block.close ? openLine.indexOf('*/') : -1;
162
+ const openBody = openLine.slice(openLead, closer > -1 ? closer : undefined);
163
+ const openContent = openBody.trimEnd();
164
+ const read = [
165
+ {
166
+ raw: openLine,
167
+ lead: openLine.slice(0, openLead),
168
+ content: openContent,
169
+ trail: openBody.slice(openContent.length) +
170
+ (closer > -1 ? openLine.slice(closer) : ''),
171
+ indent: indentOf(openLine)
172
+ }
173
+ ];
174
+ for (let index = block.open + 1; index <= block.close; index++) {
175
+ const line = lines[index];
176
+ const lead = /^\s*/.exec(line)[0];
177
+ const close = index === block.close ? line.indexOf('*/') : -1;
178
+ const body = line.slice(lead.length, close > -1 ? close : undefined);
179
+ const content = body.trimEnd();
180
+ read.push({
181
+ raw: line,
182
+ lead,
183
+ content,
184
+ trail: body.slice(content.length) + (close > -1 ? line.slice(close) : ''),
185
+ indent: lead.length
186
+ });
187
+ }
188
+ // The opener shares its paragraph with the line below it, when that line
189
+ // carries text: that is the indentation its continuation takes. When the line
190
+ // below is blank the opener stands alone, and its continuation is one
191
+ // `indentationMultiple` in from the marker.
192
+ const below = read[1];
193
+ const contentIndent = below !== undefined && below.content !== ''
194
+ ? below.indent
195
+ : indentOf(openLine) + (multiple - (indentOf(openLine) % multiple));
196
+ return { read, contentIndent };
197
+ };
198
+ /**
199
+ * Reflows the prose inside a file's block comments so that no line exceeds the
200
+ * limit that applies to it, and leaves every other line byte-identical.
201
+ *
202
+ * A paragraph is a run of comment lines at one indentation that carry prose. It
203
+ * breaks at a blank line and before anything line-oriented: an `@li` entry, a
204
+ * `@sasjslint` tag, an HTML heading, a list marker, a table row or a macro
205
+ * trigger. Wrapping one of those - or wrapping one line of a paragraph without
206
+ * reflowing the rest - is what leaves a header ragged. A `@brief` or `@param`
207
+ * line is prose, so it carries the lines that follow it.
208
+ *
209
+ * Blocks that are left entirely alone: one sharing a line with code, one inside
210
+ * a `datalines` record, one holding a `@example` / `@code` / `@verbatim` body,
211
+ * the `<h4> SAS Macros </h4>` section - whose entries other rules read and
212
+ * rewrite - and any block holding a `@sasjslint` tag, whose object has to stay
213
+ * on the line the tag opens.
214
+ *
215
+ * A paragraph is reflowed only when every line of the result fits, so the pass
216
+ * never raises the diagnostic count: a word longer than the limit - a URL,
217
+ * usually - leaves its paragraph as the author wrote it.
218
+ *
219
+ * @param {string} text - the text to reflow.
220
+ * @param {LintConfig} configuration - the configuration in force, header
221
+ * override included.
222
+ * @returns {string} the reflowed text.
223
+ */
224
+ const reflowComments = (text, configuration) => {
225
+ if (!text)
226
+ return text;
227
+ if (!configuration.lineLintRules.some((rule) => rule.name === 'maxLineLength'))
228
+ return text;
229
+ const entries = (0, rewrapText_1.splitWithTerminators)(text);
230
+ const lines = entries.map((entry) => entry.line);
231
+ const headerLinesCount = (0, getHeaderLinesCount_1.getHeaderLinesCount)(text, configuration);
232
+ const multiple = (0, longLines_1.indentationMultipleOf)(configuration);
233
+ const headerLimit = Math.max(configuration.maxLineLength, configuration.maxHeaderLineLength);
234
+ const defaultEnding = configuration.lineEndings === LineEndings_1.LineEndings.CRLF ? '\r\n' : '\n';
235
+ const output = [];
236
+ let cursor = 0;
237
+ const emitTo = (index) => {
238
+ while (cursor < index && cursor < lines.length) {
239
+ output.push(lines[cursor] + entries[cursor].ending);
240
+ cursor++;
241
+ }
242
+ };
243
+ for (const block of collectBlocks(lines, configuration)) {
244
+ const { read, contentIndent } = readBlock(lines, block, multiple);
245
+ const limit = block.open < headerLinesCount ? headerLimit : configuration.maxLineLength;
246
+ const blockText = read.map((line) => line.raw).join('\n');
247
+ const refused = macrosHeading.test(blockText) ||
248
+ codeTag.test(blockText) ||
249
+ read.some((line) => /@sasjslint\b/.test(line.content));
250
+ if (refused)
251
+ continue;
252
+ emitTo(block.open);
253
+ const emitted = [];
254
+ let paragraph = [];
255
+ let paragraphIndent = -1;
256
+ const flush = () => {
257
+ if (!paragraph.length)
258
+ return;
259
+ const last = paragraph[paragraph.length - 1];
260
+ const overlong = !lineOriented.test(paragraph[0].content) &&
261
+ paragraph.some((line) => line.lead.length + line.content.length + line.trail.length > limit);
262
+ const content = paragraph.map((line) => line.content).join(' ');
263
+ const wrapped = overlong
264
+ ? wrapWords(content, limit, paragraph[0].lead, ' '.repeat(paragraphIndent), last.trail)
265
+ : null;
266
+ if (wrapped)
267
+ emitted.push(...wrapped);
268
+ else
269
+ emitted.push(...paragraph.map((line) => line.raw));
270
+ paragraph = [];
271
+ paragraphIndent = -1;
272
+ };
273
+ read.forEach((line, index) => {
274
+ if (line.content === '') {
275
+ flush();
276
+ emitted.push(line.raw);
277
+ return;
278
+ }
279
+ if (paragraph.length) {
280
+ const continues = index > 0 &&
281
+ line.indent === paragraphIndent &&
282
+ !startsParagraph.test(line.content);
283
+ if (!continues)
284
+ flush();
285
+ }
286
+ if (!paragraph.length)
287
+ paragraphIndent = index === 0 ? contentIndent : line.indent;
288
+ paragraph.push(line);
289
+ });
290
+ flush();
291
+ // Lines inserted inside the block take the block's own final terminator, so
292
+ // a CRLF file keeps CRLF even with `lineEndings` off.
293
+ const blockEnding = entries[block.close].ending || defaultEnding;
294
+ emitted.forEach((line, index) => {
295
+ const ending = index === emitted.length - 1 ? entries[block.close].ending : blockEnding;
296
+ output.push(line + ending);
297
+ });
298
+ cursor = block.close + 1;
299
+ }
300
+ emitTo(lines.length);
301
+ const result = output.join('');
302
+ return result === text ? text : result;
303
+ };
304
+ exports.reflowComments = reflowComments;
305
+ //# sourceMappingURL=reflowComments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reflowComments.js","sourceRoot":"","sources":["../../src/format/reflowComments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { LintConfig } from '../types';
2
+ /**
3
+ * The lines of the text, each paired with the terminator that follows it.
4
+ *
5
+ * The terminator is kept rather than assumed, so a line a pass does not touch
6
+ * keeps its own bytes - including in a file whose endings are mixed, and in a
7
+ * file that has no final terminator at all.
8
+ */
9
+ export declare const splitWithTerminators: (text: string) => {
10
+ line: string;
11
+ ending: string;
12
+ }[];
13
+ /**
14
+ * Wraps the lines of a file that exceed `maxLineLength`, and leaves every other
15
+ * line byte-identical.
16
+ *
17
+ * Lines that are left alone, because a break would change what SAS reads or
18
+ * what another rule has to parse:
19
+ *
20
+ * - `datalines` / `cards` / `parmcards` records, and the statement that opens
21
+ * them, where a newline ends the record;
22
+ * - `%macro` and `%mend` declarations, which the macro rules read as one
23
+ * statement;
24
+ * - a `%*` comment statement, which is prose;
25
+ * - a `put` / `putlog` / `%put` / `%window` / `%display` statement and every
26
+ * line of it, where a newline is a line of output rather than a delimiter;
27
+ * - any line that carries a block comment, which `reflowComments` owns.
28
+ *
29
+ * A line is wrapped only when every line it becomes fits the limit, so the pass
30
+ * never turns one diagnostic into two.
31
+ *
32
+ * @param {string} text - the text to rewrap.
33
+ * @param {LintConfig} configuration - the configuration in force, header
34
+ * override included.
35
+ * @returns {string} the rewrapped text, with every untouched line's own
36
+ * terminator preserved.
37
+ */
38
+ export declare const rewrapText: (text: string, configuration: LintConfig) => string;