Skip to content

Commit 337bb8d

Browse files
committed
set modified in constructor to ensure the flag is inhereited; construct path during constructor
1 parent 802b6d4 commit 337bb8d

File tree

1 file changed

+16
-40
lines changed

1 file changed

+16
-40
lines changed

plugins/rules/memberAccess.ts

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,23 @@ const noRepeatedMemberAccess = createRule({
2828
// Tree-based approach for storing member access chains
2929
// Each node represents a property in the chain (e.g., a -> b -> c for a.b.c)
3030
class ChainNode {
31-
private name: string;
3231
private count: number = 0;
3332
private modified: boolean = false;
3433
private parent?: ChainNode;
3534
private children: Map<string, ChainNode> = new Map();
35+
private path: string;
3636

37-
constructor(name: string) {
38-
this.name = name;
39-
}
37+
constructor(name: string, parent?: ChainNode) {
38+
this.parent = parent;
39+
this.modified = this.parent?.modified || false;
4040

41-
// Getter methods for private properties
42-
get getName(): string {
43-
return this.name;
41+
if (name === "__root__") {
42+
this.path = "";
43+
} else if (!this.parent || this.parent.path === "") {
44+
this.path = name;
45+
} else {
46+
this.path = this.parent.path + "." + name;
47+
}
4448
}
4549

4650
get getCount(): number {
@@ -59,9 +63,8 @@ const noRepeatedMemberAccess = createRule({
5963
return this.children;
6064
}
6165

62-
// Setter methods for private properties
63-
set setParent(parent: ChainNode | undefined) {
64-
this.parent = parent;
66+
get getPath(): string {
67+
return this.path;
6568
}
6669

6770
incrementCount(): void {
@@ -71,30 +74,15 @@ const noRepeatedMemberAccess = createRule({
7174
// Get or create child node
7275
getOrCreateChild(childName: string): ChainNode {
7376
if (!this.children.has(childName)) {
74-
this.children.set(childName, new ChainNode(childName));
77+
this.children.set(childName, new ChainNode(childName, this));
7578
}
7679
return this.children.get(childName)!;
7780
}
7881

79-
// Get the full chain path from root to this node
80-
getChainPath(): string {
81-
// Build path from child to root, then reverse at the end
82-
const path: string[] = [];
83-
let current = this as ChainNode | undefined;
84-
while (current && current.getName !== "__root__") {
85-
path.push(current.getName);
86-
current = current.getParent;
87-
}
88-
89-
// Reverse the array once at the end
90-
path.reverse();
91-
return path.join(".");
92-
}
93-
9482
// Mark this node and all its descendants as modified
9583
markAsModified(): void {
9684
this.modified = true;
97-
for (const child of this.getChildren.values()) {
85+
for (const child of this.children.values()) {
9886
child.markAsModified();
9987
}
10088
}
@@ -103,8 +91,6 @@ const noRepeatedMemberAccess = createRule({
10391
// Root node for the tree (per scope)
10492
class ChainTree {
10593
private root: ChainNode = new ChainNode("__root__");
106-
private validChainsCache: Array<{ chain: string }> = [];
107-
private cacheValid: boolean = false;
10894

10995
// Insert a chain path into the tree and increment counts
11096
insertChain(properties: string[]): void {
@@ -113,15 +99,13 @@ const noRepeatedMemberAccess = createRule({
11399
// Navigate/create path in tree
114100
for (const prop of properties) {
115101
const child = current.getOrCreateChild(prop);
116-
child.setParent = current;
117102
current = child;
118103

119104
// Only increment count for non-single properties (chains with dots)
120105
if (properties.length > 1) {
121106
current.incrementCount();
122107
}
123108
}
124-
this.cacheValid = false;
125109
}
126110

127111
// Mark a chain and its descendants as modified
@@ -131,28 +115,22 @@ const noRepeatedMemberAccess = createRule({
131115
// Navigate to the target node, creating nodes if they don't exist
132116
for (const prop of properties) {
133117
const newChild = current.getOrCreateChild(prop);
134-
newChild.setParent = current;
135118
current = newChild;
136119
}
137120

138121
// Mark this node and all descendants as modified
139122
current.markAsModified();
140-
this.cacheValid = false;
141123
}
142124

143125
// Find any valid chain that meets the minimum occurrence threshold
144126
findValidChains() {
145-
if (this.cacheValid) {
146-
return this.validChainsCache;
147-
}
148127
const validChains: Array<{ chain: string }> = [];
149128

150129
const traverse = (node: ChainNode, depth: number) => {
151130
// Only consider chains with more than one segment (has dots)
152131
if (depth > 1 && !node.isModified && node.getCount >= 2) {
153-
const chainPath = node.getChainPath();
154132
validChains.push({
155-
chain: chainPath,
133+
chain: node.getPath,
156134
});
157135
}
158136

@@ -168,8 +146,6 @@ const noRepeatedMemberAccess = createRule({
168146
};
169147

170148
traverse(this.root, 0);
171-
this.cacheValid = true;
172-
this.validChainsCache = validChains;
173149
return validChains;
174150
}
175151
}

0 commit comments

Comments
 (0)