xshell 1.3.42 → 1.3.45
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/package.json +1 -1
- package/xlint.js +56 -50
package/package.json
CHANGED
package/xlint.js
CHANGED
|
@@ -5,7 +5,7 @@ import TSParser from '@typescript-eslint/parser';
|
|
|
5
5
|
import ts_plugin from '@typescript-eslint/eslint-plugin';
|
|
6
6
|
import react_plugin from 'eslint-plugin-react';
|
|
7
7
|
import stylistic_plugin from '@stylistic/eslint-plugin';
|
|
8
|
-
import { check } from "./utils.js";
|
|
8
|
+
import { array_equals, check } from "./utils.js";
|
|
9
9
|
import { path } from "./path.js";
|
|
10
10
|
// 用 ast explorer 选 esprima 来看
|
|
11
11
|
// 或者 https://explorer.eslint.org/
|
|
@@ -679,17 +679,18 @@ export const xlint_plugin = {
|
|
|
679
679
|
// 格式化 source, 收集 decl
|
|
680
680
|
ImportDeclaration(node) {
|
|
681
681
|
const source = node.source.value;
|
|
682
|
-
const [type, source_] = format_source(pkgs, aliases, cwd, context.filename.fp, source);
|
|
682
|
+
const [type, source_, ialias] = format_source(pkgs, aliases, cwd, context.filename.fp, source);
|
|
683
683
|
if (!source_ || source_ === source) {
|
|
684
684
|
imports.push({
|
|
685
685
|
node,
|
|
686
686
|
type,
|
|
687
|
-
style: style_fexts.has(source.fext)
|
|
687
|
+
style: style_fexts.has(source.fext),
|
|
688
|
+
ialias
|
|
688
689
|
});
|
|
689
690
|
return;
|
|
690
691
|
}
|
|
691
692
|
need_fix_source = true;
|
|
692
|
-
console.log(`自动修复 ${source} -> ${source_}`)
|
|
693
|
+
// console.log(`自动修复 ${source} -> ${source_}`)
|
|
693
694
|
context.report({
|
|
694
695
|
// @ts-ignore
|
|
695
696
|
message: `import source ${source} 应该改为 ${source_}`,
|
|
@@ -702,6 +703,17 @@ export const xlint_plugin = {
|
|
|
702
703
|
'Program:exit'() {
|
|
703
704
|
if (need_fix_source || imports.length <= 1)
|
|
704
705
|
return;
|
|
706
|
+
// 检查顺序并修复: 样式 xxx.sass < nodejs builtin < package < alias < subpath
|
|
707
|
+
// 如果为样式,则放前面,其他的就按照数组来
|
|
708
|
+
let imports_ = imports.toSorted((a, b) => {
|
|
709
|
+
if (a.style !== b.style)
|
|
710
|
+
return a.style ? -1 : 1;
|
|
711
|
+
if (a.type === 'alias' && b.type === 'alias')
|
|
712
|
+
return a.ialias - b.ialias;
|
|
713
|
+
return imtypes.indexOf(a.type) - imtypes.indexOf(b.type);
|
|
714
|
+
});
|
|
715
|
+
if (array_equals(imports, imports_))
|
|
716
|
+
return;
|
|
705
717
|
const { sourceCode: source } = context;
|
|
706
718
|
const { body } = source.ast;
|
|
707
719
|
const first = imports[0].node;
|
|
@@ -709,52 +721,38 @@ export const xlint_plugin = {
|
|
|
709
721
|
if (body.indexOf(imports.last.node, ifirst + 1) - ifirst !== imports.length - 1) {
|
|
710
722
|
context.report({
|
|
711
723
|
// @ts-ignore
|
|
712
|
-
message: 'import 语句不连续,中间有其他语句,无法自动排序修复,需手动修复',
|
|
724
|
+
message: 'import 顺序不对,且 import 语句不连续,中间有其他语句,无法自动排序修复,需手动修复',
|
|
713
725
|
node: first
|
|
714
726
|
});
|
|
715
727
|
return;
|
|
716
728
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
729
|
+
context.report({
|
|
730
|
+
// @ts-ignore
|
|
731
|
+
message: 'import 顺序不对',
|
|
732
|
+
node: imports[0].node,
|
|
733
|
+
fix(fixer) {
|
|
734
|
+
let _start = Number.MAX_SAFE_INTEGER, _end = 0;
|
|
735
|
+
let type;
|
|
736
|
+
// 收集所有排序后的 import 文本
|
|
737
|
+
const texts = imports_.map((im, i) => {
|
|
738
|
+
const [start, end] = get_range_with_comments(source, im.node);
|
|
739
|
+
if (start < _start)
|
|
740
|
+
_start = start;
|
|
741
|
+
if (end > _end)
|
|
742
|
+
_end = end;
|
|
743
|
+
let text = source.text.slice(start, end);
|
|
744
|
+
// 分组之间空一行
|
|
745
|
+
if (im.type !== type) {
|
|
746
|
+
if (type)
|
|
747
|
+
text = '\n' + text;
|
|
748
|
+
type = im.type;
|
|
749
|
+
}
|
|
750
|
+
return text;
|
|
751
|
+
});
|
|
752
|
+
// 一次性替换所有 import
|
|
753
|
+
return fixer.replaceTextRange([_start, _end], texts.join_lines(false));
|
|
754
|
+
}
|
|
723
755
|
});
|
|
724
|
-
for (let i = 0; i < imports.length; i++) {
|
|
725
|
-
let im = imports[i];
|
|
726
|
-
let im_ = imports_[i];
|
|
727
|
-
if (im.node === im_.node)
|
|
728
|
-
continue;
|
|
729
|
-
context.report({
|
|
730
|
-
// @ts-ignore
|
|
731
|
-
message: `第 ${i} 个 import 顺序不对`,
|
|
732
|
-
node: im.node,
|
|
733
|
-
fix(fixer) {
|
|
734
|
-
let _start = Number.MAX_SAFE_INTEGER, _end = 0;
|
|
735
|
-
let type;
|
|
736
|
-
// 收集所有排序后的 import 文本
|
|
737
|
-
const texts = imports_.map((im, i) => {
|
|
738
|
-
const [start, end] = get_range_with_comments(source, im.node);
|
|
739
|
-
if (start < _start)
|
|
740
|
-
_start = start;
|
|
741
|
-
if (end > _end)
|
|
742
|
-
_end = end;
|
|
743
|
-
let text = source.text.slice(start, end);
|
|
744
|
-
// 分组之间空一行
|
|
745
|
-
if (im.type !== type) {
|
|
746
|
-
if (type)
|
|
747
|
-
text = '\n' + text;
|
|
748
|
-
type = im.type;
|
|
749
|
-
}
|
|
750
|
-
return text;
|
|
751
|
-
});
|
|
752
|
-
// 一次性替换所有 import
|
|
753
|
-
return fixer.replaceTextRange([_start, _end], texts.join_lines());
|
|
754
|
-
}
|
|
755
|
-
});
|
|
756
|
-
break;
|
|
757
|
-
}
|
|
758
756
|
}
|
|
759
757
|
};
|
|
760
758
|
}
|
|
@@ -1011,7 +1009,11 @@ function get_packages(cwd) {
|
|
|
1011
1009
|
if (cache_pkgs_cwd === cwd)
|
|
1012
1010
|
return cache_pkgs;
|
|
1013
1011
|
const { dependencies = {}, devDependencies = {} } = JSON.parse(fs.readFileSync(`${cwd}package.json`, 'utf-8'));
|
|
1014
|
-
const pkgs = [
|
|
1012
|
+
const pkgs = [
|
|
1013
|
+
...Object.keys(dependencies),
|
|
1014
|
+
...Object.keys(devDependencies)
|
|
1015
|
+
.map(pkg => pkg.startsWith('@types/') ? pkg.strip_start('@types/') : pkg),
|
|
1016
|
+
].unique();
|
|
1015
1017
|
cache_pkgs_cwd = cwd;
|
|
1016
1018
|
return cache_pkgs = pkgs;
|
|
1017
1019
|
}
|
|
@@ -1057,9 +1059,10 @@ function format_source(pkgs, aliases, cwd, fp, source) {
|
|
|
1057
1059
|
source = `${source}.${resolve_suffix(source)}`;
|
|
1058
1060
|
}
|
|
1059
1061
|
const relative = source.strip_start(cwd, true);
|
|
1060
|
-
const
|
|
1061
|
-
check(
|
|
1062
|
-
|
|
1062
|
+
const ialias = aliases.findIndex(({ fp }) => relative.startsWith(fp));
|
|
1063
|
+
check(ialias !== -1, '一定能找到匹配的 alias');
|
|
1064
|
+
const alias_ = aliases[ialias];
|
|
1065
|
+
return ['alias', alias_.alias + relative.strip_start(alias_.fp), ialias];
|
|
1063
1066
|
}
|
|
1064
1067
|
let cache_exists = new Map();
|
|
1065
1068
|
function resolve_suffix(fp_base) {
|
|
@@ -1067,7 +1070,10 @@ function resolve_suffix(fp_base) {
|
|
|
1067
1070
|
const fp = `${fp_base}.${suffix}`;
|
|
1068
1071
|
const c = cache_exists.get(fp);
|
|
1069
1072
|
if (c !== undefined)
|
|
1070
|
-
|
|
1073
|
+
if (c)
|
|
1074
|
+
return suffix;
|
|
1075
|
+
else
|
|
1076
|
+
continue;
|
|
1071
1077
|
const e = fs.existsSync(fp);
|
|
1072
1078
|
cache_exists.set(fp, e);
|
|
1073
1079
|
if (e)
|