diff options
Diffstat (limited to 'tools/eslint/lib/rules/spaced-comment.js')
-rw-r--r-- | tools/eslint/lib/rules/spaced-comment.js | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/tools/eslint/lib/rules/spaced-comment.js b/tools/eslint/lib/rules/spaced-comment.js new file mode 100644 index 00000000000..a57cd8699d0 --- /dev/null +++ b/tools/eslint/lib/rules/spaced-comment.js @@ -0,0 +1,143 @@ +/** + * @fileoverview Source code for spaced-comments rule + * @author Gyandeep Singh + * @copyright 2015 Gyandeep Singh. All rights reserved. + * @copyright 2014 Greg Cochard. All rights reserved. + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = function(context) { + + // Unless the first option is never, require a space + var requireSpace = context.options[0] !== "never"; + + // Default to match anything, so all will fail if there are no exceptions + var exceptionMatcher = new RegExp(" "); + var markerMatcher = new RegExp(" "); + var jsDocMatcher = new RegExp("((^(\\*)))[ \\n]"); + + // Fetch the options dict + var hasOptions = context.options.length === 2; + var optionsDict = hasOptions ? context.options[1] : {}; + + // Grab the exceptions array and build a RegExp matcher for it + var hasExceptions = hasOptions && optionsDict.exceptions && optionsDict.exceptions.length; + var unescapedExceptions = hasExceptions ? optionsDict.exceptions : []; + var exceptions; + + // Now do the same for markers + var hasMarkers = hasOptions && optionsDict.markers && optionsDict.markers.length; + var unescapedMarkers = hasMarkers ? optionsDict.markers : []; + var markers; + + function escaper(s) { + return s.replace(/([.*+?${}()|\^\[\]\/\\])/g, "\\$1"); + } + + if (hasExceptions) { + exceptions = unescapedExceptions.map(escaper); + exceptionMatcher = new RegExp("(^(" + exceptions.join(")+$)|(^(") + ")+$)"); + } + + if (hasMarkers) { + markers = unescapedMarkers.map(escaper); + + // the markerMatcher includes any markers in the list, followed by space/tab + markerMatcher = new RegExp("((^(" + markers.join("))|(^(") + ")))[ \\t\\n]"); + } + + /** + * Check to see if the block comment is jsDoc comment + * @param {ASTNode} node comment node + * @returns {boolean} True if its jsdoc comment + * @private + */ + function isJsdoc(node) { + // make sure comment type is block and it start with /**\n + return node.type === "Block" && jsDocMatcher.test(node.value); + } + + + function checkCommentForSpace(node) { + var commentIdentifier = node.type === "Block" ? "/*" : "//"; + + if (requireSpace) { + + // If length is zero, ignore it + if (node.value.length === 0) { + return; + } + + // if comment is jsdoc style then ignore it + if (isJsdoc(node)) { + return; + } + + // Check for markers now, and short-circuit if found + if (hasMarkers && markerMatcher.test(node.value)) { + return; + } + + // Space expected and not found + if (node.value.indexOf(" ") !== 0 && node.value.indexOf("\t") !== 0 && node.value.indexOf("\n") !== 0) { + + /* + * Do two tests; one for space starting the line, + * and one for a comment comprised only of exceptions + */ + if (hasExceptions && !exceptionMatcher.test(node.value)) { + context.report(node, "Expected exception block, space or tab after " + commentIdentifier + " in comment."); + } else if (!hasExceptions) { + context.report(node, "Expected space or tab after " + commentIdentifier + " in comment."); + } + } + + } else { + + if (node.value.indexOf(" ") === 0 || node.value.indexOf("\t") === 0) { + context.report(node, "Unexpected space or tab after " + commentIdentifier + " in comment."); + } + // there won't be a space or tab after commentIdentifier here, but check for the markers and whitespace + if (hasMarkers && markerMatcher.test(node.value)) { + var matches = node.value.match(markerMatcher), match = matches.length ? matches[0] : ""; + + context.report(node, "Unexpected space or tab after marker (" + match + ") in comment."); + } + } + } + + return { + + "LineComment": checkCommentForSpace, + "BlockComment": checkCommentForSpace + + }; +}; + +module.exports.schema = [ + { + "enum": ["always", "never"] + }, + { + "type": "object", + "properties": { + "exceptions": { + "type": "array", + "items": { + "type": "string" + } + }, + "markers": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } +]; |