项目原始demo,不改动
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
此仓库已存档。您可以查看文件和克隆,但不能推送或创建工单/合并请求。
 
 
 
 

150 行
5.1 KiB

  1. /**
  2. * @fileoverview A rule to ensure whitespace before blocks.
  3. * @author Mathias Schreck <https://github.com/lo1tuma>
  4. */
  5. "use strict";
  6. const astUtils = require("../ast-utils");
  7. //------------------------------------------------------------------------------
  8. // Rule Definition
  9. //------------------------------------------------------------------------------
  10. module.exports = {
  11. meta: {
  12. docs: {
  13. description: "enforce consistent spacing before blocks",
  14. category: "Stylistic Issues",
  15. recommended: false,
  16. url: "https://eslint.org/docs/rules/space-before-blocks"
  17. },
  18. fixable: "whitespace",
  19. schema: [
  20. {
  21. oneOf: [
  22. {
  23. enum: ["always", "never"]
  24. },
  25. {
  26. type: "object",
  27. properties: {
  28. keywords: {
  29. enum: ["always", "never"]
  30. },
  31. functions: {
  32. enum: ["always", "never"]
  33. },
  34. classes: {
  35. enum: ["always", "never"]
  36. }
  37. },
  38. additionalProperties: false
  39. }
  40. ]
  41. }
  42. ]
  43. },
  44. create(context) {
  45. const config = context.options[0],
  46. sourceCode = context.getSourceCode();
  47. let checkFunctions = true,
  48. checkKeywords = true,
  49. checkClasses = true;
  50. if (typeof config === "object") {
  51. checkFunctions = config.functions !== "never";
  52. checkKeywords = config.keywords !== "never";
  53. checkClasses = config.classes !== "never";
  54. } else if (config === "never") {
  55. checkFunctions = false;
  56. checkKeywords = false;
  57. checkClasses = false;
  58. }
  59. /**
  60. * Checks whether or not a given token is an arrow operator (=>) or a keyword
  61. * in order to avoid to conflict with `arrow-spacing` and `keyword-spacing`.
  62. *
  63. * @param {Token} token - A token to check.
  64. * @returns {boolean} `true` if the token is an arrow operator.
  65. */
  66. function isConflicted(token) {
  67. return (token.type === "Punctuator" && token.value === "=>") || token.type === "Keyword";
  68. }
  69. /**
  70. * Checks the given BlockStatement node has a preceding space if it doesn’t start on a new line.
  71. * @param {ASTNode|Token} node The AST node of a BlockStatement.
  72. * @returns {void} undefined.
  73. */
  74. function checkPrecedingSpace(node) {
  75. const precedingToken = sourceCode.getTokenBefore(node);
  76. if (precedingToken && !isConflicted(precedingToken) && astUtils.isTokenOnSameLine(precedingToken, node)) {
  77. const hasSpace = sourceCode.isSpaceBetweenTokens(precedingToken, node);
  78. const parent = context.getAncestors().pop();
  79. let requireSpace;
  80. if (parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration") {
  81. requireSpace = checkFunctions;
  82. } else if (node.type === "ClassBody") {
  83. requireSpace = checkClasses;
  84. } else {
  85. requireSpace = checkKeywords;
  86. }
  87. if (requireSpace) {
  88. if (!hasSpace) {
  89. context.report({
  90. node,
  91. message: "Missing space before opening brace.",
  92. fix(fixer) {
  93. return fixer.insertTextBefore(node, " ");
  94. }
  95. });
  96. }
  97. } else {
  98. if (hasSpace) {
  99. context.report({
  100. node,
  101. message: "Unexpected space before opening brace.",
  102. fix(fixer) {
  103. return fixer.removeRange([precedingToken.range[1], node.range[0]]);
  104. }
  105. });
  106. }
  107. }
  108. }
  109. }
  110. /**
  111. * Checks if the CaseBlock of an given SwitchStatement node has a preceding space.
  112. * @param {ASTNode} node The node of a SwitchStatement.
  113. * @returns {void} undefined.
  114. */
  115. function checkSpaceBeforeCaseBlock(node) {
  116. const cases = node.cases;
  117. let openingBrace;
  118. if (cases.length > 0) {
  119. openingBrace = sourceCode.getTokenBefore(cases[0]);
  120. } else {
  121. openingBrace = sourceCode.getLastToken(node, 1);
  122. }
  123. checkPrecedingSpace(openingBrace);
  124. }
  125. return {
  126. BlockStatement: checkPrecedingSpace,
  127. ClassBody: checkPrecedingSpace,
  128. SwitchStatement: checkSpaceBeforeCaseBlock
  129. };
  130. }
  131. };