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