File: no-callback-literal.js

package info (click to toggle)
node-eslint-plugin-node 11.1.0~ds-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 2,084 kB
  • sloc: javascript: 23,756; perl: 48; makefile: 38; sh: 32
file content (82 lines) | stat: -rw-r--r-- 2,336 bytes parent folder | download
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
 * @author Jamund Ferguson
 * See LICENSE file in root directory for full license.
 */
"use strict"

module.exports = {
    meta: {
        docs: {
            description:
                "ensure Node.js-style error-first callback pattern is followed",
            category: "Possible Errors",
            recommended: false,
            url:
                "https://github.com/mysticatea/eslint-plugin-node/blob/v11.1.0/docs/rules/no-callback-literal.md",
        },
        fixable: null,
        schema: [],
        type: "problem",
    },

    create(context) {
        const callbackNames = ["callback", "cb"]

        function isCallback(name) {
            return callbackNames.indexOf(name) > -1
        }

        return {
            CallExpression(node) {
                const errorArg = node.arguments[0]
                const calleeName = node.callee.name

                if (
                    errorArg &&
                    !couldBeError(errorArg) &&
                    isCallback(calleeName)
                ) {
                    context.report({
                        node,
                        message:
                            "Unexpected literal in error position of callback.",
                    })
                }
            },
        }
    },
}

/**
 * Determine if a node has a possiblity to be an Error object
 * @param  {ASTNode}  node  ASTNode to check
 * @returns {boolean}       True if there is a chance it contains an Error obj
 */
function couldBeError(node) {
    switch (node.type) {
        case "Identifier":
        case "CallExpression":
        case "NewExpression":
        case "MemberExpression":
        case "TaggedTemplateExpression":
        case "YieldExpression":
            return true // possibly an error object.

        case "AssignmentExpression":
            return couldBeError(node.right)

        case "SequenceExpression": {
            const exprs = node.expressions
            return exprs.length !== 0 && couldBeError(exprs[exprs.length - 1])
        }

        case "LogicalExpression":
            return couldBeError(node.left) || couldBeError(node.right)

        case "ConditionalExpression":
            return couldBeError(node.consequent) || couldBeError(node.alternate)

        default:
            return node.value === null
    }
}