computed-property-even-spacing.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. 'use strict'
  2. /**
  3. * @fileoverview Disallows or enforces spaces inside computed properties.
  4. * @author Jamund Ferguson
  5. * @copyright 2015 Jamund Ferguson. All rights reserved.
  6. */
  7. // ------------------------------------------------------------------------------
  8. // Rule Definition
  9. // ------------------------------------------------------------------------------
  10. module.exports = {
  11. meta: {
  12. docs: {
  13. url: 'https://github.com/xjamundx/eslint-plugin-standard#rules-explanations'
  14. }
  15. },
  16. create: function (context) {
  17. var propertyNameMustBeSpaced = context.options[0] === 'always' // default is "never"
  18. var propertyNameMustBeEven = context.options[0] === 'even' // default is "never"
  19. // --------------------------------------------------------------------------
  20. // Helpers
  21. // --------------------------------------------------------------------------
  22. /**
  23. * Determines whether two adjacent tokens are have whitespace between them.
  24. * @param {Object} left - The left token object.
  25. * @param {Object} right - The right token object.
  26. * @returns {boolean} Whether or not there is space between the tokens.
  27. */
  28. function isSpaced (left, right) {
  29. return left.range[1] < right.range[0]
  30. }
  31. /**
  32. * Determines whether two adjacent tokens are on the same line.
  33. * @param {Object} left - The left token object.
  34. * @param {Object} right - The right token object.
  35. * @returns {boolean} Whether or not the tokens are on the same line.
  36. */
  37. function isSameLine (left, right) {
  38. return left.loc.start.line === right.loc.start.line
  39. }
  40. /**
  41. * Reports that there shouldn't be a space after the first token
  42. * @param {ASTNode} node - The node to report in the event of an error.
  43. * @param {Token} token - The token to use for the report.
  44. * @returns {void}
  45. */
  46. function reportNoBeginningSpace (node, token) {
  47. context.report(node, token.loc.start,
  48. "There should be no space after '" + token.value + "'")
  49. }
  50. /**
  51. * Reports that there shouldn't be a space before the last token
  52. * @param {ASTNode} node - The node to report in the event of an error.
  53. * @param {Token} token - The token to use for the report.
  54. * @returns {void}
  55. */
  56. function reportNoEndingSpace (node, token) {
  57. context.report(node, token.loc.start,
  58. "There should be no space before '" + token.value + "'")
  59. }
  60. /**
  61. * Reports that there should be a space after the first token
  62. * @param {ASTNode} node - The node to report in the event of an error.
  63. * @param {Token} token - The token to use for the report.
  64. * @returns {void}
  65. */
  66. function reportRequiredBeginningSpace (node, token) {
  67. context.report(node, token.loc.start,
  68. "A space is required after '" + token.value + "'")
  69. }
  70. /**
  71. * Reports that there should be a space before the last token
  72. * @param {ASTNode} node - The node to report in the event of an error.
  73. * @param {Token} token - The token to use for the report.
  74. * @returns {void}
  75. */
  76. function reportRequiredEndingSpace (node, token) {
  77. context.report(node, token.loc.start,
  78. "A space is required before '" + token.value + "'")
  79. }
  80. /**
  81. * Returns a function that checks the spacing of a node on the property name
  82. * that was passed in.
  83. * @param {String} propertyName The property on the node to check for spacing
  84. * @returns {Function} A function that will check spacing on a node
  85. */
  86. function checkSpacing (propertyName) {
  87. return function (node) {
  88. if (!node.computed) {
  89. return
  90. }
  91. var property = node[propertyName]
  92. var before = context.getTokenBefore(property)
  93. var first = context.getFirstToken(property)
  94. var last = context.getLastToken(property)
  95. var after = context.getTokenAfter(property)
  96. var startSpace, endSpace
  97. if (propertyNameMustBeEven) {
  98. if (!isSameLine(before, after)) {
  99. context.report(node, 'Expected "[" and "]" to be on the same line')
  100. return
  101. }
  102. startSpace = first.loc.start.column - before.loc.end.column
  103. endSpace = after.loc.start.column - last.loc.end.column
  104. if (startSpace !== endSpace || startSpace > 1) {
  105. context.report(node, 'Expected 1 or 0 spaces around "[" and "]"')
  106. }
  107. return
  108. }
  109. if (isSameLine(before, first)) {
  110. if (propertyNameMustBeSpaced) {
  111. if (!isSpaced(before, first) && isSameLine(before, first)) {
  112. reportRequiredBeginningSpace(node, before)
  113. }
  114. } else {
  115. if (isSpaced(before, first)) {
  116. reportNoBeginningSpace(node, before)
  117. }
  118. }
  119. }
  120. if (isSameLine(last, after)) {
  121. if (propertyNameMustBeSpaced) {
  122. if (!isSpaced(last, after) && isSameLine(last, after)) {
  123. reportRequiredEndingSpace(node, after)
  124. }
  125. } else {
  126. if (isSpaced(last, after)) {
  127. reportNoEndingSpace(node, after)
  128. }
  129. }
  130. }
  131. }
  132. }
  133. // --------------------------------------------------------------------------
  134. // Public
  135. // --------------------------------------------------------------------------
  136. return {
  137. Property: checkSpacing('key'),
  138. MemberExpression: checkSpacing('property')
  139. }
  140. }
  141. }