empty-brace-spaces.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. 'use strict';
  2. const {isOpeningBraceToken} = require('eslint-utils');
  3. const {matches} = require('./selectors/index.js');
  4. const MESSAGE_ID = 'empty-brace-spaces';
  5. const messages = {
  6. [MESSAGE_ID]: 'Do not add spaces between braces.',
  7. };
  8. const selector = matches([
  9. 'BlockStatement[body.length=0]',
  10. 'ClassBody[body.length=0]',
  11. 'ObjectExpression[properties.length=0]',
  12. 'StaticBlock[body.length=0]',
  13. // Experimental https://github.com/tc39/proposal-record-tuple
  14. 'RecordExpression[properties.length=0]',
  15. ]);
  16. /** @param {import('eslint').Rule.RuleContext} context */
  17. const create = context => ({
  18. [selector](node) {
  19. const sourceCode = context.getSourceCode();
  20. const filter = node.type === 'RecordExpression'
  21. ? token => token.type === 'Punctuator' && (token.value === '#{' || token.value === '{|')
  22. : isOpeningBraceToken;
  23. const openingBrace = sourceCode.getFirstToken(node, {filter});
  24. const closingBrace = sourceCode.getLastToken(node);
  25. const [, start] = openingBrace.range;
  26. const [end] = closingBrace.range;
  27. const textBetween = sourceCode.text.slice(start, end);
  28. if (!/^\s+$/.test(textBetween)) {
  29. return;
  30. }
  31. return {
  32. loc: {
  33. start: openingBrace.loc.end,
  34. end: closingBrace.loc.start,
  35. },
  36. messageId: MESSAGE_ID,
  37. fix: fixer => fixer.removeRange([start, end]),
  38. };
  39. },
  40. });
  41. /** @type {import('eslint').Rule.RuleModule} */
  42. module.exports = {
  43. create,
  44. meta: {
  45. type: 'layout',
  46. docs: {
  47. description: 'Enforce no spaces between braces.',
  48. },
  49. fixable: 'whitespace',
  50. messages,
  51. },
  52. };