From be070d775f768b7517ad5b4be1ae3ee283407d3d Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 15 Apr 2016 21:22:12 -0700 Subject: [PATCH] tools: lint for alignment of variable assignments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enforce alignment/indentation on variable assignments that span multiple lines. PR-URL: https://github.com/nodejs/node/pull/6242 Reviewed-By: Ben Noordhuis Reviewed-By: Johan Bergström Reviewed-By: James M Snell --- .eslintrc | 4 +- .../align-multiline-assignment.js | 67 +++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 tools/eslint-rules/align-multiline-assignment.js diff --git a/.eslintrc b/.eslintrc index 8e01cc4c94c0e4..e8496e8560f0a7 100644 --- a/.eslintrc +++ b/.eslintrc @@ -13,7 +13,7 @@ rules: no-duplicate-case: 2 no-empty-character-class: 2 no-ex-assign: 2 - no-extra-boolean-cast : 2 + no-extra-boolean-cast: 2 no-extra-parens: [2, "functions"] no-extra-semi: 2 no-func-assign: 2 @@ -86,7 +86,7 @@ rules: # Custom rules in tools/eslint-rules new-with-error: [2, "Error", "RangeError", "TypeError", "SyntaxError", "ReferenceError"] - + align-multiline-assignment: 2 # Global scoped method and vars globals: diff --git a/tools/eslint-rules/align-multiline-assignment.js b/tools/eslint-rules/align-multiline-assignment.js new file mode 100644 index 00000000000000..8e2f5ed1ee7e90 --- /dev/null +++ b/tools/eslint-rules/align-multiline-assignment.js @@ -0,0 +1,67 @@ +/** + * @fileoverview Align multiline variable assignments + * @author Rich Trott + */ +'use strict'; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ +function getBinaryExpressionStarts(binaryExpression, starts) { + function getStartsFromOneSide(side, starts) { + starts.push(side.loc.start); + if (side.type === 'BinaryExpression') { + starts = getBinaryExpressionStarts(side, starts); + } + return starts; + } + + starts = getStartsFromOneSide(binaryExpression.left, starts); + starts = getStartsFromOneSide(binaryExpression.right, starts); + return starts; +} + +function checkExpressionAlignment(expression) { + if (!expression) + return; + + var msg = ''; + + switch (expression.type) { + case 'BinaryExpression': + var starts = getBinaryExpressionStarts(expression, []); + var startLine = starts[0].line; + const startColumn = starts[0].column; + starts.forEach((loc) => { + if (loc.line > startLine) { + startLine = loc.line; + if (loc.column !== startColumn) { + msg = 'Misaligned multiline assignment'; + } + } + }); + break; + } + return msg; +} + +function testAssignment(context, node) { + const msg = checkExpressionAlignment(node.right); + if (msg) + context.report(node, msg); +} + +function testDeclaration(context, node) { + node.declarations.forEach((declaration) => { + const msg = checkExpressionAlignment(declaration.init); + if (msg) + context.report(node, msg); + }); +} + +module.exports = function(context) { + return { + 'AssignmentExpression': (node) => testAssignment(context, node), + 'VariableDeclaration': (node) => testDeclaration(context, node) + }; +};