node/tools/eslint/lib/rules/operator-linebreak.js
Yosuke Furukawa f9dd34d301 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>
2015-05-09 12:09:52 +09:00

101 lines
3.6 KiB
JavaScript

/**
* @fileoverview Operator linebreak - enforces operator linebreak style of two types: after and before
* @author Benoît Zugmeyer
* @copyright 2015 Benoît Zugmeyer. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var style = context.options[0] || "after";
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Checks whether two tokens are on the same line.
* @param {ASTNode} left The leftmost token.
* @param {ASTNode} right The rightmost token.
* @returns {boolean} True if the tokens are on the same line, false if not.
* @private
*/
function isSameLine(left, right) {
return left.loc.end.line === right.loc.start.line;
}
/**
* Checks the operator placement
* @param {ASTNode} node The binary operator node to check
* @private
* @returns {void}
*/
function validateBinaryExpression(node) {
var leftToken = context.getLastToken(node.left || node.id);
var operatorToken = context.getTokenAfter(leftToken);
// When the left part of a binary expression is a single expression wrapped in
// parentheses (ex: `(a) + b`), leftToken will be the last token of the expression
// and operatorToken will be the closing parenthesis.
// The leftToken should be the last closing parenthesis, and the operatorToken
// should be the token right after that.
while (operatorToken.value === ")") {
leftToken = operatorToken;
operatorToken = context.getTokenAfter(operatorToken);
}
var rightToken = context.getTokenAfter(operatorToken);
var operator = operatorToken.value;
// if single line
if (isSameLine(leftToken, operatorToken) &&
isSameLine(operatorToken, rightToken)) {
return;
} else if (!isSameLine(leftToken, operatorToken) &&
!isSameLine(operatorToken, rightToken)) {
// lone operator
context.report(node, {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
}, "Bad line breaking before and after '" + operator + "'.");
} else if (style === "before" && isSameLine(leftToken, operatorToken)) {
context.report(node, {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
}, "'" + operator + "' should be placed at the beginning of the line.");
} else if (style === "after" && isSameLine(operatorToken, rightToken)) {
context.report(node, {
line: operatorToken.loc.end.line,
column: operatorToken.loc.end.column
}, "'" + operator + "' should be placed at the end of the line.");
}
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"BinaryExpression": validateBinaryExpression,
"LogicalExpression": validateBinaryExpression,
"AssignmentExpression": validateBinaryExpression,
"VariableDeclarator": function (node) {
if (node.init) {
validateBinaryExpression(node);
}
}
};
};