forked from eslint/eslint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
no-unused-private-class-members.js
88 lines (72 loc) · 3.14 KB
/
no-unused-private-class-members.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/**
* @fileoverview Rule to flag declared but unused private class members
* @author Tim van der Lippe
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
type: "problem",
docs: {
description: "disallow unused private class members",
category: "Variables",
recommended: true,
url: "https://eslint.org/docs/rules/no-unused-private-class-members"
},
schema: [],
messages: {
unusedPrivateClassMember: "'{{classMemberName}}' is defined but never used."
}
},
create(context) {
const declaredAndUnusedPrivateMembers = new Map();
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
// Collect all declared members up front and assume they are all unused
ClassBody(classBodyNode) {
for (const bodyMember of classBodyNode.body) {
if (bodyMember.type === "PropertyDefinition" || bodyMember.type === "MethodDefinition") {
if (bodyMember.key.type === "PrivateIdentifier") {
declaredAndUnusedPrivateMembers.set(bodyMember.key.name, bodyMember);
}
}
}
},
/*
* Process all usages of the private identifier and remove a member from
* `declaredAndUnusedPrivateMembers` if we deem it used.
*/
PrivateIdentifier(privateIdentifierNode) {
if (
// The definition of the class member itself
privateIdentifierNode.parent.type !== "PropertyDefinition" &&
privateIdentifierNode.parent.type !== "MethodDefinition" &&
// Any usage of this member, except for writes (if it is a property)
privateIdentifierNode.parent.parent.type !== "AssignmentExpression") {
declaredAndUnusedPrivateMembers.delete(privateIdentifierNode.name);
}
},
/*
* Post-process the class members and report any remaining members.
* Since private members can only be accessed in the current class context,
* we can safely assume that all usages are within the current class body.
*/
"ClassBody:exit"() {
for (const [classMemberName, remainingDeclaredMember] of declaredAndUnusedPrivateMembers.entries()) {
context.report({
node: remainingDeclaredMember,
messageId: "unusedPrivateClassMember",
data: {
classMemberName
}
});
}
declaredAndUnusedPrivateMembers.clear();
}
};
}
};