]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/semi-style.js
2d17d028c2fb06b6cc2d824b0f338bba2e89e686
2 * @fileoverview Rule to enforce location of semicolons.
3 * @author Toru Nagashima
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const astUtils
= require("./utils/ast-utils");
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
19 "BreakStatement", "ContinueStatement", "DebuggerStatement",
20 "DoWhileStatement", "ExportAllDeclaration",
21 "ExportDefaultDeclaration", "ExportNamedDeclaration",
22 "ExpressionStatement", "ImportDeclaration", "ReturnStatement",
23 "ThrowStatement", "VariableDeclaration", "PropertyDefinition"
27 * Get the child node list of a given node.
28 * This returns `BlockStatement#body`, `StaticBlock#body`, `Program#body`,
29 * `ClassBody#body`, or `SwitchCase#consequent`.
30 * This is used to check whether a node is the first/last child.
31 * @param {Node} node A node to get child node list.
32 * @returns {Node[]|null} The child node list.
34 function getChildren(node
) {
38 t
=== "BlockStatement" ||
39 t
=== "StaticBlock" ||
45 if (t
=== "SwitchCase") {
46 return node
.consequent
;
52 * Check whether a given node is the last statement in the parent block.
53 * @param {Node} node A node to check.
54 * @returns {boolean} `true` if the node is the last statement in the parent block.
56 function isLastChild(node
) {
57 const t
= node
.parent
.type
;
59 if (t
=== "IfStatement" && node
.parent
.consequent
=== node
&& node
.parent
.alternate
) { // before `else` keyword.
62 if (t
=== "DoWhileStatement") { // before `while` keyword.
65 const nodeList
= getChildren(node
.parent
);
67 return nodeList
!== null && nodeList
[nodeList
.length
- 1] === node
; // before `}` or etc.
75 description
: "enforce location of semicolons",
77 url
: "https://eslint.org/docs/rules/semi-style"
80 schema
: [{ enum: ["last", "first"] }],
81 fixable
: "whitespace",
84 expectedSemiColon
: "Expected this semicolon to be at {{pos}}."
89 const sourceCode
= context
.getSourceCode();
90 const option
= context
.options
[0] || "last";
93 * Check the given semicolon token.
94 * @param {Token} semiToken The semicolon token to check.
95 * @param {"first"|"last"} expected The expected location to check.
98 function check(semiToken
, expected
) {
99 const prevToken
= sourceCode
.getTokenBefore(semiToken
);
100 const nextToken
= sourceCode
.getTokenAfter(semiToken
);
101 const prevIsSameLine
= !prevToken
|| astUtils
.isTokenOnSameLine(prevToken
, semiToken
);
102 const nextIsSameLine
= !nextToken
|| astUtils
.isTokenOnSameLine(semiToken
, nextToken
);
104 if ((expected
=== "last" && !prevIsSameLine
) || (expected
=== "first" && !nextIsSameLine
)) {
107 messageId
: "expectedSemiColon",
109 pos
: (expected
=== "last")
110 ? "the end of the previous line"
111 : "the beginning of the next line"
114 if (prevToken
&& nextToken
&& sourceCode
.commentsExistBetween(prevToken
, nextToken
)) {
118 const start
= prevToken
? prevToken
.range
[1] : semiToken
.range
[0];
119 const end
= nextToken
? nextToken
.range
[0] : semiToken
.range
[1];
120 const text
= (expected
=== "last") ? ";\n" : "\n;";
122 return fixer
.replaceTextRange([start
, end
], text
);
130 if (option
=== "first" && isLastChild(node
)) {
134 const lastToken
= sourceCode
.getLastToken(node
);
136 if (astUtils
.isSemicolonToken(lastToken
)) {
137 check(lastToken
, option
);
142 const firstSemi
= node
.init
&& sourceCode
.getTokenAfter(node
.init
, astUtils
.isSemicolonToken
);
143 const secondSemi
= node
.test
&& sourceCode
.getTokenAfter(node
.test
, astUtils
.isSemicolonToken
);
146 check(firstSemi
, "last");
149 check(secondSemi
, "last");