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

237 строки
8.8 KiB

  1. /**
  2. * @fileoverview Disallows or enforces spaces inside of array brackets.
  3. * @author Jamund Ferguson
  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 inside array brackets",
  14. category: "Stylistic Issues",
  15. recommended: false,
  16. url: "https://eslint.org/docs/rules/array-bracket-spacing"
  17. },
  18. fixable: "whitespace",
  19. schema: [
  20. {
  21. enum: ["always", "never"]
  22. },
  23. {
  24. type: "object",
  25. properties: {
  26. singleValue: {
  27. type: "boolean"
  28. },
  29. objectsInArrays: {
  30. type: "boolean"
  31. },
  32. arraysInArrays: {
  33. type: "boolean"
  34. }
  35. },
  36. additionalProperties: false
  37. }
  38. ],
  39. messages: {
  40. unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.",
  41. unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.",
  42. missingSpaceAfter: "A space is required after '{{tokenValue}}'.",
  43. missingSpaceBefore: "A space is required before '{{tokenValue}}'."
  44. }
  45. },
  46. create(context) {
  47. const spaced = context.options[0] === "always",
  48. sourceCode = context.getSourceCode();
  49. /**
  50. * Determines whether an option is set, relative to the spacing option.
  51. * If spaced is "always", then check whether option is set to false.
  52. * If spaced is "never", then check whether option is set to true.
  53. * @param {Object} option - The option to exclude.
  54. * @returns {boolean} Whether or not the property is excluded.
  55. */
  56. function isOptionSet(option) {
  57. return context.options[1] ? context.options[1][option] === !spaced : false;
  58. }
  59. const options = {
  60. spaced,
  61. singleElementException: isOptionSet("singleValue"),
  62. objectsInArraysException: isOptionSet("objectsInArrays"),
  63. arraysInArraysException: isOptionSet("arraysInArrays")
  64. };
  65. //--------------------------------------------------------------------------
  66. // Helpers
  67. //--------------------------------------------------------------------------
  68. /**
  69. * Reports that there shouldn't be a space after the first token
  70. * @param {ASTNode} node - The node to report in the event of an error.
  71. * @param {Token} token - The token to use for the report.
  72. * @returns {void}
  73. */
  74. function reportNoBeginningSpace(node, token) {
  75. context.report({
  76. node,
  77. loc: token.loc.start,
  78. messageId: "unexpectedSpaceAfter",
  79. data: {
  80. tokenValue: token.value
  81. },
  82. fix(fixer) {
  83. const nextToken = sourceCode.getTokenAfter(token);
  84. return fixer.removeRange([token.range[1], nextToken.range[0]]);
  85. }
  86. });
  87. }
  88. /**
  89. * Reports that there shouldn't be a space before the last token
  90. * @param {ASTNode} node - The node to report in the event of an error.
  91. * @param {Token} token - The token to use for the report.
  92. * @returns {void}
  93. */
  94. function reportNoEndingSpace(node, token) {
  95. context.report({
  96. node,
  97. loc: token.loc.start,
  98. messageId: "unexpectedSpaceBefore",
  99. data: {
  100. tokenValue: token.value
  101. },
  102. fix(fixer) {
  103. const previousToken = sourceCode.getTokenBefore(token);
  104. return fixer.removeRange([previousToken.range[1], token.range[0]]);
  105. }
  106. });
  107. }
  108. /**
  109. * Reports that there should be a space after the first token
  110. * @param {ASTNode} node - The node to report in the event of an error.
  111. * @param {Token} token - The token to use for the report.
  112. * @returns {void}
  113. */
  114. function reportRequiredBeginningSpace(node, token) {
  115. context.report({
  116. node,
  117. loc: token.loc.start,
  118. messageId: "missingSpaceAfter",
  119. data: {
  120. tokenValue: token.value
  121. },
  122. fix(fixer) {
  123. return fixer.insertTextAfter(token, " ");
  124. }
  125. });
  126. }
  127. /**
  128. * Reports that there should be a space before the last token
  129. * @param {ASTNode} node - The node to report in the event of an error.
  130. * @param {Token} token - The token to use for the report.
  131. * @returns {void}
  132. */
  133. function reportRequiredEndingSpace(node, token) {
  134. context.report({
  135. node,
  136. loc: token.loc.start,
  137. messageId: "missingSpaceBefore",
  138. data: {
  139. tokenValue: token.value
  140. },
  141. fix(fixer) {
  142. return fixer.insertTextBefore(token, " ");
  143. }
  144. });
  145. }
  146. /**
  147. * Determines if a node is an object type
  148. * @param {ASTNode} node - The node to check.
  149. * @returns {boolean} Whether or not the node is an object type.
  150. */
  151. function isObjectType(node) {
  152. return node && (node.type === "ObjectExpression" || node.type === "ObjectPattern");
  153. }
  154. /**
  155. * Determines if a node is an array type
  156. * @param {ASTNode} node - The node to check.
  157. * @returns {boolean} Whether or not the node is an array type.
  158. */
  159. function isArrayType(node) {
  160. return node && (node.type === "ArrayExpression" || node.type === "ArrayPattern");
  161. }
  162. /**
  163. * Validates the spacing around array brackets
  164. * @param {ASTNode} node - The node we're checking for spacing
  165. * @returns {void}
  166. */
  167. function validateArraySpacing(node) {
  168. if (options.spaced && node.elements.length === 0) {
  169. return;
  170. }
  171. const first = sourceCode.getFirstToken(node),
  172. second = sourceCode.getFirstToken(node, 1),
  173. last = node.typeAnnotation
  174. ? sourceCode.getTokenBefore(node.typeAnnotation)
  175. : sourceCode.getLastToken(node),
  176. penultimate = sourceCode.getTokenBefore(last),
  177. firstElement = node.elements[0],
  178. lastElement = node.elements[node.elements.length - 1];
  179. const openingBracketMustBeSpaced =
  180. options.objectsInArraysException && isObjectType(firstElement) ||
  181. options.arraysInArraysException && isArrayType(firstElement) ||
  182. options.singleElementException && node.elements.length === 1
  183. ? !options.spaced : options.spaced;
  184. const closingBracketMustBeSpaced =
  185. options.objectsInArraysException && isObjectType(lastElement) ||
  186. options.arraysInArraysException && isArrayType(lastElement) ||
  187. options.singleElementException && node.elements.length === 1
  188. ? !options.spaced : options.spaced;
  189. if (astUtils.isTokenOnSameLine(first, second)) {
  190. if (openingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(first, second)) {
  191. reportRequiredBeginningSpace(node, first);
  192. }
  193. if (!openingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(first, second)) {
  194. reportNoBeginningSpace(node, first);
  195. }
  196. }
  197. if (first !== penultimate && astUtils.isTokenOnSameLine(penultimate, last)) {
  198. if (closingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(penultimate, last)) {
  199. reportRequiredEndingSpace(node, last);
  200. }
  201. if (!closingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(penultimate, last)) {
  202. reportNoEndingSpace(node, last);
  203. }
  204. }
  205. }
  206. //--------------------------------------------------------------------------
  207. // Public
  208. //--------------------------------------------------------------------------
  209. return {
  210. ArrayPattern: validateArraySpacing,
  211. ArrayExpression: validateArraySpacing
  212. };
  213. }
  214. };