UNPKG

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