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