2 * @fileoverview Disallow mixed spaces and tabs for indentation
7 //------------------------------------------------------------------------------
9 //------------------------------------------------------------------------------
16 description: "disallow mixed spaces and tabs for indentation",
17 category: "Stylistic Issues",
19 url: "https://eslint.org/docs/rules/no-mixed-spaces-and-tabs"
24 enum: ["smart-tabs", true, false]
29 mixedSpacesAndTabs: "Mixed spaces and tabs."
34 const sourceCode = context.getSourceCode();
38 switch (context.options[0]) {
39 case true: // Support old syntax, maybe add deprecation warning here
47 //--------------------------------------------------------------------------
49 //--------------------------------------------------------------------------
53 "Program:exit"(node) {
54 const lines = sourceCode.lines,
55 comments = sourceCode.getAllComments(),
56 ignoredCommentLines = new Set();
58 // Add all lines except the first ones.
59 comments.forEach(comment => {
60 for (let i = comment.loc.start.line + 1; i <= comment.loc.end.line; i++) {
61 ignoredCommentLines.add(i);
66 * At least one space followed by a tab
67 * or the reverse before non-tab/-space
70 let regex = /^(?=( +|\t+))\1(?:\t| )/u;
75 * At least one space followed by a tab
76 * before non-tab/-space characters begin.
78 regex = /^(?=(\t*))\1(?=( +))\2\t/u;
81 lines.forEach((line, i) => {
82 const match = regex.exec(line);
85 const lineNumber = i + 1;
89 column: match[0].length - 2
93 column: match[0].length
97 if (!ignoredCommentLines.has(lineNumber)) {
98 const containingNode = sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(loc.start));
100 if (!(containingNode && ["Literal", "TemplateElement"].includes(containingNode.type))) {
104 messageId: "mixedSpacesAndTabs"