Skip to content

Commit f9382c6

Browse files
committed
clean up class member & rewrite path generate logic & add visitor function
1 parent 337bb8d commit f9382c6

File tree

1 file changed

+30
-42
lines changed

1 file changed

+30
-42
lines changed

plugins/rules/memberAccess.ts

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,10 @@ const noRepeatedMemberAccess = createRule({
3232
private modified: boolean = false;
3333
private parent?: ChainNode;
3434
private children: Map<string, ChainNode> = new Map();
35-
private path: string;
3635

37-
constructor(name: string, parent?: ChainNode) {
36+
constructor(parent?: ChainNode) {
3837
this.parent = parent;
3938
this.modified = this.parent?.modified || false;
40-
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-
}
4839
}
4940

5041
get getCount(): number {
@@ -55,26 +46,18 @@ const noRepeatedMemberAccess = createRule({
5546
return this.modified;
5647
}
5748

58-
get getParent(): ChainNode | undefined {
59-
return this.parent;
60-
}
61-
6249
get getChildren(): Map<string, ChainNode> {
6350
return this.children;
6451
}
6552

66-
get getPath(): string {
67-
return this.path;
68-
}
69-
7053
incrementCount(): void {
7154
this.count++;
7255
}
7356

7457
// Get or create child node
7558
getOrCreateChild(childName: string): ChainNode {
7659
if (!this.children.has(childName)) {
77-
this.children.set(childName, new ChainNode(childName, this));
60+
this.children.set(childName, new ChainNode(this));
7861
}
7962
return this.children.get(childName)!;
8063
}
@@ -90,47 +73,49 @@ const noRepeatedMemberAccess = createRule({
9073

9174
// Root node for the tree (per scope)
9275
class ChainTree {
93-
private root: ChainNode = new ChainNode("__root__");
76+
private root: ChainNode = new ChainNode();
9477

95-
// Insert a chain path into the tree and increment counts
96-
insertChain(properties: string[]): void {
78+
// Visitor function to navigate through property chain
79+
private visitChainPath(
80+
properties: string[],
81+
process: (node: ChainNode) => void
82+
): ChainNode {
9783
let current = this.root;
9884

99-
// Navigate/create path in tree
85+
// Navigate/process node in the tree
10086
for (const prop of properties) {
10187
const child = current.getOrCreateChild(prop);
10288
current = child;
103-
104-
// Only increment count for non-single properties (chains with dots)
105-
if (properties.length > 1) {
106-
current.incrementCount();
107-
}
89+
process(current);
10890
}
91+
92+
return current;
93+
}
94+
95+
// Insert a chain path into the tree and increment counts
96+
insertChain(properties: string[]): void {
97+
this.visitChainPath(properties, (node) => {
98+
node.incrementCount();
99+
});
109100
}
110101

111102
// Mark a chain and its descendants as modified
112103
markChainAsModified(properties: string[]): void {
113-
let current = this.root;
114-
115-
// Navigate to the target node, creating nodes if they don't exist
116-
for (const prop of properties) {
117-
const newChild = current.getOrCreateChild(prop);
118-
current = newChild;
119-
}
104+
const targetNode = this.visitChainPath(properties, () => {});
120105

121106
// Mark this node and all descendants as modified
122-
current.markAsModified();
107+
targetNode.markAsModified();
123108
}
124109

125110
// Find any valid chain that meets the minimum occurrence threshold
126111
findValidChains() {
127112
const validChains: Array<{ chain: string }> = [];
128113

129-
const traverse = (node: ChainNode, depth: number) => {
114+
const dfs = (node: ChainNode, pathArray: string[]) => {
130115
// Only consider chains with more than one segment (has dots)
131-
if (depth > 1 && !node.isModified && node.getCount >= 2) {
116+
if (pathArray.length > 1 && !node.isModified && node.getCount >= 2) {
132117
validChains.push({
133-
chain: node.getPath,
118+
chain: pathArray.join("."),
134119
});
135120
}
136121

@@ -140,12 +125,15 @@ const noRepeatedMemberAccess = createRule({
140125
}
141126

142127
// Recursively traverse children
143-
for (const child of node.getChildren.values()) {
144-
traverse(child, depth + 1);
128+
for (const [childName, child] of node.getChildren) {
129+
pathArray.push(childName);
130+
dfs(child, pathArray);
131+
pathArray.pop();
145132
}
146133
};
147134

148-
traverse(this.root, 0);
135+
// Start DFS from root with empty path array
136+
dfs(this.root, []);
149137
return validChains;
150138
}
151139
}

0 commit comments

Comments
 (0)