index.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // @ts-nocheck
  2. 'use strict';
  3. const hasBlock = require('../../utils/hasBlock');
  4. const report = require('../../utils/report');
  5. const ruleMessages = require('../../utils/ruleMessages');
  6. const validateOptions = require('../../utils/validateOptions');
  7. const ruleName = 'declaration-block-trailing-semicolon';
  8. const messages = ruleMessages(ruleName, {
  9. expected: 'Expected a trailing semicolon',
  10. rejected: 'Unexpected trailing semicolon',
  11. });
  12. function rule(expectation, _, context) {
  13. return (root, result) => {
  14. const validOptions = validateOptions(result, ruleName, {
  15. actual: expectation,
  16. possible: ['always', 'never'],
  17. });
  18. if (!validOptions) {
  19. return;
  20. }
  21. root.walkAtRules((atRule) => {
  22. if (atRule.parent === root) {
  23. return;
  24. }
  25. if (atRule !== atRule.parent.last) {
  26. return;
  27. }
  28. if (hasBlock(atRule)) {
  29. return;
  30. }
  31. checkLastNode(atRule);
  32. });
  33. root.walkDecls((decl) => {
  34. if (decl.parent.type === 'object') {
  35. return;
  36. }
  37. if (decl !== decl.parent.last) {
  38. return;
  39. }
  40. checkLastNode(decl);
  41. });
  42. function checkLastNode(node) {
  43. let message;
  44. if (expectation === 'always') {
  45. if (node.parent.raws.semicolon) {
  46. return;
  47. }
  48. // auto-fix
  49. if (context.fix) {
  50. node.parent.raws.semicolon = true;
  51. if (node.type === 'atrule') {
  52. node.raws.between = '';
  53. node.parent.raws.after = ' ';
  54. }
  55. return;
  56. }
  57. message = messages.expected;
  58. } else if (expectation === 'never') {
  59. if (!node.parent.raws.semicolon) {
  60. return;
  61. }
  62. // auto-fix
  63. if (context.fix) {
  64. node.parent.raws.semicolon = false;
  65. return;
  66. }
  67. message = messages.rejected;
  68. }
  69. report({
  70. message,
  71. node,
  72. index: node.toString().trim().length - 1,
  73. result,
  74. ruleName,
  75. });
  76. }
  77. };
  78. }
  79. rule.ruleName = ruleName;
  80. rule.messages = messages;
  81. module.exports = rule;