项目原始demo,不改动
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 

108 lines
3.1 KiB

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