Blame view
node_modules/eslint/lib/rules/no-mixed-spaces-and-tabs.js
4.01 KB
c39994410
|
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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
/** * @fileoverview Disallow mixed spaces and tabs for indentation * @author Jary Niebur * @copyright 2014 Nicholas C. Zakas. All rights reserved. * @copyright 2014 Jary Niebur. All rights reserved. * See LICENSE in root directory for full license. */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = function(context) { var smartTabs, ignoredLocs = []; switch (context.options[0]) { case true: // Support old syntax, maybe add deprecation warning here case "smart-tabs": smartTabs = true; break; default: smartTabs = false; } /** * Determines if a given line and column are before a location. * @param {Location} loc The location object from an AST node. * @param {int} line The line to check. * @param {int} column The column to check. * @returns {boolean} True if the line and column are before the location, false if not. * @private */ function beforeLoc(loc, line, column) { if (line < loc.start.line) { return true; } return line === loc.start.line && column < loc.start.column; } /** * Determines if a given line and column are after a location. * @param {Location} loc The location object from an AST node. * @param {int} line The line to check. * @param {int} column The column to check. * @returns {boolean} True if the line and column are after the location, false if not. * @private */ function afterLoc(loc, line, column) { if (line > loc.end.line) { return true; } return line === loc.end.line && column > loc.end.column; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { "TemplateElement": function(node) { ignoredLocs.push(node.loc); }, "Program:exit": function(node) { /* * At least one space followed by a tab * or the reverse before non-tab/-space * characters begin. */ var regex = /^(?=[\t ]*(\t | \t))/, match, lines = context.getSourceLines(), comments = context.getAllComments(); comments.forEach(function(comment) { ignoredLocs.push(comment.loc); }); ignoredLocs.sort(function(first, second) { if (beforeLoc(first, second.start.line, second.start.column)) { return 1; } if (beforeLoc(second, first.start.line, second.start.column)) { return -1; } return 0; }); if (smartTabs) { /* * At least one space followed by a tab * before non-tab/-space characters begin. */ regex = /^(?=[\t ]* \t)/; } lines.forEach(function(line, i) { match = regex.exec(line); if (match) { var lineNumber = i + 1, column = match.index + 1; for (var j = 0; j < ignoredLocs.length; j++) { if (beforeLoc(ignoredLocs[j], lineNumber, column)) { continue; } if (afterLoc(ignoredLocs[j], lineNumber, column)) { continue; } return; } context.report(node, { line: lineNumber, column: column }, "Mixed spaces and tabs."); } }); } }; }; module.exports.schema = [ { "enum": ["smart-tabs", true, false] } ]; |