linebreak-style.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /**
  2. * @fileoverview Rule to enforce a single linebreak style.
  3. * @author Erik Mueller
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Requirements
  8. //------------------------------------------------------------------------------
  9. const astUtils = require("./utils/ast-utils");
  10. //------------------------------------------------------------------------------
  11. // Rule Definition
  12. //------------------------------------------------------------------------------
  13. /** @type {import('../shared/types').Rule} */
  14. module.exports = {
  15. meta: {
  16. type: "layout",
  17. docs: {
  18. description: "Enforce consistent linebreak style",
  19. recommended: false,
  20. url: "https://eslint.org/docs/rules/linebreak-style"
  21. },
  22. fixable: "whitespace",
  23. schema: [
  24. {
  25. enum: ["unix", "windows"]
  26. }
  27. ],
  28. messages: {
  29. expectedLF: "Expected linebreaks to be 'LF' but found 'CRLF'.",
  30. expectedCRLF: "Expected linebreaks to be 'CRLF' but found 'LF'."
  31. }
  32. },
  33. create(context) {
  34. const sourceCode = context.getSourceCode();
  35. //--------------------------------------------------------------------------
  36. // Helpers
  37. //--------------------------------------------------------------------------
  38. /**
  39. * Builds a fix function that replaces text at the specified range in the source text.
  40. * @param {int[]} range The range to replace
  41. * @param {string} text The text to insert.
  42. * @returns {Function} Fixer function
  43. * @private
  44. */
  45. function createFix(range, text) {
  46. return function(fixer) {
  47. return fixer.replaceTextRange(range, text);
  48. };
  49. }
  50. //--------------------------------------------------------------------------
  51. // Public
  52. //--------------------------------------------------------------------------
  53. return {
  54. Program: function checkForLinebreakStyle(node) {
  55. const linebreakStyle = context.options[0] || "unix",
  56. expectedLF = linebreakStyle === "unix",
  57. expectedLFChars = expectedLF ? "\n" : "\r\n",
  58. source = sourceCode.getText(),
  59. pattern = astUtils.createGlobalLinebreakMatcher();
  60. let match;
  61. let i = 0;
  62. while ((match = pattern.exec(source)) !== null) {
  63. i++;
  64. if (match[0] === expectedLFChars) {
  65. continue;
  66. }
  67. const index = match.index;
  68. const range = [index, index + match[0].length];
  69. context.report({
  70. node,
  71. loc: {
  72. start: {
  73. line: i,
  74. column: sourceCode.lines[i - 1].length
  75. },
  76. end: {
  77. line: i + 1,
  78. column: 0
  79. }
  80. },
  81. messageId: expectedLF ? "expectedLF" : "expectedCRLF",
  82. fix: createFix(range, expectedLFChars)
  83. });
  84. }
  85. }
  86. };
  87. }
  88. };