Skip to content

Commit 7086e8e

Browse files
committed
feat: add bind:this -> attachment autofixer
1 parent d93d3a3 commit 7086e8e

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

src/lib/mcp/autofixers/add-autofixers-issues.test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,4 +374,67 @@ describe('add_autofixers_issues', () => {
374374
);
375375
});
376376
});
377+
378+
describe('bind_this_attachment', () => {
379+
it('should add suggestions when using bind:this on an element', () => {
380+
const content = run_autofixers_on_code(`
381+
<script>
382+
let a = $state();
383+
</script>
384+
385+
<a bind:this={a} />`);
386+
387+
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
388+
expect(content.suggestions).toContain(
389+
'The usage of `bind:this` can often be replaced with an easier to read `action` or even better an `attachment`. Consider using the latter if possible.',
390+
);
391+
});
392+
393+
it('should not add suggestions when using bind:this on a component', () => {
394+
const content = run_autofixers_on_code(`
395+
<script>
396+
import Child from './Child.svelte';
397+
let a = $state();
398+
</script>
399+
400+
<Child bind:this={a} />`);
401+
402+
expect(content.suggestions).not.toContain(
403+
'The usage of `bind:this` can often be replaced with an easier to read `action` or even better an `attachment`. Consider using the latter if possible.',
404+
);
405+
});
406+
407+
it('should not add suggestions when using bind:this on a component nested in an element', () => {
408+
const content = run_autofixers_on_code(`
409+
<script>
410+
import Child from './Child.svelte';
411+
let a = $state();
412+
</script>
413+
414+
<div>
415+
<Child bind:this={a} />
416+
</div>`);
417+
418+
expect(content.suggestions).not.toContain(
419+
'The usage of `bind:this` can often be replaced with an easier to read `action` or even better an `attachment`. Consider using the latter if possible.',
420+
);
421+
});
422+
423+
it('should add suggestions but not suggest attachments when using bind:this on an element and the desired svelte version is 4', () => {
424+
const content = run_autofixers_on_code(
425+
`
426+
<script>
427+
let a;
428+
</script>
429+
430+
<a bind:this={a} />`,
431+
4,
432+
);
433+
434+
expect(content.suggestions.length).toBeGreaterThanOrEqual(1);
435+
expect(content.suggestions).toContain(
436+
'The usage of `bind:this` can often be replaced with an easier to read `action`. Consider using the latter if possible.',
437+
);
438+
});
439+
});
377440
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { Autofixer } from '.';
2+
export const bind_this_attachment: Autofixer = {
3+
SvelteDirective(node, { state, next, path }) {
4+
if (node.kind === 'Binding' && node.key.name.name === 'this') {
5+
const parent_element = path.findLast((p) => p.type === 'SvelteElement');
6+
if (parent_element?.kind === 'html' && parent_element.startTag.attributes.includes(node)) {
7+
let better_an_attachment = ` or even better an \`attachment\``;
8+
if (state.desired_svelte_version === 4) {
9+
better_an_attachment = ``;
10+
}
11+
state.output.suggestions.push(
12+
`The usage of \`bind:this\` can often be replaced with an easier to read \`action\`${better_an_attachment}. Consider using the latter if possible.`,
13+
);
14+
}
15+
}
16+
next();
17+
},
18+
};

src/lib/mcp/autofixers/visitors/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ export * from './set-or-update-state.js';
1616
export * from './imported-runes.js';
1717
export * from './derived-with-function.js';
1818
export * from './use-runes-instead-of-store.js';
19+
export * from './bind-this-attachment.js';

0 commit comments

Comments
 (0)