]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
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 | ||
12 | const astUtils = require("./utils/ast-utils"); | |
13 | ||
14 | //------------------------------------------------------------------------------ | |
15 | // Rule Definition | |
16 | //------------------------------------------------------------------------------ | |
17 | ||
18 | module.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: { | |
ebb53d86 TL |
89 | start: { |
90 | line: i, | |
91 | column: sourceCode.lines[i - 1].length | |
92 | }, | |
93 | end: { | |
94 | line: i + 1, | |
95 | column: 0 | |
96 | } | |
eb39fafa DC |
97 | }, |
98 | messageId: expectedLF ? "expectedLF" : "expectedCRLF", | |
99 | fix: createFix(range, expectedLFChars) | |
100 | }); | |
101 | } | |
102 | } | |
103 | }; | |
104 | } | |
105 | }; |