项目原始demo,不改动
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
Це архівний репозитарій. Ви можете переглядати і клонувати файли, але не можете робити пуш або відкривати питання/запити.

4 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /**
  2. * @fileoverview Rule to enforce var declarations are only at the top of a function.
  3. * @author Danny Fritz
  4. * @author Gyandeep Singh
  5. */
  6. "use strict";
  7. //------------------------------------------------------------------------------
  8. // Rule Definition
  9. //------------------------------------------------------------------------------
  10. module.exports = {
  11. meta: {
  12. docs: {
  13. description: "require `var` declarations be placed at the top of their containing scope",
  14. category: "Best Practices",
  15. recommended: false,
  16. url: "https://eslint.org/docs/rules/vars-on-top"
  17. },
  18. schema: []
  19. },
  20. create(context) {
  21. const errorMessage = "All 'var' declarations must be at the top of the function scope.";
  22. //--------------------------------------------------------------------------
  23. // Helpers
  24. //--------------------------------------------------------------------------
  25. /**
  26. * @param {ASTNode} node - any node
  27. * @returns {boolean} whether the given node structurally represents a directive
  28. */
  29. function looksLikeDirective(node) {
  30. return node.type === "ExpressionStatement" &&
  31. node.expression.type === "Literal" && typeof node.expression.value === "string";
  32. }
  33. /**
  34. * Check to see if its a ES6 import declaration
  35. * @param {ASTNode} node - any node
  36. * @returns {boolean} whether the given node represents a import declaration
  37. */
  38. function looksLikeImport(node) {
  39. return node.type === "ImportDeclaration" || node.type === "ImportSpecifier" ||
  40. node.type === "ImportDefaultSpecifier" || node.type === "ImportNamespaceSpecifier";
  41. }
  42. /**
  43. * Checks whether a given node is a variable declaration or not.
  44. *
  45. * @param {ASTNode} node - any node
  46. * @returns {boolean} `true` if the node is a variable declaration.
  47. */
  48. function isVariableDeclaration(node) {
  49. return (
  50. node.type === "VariableDeclaration" ||
  51. (
  52. node.type === "ExportNamedDeclaration" &&
  53. node.declaration &&
  54. node.declaration.type === "VariableDeclaration"
  55. )
  56. );
  57. }
  58. /**
  59. * Checks whether this variable is on top of the block body
  60. * @param {ASTNode} node - The node to check
  61. * @param {ASTNode[]} statements - collection of ASTNodes for the parent node block
  62. * @returns {boolean} True if var is on top otherwise false
  63. */
  64. function isVarOnTop(node, statements) {
  65. const l = statements.length;
  66. let i = 0;
  67. // skip over directives
  68. for (; i < l; ++i) {
  69. if (!looksLikeDirective(statements[i]) && !looksLikeImport(statements[i])) {
  70. break;
  71. }
  72. }
  73. for (; i < l; ++i) {
  74. if (!isVariableDeclaration(statements[i])) {
  75. return false;
  76. }
  77. if (statements[i] === node) {
  78. return true;
  79. }
  80. }
  81. return false;
  82. }
  83. /**
  84. * Checks whether variable is on top at the global level
  85. * @param {ASTNode} node - The node to check
  86. * @param {ASTNode} parent - Parent of the node
  87. * @returns {void}
  88. */
  89. function globalVarCheck(node, parent) {
  90. if (!isVarOnTop(node, parent.body)) {
  91. context.report({ node, message: errorMessage });
  92. }
  93. }
  94. /**
  95. * Checks whether variable is on top at functional block scope level
  96. * @param {ASTNode} node - The node to check
  97. * @param {ASTNode} parent - Parent of the node
  98. * @param {ASTNode} grandParent - Parent of the node's parent
  99. * @returns {void}
  100. */
  101. function blockScopeVarCheck(node, parent, grandParent) {
  102. if (!(/Function/.test(grandParent.type) &&
  103. parent.type === "BlockStatement" &&
  104. isVarOnTop(node, parent.body))) {
  105. context.report({ node, message: errorMessage });
  106. }
  107. }
  108. //--------------------------------------------------------------------------
  109. // Public API
  110. //--------------------------------------------------------------------------
  111. return {
  112. "VariableDeclaration[kind='var']"(node) {
  113. if (node.parent.type === "ExportNamedDeclaration") {
  114. globalVarCheck(node.parent, node.parent.parent);
  115. } else if (node.parent.type === "Program") {
  116. globalVarCheck(node, node.parent);
  117. } else {
  118. blockScopeVarCheck(node, node.parent, node.parent.parent);
  119. }
  120. }
  121. };
  122. }
  123. };