@sasjs/lint 5.3.1 → 5.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -0
- package/format/adjustLineLength.d.ts +34 -0
- package/format/adjustLineLength.js +159 -0
- package/format/adjustLineLength.js.map +1 -0
- package/format/formatFile.d.ts +3 -1
- package/format/formatFile.js +4 -4
- package/format/formatFile.js.map +1 -1
- package/format/formatFolder.d.ts +3 -1
- package/format/formatFolder.js +38 -7
- package/format/formatFolder.js.map +1 -1
- package/format/formatProject.d.ts +2 -1
- package/format/formatProject.js +2 -2
- package/format/formatProject.js.map +1 -1
- package/format/formatText.d.ts +19 -1
- package/format/formatText.js +23 -3
- package/format/formatText.js.map +1 -1
- package/format/longLines.d.ts +60 -0
- package/format/longLines.js +90 -0
- package/format/longLines.js.map +1 -0
- package/format/reflowComments.d.ts +28 -0
- package/format/reflowComments.js +305 -0
- package/format/reflowComments.js.map +1 -0
- package/format/rewrapText.d.ts +38 -0
- package/format/rewrapText.js +389 -0
- package/format/rewrapText.js.map +1 -0
- package/format/shared.js +34 -5
- package/format/shared.js.map +1 -1
- package/format/splitTrailingComments.d.ts +22 -0
- package/format/splitTrailingComments.js +68 -0
- package/format/splitTrailingComments.js.map +1 -0
- package/package.json +11 -24
- package/sasjslint-schema.json +10 -1
- package/types/FormatOptions.d.ts +29 -0
- package/types/FormatOptions.js +3 -0
- package/types/FormatOptions.js.map +1 -0
- package/types/KeywordCase.d.ts +10 -0
- package/types/KeywordCase.js +13 -0
- package/types/KeywordCase.js.map +1 -0
- package/types/LintConfig.d.ts +10 -0
- package/types/LintConfig.js +17 -0
- package/types/LintConfig.js.map +1 -1
- package/types/index.d.ts +2 -0
- package/types/index.js +2 -0
- package/types/index.js.map +1 -1
- package/utils/getDataSectionsDetail.d.ts +14 -0
- package/utils/getDataSectionsDetail.js +29 -13
- package/utils/getDataSectionsDetail.js.map +1 -1
- package/utils/getLintConfig.d.ts +1 -0
- package/utils/getLintConfig.js +1 -0
- package/utils/getLintConfig.js.map +1 -1
- package/utils/scanLine.d.ts +59 -0
- package/utils/scanLine.js +115 -0
- package/utils/scanLine.js.map +1 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.breakAwareState = exports.indentationMultipleOf = exports.continuationIndentFor = exports.firstNonSpace = exports.putTextStart = exports.breakAwareStatement = exports.macroComment = exports.macroDeclaration = void 0;
|
|
4
|
+
/** A macro declaration, which the macro rules read as one statement. */
|
|
5
|
+
exports.macroDeclaration = /^\s*%(?:macro|mend)\b/i;
|
|
6
|
+
/**
|
|
7
|
+
* A macro comment statement - `%* text ;` - which is prose that happens to start
|
|
8
|
+
* with a trigger. Breaking it would put the terminator on a line of its own, and
|
|
9
|
+
* like a block comment it belongs to its author.
|
|
10
|
+
*/
|
|
11
|
+
exports.macroComment = /^\s*%\*/;
|
|
12
|
+
/**
|
|
13
|
+
* A statement whose line breaks are data rather than space between tokens.
|
|
14
|
+
*
|
|
15
|
+
* For the DATA step's `put` and `putlog`, and the macro and window statements
|
|
16
|
+
* that write text a reader sees, a break adds a line to the log or to the file
|
|
17
|
+
* being written. For `%let` a break lands inside the value, and the value keeps
|
|
18
|
+
* the newline and the continuation indent - measured on a live engine, where a
|
|
19
|
+
* wrapped `%let` message compared against a single-spaced one failed.
|
|
20
|
+
*
|
|
21
|
+
* Both are broken with the `%trim(` idiom rather than by a plain newline, and
|
|
22
|
+
* neither is left as it is: a break that carries `%trim(` adds no whitespace and
|
|
23
|
+
* no output line.
|
|
24
|
+
*/
|
|
25
|
+
exports.breakAwareStatement = /^\s*%?(?:&?[\w.]*\.)?(?:put|putlog|window|display)\b|\b(?:then|else)\s+%?put\b|^\s*%let\b/i;
|
|
26
|
+
/**
|
|
27
|
+
* The index where the text of a `put`-family statement begins, so a break is
|
|
28
|
+
* never taken before the keyword that names it.
|
|
29
|
+
*
|
|
30
|
+
* A continuation line carries no keyword of its own, and its whole content is
|
|
31
|
+
* text, so there the text begins at the first non-whitespace character.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} line - the line to read.
|
|
34
|
+
* @returns {number} the index of the first character of the statement's text.
|
|
35
|
+
*/
|
|
36
|
+
const putTextStart = (line) => {
|
|
37
|
+
const match = exports.breakAwareStatement.exec(line);
|
|
38
|
+
if (!match)
|
|
39
|
+
return (0, exports.firstNonSpace)(line, 0);
|
|
40
|
+
const afterKeyword = match.index + match[0].length;
|
|
41
|
+
// A `%let` keeps its name out of the value, so the first break belongs after
|
|
42
|
+
// the `=` rather than between the keyword and the name.
|
|
43
|
+
if (/^\s*%let\b/i.test(line)) {
|
|
44
|
+
const equals = line.indexOf('=', afterKeyword);
|
|
45
|
+
if (equals > -1)
|
|
46
|
+
return equals + 1;
|
|
47
|
+
}
|
|
48
|
+
return afterKeyword;
|
|
49
|
+
};
|
|
50
|
+
exports.putTextStart = putTextStart;
|
|
51
|
+
/** The index of the first non-whitespace character at or after `from`. */
|
|
52
|
+
const firstNonSpace = (line, from) => {
|
|
53
|
+
const rest = line.slice(from);
|
|
54
|
+
return from + rest.length - rest.trimStart().length;
|
|
55
|
+
};
|
|
56
|
+
exports.firstNonSpace = firstNonSpace;
|
|
57
|
+
/**
|
|
58
|
+
* The indentation a continuation line takes: the next multiple of
|
|
59
|
+
* `indentationMultiple` after the line's own, so a break can never introduce an
|
|
60
|
+
* `indentationMultiple` diagnostic of its own.
|
|
61
|
+
*/
|
|
62
|
+
const continuationIndentFor = (indent, multiple) => indent + ' '.repeat(multiple - (indent.length % multiple));
|
|
63
|
+
exports.continuationIndentFor = continuationIndentFor;
|
|
64
|
+
/** The indentation multiple in force, with the rule's documented default. */
|
|
65
|
+
const indentationMultipleOf = (configuration) => configuration.indentationMultiple > 0 ? configuration.indentationMultiple : 2;
|
|
66
|
+
exports.indentationMultipleOf = indentationMultipleOf;
|
|
67
|
+
/**
|
|
68
|
+
* Reads whether one line opens, or carries the continuation of, a statement
|
|
69
|
+
* whose line breaks SAS reads as output lines.
|
|
70
|
+
*
|
|
71
|
+
* Splitting the code view on `;` gives one entry per statement on the line, the
|
|
72
|
+
* last entry being the part that has not reached its own terminator.
|
|
73
|
+
*
|
|
74
|
+
* @param {string} code - the line with literals and comments blanked.
|
|
75
|
+
* @param {boolean} open - whether the previous line left such a statement open.
|
|
76
|
+
* @returns {{ line: boolean, open: boolean }} whether this line belongs to one,
|
|
77
|
+
* and whether the next line still does.
|
|
78
|
+
*/
|
|
79
|
+
const breakAwareState = (code, open) => {
|
|
80
|
+
const statements = code.split(';');
|
|
81
|
+
const at = statements.findIndex((statement) => exports.breakAwareStatement.test(statement));
|
|
82
|
+
return {
|
|
83
|
+
line: open || at > -1,
|
|
84
|
+
open: open
|
|
85
|
+
? statements.length === 1
|
|
86
|
+
: at > -1 && at === statements.length - 1
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
exports.breakAwareState = breakAwareState;
|
|
90
|
+
//# sourceMappingURL=longLines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"longLines.js","sourceRoot":"","sources":["../../src/format/longLines.ts"],"names":[],"mappings":";;;AAEA,wEAAwE;AAC3D,QAAA,gBAAgB,GAAG,wBAAwB,CAAA;AAExD;;;;GAIG;AACU,QAAA,YAAY,GAAG,SAAS,CAAA;AAErC;;;;;;;;;;;;GAYG;AACU,QAAA,mBAAmB,GAC9B,4FAA4F,CAAA;AAE9F;;;;;;;;;GASG;AACI,MAAM,YAAY,GAAG,CAAC,IAAY,EAAU,EAAE;IACnD,MAAM,KAAK,GAAG,2BAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE5C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAA,qBAAa,EAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAEzC,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IAElD,6EAA6E;IAC7E,wDAAwD;IACxD,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;QAE9C,IAAI,MAAM,GAAG,CAAC,CAAC;YAAE,OAAO,MAAM,GAAG,CAAC,CAAA;IACpC,CAAC;IAED,OAAO,YAAY,CAAA;AACrB,CAAC,CAAA;AAhBY,QAAA,YAAY,gBAgBxB;AAED,0EAA0E;AACnE,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,IAAY,EAAU,EAAE;IAClE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAE7B,OAAO,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAA;AACrD,CAAC,CAAA;AAJY,QAAA,aAAa,iBAIzB;AAED;;;;GAIG;AACI,MAAM,qBAAqB,GAAG,CACnC,MAAc,EACd,QAAgB,EACR,EAAE,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAA;AAH1D,QAAA,qBAAqB,yBAGqC;AAEvE,6EAA6E;AACtE,MAAM,qBAAqB,GAAG,CAAC,aAAyB,EAAU,EAAE,CACzE,aAAa,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAA;AADlE,QAAA,qBAAqB,yBAC6C;AAE/E;;;;;;;;;;;GAWG;AACI,MAAM,eAAe,GAAG,CAC7B,IAAY,EACZ,IAAa,EACqB,EAAE;IACpC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClC,MAAM,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,EAAE,CAC5C,2BAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CACpC,CAAA;IAED,OAAO;QACL,IAAI,EAAE,IAAI,IAAI,EAAE,GAAG,CAAC,CAAC;QACrB,IAAI,EAAE,IAAI;YACR,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;YACzB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,UAAU,CAAC,MAAM,GAAG,CAAC;KAC5C,CAAA;AACH,CAAC,CAAA;AAfY,QAAA,eAAe,mBAe3B"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { LintConfig } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Reflows the prose inside a file's block comments so that no line exceeds the
|
|
4
|
+
* limit that applies to it, and leaves every other line byte-identical.
|
|
5
|
+
*
|
|
6
|
+
* A paragraph is a run of comment lines at one indentation that carry prose. It
|
|
7
|
+
* breaks at a blank line and before anything line-oriented: an `@li` entry, a
|
|
8
|
+
* `@sasjslint` tag, an HTML heading, a list marker, a table row or a macro
|
|
9
|
+
* trigger. Wrapping one of those - or wrapping one line of a paragraph without
|
|
10
|
+
* reflowing the rest - is what leaves a header ragged. A `@brief` or `@param`
|
|
11
|
+
* line is prose, so it carries the lines that follow it.
|
|
12
|
+
*
|
|
13
|
+
* Blocks that are left entirely alone: one sharing a line with code, one inside
|
|
14
|
+
* a `datalines` record, one holding a `@example` / `@code` / `@verbatim` body,
|
|
15
|
+
* the `<h4> SAS Macros </h4>` section - whose entries other rules read and
|
|
16
|
+
* rewrite - and any block holding a `@sasjslint` tag, whose object has to stay
|
|
17
|
+
* on the line the tag opens.
|
|
18
|
+
*
|
|
19
|
+
* A paragraph is reflowed only when every line of the result fits, so the pass
|
|
20
|
+
* never raises the diagnostic count: a word longer than the limit - a URL,
|
|
21
|
+
* usually - leaves its paragraph as the author wrote it.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} text - the text to reflow.
|
|
24
|
+
* @param {LintConfig} configuration - the configuration in force, header
|
|
25
|
+
* override included.
|
|
26
|
+
* @returns {string} the reflowed text.
|
|
27
|
+
*/
|
|
28
|
+
export declare const reflowComments: (text: string, configuration: LintConfig) => string;
|
|
@@ -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;
|