Blame view
node_modules/eslint/lib/rules/no-multi-spaces.js
4.37 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 135 136 137 138 139 140 |
/** * @fileoverview Disallow use of multiple spaces. * @author Nicholas C. Zakas * @copyright 2015 Brandon Mills. All rights reserved. * @copyright 2015 Nicholas C. Zakas. All rights reserved. */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = function(context) { // the index of the last comment that was checked var exceptions = { "Property": true }, hasExceptions = true, options = context.options[0], lastCommentIndex = 0; if (options && options.exceptions) { Object.keys(options.exceptions).forEach(function(key) { if (options.exceptions[key]) { exceptions[key] = true; } else { delete exceptions[key]; } }); hasExceptions = Object.keys(exceptions).length > 0; } /** * Determines if a given source index is in a comment or not by checking * the index against the comment range. Since the check goes straight * through the file, once an index is passed a certain comment, we can * go to the next comment to check that. * @param {int} index The source index to check. * @param {ASTNode[]} comments An array of comment nodes. * @returns {boolean} True if the index is within a comment, false if not. * @private */ function isIndexInComment(index, comments) { var comment; while (lastCommentIndex < comments.length) { comment = comments[lastCommentIndex]; if (comment.range[0] <= index && index < comment.range[1]) { return true; } else if (index > comment.range[1]) { lastCommentIndex++; } else { break; } } return false; } //-------------------------------------------------------------------------- // Public //-------------------------------------------------------------------------- return { "Program": function() { var source = context.getSource(), allComments = context.getAllComments(), pattern = /[^ \r\u2028\u2029 ] {2,}/g, // note: repeating space token, previousToken, parent; /** * Creates a fix function that removes the multiple spaces between the two tokens * @param {RuleFixer} leftToken left token * @param {RuleFixer} rightToken right token * @returns {function} fix function * @private */ function createFix(leftToken, rightToken) { return function(fixer) { return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " "); }; } while (pattern.test(source)) { // do not flag anything inside of comments if (!isIndexInComment(pattern.lastIndex, allComments)) { token = context.getTokenByRangeStart(pattern.lastIndex); if (token) { previousToken = context.getTokenBefore(token); if (hasExceptions) { parent = context.getNodeByRangeIndex(pattern.lastIndex - 1); } if (!parent || !exceptions[parent.type]) { context.report({ node: token, loc: token.loc.start, message: "Multiple spaces found before '{{value}}'.", data: { value: token.value }, fix: createFix(previousToken, token) }); } } } } } }; }; module.exports.schema = [ { "type": "object", "properties": { "exceptions": { "type": "object", "patternProperties": { "^([A-Z][a-z]*)+$": { "type": "boolean" } }, "additionalProperties": false } }, "additionalProperties": false } ]; |