source: imaps-frontend/node_modules/eslint/lib/rules/no-console.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 7.2 KB
RevLine 
[d565449]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
18/** @type {import('../shared/types').Rule} */
19module.exports = {
20 meta: {
21 type: "suggestion",
22
23 docs: {
24 description: "Disallow the use of `console`",
25 recommended: false,
26 url: "https://eslint.org/docs/latest/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 hasSuggestions: true,
47
48 messages: {
49 unexpected: "Unexpected console statement.",
50 removeConsole: "Remove the console.{{ propertyName }}()."
51 }
52 },
53
54 create(context) {
55 const options = context.options[0] || {};
56 const allowed = options.allow || [];
57 const sourceCode = context.sourceCode;
58
59 /**
60 * Checks whether the given reference is 'console' or not.
61 * @param {eslint-scope.Reference} reference The reference to check.
62 * @returns {boolean} `true` if the reference is 'console'.
63 */
64 function isConsole(reference) {
65 const id = reference.identifier;
66
67 return id && id.name === "console";
68 }
69
70 /**
71 * Checks whether the property name of the given MemberExpression node
72 * is allowed by options or not.
73 * @param {ASTNode} node The MemberExpression node to check.
74 * @returns {boolean} `true` if the property name of the node is allowed.
75 */
76 function isAllowed(node) {
77 const propertyName = astUtils.getStaticPropertyName(node);
78
79 return propertyName && allowed.includes(propertyName);
80 }
81
82 /**
83 * Checks whether the given reference is a member access which is not
84 * allowed by options or not.
85 * @param {eslint-scope.Reference} reference The reference to check.
86 * @returns {boolean} `true` if the reference is a member access which
87 * is not allowed by options.
88 */
89 function isMemberAccessExceptAllowed(reference) {
90 const node = reference.identifier;
91 const parent = node.parent;
92
93 return (
94 parent.type === "MemberExpression" &&
95 parent.object === node &&
96 !isAllowed(parent)
97 );
98 }
99
100 /**
101 * Checks if removing the ExpressionStatement node will cause ASI to
102 * break.
103 * eg.
104 * foo()
105 * console.log();
106 * [1, 2, 3].forEach(a => doSomething(a))
107 *
108 * Removing the console.log(); statement should leave two statements, but
109 * here the two statements will become one because [ causes continuation after
110 * foo().
111 * @param {ASTNode} node The ExpressionStatement node to check.
112 * @returns {boolean} `true` if ASI will break after removing the ExpressionStatement
113 * node.
114 */
115 function maybeAsiHazard(node) {
116 const SAFE_TOKENS_BEFORE = /^[:;{]$/u; // One of :;{
117 const UNSAFE_CHARS_AFTER = /^[-[(/+`]/u; // One of [(/+-`
118
119 const tokenBefore = sourceCode.getTokenBefore(node);
120 const tokenAfter = sourceCode.getTokenAfter(node);
121
122 return (
123 Boolean(tokenAfter) &&
124 UNSAFE_CHARS_AFTER.test(tokenAfter.value) &&
125 tokenAfter.value !== "++" &&
126 tokenAfter.value !== "--" &&
127 Boolean(tokenBefore) &&
128 !SAFE_TOKENS_BEFORE.test(tokenBefore.value)
129 );
130 }
131
132 /**
133 * Checks if the MemberExpression node's parent.parent.parent is a
134 * Program, BlockStatement, StaticBlock, or SwitchCase node. This check
135 * is necessary to avoid providing a suggestion that might cause a syntax error.
136 *
137 * eg. if (a) console.log(b), removing console.log() here will lead to a
138 * syntax error.
139 * if (a) { console.log(b) }, removing console.log() here is acceptable.
140 *
141 * Additionally, it checks if the callee of the CallExpression node is
142 * the node itself.
143 *
144 * eg. foo(console.log), cannot provide a suggestion here.
145 * @param {ASTNode} node The MemberExpression node to check.
146 * @returns {boolean} `true` if a suggestion can be provided for a node.
147 */
148 function canProvideSuggestions(node) {
149 return (
150 node.parent.type === "CallExpression" &&
151 node.parent.callee === node &&
152 node.parent.parent.type === "ExpressionStatement" &&
153 astUtils.STATEMENT_LIST_PARENTS.has(node.parent.parent.parent.type) &&
154 !maybeAsiHazard(node.parent.parent)
155 );
156 }
157
158 /**
159 * Reports the given reference as a violation.
160 * @param {eslint-scope.Reference} reference The reference to report.
161 * @returns {void}
162 */
163 function report(reference) {
164 const node = reference.identifier.parent;
165
166 const propertyName = astUtils.getStaticPropertyName(node);
167
168 context.report({
169 node,
170 loc: node.loc,
171 messageId: "unexpected",
172 suggest: canProvideSuggestions(node)
173 ? [{
174 messageId: "removeConsole",
175 data: { propertyName },
176 fix(fixer) {
177 return fixer.remove(node.parent.parent);
178 }
179 }]
180 : []
181 });
182 }
183
184 return {
185 "Program:exit"(node) {
186 const scope = sourceCode.getScope(node);
187 const consoleVar = astUtils.getVariableByName(scope, "console");
188 const shadowed = consoleVar && consoleVar.defs.length > 0;
189
190 /*
191 * 'scope.through' includes all references to undefined
192 * variables. If the variable 'console' is not defined, it uses
193 * 'scope.through'.
194 */
195 const references = consoleVar
196 ? consoleVar.references
197 : scope.through.filter(isConsole);
198
199 if (!shadowed) {
200 references
201 .filter(isMemberAccessExceptAllowed)
202 .forEach(report);
203 }
204 }
205 };
206 }
207};
Note: See TracBrowser for help on using the repository browser.