summaryrefslogtreecommitdiff
path: root/tools/eslint/lib/rules/comma-dangle.js
blob: da3776d4243dae4798dbb1333aa9f72be41e633a (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
/**
 * @fileoverview Rule to forbid or enforce dangling commas.
 * @author Ian Christian Myers
 * @copyright 2015 Mathias Schreck
 * @copyright 2013 Ian Christian Myers
 */

"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function (context) {
    var allowDangle = context.options[0];
    var forbidDangle = allowDangle !== "always-multiline" && allowDangle !== "always";
    var UNEXPECTED_MESSAGE = "Unexpected trailing comma.";
    var MISSING_MESSAGE = "Missing trailing comma.";

    /**
     * Checks the given node for trailing comma and reports violations.
     * @param {ASTNode} node The node of an ObjectExpression or ArrayExpression
     * @returns {void}
     */
    function checkForTrailingComma(node) {
        var items = node.properties || node.elements,
            length = items.length,
            nodeIsMultiLine = node.loc.start.line !== node.loc.end.line,
            lastItem,
            penultimateToken,
            hasDanglingComma;

        if (length) {
            lastItem = items[length - 1];
            if (lastItem) {
                penultimateToken = context.getLastToken(node, 1);
                hasDanglingComma = penultimateToken.value === ",";

                if (forbidDangle && hasDanglingComma) {
                    context.report(lastItem, penultimateToken.loc.start, UNEXPECTED_MESSAGE);
                } else if (allowDangle === "always-multiline") {
                    if (hasDanglingComma && !nodeIsMultiLine) {
                        context.report(lastItem, penultimateToken.loc.start, UNEXPECTED_MESSAGE);
                    } else if (!hasDanglingComma && nodeIsMultiLine) {
                        context.report(lastItem, penultimateToken.loc.end, MISSING_MESSAGE);
                    }
                } else if (allowDangle === "always" && !hasDanglingComma) {
                    context.report(lastItem, lastItem.loc.end, MISSING_MESSAGE);
                }
            }
        }
    }

    return {
        "ObjectExpression": checkForTrailingComma,
        "ArrayExpression": checkForTrailingComma
    };
};