minor adjustment to readme
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / no-alert.js
1 /**
2  * @fileoverview Rule to flag use of alert, confirm, prompt
3  * @author Nicholas C. Zakas
4  */
5 "use strict";
6
7 //------------------------------------------------------------------------------
8 // Requirements
9 //------------------------------------------------------------------------------
10
11 const getPropertyName = require("./utils/ast-utils").getStaticPropertyName;
12
13 //------------------------------------------------------------------------------
14 // Helpers
15 //------------------------------------------------------------------------------
16
17 /**
18  * Checks if the given name is a prohibited identifier.
19  * @param {string} name The name to check
20  * @returns {boolean} Whether or not the name is prohibited.
21  */
22 function isProhibitedIdentifier(name) {
23     return /^(alert|confirm|prompt)$/u.test(name);
24 }
25
26 /**
27  * Finds the eslint-scope reference in the given scope.
28  * @param {Object} scope The scope to search.
29  * @param {ASTNode} node The identifier node.
30  * @returns {Reference|null} Returns the found reference or null if none were found.
31  */
32 function findReference(scope, node) {
33     const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] &&
34             reference.identifier.range[1] === node.range[1]);
35
36     if (references.length === 1) {
37         return references[0];
38     }
39     return null;
40 }
41
42 /**
43  * Checks if the given identifier node is shadowed in the given scope.
44  * @param {Object} scope The current scope.
45  * @param {string} node The identifier node to check
46  * @returns {boolean} Whether or not the name is shadowed.
47  */
48 function isShadowed(scope, node) {
49     const reference = findReference(scope, node);
50
51     return reference && reference.resolved && reference.resolved.defs.length > 0;
52 }
53
54 /**
55  * Checks if the given identifier node is a ThisExpression in the global scope or the global window property.
56  * @param {Object} scope The current scope.
57  * @param {string} node The identifier node to check
58  * @returns {boolean} Whether or not the node is a reference to the global object.
59  */
60 function isGlobalThisReferenceOrGlobalWindow(scope, node) {
61     if (scope.type === "global" && node.type === "ThisExpression") {
62         return true;
63     }
64     if (node.name === "window") {
65         return !isShadowed(scope, node);
66     }
67
68     return false;
69 }
70
71 //------------------------------------------------------------------------------
72 // Rule Definition
73 //------------------------------------------------------------------------------
74
75 module.exports = {
76     meta: {
77         type: "suggestion",
78
79         docs: {
80             description: "disallow the use of `alert`, `confirm`, and `prompt`",
81             category: "Best Practices",
82             recommended: false,
83             url: "https://eslint.org/docs/rules/no-alert"
84         },
85
86         schema: [],
87
88         messages: {
89             unexpected: "Unexpected {{name}}."
90         }
91     },
92
93     create(context) {
94         return {
95             CallExpression(node) {
96                 const callee = node.callee,
97                     currentScope = context.getScope();
98
99                 // without window.
100                 if (callee.type === "Identifier") {
101                     const name = callee.name;
102
103                     if (!isShadowed(currentScope, callee) && isProhibitedIdentifier(callee.name)) {
104                         context.report({
105                             node,
106                             messageId: "unexpected",
107                             data: { name }
108                         });
109                     }
110
111                 } else if (callee.type === "MemberExpression" && isGlobalThisReferenceOrGlobalWindow(currentScope, callee.object)) {
112                     const name = getPropertyName(callee);
113
114                     if (isProhibitedIdentifier(name)) {
115                         context.report({
116                             node,
117                             messageId: "unexpected",
118                             data: { name }
119                         });
120                     }
121                 }
122
123             }
124         };
125
126     }
127 };