.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / no-extra-semi.js
1 /**
2  * @fileoverview Rule to flag use of unnecessary semicolons
3  * @author Nicholas C. Zakas
4  */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Requirements
10 //------------------------------------------------------------------------------
11
12 const FixTracker = require("./utils/fix-tracker");
13 const astUtils = require("./utils/ast-utils");
14
15 //------------------------------------------------------------------------------
16 // Rule Definition
17 //------------------------------------------------------------------------------
18
19 module.exports = {
20     meta: {
21         type: "suggestion",
22
23         docs: {
24             description: "disallow unnecessary semicolons",
25             category: "Possible Errors",
26             recommended: true,
27             url: "https://eslint.org/docs/rules/no-extra-semi"
28         },
29
30         fixable: "code",
31         schema: [],
32
33         messages: {
34             unexpected: "Unnecessary semicolon."
35         }
36     },
37
38     create(context) {
39         const sourceCode = context.getSourceCode();
40
41         /**
42          * Reports an unnecessary semicolon error.
43          * @param {Node|Token} nodeOrToken A node or a token to be reported.
44          * @returns {void}
45          */
46         function report(nodeOrToken) {
47             context.report({
48                 node: nodeOrToken,
49                 messageId: "unexpected",
50                 fix(fixer) {
51
52                     /*
53                      * Expand the replacement range to include the surrounding
54                      * tokens to avoid conflicting with semi.
55                      * https://github.com/eslint/eslint/issues/7928
56                      */
57                     return new FixTracker(fixer, context.getSourceCode())
58                         .retainSurroundingTokens(nodeOrToken)
59                         .remove(nodeOrToken);
60                 }
61             });
62         }
63
64         /**
65          * Checks for a part of a class body.
66          * This checks tokens from a specified token to a next MethodDefinition or the end of class body.
67          * @param {Token} firstToken The first token to check.
68          * @returns {void}
69          */
70         function checkForPartOfClassBody(firstToken) {
71             for (let token = firstToken;
72                 token.type === "Punctuator" && !astUtils.isClosingBraceToken(token);
73                 token = sourceCode.getTokenAfter(token)
74             ) {
75                 if (astUtils.isSemicolonToken(token)) {
76                     report(token);
77                 }
78             }
79         }
80
81         return {
82
83             /**
84              * Reports this empty statement, except if the parent node is a loop.
85              * @param {Node} node A EmptyStatement node to be reported.
86              * @returns {void}
87              */
88             EmptyStatement(node) {
89                 const parent = node.parent,
90                     allowedParentTypes = [
91                         "ForStatement",
92                         "ForInStatement",
93                         "ForOfStatement",
94                         "WhileStatement",
95                         "DoWhileStatement",
96                         "IfStatement",
97                         "LabeledStatement",
98                         "WithStatement"
99                     ];
100
101                 if (allowedParentTypes.indexOf(parent.type) === -1) {
102                     report(node);
103                 }
104             },
105
106             /**
107              * Checks tokens from the head of this class body to the first MethodDefinition or the end of this class body.
108              * @param {Node} node A ClassBody node to check.
109              * @returns {void}
110              */
111             ClassBody(node) {
112                 checkForPartOfClassBody(sourceCode.getFirstToken(node, 1)); // 0 is `{`.
113             },
114
115             /**
116              * Checks tokens from this MethodDefinition to the next MethodDefinition or the end of this class body.
117              * @param {Node} node A MethodDefinition node of the start point.
118              * @returns {void}
119              */
120             MethodDefinition(node) {
121                 checkForPartOfClassBody(sourceCode.getTokenAfter(node));
122             }
123         };
124
125     }
126 };