Skip to content

Commit 21c0dc6

Browse files
authored
fix: wrong scope for ts in bind: (#337)
* Fix wrong scope for ts in `bind:` * Create strong-plants-suffer.md
1 parent 180a445 commit 21c0dc6

13 files changed

+12397
-57
lines changed

.changeset/strong-plants-suffer.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"svelte-eslint-parser": patch
3+
---
4+
5+
fix: wrong scope for ts in `bind:`

package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
"eslint-plugin-node-dependencies": "^0.11.0",
8989
"eslint-plugin-prettier": "^4.0.0",
9090
"eslint-plugin-regexp": "^1.5.0",
91-
"eslint-plugin-svelte": "^2.0.0",
91+
"eslint-plugin-svelte": "^2.28.0",
9292
"eslint-plugin-svelte3": "^4.0.0",
9393
"eslint-plugin-yml": "^1.0.0",
9494
"estree-walker": "^3.0.0",
@@ -102,7 +102,6 @@
102102
"prettier-plugin-svelte": "^2.10.0",
103103
"rimraf": "^5.0.0",
104104
"semver": "^7.3.5",
105-
"string-replace-loader": "^3.0.3",
106105
"svelte": "^3.57.0",
107106
"svelte2tsx": "^0.6.11",
108107
"typescript": "~5.0.0",

src/context/script-let.ts

-9
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import type {
1515
import type { ESLintExtendedProgram } from "../parser";
1616
import { getWithLoc } from "../parser/converts/common";
1717
import {
18-
getInnermostScopeFromNode,
1918
getScopeFromNode,
2019
removeAllScopeAndVariableAndReference,
2120
removeReference,
@@ -43,7 +42,6 @@ export type ScriptLetCallback<E extends ESTree.Node> = (
4342

4443
export type ScriptLetCallbackOption = {
4544
getScope: (node: ESTree.Node) => Scope;
46-
getInnermostScope: (node: ESTree.Node) => Scope;
4745
registerNodeToScope: (node: any, scope: Scope) => void;
4846
scopeManager: ScopeManager;
4947
visitorKeys?: { [type: string]: string[] };
@@ -56,7 +54,6 @@ export type ScriptLetRestoreCallback = (
5654
) => void;
5755
type ScriptLetRestoreCallbackOption = {
5856
getScope: (node: ESTree.Node) => Scope;
59-
getInnermostScope: (node: ESTree.Node) => Scope;
6057
registerNodeToScope: (node: any, scope: Scope) => void;
6158
scopeManager: ScopeManager;
6259
visitorKeys?: { [type: string]: string[] };
@@ -643,7 +640,6 @@ export class ScriptLetContext {
643640

644641
const callbackOption: ScriptLetRestoreCallbackOption = {
645642
getScope,
646-
getInnermostScope,
647643
registerNodeToScope,
648644
scopeManager: result.scopeManager!,
649645
visitorKeys: result.visitorKeys,
@@ -660,11 +656,6 @@ export class ScriptLetContext {
660656
return getScopeFromNode(result.scopeManager!, node);
661657
}
662658

663-
/** Get innermost scope */
664-
function getInnermostScope(node: ESTree.Node) {
665-
return getInnermostScopeFromNode(result.scopeManager!, node);
666-
}
667-
668659
/** Register node to scope */
669660
function registerNodeToScope(node: any, scope: Scope): void {
670661
// If we replace the `scope.block` at this time,

src/parser/converts/attr.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,9 @@ function convertBindingDirective(
293293
expression,
294294
directive,
295295
null,
296-
(es, { getInnermostScope }) => {
296+
(es, { getScope }) => {
297297
directive.expression = es;
298-
const scope = getInnermostScope(es);
298+
const scope = getScope(es);
299299
const reference = scope.references.find(
300300
(ref) => ref.identifier === es
301301
);

src/scope/index.ts

+1-44
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function removeAllScopeAndVariableAndReference(
2626
return;
2727
}
2828
if (node.type === "Identifier") {
29-
let scope = getInnermostScopeFromNode(info.scopeManager, node);
29+
let scope = getScopeFromNode(info.scopeManager, node);
3030
while (
3131
scope &&
3232
scope.block.type !== "Program" &&
@@ -90,49 +90,6 @@ export function getProgramScope(scopeManager: ScopeManager): Scope {
9090
);
9191
}
9292

93-
/**
94-
* Get the innermost scope which contains a given node.
95-
* @returns The innermost scope.
96-
*/
97-
export function getInnermostScopeFromNode(
98-
scopeManager: ScopeManager,
99-
currentNode: ESTree.Node
100-
): Scope {
101-
return getInnermostScope(
102-
getScopeFromNode(scopeManager, currentNode),
103-
currentNode
104-
);
105-
}
106-
107-
/**
108-
* Get the innermost scope which contains a given location.
109-
* @param initialScope The initial scope to search.
110-
* @param node The location to search.
111-
* @returns The innermost scope.
112-
*/
113-
export function getInnermostScope(
114-
initialScope: Scope,
115-
node: ESTree.Node
116-
): Scope {
117-
const location = node.range![0];
118-
const isInRange =
119-
node.range![0] === node.range![1]
120-
? (range: [number, number]) =>
121-
range[0] <= location && location <= range[1]
122-
: (range: [number, number]) =>
123-
range[0] <= location && location < range[1];
124-
125-
for (const childScope of initialScope.childScopes) {
126-
const range = childScope.block.range!;
127-
128-
if (isInRange(range)) {
129-
return getInnermostScope(childScope, node);
130-
}
131-
}
132-
133-
return initialScope;
134-
}
135-
13693
/* eslint-disable complexity -- ignore X( */
13794
/** Remove variable */
13895
export function removeIdentifierVariable(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!-- from https://github.com/sveltejs/eslint-plugin-svelte/issues/484 -->
2+
<script lang="ts">
3+
import Pagination from "../components/Pagination.svelte";
4+
5+
let page = 1;
6+
const perPage = 15;
7+
$: pageStart = perPage * (page - 1);
8+
</script>
9+
10+
{#each array as _}
11+
<div on:click={() => {}} />
12+
{/each}
13+
14+
<Pagination bind:current={page} />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* eslint eslint-comments/require-description: 0, @typescript-eslint/explicit-module-boundary-types: 0 */
2+
import type { Linter } from "eslint";
3+
import { generateParserOptions } from "../../../src/parser/test-utils";
4+
import { rules } from "eslint-plugin-svelte";
5+
export function setupLinter(linter: Linter) {
6+
linter.defineRule(
7+
"svelte/no-immutable-reactive-statements",
8+
rules["no-immutable-reactive-statements"] as never
9+
);
10+
}
11+
12+
export function getConfig() {
13+
return {
14+
parser: "svelte-eslint-parser",
15+
parserOptions: generateParserOptions(),
16+
rules: {
17+
"svelte/no-immutable-reactive-statements": "error",
18+
},
19+
env: {
20+
browser: true,
21+
es2021: true,
22+
},
23+
};
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!-- from https://github.com/sveltejs/eslint-plugin-svelte/issues/484 -->
2+
<script lang="ts">
3+
import Pagination from "../components/Pagination.svelte";
4+
5+
let page = 1;
6+
const perPage = 15;
7+
$: pageStart = perPage * (page - 1);
8+
</script>
9+
10+
{#each array as _}
11+
<div on:click={() => {}} />
12+
{/each}
13+
14+
<Pagination bind:current={page} />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[
2+
{
3+
"ruleId": "no-undef",
4+
"code": "array",
5+
"line": 10,
6+
"column": 8
7+
}
8+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[
2+
{
3+
"ruleId": "no-unused-vars",
4+
"code": "pageStart",
5+
"line": 7,
6+
"column": 4
7+
},
8+
{
9+
"ruleId": "no-unused-vars",
10+
"code": "_",
11+
"line": 10,
12+
"column": 17
13+
}
14+
]

0 commit comments

Comments
 (0)