]> git.proxmox.com Git - pve-eslint.git/blame - eslint/lib/rules/no-mixed-spaces-and-tabs.js
import 8.3.0 source
[pve-eslint.git] / eslint / lib / rules / no-mixed-spaces-and-tabs.js
CommitLineData
eb39fafa
DC
1/**
2 * @fileoverview Disallow mixed spaces and tabs for indentation
3 * @author Jary Niebur
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Rule Definition
9//------------------------------------------------------------------------------
10
11module.exports = {
12 meta: {
13 type: "layout",
14
15 docs: {
16 description: "disallow mixed spaces and tabs for indentation",
eb39fafa
DC
17 recommended: true,
18 url: "https://eslint.org/docs/rules/no-mixed-spaces-and-tabs"
19 },
20
21 schema: [
22 {
23 enum: ["smart-tabs", true, false]
24 }
25 ],
26
27 messages: {
28 mixedSpacesAndTabs: "Mixed spaces and tabs."
29 }
30 },
31
32 create(context) {
33 const sourceCode = context.getSourceCode();
34
35 let smartTabs;
36
37 switch (context.options[0]) {
38 case true: // Support old syntax, maybe add deprecation warning here
39 case "smart-tabs":
40 smartTabs = true;
41 break;
42 default:
43 smartTabs = false;
44 }
45
46 //--------------------------------------------------------------------------
47 // Public
48 //--------------------------------------------------------------------------
49
50 return {
51
52 "Program:exit"(node) {
53 const lines = sourceCode.lines,
54 comments = sourceCode.getAllComments(),
55 ignoredCommentLines = new Set();
56
57 // Add all lines except the first ones.
58 comments.forEach(comment => {
59 for (let i = comment.loc.start.line + 1; i <= comment.loc.end.line; i++) {
60 ignoredCommentLines.add(i);
61 }
62 });
63
64 /*
65 * At least one space followed by a tab
66 * or the reverse before non-tab/-space
67 * characters begin.
68 */
d3726936 69 let regex = /^(?=( +|\t+))\1(?:\t| )/u;
eb39fafa
DC
70
71 if (smartTabs) {
72
73 /*
74 * At least one space followed by a tab
75 * before non-tab/-space characters begin.
76 */
d3726936 77 regex = /^(?=(\t*))\1(?=( +))\2\t/u;
eb39fafa
DC
78 }
79
80 lines.forEach((line, i) => {
81 const match = regex.exec(line);
82
83 if (match) {
d3726936
TL
84 const lineNumber = i + 1;
85 const loc = {
86 start: {
87 line: lineNumber,
88 column: match[0].length - 2
89 },
90 end: {
91 line: lineNumber,
92 column: match[0].length
93 }
94 };
eb39fafa
DC
95
96 if (!ignoredCommentLines.has(lineNumber)) {
d3726936 97 const containingNode = sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(loc.start));
eb39fafa
DC
98
99 if (!(containingNode && ["Literal", "TemplateElement"].includes(containingNode.type))) {
100 context.report({
101 node,
102 loc,
103 messageId: "mixedSpacesAndTabs"
104 });
105 }
106 }
107 }
108 });
109 }
110 };
111 }
112};