UNPKG

4.31 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to flag use of console object
3 * @author Nicholas C. Zakas
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Requirements
10//------------------------------------------------------------------------------
11
12const astUtils = require("./utils/ast-utils");
13
14//------------------------------------------------------------------------------
15// Rule Definition
16//------------------------------------------------------------------------------
17
18module.exports = {
19 meta: {
20 type: "suggestion",
21
22 docs: {
23 description: "disallow the use of `console`",
24 category: "Possible Errors",
25 recommended: false,
26 url: "https://eslint.org/docs/rules/no-console"
27 },
28
29 schema: [
30 {
31 type: "object",
32 properties: {
33 allow: {
34 type: "array",
35 items: {
36 type: "string"
37 },
38 minItems: 1,
39 uniqueItems: true
40 }
41 },
42 additionalProperties: false
43 }
44 ],
45
46 messages: {
47 unexpected: "Unexpected console statement."
48 }
49 },
50
51 create(context) {
52 const options = context.options[0] || {};
53 const allowed = options.allow || [];
54
55 /**
56 * Checks whether the given reference is 'console' or not.
57 *
58 * @param {eslint-scope.Reference} reference - The reference to check.
59 * @returns {boolean} `true` if the reference is 'console'.
60 */
61 function isConsole(reference) {
62 const id = reference.identifier;
63
64 return id && id.name === "console";
65 }
66
67 /**
68 * Checks whether the property name of the given MemberExpression node
69 * is allowed by options or not.
70 *
71 * @param {ASTNode} node - The MemberExpression node to check.
72 * @returns {boolean} `true` if the property name of the node is allowed.
73 */
74 function isAllowed(node) {
75 const propertyName = astUtils.getStaticPropertyName(node);
76
77 return propertyName && allowed.indexOf(propertyName) !== -1;
78 }
79
80 /**
81 * Checks whether the given reference is a member access which is not
82 * allowed by options or not.
83 *
84 * @param {eslint-scope.Reference} reference - The reference to check.
85 * @returns {boolean} `true` if the reference is a member access which
86 * is not allowed by options.
87 */
88 function isMemberAccessExceptAllowed(reference) {
89 const node = reference.identifier;
90 const parent = node.parent;
91
92 return (
93 parent.type === "MemberExpression" &&
94 parent.object === node &&
95 !isAllowed(parent)
96 );
97 }
98
99 /**
100 * Reports the given reference as a violation.
101 *
102 * @param {eslint-scope.Reference} reference - The reference to report.
103 * @returns {void}
104 */
105 function report(reference) {
106 const node = reference.identifier.parent;
107
108 context.report({
109 node,
110 loc: node.loc,
111 messageId: "unexpected"
112 });
113 }
114
115 return {
116 "Program:exit"() {
117 const scope = context.getScope();
118 const consoleVar = astUtils.getVariableByName(scope, "console");
119 const shadowed = consoleVar && consoleVar.defs.length > 0;
120
121 /*
122 * 'scope.through' includes all references to undefined
123 * variables. If the variable 'console' is not defined, it uses
124 * 'scope.through'.
125 */
126 const references = consoleVar
127 ? consoleVar.references
128 : scope.through.filter(isConsole);
129
130 if (!shadowed) {
131 references
132 .filter(isMemberAccessExceptAllowed)
133 .forEach(report);
134 }
135 }
136 };
137 }
138};