项目原始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.

block-scoped-var.js 3.6 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /**
  2. * @fileoverview Rule to check for "block scoped" variables by binding context
  3. * @author Matt DuVall <http://www.mattduvall.com>
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Rule Definition
  8. //------------------------------------------------------------------------------
  9. module.exports = {
  10. meta: {
  11. docs: {
  12. description: "enforce the use of variables within the scope they are defined",
  13. category: "Best Practices",
  14. recommended: false,
  15. url: "https://eslint.org/docs/rules/block-scoped-var"
  16. },
  17. schema: [],
  18. messages: {
  19. outOfScope: "'{{name}}' used outside of binding context."
  20. }
  21. },
  22. create(context) {
  23. let stack = [];
  24. /**
  25. * Makes a block scope.
  26. * @param {ASTNode} node - A node of a scope.
  27. * @returns {void}
  28. */
  29. function enterScope(node) {
  30. stack.push(node.range);
  31. }
  32. /**
  33. * Pops the last block scope.
  34. * @returns {void}
  35. */
  36. function exitScope() {
  37. stack.pop();
  38. }
  39. /**
  40. * Reports a given reference.
  41. * @param {eslint-scope.Reference} reference - A reference to report.
  42. * @returns {void}
  43. */
  44. function report(reference) {
  45. const identifier = reference.identifier;
  46. context.report({ node: identifier, messageId: "outOfScope", data: { name: identifier.name } });
  47. }
  48. /**
  49. * Finds and reports references which are outside of valid scopes.
  50. * @param {ASTNode} node - A node to get variables.
  51. * @returns {void}
  52. */
  53. function checkForVariables(node) {
  54. if (node.kind !== "var") {
  55. return;
  56. }
  57. // Defines a predicate to check whether or not a given reference is outside of valid scope.
  58. const scopeRange = stack[stack.length - 1];
  59. /**
  60. * Check if a reference is out of scope
  61. * @param {ASTNode} reference node to examine
  62. * @returns {boolean} True is its outside the scope
  63. * @private
  64. */
  65. function isOutsideOfScope(reference) {
  66. const idRange = reference.identifier.range;
  67. return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1];
  68. }
  69. // Gets declared variables, and checks its references.
  70. const variables = context.getDeclaredVariables(node);
  71. for (let i = 0; i < variables.length; ++i) {
  72. // Reports.
  73. variables[i]
  74. .references
  75. .filter(isOutsideOfScope)
  76. .forEach(report);
  77. }
  78. }
  79. return {
  80. Program(node) {
  81. stack = [node.range];
  82. },
  83. // Manages scopes.
  84. BlockStatement: enterScope,
  85. "BlockStatement:exit": exitScope,
  86. ForStatement: enterScope,
  87. "ForStatement:exit": exitScope,
  88. ForInStatement: enterScope,
  89. "ForInStatement:exit": exitScope,
  90. ForOfStatement: enterScope,
  91. "ForOfStatement:exit": exitScope,
  92. SwitchStatement: enterScope,
  93. "SwitchStatement:exit": exitScope,
  94. CatchClause: enterScope,
  95. "CatchClause:exit": exitScope,
  96. // Finds and reports references which are outside of valid scope.
  97. VariableDeclaration: checkForVariables
  98. };
  99. }
  100. };