.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / no-unused-labels.js
1 /**
2  * @fileoverview Rule to disallow unused labels.
3  * @author Toru Nagashima
4  */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Rule Definition
10 //------------------------------------------------------------------------------
11
12 module.exports = {
13     meta: {
14         type: "suggestion",
15
16         docs: {
17             description: "disallow unused labels",
18             category: "Best Practices",
19             recommended: true,
20             url: "https://eslint.org/docs/rules/no-unused-labels"
21         },
22
23         schema: [],
24
25         fixable: "code",
26
27         messages: {
28             unused: "'{{name}}:' is defined but never used."
29         }
30     },
31
32     create(context) {
33         const sourceCode = context.getSourceCode();
34         let scopeInfo = null;
35
36         /**
37          * Adds a scope info to the stack.
38          * @param {ASTNode} node A node to add. This is a LabeledStatement.
39          * @returns {void}
40          */
41         function enterLabeledScope(node) {
42             scopeInfo = {
43                 label: node.label.name,
44                 used: false,
45                 upper: scopeInfo
46             };
47         }
48
49         /**
50          * Removes the top of the stack.
51          * At the same time, this reports the label if it's never used.
52          * @param {ASTNode} node A node to report. This is a LabeledStatement.
53          * @returns {void}
54          */
55         function exitLabeledScope(node) {
56             if (!scopeInfo.used) {
57                 context.report({
58                     node: node.label,
59                     messageId: "unused",
60                     data: node.label,
61                     fix(fixer) {
62
63                         /*
64                          * Only perform a fix if there are no comments between the label and the body. This will be the case
65                          * when there is exactly one token/comment (the ":") between the label and the body.
66                          */
67                         if (sourceCode.getTokenAfter(node.label, { includeComments: true }) ===
68                                 sourceCode.getTokenBefore(node.body, { includeComments: true })) {
69                             return fixer.removeRange([node.range[0], node.body.range[0]]);
70                         }
71
72                         return null;
73                     }
74                 });
75             }
76
77             scopeInfo = scopeInfo.upper;
78         }
79
80         /**
81          * Marks the label of a given node as used.
82          * @param {ASTNode} node A node to mark. This is a BreakStatement or
83          *      ContinueStatement.
84          * @returns {void}
85          */
86         function markAsUsed(node) {
87             if (!node.label) {
88                 return;
89             }
90
91             const label = node.label.name;
92             let info = scopeInfo;
93
94             while (info) {
95                 if (info.label === label) {
96                     info.used = true;
97                     break;
98                 }
99                 info = info.upper;
100             }
101         }
102
103         return {
104             LabeledStatement: enterLabeledScope,
105             "LabeledStatement:exit": exitLabeledScope,
106             BreakStatement: markAsUsed,
107             ContinueStatement: markAsUsed
108         };
109     }
110 };