| |
| |
| |
| |
| "use strict"; |
|
|
| |
| |
| |
|
|
| |
| module.exports = { |
| meta: { |
| type: "suggestion", |
|
|
| docs: { |
| description: |
| "Enforce consistent naming when capturing the current execution context", |
| recommended: false, |
| frozen: true, |
| url: "https://eslint.org/docs/latest/rules/consistent-this", |
| }, |
|
|
| schema: { |
| type: "array", |
| items: { |
| type: "string", |
| minLength: 1, |
| }, |
| uniqueItems: true, |
| }, |
|
|
| defaultOptions: ["that"], |
|
|
| messages: { |
| aliasNotAssignedToThis: |
| "Designated alias '{{name}}' is not assigned to 'this'.", |
| unexpectedAlias: "Unexpected alias '{{name}}' for 'this'.", |
| }, |
| }, |
|
|
| create(context) { |
| const aliases = context.options; |
| const sourceCode = context.sourceCode; |
|
|
| |
| |
| |
| |
| |
| |
| |
| function reportBadAssignment(node, name) { |
| context.report({ |
| node, |
| messageId: "aliasNotAssignedToThis", |
| data: { name }, |
| }); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| function checkAssignment(node, name, value) { |
| const isThis = value.type === "ThisExpression"; |
|
|
| if (aliases.includes(name)) { |
| if (!isThis || (node.operator && node.operator !== "=")) { |
| reportBadAssignment(node, name); |
| } |
| } else if (isThis) { |
| context.report({ |
| node, |
| messageId: "unexpectedAlias", |
| data: { name }, |
| }); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| function checkWasAssigned(alias, scope) { |
| const variable = scope.set.get(alias); |
|
|
| if (!variable) { |
| return; |
| } |
|
|
| if ( |
| variable.defs.some( |
| def => |
| def.node.type === "VariableDeclarator" && |
| def.node.init !== null, |
| ) |
| ) { |
| return; |
| } |
|
|
| |
| |
| |
| |
| if ( |
| !variable.references.some(reference => { |
| const write = reference.writeExpr; |
|
|
| return ( |
| reference.from === scope && |
| write && |
| write.type === "ThisExpression" && |
| write.parent.operator === "=" |
| ); |
| }) |
| ) { |
| variable.defs |
| .map(def => def.node) |
| .forEach(node => { |
| reportBadAssignment(node, alias); |
| }); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| function ensureWasAssigned(node) { |
| const scope = sourceCode.getScope(node); |
|
|
| |
| const extraScope = |
| node.type === "Program" && node.sourceType === "module" |
| ? scope.childScopes[0] |
| : null; |
|
|
| aliases.forEach(alias => { |
| checkWasAssigned(alias, scope); |
|
|
| if (extraScope) { |
| checkWasAssigned(alias, extraScope); |
| } |
| }); |
| } |
|
|
| return { |
| "Program:exit": ensureWasAssigned, |
| "FunctionExpression:exit": ensureWasAssigned, |
| "FunctionDeclaration:exit": ensureWasAssigned, |
|
|
| VariableDeclarator(node) { |
| const id = node.id; |
| const isDestructuring = |
| id.type === "ArrayPattern" || id.type === "ObjectPattern"; |
|
|
| if (node.init !== null && !isDestructuring) { |
| checkAssignment(node, id.name, node.init); |
| } |
| }, |
|
|
| AssignmentExpression(node) { |
| if (node.left.type === "Identifier") { |
| checkAssignment(node, node.left.name, node.right); |
| } |
| }, |
| }; |
| }, |
| }; |
|
|