• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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