report.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. 'use strict';
  2. /** @typedef {import('stylelint').Problem} Problem */
  3. /**
  4. * Report a problem.
  5. *
  6. * This function accounts for `disabledRanges` attached to the result.
  7. * That is, if the reported problem is within a disabledRange,
  8. * it is ignored. Otherwise, it is attached to the result as a
  9. * postcss warning.
  10. *
  11. * It also accounts for the rule's severity.
  12. *
  13. * You *must* pass *either* a node or a line number.
  14. * @param {Problem} problem
  15. * @returns {void}
  16. */
  17. function report(problem) {
  18. const ruleName = problem.ruleName;
  19. const result = problem.result;
  20. const message = problem.message;
  21. const line = problem.line;
  22. const node = problem.node;
  23. const index = problem.index;
  24. const word = problem.word;
  25. result.stylelint = result.stylelint || {
  26. ruleSeverities: {},
  27. customMessages: {},
  28. ruleMetadata: {},
  29. };
  30. // In quiet mode, mere warnings are ignored
  31. if (result.stylelint.quiet && result.stylelint.ruleSeverities[ruleName] !== 'error') {
  32. return;
  33. }
  34. // If a line is not passed, use the node.positionBy method to get the
  35. // line number that the complaint pertains to
  36. const startLine = line || node.positionBy({ index }).line;
  37. const { ignoreDisables } = result.stylelint.config || {};
  38. if (result.stylelint.disabledRanges) {
  39. const ranges = result.stylelint.disabledRanges[ruleName] || result.stylelint.disabledRanges.all;
  40. for (const range of ranges) {
  41. if (
  42. // If the problem is within a disabledRange,
  43. // and that disabledRange's rules include this one,
  44. // do not register a warning
  45. range.start <= startLine &&
  46. (range.end === undefined || range.end >= startLine) &&
  47. (!range.rules || range.rules.includes(ruleName))
  48. ) {
  49. // Collect disabled warnings
  50. // Used to report `needlessDisables` in subsequent processing.
  51. const disabledWarnings =
  52. result.stylelint.disabledWarnings || (result.stylelint.disabledWarnings = []);
  53. disabledWarnings.push({
  54. rule: ruleName,
  55. line: startLine,
  56. });
  57. if (!ignoreDisables) {
  58. return;
  59. }
  60. break;
  61. }
  62. }
  63. }
  64. const severity = result.stylelint.ruleSeverities && result.stylelint.ruleSeverities[ruleName];
  65. if (!result.stylelint.stylelintError && severity === 'error') {
  66. result.stylelint.stylelintError = true;
  67. }
  68. /** @type {import('stylelint').WarningOptions} */
  69. const warningProperties = {
  70. severity,
  71. rule: ruleName,
  72. };
  73. if (node) {
  74. warningProperties.node = node;
  75. }
  76. if (index) {
  77. warningProperties.index = index;
  78. }
  79. if (word) {
  80. warningProperties.word = word;
  81. }
  82. const warningMessage =
  83. (result.stylelint.customMessages && result.stylelint.customMessages[ruleName]) || message;
  84. result.warn(warningMessage, warningProperties);
  85. }
  86. module.exports = /** @type {typeof import('stylelint').utils.report} */ (report);