Skip to content

Commit 3fac4ff

Browse files
committed
Add more documentation on how this rule works
1 parent 434d4e8 commit 3fac4ff

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

docs/rules/no-repeated-member-access.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ function singleAccess(obj: MyObject): void {
9494
- **Performance**: Reduces redundant property lookups, especially in tight loops
9595
- **Readability**: Makes code more readable by giving meaningful names to complex property chains
9696
- **Maintainability**: Easier to update property references when extracted to variables
97-
- **Memory Efficiency**: Can reduce memory pressure in performance-critical AssemblyScript code
9897

9998
## When Not To Use
10099

plugins/rules/memberAccess.ts

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,33 @@ import { TSESTree, AST_NODE_TYPES } from "@typescript-eslint/utils";
22
import { Scope } from "@typescript-eslint/utils/ts-eslint";
33
import createRule from "../utils/createRule.js";
44

5+
/**
6+
* Rule to optimize repeated member access patterns by extracting variables
7+
* For more rule details refer to docs/rules/no-repeated-member-access.md
8+
*
9+
* The following material is an overview of implementation details
10+
* It is divided into several phases
11+
*
12+
* 1. Analysis Phase:
13+
* - Traverse AST to identify member access chains (e.g., obj.prop.val)
14+
* - Store chains into hierarchical structures (e.g., ["obj", "obj.prop", "obj.prop.val"])
15+
* - Cache analysis results to avoid repeatedly processing
16+
*
17+
* 2. Tracking Phase:
18+
* - Count usage frequency of each chain within current scope
19+
* - Identify modified chains (assignments, increments, function calls, etc.)
20+
* - Mark all parts alongside the chain as modified
21+
*
22+
* 3. Reporting Phase:
23+
* - For chains that meet usage threshold and are not modified, suggest variable extraction
24+
* - Report only the longest valid chains
25+
*
26+
* Things to note:
27+
* - Only process chains starting with identifiers or "this" (avoid function call results)
28+
* - Skip computed property access (e.g., obj[key])
29+
* - Mark modified chains as un-extractable
30+
* - Support TypeScript non-null assertion operator (!) (minor bugs might still persist in some cases)
31+
*/
532
const noRepeatedMemberAccess = createRule({
633
name: "no-repeated-member-access",
734
meta: {
@@ -42,7 +69,6 @@ const noRepeatedMemberAccess = createRule({
4269
modified: boolean; // Whether this chain is modified (written to)
4370
}
4471
>;
45-
variables: Set<string>; // Variables already declared in this scope
4672
};
4773

4874
// Stores data for each scope using WeakMap to avoid memory leaks
@@ -63,15 +89,8 @@ const noRepeatedMemberAccess = createRule({
6389
modified: boolean;
6490
}
6591
>(),
66-
variables: new Set<string>(),
6792
};
6893

69-
// Add existing variable names to the set
70-
for (let i = 0; i < scope.variables.length; i++) {
71-
const variable = scope.variables[i];
72-
newScopeData.variables.add(variable.name);
73-
}
74-
7594
scopeDataMap.set(scope, newScopeData);
7695
}
7796

@@ -132,8 +151,7 @@ const noRepeatedMemberAccess = createRule({
132151
parts.push("this");
133152
} else {
134153
// Skip chains with non-identifier base objects
135-
// Example: (getObject()).prop is not optimized because
136-
// function call results shouldn't be cached
154+
// Example: (getObject()).prop is not optimized because function call results shouldn't be cached
137155
isValid = false;
138156
}
139157

@@ -200,7 +218,7 @@ const noRepeatedMemberAccess = createRule({
200218
}
201219
}
202220
// Mark the chain as modified regardless of it has been created or not!! Otherwise properties that get written will be reported in the first time, but they should not be reported.
203-
// Examples:
221+
// Here is a more concrete example:
204222
// "this.vehicleSys!" should not be extracted as it is written later
205223
// this.vehicleSys!.automobile = new TransportCore(new TransportBlueprint()); // THIS line will get reported if we don't mark the chain as modified
206224
// this.vehicleSys!.automobile!.apple = new ChassisAssembly(new ChassisSchema());

0 commit comments

Comments
 (0)