diff options
author | Yosuke Furukawa <yosuke.furukawa@gmail.com> | 2015-04-29 02:03:05 +0900 |
---|---|---|
committer | Yosuke Furukawa <yosuke.furukawa@gmail.com> | 2015-05-09 12:09:52 +0900 |
commit | f9dd34d301ab385ae316769b85ef916f9b70b6f6 (patch) | |
tree | 9ce5db7bdff46e587535de5549eef7e02656f5d8 /tools/eslint/lib/rules/brace-style.js | |
parent | 5883a59b21a97e8b7339f435c977155a2c29ba8d (diff) | |
download | android-node-v8-f9dd34d301ab385ae316769b85ef916f9b70b6f6.tar.gz android-node-v8-f9dd34d301ab385ae316769b85ef916f9b70b6f6.tar.bz2 android-node-v8-f9dd34d301ab385ae316769b85ef916f9b70b6f6.zip |
tools: replace closure-linter with eslint
PR-URL: https://github.com/iojs/io.js/pull/1539
Fixes: https://github.com/iojs/io.js/issues/1253
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
Reviewed-By: Johan Bergström <bugs@bergstroem.nu>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Diffstat (limited to 'tools/eslint/lib/rules/brace-style.js')
-rw-r--r-- | tools/eslint/lib/rules/brace-style.js | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/tools/eslint/lib/rules/brace-style.js b/tools/eslint/lib/rules/brace-style.js new file mode 100644 index 0000000000..599e86f68b --- /dev/null +++ b/tools/eslint/lib/rules/brace-style.js @@ -0,0 +1,204 @@ +/** + * @fileoverview Rule to flag block statements that do not use the one true brace style + * @author Ian Christian Myers + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = function(context) { + var style = context.options[0] || "1tbs"; + var params = context.options[1] || {}; + + var OPEN_MESSAGE = "Opening curly brace does not appear on the same line as controlling statement.", + BODY_MESSAGE = "Statement inside of curly braces should be on next line.", + CLOSE_MESSAGE = "Closing curly brace does not appear on the same line as the subsequent block.", + CLOSE_MESSAGE_SINGLE = "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.", + CLOSE_MESSAGE_STROUSTRUP = "Closing curly brace appears on the same line as the subsequent block."; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Determines if a given node is a block statement. + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node is a block statement, false if not. + * @private + */ + function isBlock(node) { + return node && node.type === "BlockStatement"; + } + + + /** + * Binds a list of properties to a function that verifies that the opening + * curly brace is on the same line as its controlling statement of a given + * node. + * @param {...string} The properties to check on the node. + * @returns {Function} A function that will perform the check on a node + * @private + */ + function checkBlock() { + var blockProperties = arguments; + + return function(node) { + [].forEach.call(blockProperties, function(blockProp) { + var block = node[blockProp], previousToken, curlyToken, curlyTokenEnd, curlyTokensOnSameLine; + block = node[blockProp]; + + if (isBlock(block)) { + + previousToken = context.getTokenBefore(block); + curlyToken = context.getFirstToken(block); + curlyTokenEnd = context.getLastToken(block); + curlyTokensOnSameLine = curlyToken.loc.start.line === curlyTokenEnd.loc.start.line; + + if (previousToken.loc.start.line !== curlyToken.loc.start.line) { + context.report(node, OPEN_MESSAGE); + } else if (block.body.length && params.allowSingleLine) { + + if (curlyToken.loc.start.line === block.body[0].loc.start.line && !curlyTokensOnSameLine) { + context.report(block.body[0], BODY_MESSAGE); + } else if (curlyTokenEnd.loc.start.line === block.body[block.body.length - 1].loc.start.line && !curlyTokensOnSameLine) { + context.report(block.body[block.body.length - 1], CLOSE_MESSAGE_SINGLE); + } + + } else if (block.body.length && curlyToken.loc.start.line === block.body[0].loc.start.line) { + context.report(block.body[0], BODY_MESSAGE); + } + } + }); + }; + } + + /** + * Enforces the configured brace style on IfStatements + * @param {ASTNode} node An IfStatement node. + * @returns {void} + * @private + */ + function checkIfStatement(node) { + var tokens, + alternateIsBlock = false, + alternateIsIfBlock = false; + + checkBlock("consequent", "alternate")(node); + + if (node.alternate) { + + alternateIsBlock = isBlock(node.alternate); + alternateIsIfBlock = node.alternate.type === "IfStatement" && isBlock(node.alternate.consequent); + + if (alternateIsBlock || alternateIsIfBlock) { + tokens = context.getTokensBefore(node.alternate, 2); + + if (style === "1tbs") { + if (tokens[0].loc.start.line !== tokens[1].loc.start.line) { + context.report(node.alternate, CLOSE_MESSAGE); + } + } else if (style === "stroustrup") { + if (tokens[0].loc.start.line === tokens[1].loc.start.line) { + context.report(node.alternate, CLOSE_MESSAGE_STROUSTRUP); + } + } + } + + } + } + + /** + * Enforces the configured brace style on TryStatements + * @param {ASTNode} node A TryStatement node. + * @returns {void} + * @private + */ + function checkTryStatement(node) { + var tokens; + + checkBlock("block", "finalizer")(node); + + if (isBlock(node.finalizer)) { + tokens = context.getTokensBefore(node.finalizer, 2); + if (style === "1tbs") { + if (tokens[0].loc.start.line !== tokens[1].loc.start.line) { + context.report(node.finalizer, CLOSE_MESSAGE); + } + } else if (style === "stroustrup") { + if (tokens[0].loc.start.line === tokens[1].loc.start.line) { + context.report(node.finalizer, CLOSE_MESSAGE_STROUSTRUP); + } + } + } + } + + /** + * Enforces the configured brace style on CatchClauses + * @param {ASTNode} node A CatchClause node. + * @returns {void} + * @private + */ + function checkCatchClause(node) { + var previousToken = context.getTokenBefore(node), + firstToken = context.getFirstToken(node); + + checkBlock("body")(node); + + if (isBlock(node.body)) { + if (style === "1tbs") { + if (previousToken.loc.start.line !== firstToken.loc.start.line) { + context.report(node, CLOSE_MESSAGE); + } + } else if (style === "stroustrup") { + if (previousToken.loc.start.line === firstToken.loc.start.line) { + context.report(node, CLOSE_MESSAGE_STROUSTRUP); + } + } + } + } + + /** + * Enforces the configured brace style on SwitchStatements + * @param {ASTNode} node A SwitchStatement node. + * @returns {void} + * @private + */ + function checkSwitchStatement(node) { + var tokens; + if (node.cases && node.cases.length) { + tokens = context.getTokensBefore(node.cases[0], 2); + if (tokens[0].loc.start.line !== tokens[1].loc.start.line) { + context.report(node, OPEN_MESSAGE); + } + } else { + tokens = context.getLastTokens(node, 3); + if (tokens[0].loc.start.line !== tokens[1].loc.start.line) { + context.report(node, OPEN_MESSAGE); + } + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + "FunctionDeclaration": checkBlock("body"), + "FunctionExpression": checkBlock("body"), + "ArrowFunctionExpression": checkBlock("body"), + "IfStatement": checkIfStatement, + "TryStatement": checkTryStatement, + "CatchClause": checkCatchClause, + "DoWhileStatement": checkBlock("body"), + "WhileStatement": checkBlock("body"), + "WithStatement": checkBlock("body"), + "ForStatement": checkBlock("body"), + "ForInStatement": checkBlock("body"), + "ForOfStatement": checkBlock("body"), + "SwitchStatement": checkSwitchStatement + }; + +}; |