@so1ve/eslint-plugin 4.1.7 → 4.2.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/dist/index.d.mts +25 -83
- package/dist/index.mjs +13 -1254
- package/dist/rules/function-style.d.mts +8 -0
- package/dist/rules/function-style.mjs +145 -0
- package/dist/rules/html-spaced-comment.d.mts +8 -0
- package/dist/rules/html-spaced-comment.mjs +41 -0
- package/dist/rules/import-dedupe.d.mts +8 -0
- package/dist/rules/import-dedupe.mjs +42 -0
- package/dist/rules/import-export-newline.d.mts +8 -0
- package/dist/rules/import-export-newline.mjs +98 -0
- package/dist/rules/no-import-promises-as.d.mts +8 -0
- package/dist/rules/no-import-promises-as.mjs +45 -0
- package/dist/rules/no-inline-type-modifier.d.mts +8 -0
- package/dist/rules/no-inline-type-modifier.mjs +86 -0
- package/dist/rules/no-negated-comparison.d.mts +8 -0
- package/dist/rules/no-negated-comparison.mjs +45 -0
- package/dist/rules/no-useless-template-string.d.mts +8 -0
- package/dist/rules/no-useless-template-string.mjs +30 -0
- package/dist/rules/prefer-ts-expect-error.d.mts +8 -0
- package/dist/rules/prefer-ts-expect-error.mjs +46 -0
- package/dist/rules/require-async-with-await.d.mts +8 -0
- package/dist/rules/require-async-with-await.mjs +51 -0
- package/dist/rules/sort-exports.d.mts +8 -0
- package/dist/rules/sort-exports.mjs +68 -0
- package/dist/rules/sort-imports.d.mts +10 -0
- package/dist/rules/sort-imports.mjs +104 -0
- package/dist/rules/vue-root-element-sort-attributes.d.mts +11 -0
- package/dist/rules/vue-root-element-sort-attributes.mjs +66 -0
- package/dist/utils/index.mjs +19 -0
- package/dist/utils/sort-imports.mjs +417 -0
- package/package.json +1 -1
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import natsort from "natsort";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/sort-imports.ts
|
|
4
|
+
const NEWLINE = /(\r?\n)/;
|
|
5
|
+
const hasNewline = (text) => NEWLINE.test(text);
|
|
6
|
+
function guessNewline(sourceCode) {
|
|
7
|
+
const match = NEWLINE.exec(sourceCode.text);
|
|
8
|
+
return match == null ? "\n" : match[0];
|
|
9
|
+
}
|
|
10
|
+
const withCode = (token, sourceCode) => ({
|
|
11
|
+
...token,
|
|
12
|
+
code: sourceCode.getText(token)
|
|
13
|
+
});
|
|
14
|
+
function parseWhitespace(whitespace) {
|
|
15
|
+
const allItems = whitespace.split(NEWLINE);
|
|
16
|
+
return (allItems.length >= 5 ? [...allItems.slice(0, 2), ...allItems.slice(-1)] : allItems).map((spacesOrNewline, index) => index % 2 === 0 ? {
|
|
17
|
+
type: "Spaces",
|
|
18
|
+
code: spacesOrNewline
|
|
19
|
+
} : {
|
|
20
|
+
type: "Newline",
|
|
21
|
+
code: spacesOrNewline
|
|
22
|
+
}).filter((token) => token.code !== "");
|
|
23
|
+
}
|
|
24
|
+
const naturalSort = ("default" in natsort ? natsort.default : natsort)();
|
|
25
|
+
function compare(path1, path2) {
|
|
26
|
+
const path1Depth = path1.split("-").filter((p) => p === "__").length;
|
|
27
|
+
const path2Depth = path2.split("-").filter((p) => p === "__").length;
|
|
28
|
+
const path1IsDot = path1 === "_-,";
|
|
29
|
+
const path2IsDot = path2 === "_-,";
|
|
30
|
+
if (path1IsDot && !path2IsDot) return 1;
|
|
31
|
+
if (path2IsDot && !path1IsDot) return -1;
|
|
32
|
+
return path1Depth === path2Depth ? naturalSort(path1, path2) : path2Depth - path1Depth;
|
|
33
|
+
}
|
|
34
|
+
const isIdentifier = (node) => node.type === "Identifier";
|
|
35
|
+
const isKeyword = (node) => node.type === "Keyword";
|
|
36
|
+
const isPunctuator = (node, value) => node.type === "Punctuator" && typeof node.value === "string" && node.value === value;
|
|
37
|
+
const isBlockComment = (node) => node.type === "Block";
|
|
38
|
+
const isLineComment = (node) => node.type === "Line";
|
|
39
|
+
const isSpaces = (node) => node.type === "Spaces";
|
|
40
|
+
const isNewline = (node) => node.type === "Newline";
|
|
41
|
+
const getImportExportKind = (node) => node.importKind ?? node.exportKind ?? "value";
|
|
42
|
+
function getSource(node) {
|
|
43
|
+
const source = String(node.source.value);
|
|
44
|
+
return {
|
|
45
|
+
source: source.replace(/^[./]*\.$/, "$&/").replace(/^[./]*\/$/, "$&,").replace(/[./_-]/g, (char) => {
|
|
46
|
+
switch (char) {
|
|
47
|
+
case ".": return "_";
|
|
48
|
+
case "/": return "-";
|
|
49
|
+
case "_": return ".";
|
|
50
|
+
case "-": return "/";
|
|
51
|
+
default: throw new Error(`Unknown source substitution character: ${char}`);
|
|
52
|
+
}
|
|
53
|
+
}),
|
|
54
|
+
originalSource: source,
|
|
55
|
+
kind: getImportExportKind(node)
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
function findLastIndex(array, fn) {
|
|
59
|
+
for (let index = array.length - 1; index >= 0; index--) if (fn(array[index], index, array)) return index;
|
|
60
|
+
return -1;
|
|
61
|
+
}
|
|
62
|
+
const flatMap = (array, fn) => array.flatMap((item, index) => fn(item, index));
|
|
63
|
+
function getAllTokens(node, sourceCode) {
|
|
64
|
+
const tokens = sourceCode.getTokens(node);
|
|
65
|
+
const lastTokenIndex = tokens.length - 1;
|
|
66
|
+
return flatMap(tokens, (token, tokenIndex) => {
|
|
67
|
+
const newToken = withCode(token, sourceCode);
|
|
68
|
+
if (tokenIndex === lastTokenIndex) return [newToken];
|
|
69
|
+
const comments = sourceCode.getCommentsAfter(token);
|
|
70
|
+
const last = comments.length > 0 ? comments[comments.length - 1] : token;
|
|
71
|
+
const nextToken = tokens[tokenIndex + 1];
|
|
72
|
+
return [
|
|
73
|
+
newToken,
|
|
74
|
+
...flatMap(comments, (comment, commentIndex) => {
|
|
75
|
+
const previous = commentIndex === 0 ? token : comments[commentIndex - 1];
|
|
76
|
+
return [...parseWhitespace(sourceCode.text.slice(previous.range[1], comment.range[0])), withCode(comment, sourceCode)];
|
|
77
|
+
}),
|
|
78
|
+
...parseWhitespace(sourceCode.text.slice(last.range[1], nextToken.range[0]))
|
|
79
|
+
];
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const printTokens = (tokens) => tokens.map((token) => token.code).join("");
|
|
83
|
+
const removeBlankLines = (whitespace) => printTokens(parseWhitespace(whitespace));
|
|
84
|
+
function printCommentsBefore(node, comments, sourceCode) {
|
|
85
|
+
const lastIndex = comments.length - 1;
|
|
86
|
+
return comments.map((comment, index) => {
|
|
87
|
+
const next = index === lastIndex ? node : comments[index + 1];
|
|
88
|
+
return sourceCode.getText(comment) + removeBlankLines(sourceCode.text.slice(comment.range[1], next.range[0]));
|
|
89
|
+
}).join("");
|
|
90
|
+
}
|
|
91
|
+
const printCommentsAfter = (node, comments, sourceCode) => comments.map((comment, index) => {
|
|
92
|
+
const previous = index === 0 ? node : comments[index - 1];
|
|
93
|
+
return removeBlankLines(sourceCode.text.slice(previous.range[1], comment.range[0])) + sourceCode.getText(comment);
|
|
94
|
+
}).join("");
|
|
95
|
+
function getIndentationAt(index, sourceCode) {
|
|
96
|
+
const lines = sourceCode.text.slice(0, index).split(NEWLINE);
|
|
97
|
+
const linePrefix = lines[lines.length - 1];
|
|
98
|
+
return /^\s*$/u.test(linePrefix) ? linePrefix : "";
|
|
99
|
+
}
|
|
100
|
+
function getTrailingSpacesAt(index, sourceCode) {
|
|
101
|
+
const { text } = sourceCode;
|
|
102
|
+
let end = index;
|
|
103
|
+
while (end < text.length) {
|
|
104
|
+
const char = text[end];
|
|
105
|
+
if (char === " " || char === " ") {
|
|
106
|
+
end++;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
return text.slice(index, end);
|
|
112
|
+
}
|
|
113
|
+
const sortImportExportItems = (items) => [...items].sort((itemA, itemB) => itemA.isSideEffectImport && itemB.isSideEffectImport ? itemA.index - itemB.index : itemA.isSideEffectImport ? -1 : itemB.isSideEffectImport ? 1 : compare(itemA.source.source, itemB.source.source) || compare(itemA.source.originalSource, itemB.source.originalSource) || compare(itemA.source.kind, itemB.source.kind) || itemA.index - itemB.index);
|
|
114
|
+
const getSpecifierName = (node) => node.type === "Identifier" ? node.name : node.value;
|
|
115
|
+
const getExternalName = (node) => getSpecifierName("imported" in node ? node.imported : node.exported);
|
|
116
|
+
const getLocalName = (node) => getSpecifierName(node.local);
|
|
117
|
+
function compareImportExportKind(kindA, kindB) {
|
|
118
|
+
if (kindA === kindB) return 0;
|
|
119
|
+
return kindA === "type" ? -1 : 1;
|
|
120
|
+
}
|
|
121
|
+
const sortSpecifierItems = (items) => [...items].sort((itemA, itemB) => compareImportExportKind(getImportExportKind(itemA.node), getImportExportKind(itemB.node)) || compare(getExternalName(itemA.node), getExternalName(itemB.node)) || compare(getLocalName(itemA.node), getLocalName(itemB.node)) || itemA.index - itemB.index);
|
|
122
|
+
function extractChunks(parentNode, isPartOfChunk) {
|
|
123
|
+
const chunks = [];
|
|
124
|
+
let chunk = [];
|
|
125
|
+
let lastNode;
|
|
126
|
+
for (const node of parentNode.body) {
|
|
127
|
+
const result = isPartOfChunk(node, lastNode);
|
|
128
|
+
switch (result) {
|
|
129
|
+
case "PartOfChunk":
|
|
130
|
+
chunk.push(node);
|
|
131
|
+
break;
|
|
132
|
+
case "PartOfNewChunk":
|
|
133
|
+
if (chunk.length > 0) chunks.push(chunk);
|
|
134
|
+
chunk = [node];
|
|
135
|
+
break;
|
|
136
|
+
case "NotPartOfChunk":
|
|
137
|
+
if (chunk.length > 0) {
|
|
138
|
+
chunks.push(chunk);
|
|
139
|
+
chunk = [];
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
default: {
|
|
143
|
+
const _never = result;
|
|
144
|
+
throw new Error(`Unknown chunk result: ${String(_never)}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
lastNode = node;
|
|
148
|
+
}
|
|
149
|
+
if (chunk.length > 0) chunks.push(chunk);
|
|
150
|
+
return chunks;
|
|
151
|
+
}
|
|
152
|
+
function maybeReportSorting(context, sorted, start, end) {
|
|
153
|
+
const sourceCode = context.sourceCode;
|
|
154
|
+
if (sourceCode.getText().slice(start, end) !== sorted) context.report({
|
|
155
|
+
messageId: "sort",
|
|
156
|
+
loc: {
|
|
157
|
+
start: sourceCode.getLocFromIndex(start),
|
|
158
|
+
end: sourceCode.getLocFromIndex(end)
|
|
159
|
+
},
|
|
160
|
+
fix: (fixer) => fixer.replaceTextRange([start, end], sorted)
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
function printSortedItems(sortedItems, originalItems, sourceCode) {
|
|
164
|
+
const newline = guessNewline(sourceCode);
|
|
165
|
+
const sorted = sortedItems.map((groups) => groups.map((groupItems) => groupItems.map((item) => item.code).join(newline)).join(newline)).join(newline + newline);
|
|
166
|
+
const flattened = flatMap(sortedItems, (groups) => flatMap(groups, (g) => g));
|
|
167
|
+
const lastSortedItem = flattened[flattened.length - 1];
|
|
168
|
+
const lastOriginalItem = originalItems[originalItems.length - 1];
|
|
169
|
+
const nextToken = lastSortedItem.needsNewline ? sourceCode.getTokenAfter(lastOriginalItem.node, {
|
|
170
|
+
includeComments: true,
|
|
171
|
+
filter: (token) => token.type !== "Line" && (token.type !== "Block" || token.loc.end.line !== lastOriginalItem.node.loc.end.line)
|
|
172
|
+
}) : void 0;
|
|
173
|
+
return sorted + (nextToken != null && nextToken.loc.start.line === lastOriginalItem.node.loc.end.line ? newline : "");
|
|
174
|
+
}
|
|
175
|
+
const makeEmptyItem = () => ({
|
|
176
|
+
state: "before",
|
|
177
|
+
before: [],
|
|
178
|
+
after: [],
|
|
179
|
+
specifier: [],
|
|
180
|
+
hadComma: false
|
|
181
|
+
});
|
|
182
|
+
function getSpecifierItems(tokens) {
|
|
183
|
+
const result = {
|
|
184
|
+
before: [],
|
|
185
|
+
after: [],
|
|
186
|
+
items: []
|
|
187
|
+
};
|
|
188
|
+
let current = makeEmptyItem();
|
|
189
|
+
for (const token of tokens) switch (current.state) {
|
|
190
|
+
case "before":
|
|
191
|
+
switch (token.type) {
|
|
192
|
+
case "Newline":
|
|
193
|
+
current.before.push(token);
|
|
194
|
+
if (result.before.length === 0 && result.items.length === 0) {
|
|
195
|
+
result.before = current.before;
|
|
196
|
+
current = makeEmptyItem();
|
|
197
|
+
}
|
|
198
|
+
break;
|
|
199
|
+
case "Spaces":
|
|
200
|
+
case "Block":
|
|
201
|
+
case "Line":
|
|
202
|
+
current.before.push(token);
|
|
203
|
+
break;
|
|
204
|
+
default:
|
|
205
|
+
if (result.before.length === 0 && result.items.length === 0) {
|
|
206
|
+
result.before = current.before;
|
|
207
|
+
current = makeEmptyItem();
|
|
208
|
+
}
|
|
209
|
+
current.state = "specifier";
|
|
210
|
+
current.specifier.push(token);
|
|
211
|
+
}
|
|
212
|
+
break;
|
|
213
|
+
case "specifier":
|
|
214
|
+
switch (token.type) {
|
|
215
|
+
case "Punctuator":
|
|
216
|
+
if (isPunctuator(token, ",")) {
|
|
217
|
+
current.hadComma = true;
|
|
218
|
+
current.state = "after";
|
|
219
|
+
} else current.specifier.push(token);
|
|
220
|
+
break;
|
|
221
|
+
default: current.specifier.push(token);
|
|
222
|
+
}
|
|
223
|
+
break;
|
|
224
|
+
case "after":
|
|
225
|
+
switch (token.type) {
|
|
226
|
+
case "Newline":
|
|
227
|
+
current.after.push(token);
|
|
228
|
+
result.items.push(current);
|
|
229
|
+
current = makeEmptyItem();
|
|
230
|
+
break;
|
|
231
|
+
case "Spaces":
|
|
232
|
+
case "Line":
|
|
233
|
+
current.after.push(token);
|
|
234
|
+
break;
|
|
235
|
+
case "Block":
|
|
236
|
+
if (hasNewline(token.code)) {
|
|
237
|
+
result.items.push(current);
|
|
238
|
+
current = makeEmptyItem();
|
|
239
|
+
current.before.push(token);
|
|
240
|
+
} else current.after.push(token);
|
|
241
|
+
break;
|
|
242
|
+
default:
|
|
243
|
+
result.items.push(current);
|
|
244
|
+
current = makeEmptyItem();
|
|
245
|
+
current.state = "specifier";
|
|
246
|
+
current.specifier.push(token);
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
default: {
|
|
250
|
+
const _never = current.state;
|
|
251
|
+
throw new Error(`Unknown state: ${String(_never)}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
switch (current.state) {
|
|
255
|
+
case "before":
|
|
256
|
+
result.after = current.before;
|
|
257
|
+
break;
|
|
258
|
+
case "specifier": {
|
|
259
|
+
const lastIdentifierIndex = findLastIndex(current.specifier, (t) => isIdentifier(t) || isKeyword(t));
|
|
260
|
+
const specifier = current.specifier.slice(0, lastIdentifierIndex + 1);
|
|
261
|
+
const after = current.specifier.slice(lastIdentifierIndex + 1);
|
|
262
|
+
const newlineIndexRaw = after.findIndex((t) => isNewline(t));
|
|
263
|
+
const newlineIndex = newlineIndexRaw === -1 ? -1 : newlineIndexRaw + 1;
|
|
264
|
+
const multilineBlockCommentIndex = after.findIndex((t) => isBlockComment(t) && hasNewline(t.code));
|
|
265
|
+
const sliceIndex = newlineIndex >= 0 && multilineBlockCommentIndex !== -1 ? Math.min(newlineIndex, multilineBlockCommentIndex) : newlineIndex >= 0 ? newlineIndex : multilineBlockCommentIndex === -1 ? endsWithSpaces(after) ? after.length - 1 : -1 : multilineBlockCommentIndex;
|
|
266
|
+
current.specifier = specifier;
|
|
267
|
+
current.after = sliceIndex === -1 ? after : after.slice(0, sliceIndex);
|
|
268
|
+
result.items.push(current);
|
|
269
|
+
result.after = sliceIndex === -1 ? [] : after.slice(sliceIndex);
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
case "after":
|
|
273
|
+
if (endsWithSpaces(current.after)) {
|
|
274
|
+
const last = current.after.pop();
|
|
275
|
+
if (last) result.after = [last];
|
|
276
|
+
}
|
|
277
|
+
result.items.push(current);
|
|
278
|
+
break;
|
|
279
|
+
default: {
|
|
280
|
+
const _never = current.state;
|
|
281
|
+
throw new Error(`Unknown state: ${String(_never)}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
before: result.before,
|
|
286
|
+
after: result.after,
|
|
287
|
+
items: result.items.map((item) => ({
|
|
288
|
+
before: item.before,
|
|
289
|
+
after: item.after,
|
|
290
|
+
specifier: item.specifier,
|
|
291
|
+
hadComma: item.hadComma
|
|
292
|
+
}))
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
function needsStartingNewline(tokens) {
|
|
296
|
+
const before = tokens.filter((token) => !isSpaces(token));
|
|
297
|
+
if (before.length === 0) return false;
|
|
298
|
+
const firstToken = before[0];
|
|
299
|
+
return isLineComment(firstToken) || isBlockComment(firstToken) && !hasNewline(firstToken.code);
|
|
300
|
+
}
|
|
301
|
+
function endsWithSpaces(tokens) {
|
|
302
|
+
const last = tokens.length > 0 ? tokens[tokens.length - 1] : void 0;
|
|
303
|
+
return last == null ? false : isSpaces(last);
|
|
304
|
+
}
|
|
305
|
+
function printWithSortedSpecifiers(node, sourceCode, getSpecifiers) {
|
|
306
|
+
const allTokens = getAllTokens(node, sourceCode);
|
|
307
|
+
const openBraceIndex = allTokens.findIndex((token) => isPunctuator(token, "{"));
|
|
308
|
+
const closeBraceIndex = allTokens.findIndex((token) => isPunctuator(token, "}"));
|
|
309
|
+
const specifiers = getSpecifiers(node);
|
|
310
|
+
if (openBraceIndex === -1 || closeBraceIndex === -1 || specifiers.length <= 1) return printTokens(allTokens);
|
|
311
|
+
const itemsResult = getSpecifierItems(allTokens.slice(openBraceIndex + 1, closeBraceIndex));
|
|
312
|
+
const sortedItems = sortSpecifierItems(itemsResult.items.map((originalItem, index) => ({
|
|
313
|
+
...originalItem,
|
|
314
|
+
node: specifiers[index],
|
|
315
|
+
index
|
|
316
|
+
})));
|
|
317
|
+
const newline = guessNewline(sourceCode);
|
|
318
|
+
const hasTrailingComma = (() => {
|
|
319
|
+
for (let index = closeBraceIndex - 1; index > openBraceIndex; index--) {
|
|
320
|
+
const token = allTokens[index];
|
|
321
|
+
if (token.type === "Spaces" || token.type === "Newline" || token.type === "Block" || token.type === "Line") continue;
|
|
322
|
+
return isPunctuator(token, ",");
|
|
323
|
+
}
|
|
324
|
+
return false;
|
|
325
|
+
})();
|
|
326
|
+
const lastIndex = sortedItems.length - 1;
|
|
327
|
+
const sorted = flatMap(sortedItems, (item, index) => {
|
|
328
|
+
const previous = index === 0 ? void 0 : sortedItems[index - 1];
|
|
329
|
+
const maybeNewline$1 = previous != null && needsStartingNewline(item.before) && (previous.after.length <= 0 || !isNewline(previous.after[previous.after.length - 1])) ? [{
|
|
330
|
+
type: "Newline",
|
|
331
|
+
code: newline
|
|
332
|
+
}] : [];
|
|
333
|
+
if (index < lastIndex || hasTrailingComma) return [
|
|
334
|
+
...maybeNewline$1,
|
|
335
|
+
...item.before,
|
|
336
|
+
...item.specifier,
|
|
337
|
+
{
|
|
338
|
+
type: "Comma",
|
|
339
|
+
code: ","
|
|
340
|
+
},
|
|
341
|
+
...item.after
|
|
342
|
+
];
|
|
343
|
+
const nonBlankIndex = item.after.findIndex((token) => !isNewline(token) && !isSpaces(token));
|
|
344
|
+
const after = item.hadComma ? nonBlankIndex === -1 ? [] : item.after.slice(nonBlankIndex) : item.after;
|
|
345
|
+
return [
|
|
346
|
+
...maybeNewline$1,
|
|
347
|
+
...item.before,
|
|
348
|
+
...item.specifier,
|
|
349
|
+
...after
|
|
350
|
+
];
|
|
351
|
+
});
|
|
352
|
+
const maybeNewline = needsStartingNewline(itemsResult.after) && !isNewline(sorted[sorted.length - 1]) ? [{
|
|
353
|
+
type: "Newline",
|
|
354
|
+
code: newline
|
|
355
|
+
}] : [];
|
|
356
|
+
return printTokens([
|
|
357
|
+
...allTokens.slice(0, openBraceIndex + 1),
|
|
358
|
+
...itemsResult.before,
|
|
359
|
+
...sorted,
|
|
360
|
+
...maybeNewline,
|
|
361
|
+
...itemsResult.after,
|
|
362
|
+
...allTokens.slice(closeBraceIndex)
|
|
363
|
+
]);
|
|
364
|
+
}
|
|
365
|
+
function handleLastSemicolon(chunk, sourceCode) {
|
|
366
|
+
const lastIndex = chunk.length - 1;
|
|
367
|
+
const lastNode = chunk[lastIndex];
|
|
368
|
+
const tokens = sourceCode.getLastTokens(lastNode, { count: 2 });
|
|
369
|
+
if (tokens.length < 2) return [...chunk];
|
|
370
|
+
const [nextToLastToken, lastToken] = tokens;
|
|
371
|
+
if (!(lastToken.type === "Punctuator" && lastToken.value === ";")) return [...chunk];
|
|
372
|
+
if (nextToLastToken.loc.end.line === lastToken.loc.start.line || sourceCode.getTokenAfter(lastToken) == null) return [...chunk];
|
|
373
|
+
const newLastNode = {
|
|
374
|
+
...lastNode,
|
|
375
|
+
range: [lastNode.range[0], nextToLastToken.range[1]],
|
|
376
|
+
loc: {
|
|
377
|
+
start: lastNode.loc.start,
|
|
378
|
+
end: nextToLastToken.loc.end
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
return [...chunk.slice(0, lastIndex), newLastNode];
|
|
382
|
+
}
|
|
383
|
+
function getImportExportItems(passedChunk, sourceCode, isSideEffectImport, getSpecifiers) {
|
|
384
|
+
const chunk = handleLastSemicolon(passedChunk, sourceCode);
|
|
385
|
+
return chunk.map((node, nodeIndex) => {
|
|
386
|
+
const lastLine = nodeIndex === 0 ? node.loc.start.line - 1 : chunk[nodeIndex - 1].loc.end.line;
|
|
387
|
+
const commentsBefore = sourceCode.getCommentsBefore(node).filter((comment) => comment.loc.start.line <= node.loc.start.line && comment.loc.end.line > lastLine && (nodeIndex > 0 || comment.loc.start.line > lastLine));
|
|
388
|
+
const commentsAfter = sourceCode.getCommentsAfter(node).filter((comment) => comment.loc.end.line === node.loc.end.line);
|
|
389
|
+
const before = printCommentsBefore(node, commentsBefore, sourceCode);
|
|
390
|
+
const after = printCommentsAfter(node, commentsAfter, sourceCode);
|
|
391
|
+
const indentation = getIndentationAt((commentsBefore.length > 0 ? commentsBefore[0] : node).range[0], sourceCode);
|
|
392
|
+
const trailingSpaces = getTrailingSpacesAt((commentsAfter.length > 0 ? commentsAfter[commentsAfter.length - 1] : node).range[1], sourceCode);
|
|
393
|
+
const code = indentation + before + printWithSortedSpecifiers(node, sourceCode, getSpecifiers) + after + trailingSpaces;
|
|
394
|
+
const all = [
|
|
395
|
+
...commentsBefore,
|
|
396
|
+
node,
|
|
397
|
+
...commentsAfter
|
|
398
|
+
];
|
|
399
|
+
const [start] = all[0].range;
|
|
400
|
+
const [, end] = all[all.length - 1].range;
|
|
401
|
+
const source = getSource(node);
|
|
402
|
+
const lastAfter = commentsAfter.length > 0 ? commentsAfter[commentsAfter.length - 1] : void 0;
|
|
403
|
+
return {
|
|
404
|
+
node,
|
|
405
|
+
code,
|
|
406
|
+
start: start - indentation.length,
|
|
407
|
+
end: end + trailingSpaces.length,
|
|
408
|
+
isSideEffectImport: isSideEffectImport(node, sourceCode),
|
|
409
|
+
source,
|
|
410
|
+
index: nodeIndex,
|
|
411
|
+
needsNewline: lastAfter?.type === "Line"
|
|
412
|
+
};
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
//#endregion
|
|
417
|
+
export { extractChunks, getImportExportItems, isPunctuator, maybeReportSorting, printSortedItems, printWithSortedSpecifiers, sortImportExportItems };
|