@tai-kun/vp-lint-plugins 0.0.1 → 0.0.2
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/src/rules/blank-line-after-variable-declaration.d.ts +1 -0
- package/dist/src/rules/blank-line-after-variable-declaration.d.ts.map +1 -1
- package/dist/src/rules/blank-line-after-variable-declaration.js +68 -12
- package/dist/src/rules/blank-line.d.ts +5 -1
- package/dist/src/rules/blank-line.d.ts.map +1 -1
- package/dist/src/rules/blank-line.js +19 -1
- package/dist/src/rules/comment-one-sentence-per-line.d.ts.map +1 -1
- package/dist/src/rules/jsdoc-utils.d.ts.map +1 -1
- package/dist/src/rules/object-sort-utils.d.ts.map +1 -1
- package/dist/src/rules/overload-signatures-adjacent.d.ts.map +1 -1
- package/dist/src/rules/overload-signatures-adjacent.js +2 -17
- package/dist/src/rules/sort-jsx-props.d.ts.map +1 -1
- package/dist/src/rules/spaced-comment.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/rules/blank-line-after-variable-declaration.ts +93 -12
- package/src/rules/blank-line.ts +30 -0
- package/src/rules/comment-one-sentence-per-line.ts +1 -2
- package/src/rules/jsdoc-utils.ts +1 -2
- package/src/rules/object-sort-utils.ts +2 -3
- package/src/rules/overload-signatures-adjacent.ts +3 -29
- package/src/rules/sort-jsx-props.ts +0 -1
- package/src/rules/sort-type-members.ts +1 -1
- package/src/rules/spaced-comment.ts +0 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blank-line-after-variable-declaration.d.ts","sourceRoot":"","sources":["../../../src/rules/blank-line-after-variable-declaration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"blank-line-after-variable-declaration.d.ts","sourceRoot":"","sources":["../../../src/rules/blank-line-after-variable-declaration.ts"],"names":[],"mappings":"AA8CA;;;;;GAKG;AACH,QAAA,MAAM,iCAAiC,uCA8GrC,CAAC;eAEY,iCAAiC"}
|
|
@@ -1,49 +1,105 @@
|
|
|
1
1
|
import { defineRule } from "vite-plus/lint/plugins";
|
|
2
|
-
import { hasBlankLine, getBlankLineFix, getNextStatement, getInsertionTarget, } from "./blank-line.js";
|
|
3
|
-
function
|
|
2
|
+
import { hasBlankLine, getBlankLineFix, getNextStatement, getInsertionTarget, getPreviousStatement, getRemoveBlankLineFix, } from "./blank-line.js";
|
|
3
|
+
function getVariableDeclaration(node) {
|
|
4
4
|
if (node.type === "VariableDeclaration") {
|
|
5
|
-
return
|
|
5
|
+
return node;
|
|
6
6
|
}
|
|
7
|
-
|
|
7
|
+
if (node.type === "ExportNamedDeclaration" && node.declaration?.type === "VariableDeclaration") {
|
|
8
|
+
return node.declaration;
|
|
9
|
+
}
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
function isRelatedExpression(statement, variables) {
|
|
13
|
+
if (statement.type !== "ExpressionStatement") {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
for (const variable of variables) {
|
|
17
|
+
for (const reference of variable.references) {
|
|
18
|
+
if (reference.identifier.range[0] >= statement.range[0] &&
|
|
19
|
+
reference.identifier.range[1] <= statement.range[1]) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
8
25
|
}
|
|
9
26
|
/**
|
|
10
27
|
* 連続する変数宣言の後に別の種類の文が続く場合、空行を 1 行以上確保します。
|
|
11
28
|
*
|
|
29
|
+
* 宣言した変数を使う式文は同じ宣言グループとして扱い、グループ内の空行は削除します。
|
|
12
30
|
* return の直前は blank-line-before-return が担当するため対象外にします。
|
|
13
31
|
*/
|
|
14
32
|
const blankLineAfterVariableDeclaration = defineRule({
|
|
15
33
|
meta: {
|
|
16
34
|
docs: {
|
|
17
|
-
description: "Require a blank line after a variable declaration group
|
|
35
|
+
description: "Require a blank line after a variable declaration group and remove blank lines before related statements.",
|
|
18
36
|
},
|
|
19
37
|
type: "layout",
|
|
20
38
|
fixable: "whitespace",
|
|
21
39
|
messages: {
|
|
22
40
|
blankLine: "Expected a blank line after a variable declaration group when another statement follows.",
|
|
41
|
+
unexpectedBlankLine: "Expected no blank line between a variable declaration and its related statement.",
|
|
23
42
|
},
|
|
24
43
|
},
|
|
25
44
|
create(context) {
|
|
26
45
|
const sourceCode = context.sourceCode;
|
|
27
46
|
function checkStatement(node) {
|
|
47
|
+
const variableDeclaration = getVariableDeclaration(node);
|
|
48
|
+
if (variableDeclaration === null) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
28
51
|
if (node.type === "VariableDeclaration" && node.parent.type === "ExportNamedDeclaration") {
|
|
29
52
|
return;
|
|
30
53
|
}
|
|
31
|
-
const
|
|
54
|
+
const previousStatement = getPreviousStatement(node);
|
|
55
|
+
if (previousStatement !== null && getVariableDeclaration(previousStatement) !== null) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const variables = new Set(sourceCode.getDeclaredVariables(variableDeclaration));
|
|
59
|
+
let last = node;
|
|
60
|
+
let nextStatement = getNextStatement(last);
|
|
61
|
+
while (nextStatement !== null) {
|
|
62
|
+
const nextVariableDeclaration = getVariableDeclaration(nextStatement);
|
|
63
|
+
if (nextVariableDeclaration !== null && getVariableDeclaration(last) !== null) {
|
|
64
|
+
for (const variable of sourceCode.getDeclaredVariables(nextVariableDeclaration)) {
|
|
65
|
+
variables.add(variable);
|
|
66
|
+
}
|
|
67
|
+
last = nextStatement;
|
|
68
|
+
nextStatement = getNextStatement(last);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (nextStatement.type === "ExpressionStatement" &&
|
|
72
|
+
isRelatedExpression(nextStatement, variables)) {
|
|
73
|
+
const target = getInsertionTarget(last, nextStatement, sourceCode);
|
|
74
|
+
if (hasBlankLine(last, target)) {
|
|
75
|
+
context.report({
|
|
76
|
+
fix(fixer) {
|
|
77
|
+
return getRemoveBlankLineFix(fixer, sourceCode, last, target);
|
|
78
|
+
},
|
|
79
|
+
node: nextStatement,
|
|
80
|
+
messageId: "unexpectedBlankLine",
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
last = nextStatement;
|
|
84
|
+
nextStatement = getNextStatement(last);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
32
89
|
if (nextStatement === null ||
|
|
33
90
|
nextStatement.type === "EmptyStatement" ||
|
|
34
|
-
nextStatement.type === "ReturnStatement"
|
|
35
|
-
isVariableDeclarationStatement(nextStatement)) {
|
|
91
|
+
nextStatement.type === "ReturnStatement") {
|
|
36
92
|
return;
|
|
37
93
|
}
|
|
38
|
-
const target = getInsertionTarget(
|
|
39
|
-
if (hasBlankLine(
|
|
94
|
+
const target = getInsertionTarget(last, nextStatement, sourceCode);
|
|
95
|
+
if (hasBlankLine(last, target)) {
|
|
40
96
|
return;
|
|
41
97
|
}
|
|
42
98
|
context.report({
|
|
43
99
|
fix(fixer) {
|
|
44
|
-
return getBlankLineFix(fixer, sourceCode,
|
|
100
|
+
return getBlankLineFix(fixer, sourceCode, last, target);
|
|
45
101
|
},
|
|
46
|
-
node,
|
|
102
|
+
node: nextStatement,
|
|
47
103
|
messageId: "blankLine",
|
|
48
104
|
});
|
|
49
105
|
}
|
|
@@ -10,5 +10,9 @@ declare function getPreviousStatement(node: ESTree.Node): ESTree.Node | null;
|
|
|
10
10
|
declare function getInsertionTarget(node: ESTree.Node, nextStatement: ESTree.Node, sourceCode: SourceCode): ESTree.Node | Comment;
|
|
11
11
|
declare function hasBlankLine(node: ESTree.Node, target: ESTree.Node | Comment): boolean;
|
|
12
12
|
declare function getBlankLineFix(fixer: Fixer, sourceCode: SourceCode, node: ESTree.Node, target: ESTree.Node | Comment): Fix | null;
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* 指定したノードと対象の間の空行を削除します。
|
|
15
|
+
*/
|
|
16
|
+
declare function getRemoveBlankLineFix(fixer: Fixer, sourceCode: SourceCode, node: ESTree.Node, target: ESTree.Node | Comment): Fix | null;
|
|
17
|
+
export { hasBlankLine, getBlankLineFix, getNextStatement, getInsertionTarget, getPreviousStatement, getRemoveBlankLineFix, };
|
|
14
18
|
//# sourceMappingURL=blank-line.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blank-line.d.ts","sourceRoot":"","sources":["../../../src/rules/blank-line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA4BtF,iBAAS,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,CAc/D;AAED,iBAAS,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,CAcnE;AAED;;;;;GAKG;AACH,iBAAS,kBAAkB,CACzB,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,aAAa,EAAE,MAAM,CAAC,IAAI,EAC1B,UAAU,EAAE,UAAU,GACrB,MAAM,CAAC,IAAI,GAAG,OAAO,CAWvB;AAED,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,GAAG,OAAO,GAAG,OAAO,CAE/E;AAED,iBAAS,eAAe,CACtB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,MAAM,EAAE,MAAM,CAAC,IAAI,GAAG,OAAO,GAC5B,GAAG,GAAG,IAAI,CAYZ;AAED,OAAO,EACL,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"blank-line.d.ts","sourceRoot":"","sources":["../../../src/rules/blank-line.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA4BtF,iBAAS,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,CAc/D;AAED,iBAAS,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,GAAG,IAAI,CAcnE;AAED;;;;;GAKG;AACH,iBAAS,kBAAkB,CACzB,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,aAAa,EAAE,MAAM,CAAC,IAAI,EAC1B,UAAU,EAAE,UAAU,GACrB,MAAM,CAAC,IAAI,GAAG,OAAO,CAWvB;AAED,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,GAAG,OAAO,GAAG,OAAO,CAE/E;AAED,iBAAS,eAAe,CACtB,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,MAAM,EAAE,MAAM,CAAC,IAAI,GAAG,OAAO,GAC5B,GAAG,GAAG,IAAI,CAYZ;AAED;;GAEG;AACH,iBAAS,qBAAqB,CAC5B,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,MAAM,EAAE,MAAM,CAAC,IAAI,GAAG,OAAO,GAC5B,GAAG,GAAG,IAAI,CAmBZ;AAED,OAAO,EACL,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,GACtB,CAAC"}
|
|
@@ -65,4 +65,22 @@ function getBlankLineFix(fixer, sourceCode, node, target) {
|
|
|
65
65
|
}
|
|
66
66
|
return fixer.insertTextBeforeRange([lineEnd, lineEnd + 1], "\n");
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
/**
|
|
69
|
+
* 指定したノードと対象の間の空行を削除します。
|
|
70
|
+
*/
|
|
71
|
+
function getRemoveBlankLineFix(fixer, sourceCode, node, target) {
|
|
72
|
+
if (target.loc.start.line <= node.loc.end.line + 1) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const fromLineEnd = sourceCode.text.indexOf("\n", node.range[1]);
|
|
76
|
+
if (fromLineEnd === -1) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
const targetLineStart = sourceCode.text.lastIndexOf("\n", target.range[0]) + 1;
|
|
80
|
+
const indent = sourceCode.text.slice(targetLineStart, target.range[0]);
|
|
81
|
+
if (indent.trim() !== "") {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return fixer.replaceTextRange([fromLineEnd, target.range[0]], `\n${indent}`);
|
|
85
|
+
}
|
|
86
|
+
export { hasBlankLine, getBlankLineFix, getNextStatement, getInsertionTarget, getPreviousStatement, getRemoveBlankLineFix, };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"comment-one-sentence-per-line.d.ts","sourceRoot":"","sources":["../../../src/rules/comment-one-sentence-per-line.ts"],"names":[],"mappings":"AAiKA;;;;;GAKG;AACH,QAAA,MAAM,yBAAyB,
|
|
1
|
+
{"version":3,"file":"comment-one-sentence-per-line.d.ts","sourceRoot":"","sources":["../../../src/rules/comment-one-sentence-per-line.ts"],"names":[],"mappings":"AAiKA;;;;;GAKG;AACH,QAAA,MAAM,yBAAyB,uCA6F7B,CAAC;eAEY,yBAAyB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsdoc-utils.d.ts","sourceRoot":"","sources":["../../../src/rules/jsdoc-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAI1E,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI/C;AAyBD;;GAEG;AACH,iBAAS,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqBpD;AAED;;;;GAIG;AACH,iBAAS,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GAAG,SAAS,EAAE,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"jsdoc-utils.d.ts","sourceRoot":"","sources":["../../../src/rules/jsdoc-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAI1E,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,iBAAS,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI/C;AAyBD;;GAEG;AACH,iBAAS,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqBpD;AAED;;;;GAIG;AACH,iBAAS,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,GAAG,SAAS,EAAE,GAAG,IAAI,CA8DnF;AAED,iBAAS,iBAAiB,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,GAAG,OAAO,CAE/D;AAcD;;GAEG;AACH,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,GAAG,IAAI,CAmB/E;AAED,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-sort-utils.d.ts","sourceRoot":"","sources":["../../../src/rules/object-sort-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAW,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAE1E,KAAK,cAAc,GAAG,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,aAAa,CAAC;AAIrE,UAAU,eAAe;IACvB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAYD,KAAK,QAAQ,GACT;IACE,QAAQ,EAAE,KAAK,CAAC;IAChB,WAAW,EAAE,IAAI,CAAC;CACnB,GACD;IACE,QAAQ,EAAE,IAAI,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAuEN,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBzD;AAeD;;;;;;;;GAQG;AACH,iBAAS,WAAW,CAClB,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,eAAoB,GAC5B,QAAQ,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"object-sort-utils.d.ts","sourceRoot":"","sources":["../../../src/rules/object-sort-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAW,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAE1E,KAAK,cAAc,GAAG,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,aAAa,CAAC;AAIrE,UAAU,eAAe;IACvB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAYD,KAAK,QAAQ,GACT;IACE,QAAQ,EAAE,KAAK,CAAC;IAChB,WAAW,EAAE,IAAI,CAAC;CACnB,GACD;IACE,QAAQ,EAAE,IAAI,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAuEN,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAiBzD;AAeD;;;;;;;;GAQG;AACH,iBAAS,WAAW,CAClB,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,eAAoB,GAC5B,QAAQ,GAAG,IAAI,CAuLjB;AAED,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overload-signatures-adjacent.d.ts","sourceRoot":"","sources":["../../../src/rules/overload-signatures-adjacent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"overload-signatures-adjacent.d.ts","sourceRoot":"","sources":["../../../src/rules/overload-signatures-adjacent.ts"],"names":[],"mappings":"AAuEA;;GAEG;AACH,QAAA,MAAM,0BAA0B,uCAqG9B,CAAC;eAEY,0BAA0B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineRule } from "vite-plus/lint/plugins";
|
|
2
|
-
import { getNextStatement } from "./blank-line.js";
|
|
2
|
+
import { getNextStatement, getRemoveBlankLineFix } from "./blank-line.js";
|
|
3
3
|
function getFunction(node) {
|
|
4
4
|
if (node.type === "FunctionDeclaration" || node.type === "TSDeclareFunction") {
|
|
5
5
|
return node;
|
|
@@ -25,21 +25,6 @@ function getKeyName(node) {
|
|
|
25
25
|
}
|
|
26
26
|
return null;
|
|
27
27
|
}
|
|
28
|
-
function getRemoveBlankLinesFix(fixer, sourceCode, previous, next) {
|
|
29
|
-
if (next.loc.start.line <= previous.loc.end.line + 1) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
const fromLineEnd = sourceCode.text.indexOf("\n", previous.range[1]);
|
|
33
|
-
if (fromLineEnd === -1) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
const nextLineStart = sourceCode.text.lastIndexOf("\n", next.range[0]) + 1;
|
|
37
|
-
const indent = sourceCode.text.slice(nextLineStart, next.range[0]);
|
|
38
|
-
if (indent.trim() !== "") {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
return fixer.replaceTextRange([fromLineEnd, next.range[0]], `\n${indent}`);
|
|
42
|
-
}
|
|
43
28
|
function hasCommentBetween(sourceCode, previous, next) {
|
|
44
29
|
return sourceCode
|
|
45
30
|
.getAllComments()
|
|
@@ -52,7 +37,7 @@ function reportIfSeparated(context, sourceCode, previous, next) {
|
|
|
52
37
|
}
|
|
53
38
|
context.report({
|
|
54
39
|
fix(fixer) {
|
|
55
|
-
return
|
|
40
|
+
return getRemoveBlankLineFix(fixer, sourceCode, previous, next);
|
|
56
41
|
},
|
|
57
42
|
node: next,
|
|
58
43
|
messageId: "adjacent",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort-jsx-props.d.ts","sourceRoot":"","sources":["../../../src/rules/sort-jsx-props.ts"],"names":[],"mappings":"AAsEA;;;GAGG;AACH,QAAA,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"sort-jsx-props.d.ts","sourceRoot":"","sources":["../../../src/rules/sort-jsx-props.ts"],"names":[],"mappings":"AAsEA;;;GAGG;AACH,QAAA,MAAM,YAAY,uCAuEhB,CAAC;eAEY,YAAY"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spaced-comment.d.ts","sourceRoot":"","sources":["../../../src/rules/spaced-comment.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,QAAA,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"spaced-comment.d.ts","sourceRoot":"","sources":["../../../src/rules/spaced-comment.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,QAAA,MAAM,aAAa,uCAgGjB,CAAC;eAEY,aAAa"}
|
package/package.json
CHANGED
|
@@ -1,69 +1,150 @@
|
|
|
1
1
|
import { defineRule } from "vite-plus/lint/plugins";
|
|
2
|
-
import type { ESTree } from "vite-plus/lint/plugins";
|
|
2
|
+
import type { ESTree, Variable } from "vite-plus/lint/plugins";
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
hasBlankLine,
|
|
6
6
|
getBlankLineFix,
|
|
7
7
|
getNextStatement,
|
|
8
8
|
getInsertionTarget,
|
|
9
|
+
getPreviousStatement,
|
|
10
|
+
getRemoveBlankLineFix,
|
|
9
11
|
} from "./blank-line.js";
|
|
10
12
|
|
|
11
|
-
function
|
|
13
|
+
function getVariableDeclaration(node: ESTree.Node): ESTree.VariableDeclaration | null {
|
|
12
14
|
if (node.type === "VariableDeclaration") {
|
|
13
|
-
return
|
|
15
|
+
return node;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
if (node.type === "ExportNamedDeclaration" && node.declaration?.type === "VariableDeclaration") {
|
|
19
|
+
return node.declaration;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isRelatedExpression(
|
|
26
|
+
statement: ESTree.Statement,
|
|
27
|
+
variables: ReadonlySet<Variable>,
|
|
28
|
+
): boolean {
|
|
29
|
+
if (statement.type !== "ExpressionStatement") {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for (const variable of variables) {
|
|
34
|
+
for (const reference of variable.references) {
|
|
35
|
+
if (
|
|
36
|
+
reference.identifier.range[0] >= statement.range[0] &&
|
|
37
|
+
reference.identifier.range[1] <= statement.range[1]
|
|
38
|
+
) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return false;
|
|
17
45
|
}
|
|
18
46
|
|
|
19
47
|
/**
|
|
20
48
|
* 連続する変数宣言の後に別の種類の文が続く場合、空行を 1 行以上確保します。
|
|
21
49
|
*
|
|
50
|
+
* 宣言した変数を使う式文は同じ宣言グループとして扱い、グループ内の空行は削除します。
|
|
22
51
|
* return の直前は blank-line-before-return が担当するため対象外にします。
|
|
23
52
|
*/
|
|
24
53
|
const blankLineAfterVariableDeclaration = defineRule({
|
|
25
54
|
meta: {
|
|
26
55
|
docs: {
|
|
27
56
|
description:
|
|
28
|
-
"Require a blank line after a variable declaration group
|
|
57
|
+
"Require a blank line after a variable declaration group and remove blank lines before related statements.",
|
|
29
58
|
},
|
|
30
59
|
type: "layout",
|
|
31
60
|
fixable: "whitespace",
|
|
32
61
|
messages: {
|
|
33
62
|
blankLine:
|
|
34
63
|
"Expected a blank line after a variable declaration group when another statement follows.",
|
|
64
|
+
unexpectedBlankLine:
|
|
65
|
+
"Expected no blank line between a variable declaration and its related statement.",
|
|
35
66
|
},
|
|
36
67
|
},
|
|
37
68
|
create(context) {
|
|
38
69
|
const sourceCode = context.sourceCode;
|
|
39
70
|
|
|
40
71
|
function checkStatement(node: ESTree.Node): void {
|
|
72
|
+
const variableDeclaration = getVariableDeclaration(node);
|
|
73
|
+
|
|
74
|
+
if (variableDeclaration === null) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
41
78
|
if (node.type === "VariableDeclaration" && node.parent.type === "ExportNamedDeclaration") {
|
|
42
79
|
return;
|
|
43
80
|
}
|
|
44
81
|
|
|
45
|
-
const
|
|
82
|
+
const previousStatement = getPreviousStatement(node);
|
|
83
|
+
|
|
84
|
+
if (previousStatement !== null && getVariableDeclaration(previousStatement) !== null) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const variables = new Set<Variable>(sourceCode.getDeclaredVariables(variableDeclaration));
|
|
89
|
+
let last = node;
|
|
90
|
+
let nextStatement = getNextStatement(last);
|
|
91
|
+
|
|
92
|
+
while (nextStatement !== null) {
|
|
93
|
+
const nextVariableDeclaration = getVariableDeclaration(nextStatement);
|
|
94
|
+
|
|
95
|
+
if (nextVariableDeclaration !== null && getVariableDeclaration(last) !== null) {
|
|
96
|
+
for (const variable of sourceCode.getDeclaredVariables(nextVariableDeclaration)) {
|
|
97
|
+
variables.add(variable);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
last = nextStatement;
|
|
101
|
+
nextStatement = getNextStatement(last);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (
|
|
106
|
+
nextStatement.type === "ExpressionStatement" &&
|
|
107
|
+
isRelatedExpression(nextStatement, variables)
|
|
108
|
+
) {
|
|
109
|
+
const target = getInsertionTarget(last, nextStatement, sourceCode);
|
|
110
|
+
|
|
111
|
+
if (hasBlankLine(last, target)) {
|
|
112
|
+
context.report({
|
|
113
|
+
fix(fixer) {
|
|
114
|
+
return getRemoveBlankLineFix(fixer, sourceCode, last, target);
|
|
115
|
+
},
|
|
116
|
+
node: nextStatement,
|
|
117
|
+
messageId: "unexpectedBlankLine",
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
last = nextStatement;
|
|
122
|
+
nextStatement = getNextStatement(last);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
46
128
|
|
|
47
129
|
if (
|
|
48
130
|
nextStatement === null ||
|
|
49
131
|
nextStatement.type === "EmptyStatement" ||
|
|
50
|
-
nextStatement.type === "ReturnStatement"
|
|
51
|
-
isVariableDeclarationStatement(nextStatement)
|
|
132
|
+
nextStatement.type === "ReturnStatement"
|
|
52
133
|
) {
|
|
53
134
|
return;
|
|
54
135
|
}
|
|
55
136
|
|
|
56
|
-
const target = getInsertionTarget(
|
|
137
|
+
const target = getInsertionTarget(last, nextStatement, sourceCode);
|
|
57
138
|
|
|
58
|
-
if (hasBlankLine(
|
|
139
|
+
if (hasBlankLine(last, target)) {
|
|
59
140
|
return;
|
|
60
141
|
}
|
|
61
142
|
|
|
62
143
|
context.report({
|
|
63
144
|
fix(fixer) {
|
|
64
|
-
return getBlankLineFix(fixer, sourceCode,
|
|
145
|
+
return getBlankLineFix(fixer, sourceCode, last, target);
|
|
65
146
|
},
|
|
66
|
-
node,
|
|
147
|
+
node: nextStatement,
|
|
67
148
|
messageId: "blankLine",
|
|
68
149
|
});
|
|
69
150
|
}
|
package/src/rules/blank-line.ts
CHANGED
|
@@ -104,10 +104,40 @@ function getBlankLineFix(
|
|
|
104
104
|
return fixer.insertTextBeforeRange([lineEnd, lineEnd + 1], "\n");
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* 指定したノードと対象の間の空行を削除します。
|
|
109
|
+
*/
|
|
110
|
+
function getRemoveBlankLineFix(
|
|
111
|
+
fixer: Fixer,
|
|
112
|
+
sourceCode: SourceCode,
|
|
113
|
+
node: ESTree.Node,
|
|
114
|
+
target: ESTree.Node | Comment,
|
|
115
|
+
): Fix | null {
|
|
116
|
+
if (target.loc.start.line <= node.loc.end.line + 1) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const fromLineEnd = sourceCode.text.indexOf("\n", node.range[1]);
|
|
121
|
+
|
|
122
|
+
if (fromLineEnd === -1) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const targetLineStart = sourceCode.text.lastIndexOf("\n", target.range[0]) + 1;
|
|
127
|
+
const indent = sourceCode.text.slice(targetLineStart, target.range[0]);
|
|
128
|
+
|
|
129
|
+
if (indent.trim() !== "") {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return fixer.replaceTextRange([fromLineEnd, target.range[0]], `\n${indent}`);
|
|
134
|
+
}
|
|
135
|
+
|
|
107
136
|
export {
|
|
108
137
|
hasBlankLine,
|
|
109
138
|
getBlankLineFix,
|
|
110
139
|
getNextStatement,
|
|
111
140
|
getInsertionTarget,
|
|
112
141
|
getPreviousStatement,
|
|
142
|
+
getRemoveBlankLineFix,
|
|
113
143
|
};
|
|
@@ -129,7 +129,6 @@ function collectDiagnostics(
|
|
|
129
129
|
if (next !== undefined && next !== null && canContinue(content, next)) {
|
|
130
130
|
const nextLeadingSpace = /^\s*/u.exec(next.content)?.[0] ?? "";
|
|
131
131
|
const separator = nextLeadingSpace === "" && needsSpace(content, next.content) ? " " : "";
|
|
132
|
-
|
|
133
132
|
fixes.push({
|
|
134
133
|
end: next.start,
|
|
135
134
|
loc: {
|
|
@@ -145,6 +144,7 @@ function collectDiagnostics(
|
|
|
145
144
|
text: separator,
|
|
146
145
|
start: info.end,
|
|
147
146
|
});
|
|
147
|
+
|
|
148
148
|
continue;
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -205,7 +205,6 @@ const commentOneSentencePerLine = defineRule({
|
|
|
205
205
|
|
|
206
206
|
for (const info of diagnostics.missingPunctuation) {
|
|
207
207
|
const column = info.column + info.content.trimEnd().length;
|
|
208
|
-
|
|
209
208
|
context.report({
|
|
210
209
|
loc: {
|
|
211
210
|
end: {
|
package/src/rules/jsdoc-utils.ts
CHANGED
|
@@ -101,13 +101,13 @@ function getJSDocLines(comment: Comment, sourceCode: SourceCode): JSDocLine[] |
|
|
|
101
101
|
const closeIndex = line.lastIndexOf("*/");
|
|
102
102
|
const contentEnd = closeIndex === -1 ? line.length : Math.max(contentStart, closeIndex);
|
|
103
103
|
const content = line.slice(contentStart, contentEnd);
|
|
104
|
-
|
|
105
104
|
lines.push({
|
|
106
105
|
raw: line,
|
|
107
106
|
prefix: line.slice(0, contentStart),
|
|
108
107
|
content,
|
|
109
108
|
tagName: getTagName(content),
|
|
110
109
|
});
|
|
110
|
+
|
|
111
111
|
continue;
|
|
112
112
|
}
|
|
113
113
|
|
|
@@ -122,7 +122,6 @@ function getJSDocLines(comment: Comment, sourceCode: SourceCode): JSDocLine[] |
|
|
|
122
122
|
const closeIndex = line.lastIndexOf("*/");
|
|
123
123
|
const contentEnd = closeIndex === -1 ? line.length : Math.max(contentStart, closeIndex);
|
|
124
124
|
const content = line.slice(contentStart, contentEnd);
|
|
125
|
-
|
|
126
125
|
lines.push({
|
|
127
126
|
raw: line,
|
|
128
127
|
prefix,
|
|
@@ -130,8 +130,8 @@ function compareUnits(left: NamedSortUnit, right: NamedSortUnit): number {
|
|
|
130
130
|
|
|
131
131
|
function sortGroup(group: readonly SortUnit[]): SortUnit[] {
|
|
132
132
|
const sortable = group.filter((unit): unit is NamedSortUnit => unit.name !== null);
|
|
133
|
-
|
|
134
133
|
sortable.sort(compareUnits);
|
|
134
|
+
|
|
135
135
|
const rest = group.filter((unit) => unit.name === null);
|
|
136
136
|
|
|
137
137
|
return [...sortable, ...rest];
|
|
@@ -181,7 +181,6 @@ function getSortPlan(
|
|
|
181
181
|
|
|
182
182
|
for (const property of node.properties) {
|
|
183
183
|
const isRest = property.type === "RestElement";
|
|
184
|
-
|
|
185
184
|
units.push({
|
|
186
185
|
name: isRest ? null : getPropertyName(property),
|
|
187
186
|
text: source.slice(property.range[0], property.range[1]),
|
|
@@ -246,7 +245,6 @@ function getSortPlan(
|
|
|
246
245
|
const startLine = first.loc.start.line;
|
|
247
246
|
const unitStart = lineStarts[startLine - 1] ?? 0;
|
|
248
247
|
const isRest = property.type === "RestElement";
|
|
249
|
-
|
|
250
248
|
units.push({
|
|
251
249
|
name: isRest ? null : getPropertyName(property),
|
|
252
250
|
text: source.slice(unitStart, property.range[1]),
|
|
@@ -254,6 +252,7 @@ function getSortPlan(
|
|
|
254
252
|
property,
|
|
255
253
|
startLine,
|
|
256
254
|
});
|
|
255
|
+
|
|
257
256
|
previousProperty = property;
|
|
258
257
|
}
|
|
259
258
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineRule } from "vite-plus/lint/plugins";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ESTree, Context, SourceCode } from "vite-plus/lint/plugins";
|
|
3
3
|
|
|
4
|
-
import { getNextStatement } from "./blank-line.js";
|
|
4
|
+
import { getNextStatement, getRemoveBlankLineFix } from "./blank-line.js";
|
|
5
5
|
|
|
6
6
|
function getFunction(node: ESTree.Node): ESTree.Function | null {
|
|
7
7
|
if (node.type === "FunctionDeclaration" || node.type === "TSDeclareFunction") {
|
|
@@ -37,32 +37,6 @@ function getKeyName(node: ESTree.MethodDefinition): string | null {
|
|
|
37
37
|
return null;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function getRemoveBlankLinesFix(
|
|
41
|
-
fixer: Fixer,
|
|
42
|
-
sourceCode: SourceCode,
|
|
43
|
-
previous: ESTree.Node,
|
|
44
|
-
next: ESTree.Node,
|
|
45
|
-
): Fix | null {
|
|
46
|
-
if (next.loc.start.line <= previous.loc.end.line + 1) {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const fromLineEnd = sourceCode.text.indexOf("\n", previous.range[1]);
|
|
51
|
-
|
|
52
|
-
if (fromLineEnd === -1) {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const nextLineStart = sourceCode.text.lastIndexOf("\n", next.range[0]) + 1;
|
|
57
|
-
const indent = sourceCode.text.slice(nextLineStart, next.range[0]);
|
|
58
|
-
|
|
59
|
-
if (indent.trim() !== "") {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return fixer.replaceTextRange([fromLineEnd, next.range[0]], `\n${indent}`);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
40
|
function hasCommentBetween(
|
|
67
41
|
sourceCode: SourceCode,
|
|
68
42
|
previous: ESTree.Node,
|
|
@@ -88,7 +62,7 @@ function reportIfSeparated(
|
|
|
88
62
|
|
|
89
63
|
context.report({
|
|
90
64
|
fix(fixer) {
|
|
91
|
-
return
|
|
65
|
+
return getRemoveBlankLineFix(fixer, sourceCode, previous, next);
|
|
92
66
|
},
|
|
93
67
|
node: next,
|
|
94
68
|
messageId: "adjacent",
|
|
@@ -176,8 +176,8 @@ function splitGroups(units: readonly MemberUnit[]): MemberUnit[][] {
|
|
|
176
176
|
|
|
177
177
|
function sortGroup(group: readonly MemberUnit[]): MemberUnit[] {
|
|
178
178
|
const sortable = group.filter((unit): unit is NamedUnit => unit.name !== null);
|
|
179
|
-
|
|
180
179
|
sortable.sort((left, right) => compareNames(left.name, right.name));
|
|
180
|
+
|
|
181
181
|
const rest = group.filter((unit) => unit.name === null);
|
|
182
182
|
|
|
183
183
|
return [...sortable, ...rest];
|
|
@@ -70,7 +70,6 @@ const spacedComment = defineRule({
|
|
|
70
70
|
const contentStart = prefixLength;
|
|
71
71
|
const contentEnd = raw.lastIndexOf("*/");
|
|
72
72
|
const content = raw.slice(contentStart, contentEnd);
|
|
73
|
-
|
|
74
73
|
needsLeading = content !== "" && !isWhitespace(content[0]);
|
|
75
74
|
needsTrailing = content !== "" && !isWhitespace(content.at(-1));
|
|
76
75
|
} else {
|
|
@@ -79,7 +78,6 @@ const spacedComment = defineRule({
|
|
|
79
78
|
const leadingContent = firstLine.slice(prefixLength);
|
|
80
79
|
const closeIndex = lastLine.lastIndexOf("*/");
|
|
81
80
|
const trailingContent = lastLine.slice(0, closeIndex);
|
|
82
|
-
|
|
83
81
|
needsLeading = leadingContent !== "" && !isWhitespace(leadingContent[0]);
|
|
84
82
|
needsTrailing = trailingContent !== "" && !isWhitespace(trailingContent.at(-1));
|
|
85
83
|
}
|