diff options
Diffstat (limited to 'tools/eslint/lib/rules/no-multi-spaces.js')
-rw-r--r-- | tools/eslint/lib/rules/no-multi-spaces.js | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/tools/eslint/lib/rules/no-multi-spaces.js b/tools/eslint/lib/rules/no-multi-spaces.js new file mode 100644 index 0000000000..9e247c1533 --- /dev/null +++ b/tools/eslint/lib/rules/no-multi-spaces.js @@ -0,0 +1,101 @@ +/** + * @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 = /[^\n\r\u2028\u2029 ] {2,}/g, // note: repeating space + token, + parent; + + while (pattern.test(source)) { + + // do not flag anything inside of comments + if (!isIndexInComment(pattern.lastIndex, allComments)) { + + token = context.getTokenByRangeStart(pattern.lastIndex); + + if (token) { + if (hasExceptions) { + parent = context.getNodeByRangeIndex(pattern.lastIndex - 1); + } + + if (!parent || !exceptions[parent.type]) { + context.report(token, token.loc.start, + "Multiple spaces found before '{{value}}'.", + { value: token.value }); + } + } + + } + } + } + }; + +}; |