]> git.proxmox.com Git - pve-eslint.git/blame - eslint/lib/rules/consistent-this.js
import 8.3.0 source
[pve-eslint.git] / eslint / lib / rules / consistent-this.js
CommitLineData
eb39fafa
DC
1/**
2 * @fileoverview Rule to enforce consistent naming of "this" context variables
3 * @author Raphael Pigulla
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Rule Definition
9//------------------------------------------------------------------------------
10
11module.exports = {
12 meta: {
13 type: "suggestion",
14
15 docs: {
16 description: "enforce consistent naming when capturing the current execution context",
eb39fafa
DC
17 recommended: false,
18 url: "https://eslint.org/docs/rules/consistent-this"
19 },
20
21 schema: {
22 type: "array",
23 items: {
24 type: "string",
25 minLength: 1
26 },
27 uniqueItems: true
28 },
29
30 messages: {
31 aliasNotAssignedToThis: "Designated alias '{{name}}' is not assigned to 'this'.",
32 unexpectedAlias: "Unexpected alias '{{name}}' for 'this'."
33 }
34 },
35
36 create(context) {
37 let aliases = [];
38
39 if (context.options.length === 0) {
40 aliases.push("that");
41 } else {
42 aliases = context.options;
43 }
44
45 /**
46 * Reports that a variable declarator or assignment expression is assigning
47 * a non-'this' value to the specified alias.
48 * @param {ASTNode} node The assigning node.
609c276f 49 * @param {string} name the name of the alias that was incorrectly used.
eb39fafa
DC
50 * @returns {void}
51 */
52 function reportBadAssignment(node, name) {
53 context.report({ node, messageId: "aliasNotAssignedToThis", data: { name } });
54 }
55
56 /**
57 * Checks that an assignment to an identifier only assigns 'this' to the
58 * appropriate alias, and the alias is only assigned to 'this'.
59 * @param {ASTNode} node The assigning node.
60 * @param {Identifier} name The name of the variable assigned to.
61 * @param {Expression} value The value of the assignment.
62 * @returns {void}
63 */
64 function checkAssignment(node, name, value) {
65 const isThis = value.type === "ThisExpression";
66
67 if (aliases.indexOf(name) !== -1) {
68 if (!isThis || node.operator && node.operator !== "=") {
69 reportBadAssignment(node, name);
70 }
71 } else if (isThis) {
72 context.report({ node, messageId: "unexpectedAlias", data: { name } });
73 }
74 }
75
76 /**
77 * Ensures that a variable declaration of the alias in a program or function
78 * is assigned to the correct value.
79 * @param {string} alias alias the check the assignment of.
80 * @param {Object} scope scope of the current code we are checking.
81 * @private
82 * @returns {void}
83 */
84 function checkWasAssigned(alias, scope) {
85 const variable = scope.set.get(alias);
86
87 if (!variable) {
88 return;
89 }
90
91 if (variable.defs.some(def => def.node.type === "VariableDeclarator" &&
92 def.node.init !== null)) {
93 return;
94 }
95
96 /*
97 * The alias has been declared and not assigned: check it was
98 * assigned later in the same scope.
99 */
100 if (!variable.references.some(reference => {
101 const write = reference.writeExpr;
102
103 return (
104 reference.from === scope &&
105 write && write.type === "ThisExpression" &&
106 write.parent.operator === "="
107 );
108 })) {
109 variable.defs.map(def => def.node).forEach(node => {
110 reportBadAssignment(node, alias);
111 });
112 }
113 }
114
115 /**
116 * Check each alias to ensure that is was assigned to the correct value.
117 * @returns {void}
118 */
119 function ensureWasAssigned() {
120 const scope = context.getScope();
121
122 aliases.forEach(alias => {
123 checkWasAssigned(alias, scope);
124 });
125 }
126
127 return {
128 "Program:exit": ensureWasAssigned,
129 "FunctionExpression:exit": ensureWasAssigned,
130 "FunctionDeclaration:exit": ensureWasAssigned,
131
132 VariableDeclarator(node) {
133 const id = node.id;
134 const isDestructuring =
135 id.type === "ArrayPattern" || id.type === "ObjectPattern";
136
137 if (node.init !== null && !isDestructuring) {
138 checkAssignment(node, id.name, node.init);
139 }
140 },
141
142 AssignmentExpression(node) {
143 if (node.left.type === "Identifier") {
144 checkAssignment(node, node.left.name, node.right);
145 }
146 }
147 };
148
149 }
150};