Skip to content

Feat: Add no-member-access rule #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Jul 3, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2a05148
initial work on no-repeated-member-access rule
meowbmw May 23, 2025
00f0549
second attempt; still trying to figure this out
meowbmw May 26, 2025
434d4e8
Add no repeated member access rule
meowbmw Jun 3, 2025
3fac4ff
Add more documentation on how this rule works
meowbmw Jun 5, 2025
9b6f232
Merge branch 'main' into main
xpirad Jun 6, 2025
7667f9d
change default minOcurrences to 3; small code clean up
meowbmw Jun 6, 2025
21732a1
clean up test case
meowbmw Jun 6, 2025
6221add
enable debug support
meowbmw Jun 13, 2025
4f44e12
add barebone rewrite
meowbmw Jun 13, 2025
defaea0
still wip;
xpirad Jun 15, 2025
500b0ca
wip 2: refactor old version
meowbmw Jun 16, 2025
edecf9f
wip 3; near completion??
xpirad Jun 16, 2025
00709fb
ready for review
meowbmw Jun 17, 2025
a84bc60
clearer naming
meowbmw Jun 17, 2025
af3a92e
clean up comment
meowbmw Jun 17, 2025
b6e7556
clean up draft file
xpirad Jun 17, 2025
dd0221a
remove files to support ts debug; add force curly after if; minor adj…
meowbmw Jun 30, 2025
2c569fa
refactor memberaccess using tree structures
meowbmw Jun 30, 2025
7cfe59d
change test case
meowbmw Jun 30, 2025
8608146
fix logic in mark modified
meowbmw Jun 30, 2025
802b6d4
set class members to private & add chains cache
meowbmw Jun 30, 2025
337bb8d
set modified in constructor to ensure the flag is inhereited; constru…
meowbmw Jun 30, 2025
f9382c6
clean up class member & rewrite path generate logic & add visitor fun…
meowbmw Jul 1, 2025
c105abb
Update readme
meowbmw Jul 1, 2025
857cca2
Merge branch 'main' into main
xpirad Jul 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions docs/rules/no-repeated-member-access.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# no-repeated-member-access

> Optimize repeated member access patterns by extracting variables

## Rule Details

This rule identifies repeated member access patterns in your code and suggests extracting them to variables for better performance and readability. In AssemblyScript, repeated property access can have performance implications (due to when they are compiled to WASM bytecode, they will induce more instructions), especially in loops or frequently called functions.

This rule doesn't extract computed properties/array index. These can change unexpectedly and therefore should be avoid for extraction. Examples include:

```ts
arr[0];
arr[0][1];
arr[0].property;
obj.arr[0].value;
data.items[0].config;
obj["prop"];
obj[getKey()];
```

The rule will also avoid to warn when functions are invoked upon properties, as this could have implications that alter the extracted value.
Examples include:

```ts
x = a.b.c;
a.b.doSomething(); // this line will prevent a.b.c from being warned although it is used multiple times, as doSomething() could potentially change the value of a.b
y = a.b.c;
z = a.b.c;
```

## Rule Options

This rule accepts an options object with the following properties:

```json
{
"minOccurrences": 3
}
```

- `minOccurrences` (default: 3): Minimum number of times a member chain must be accessed before triggering the rule

## Examples

### Incorrect

```ts
// Repeated access to the same property chain (3+ times)
function processData(obj: MyObject): void {
if (obj.config.settings.enabled) {
obj.config.settings.value = 10;
console.log(obj.config.settings.name);
obj.config.settings.timestamp = Date.now();
}
}

// Deep property chains accessed multiple times
function renderUI(app: Application): void {
app.ui.layout.header.title.text = "New Title";
app.ui.layout.header.title.fontSize = 16;
app.ui.layout.header.title.color = "blue";
}
```

### Correct

```ts
// Extract repeated property access to variables
function processData(obj: MyObject): void {
const settings = obj.config.settings;
if (settings.enabled) {
settings.value = 10;
console.log(settings.name);
settings.timestamp = Date.now();
}
}

// Extract deep property chains
function renderUI(app: Application): void {
const title = app.ui.layout.header.title;
title.text = "New Title";
title.fontSize = 16;
title.color = "blue";
}

// Single or infrequent access is allowed
function singleAccess(obj: MyObject): void {
console.log(obj.config.settings.enabled); // Only accessed once
}
```

## Benefits

- **Performance**: Reduces redundant property lookups, especially in tight loops
- **Readability**: Makes code more readable by giving meaningful names to complex property chains
- **Maintainability**: Easier to update property references when extracted to variables

## When Not To Use

- If the property chains are very short (single level) and performance is not critical
- When the object properties are frequently modified, making extraction less beneficial
- In very simple functions where the overhead of variable extraction outweighs the benefits

## Related Rules

- Consider using this rule alongside other performance-focused rules for optimal AssemblyScript code generation
2 changes: 2 additions & 0 deletions plugins/perfPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
* in AssemblyScript code.
*/
import arrayInitStyle from "./rules/arrayInitStyle.js";
import noRepeatedMemberAccess from "./rules/memberAccess.js";

export default {
rules: {
"array-init-style": arrayInitStyle,
"no-repeated-member-access": noRepeatedMemberAccess,
},
};
Loading