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