aboutsummaryrefslogtreecommitdiff
path: root/tools/eslint-rules/align-multiline-assignment.js
blob: 80896b5e96296de7fa8e6fc886c831b398b238cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
 * @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);
    // const start = declaration.init.loc.start;
    if (msg)
      context.report(node, msg);
  });
}

module.exports = function(context) {
  return {
    'AssignmentExpression': (node) => testAssignment(context, node),
    'VariableDeclaration': (node) => testDeclaration(context, node)
  };
};