Repository: sveltejs/language-tools
Pull request #1941 (2023-03-16 04:14:36)

(fix) more function scope check
#1938

Found there is an `isFunctionLike` function. 


Patch:
diff --git a/packages/svelte2tsx/rollup.config.mjs b/packages/svelte2tsx/rollup.config.mjs
index 1105a86b..ccd67376 100644
--- a/packages/svelte2tsx/rollup.config.mjs
+++ b/packages/svelte2tsx/rollup.config.mjs
@@ -6,10 +6,15 @@ import builtins from 'builtin-modules';
 import fs from 'fs';
 import path from 'path';
 import { decode } from '@jridgewell/sourcemap-codec';
+import { createRequire } from 'module';
+import { fileURLToPath } from 'url'
 
 const DEV = !!process.env.ROLLUP_WATCH;
 
 function repl() {
+    const require = createRequire(import.meta.url);
+    const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
     require('ts-node').register({
         project: 'test/tsconfig.json',
         transpileOnly: true
diff --git a/packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts b/packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts
index d7939d19..be3c447e 100644
--- a/packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts
+++ b/packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts
@@ -1,6 +1,6 @@
 import MagicString from 'magic-string';
 import { Node } from 'estree-walker';
-import * as ts from 'typescript';
+import ts from 'typescript';
 import { getBinaryAssignmentExpr, isNotPropertyNameOfImport, moveNode } from './utils/tsAst';
 import { ExportedNames, is$$PropsDeclaration } from './nodes/ExportedNames';
 import { ImplicitTopLevelNames } from './nodes/ImplicitTopLevelNames';
@@ -158,16 +158,13 @@ export function processInstanceScriptContent(
 
         if (ts.isFunctionDeclaration(node)) {
             exportedNames.handleExportFunctionOrClass(node);
-
-            pushScope();
-            onLeaveCallbacks.push(() => popScope());
         }
 
         if (ts.isClassDeclaration(node)) {
             exportedNames.handleExportFunctionOrClass(node);
         }
 
-        if (ts.isBlock(node) || ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
+        if (ts.isBlock(node) || ts.isFunctionLike(node)) {
             pushScope();
             onLeaveCallbacks.push(() => popScope());
         }


Test patch:
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/function-scope/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/function-scope/expectedv2.ts
new file mode 100644
index 00000000..44b3cfd0
--- /dev/null
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/function-scope/expectedv2.ts
@@ -0,0 +1,19 @@
+///<reference types="svelte" />
+;function render() {
+
+    let callback = (id) => undefined;
+    class B {
+        constructor(id) { }
+
+        method(id) { }
+
+        set id(id) { }
+    }
+
+    let  { id } = __sveltets_2_invalidate(() => ({ id: '' }));
+;
+async () => {};
+return { props: /** @type {Record<string, never>} */ ({}), slots: {}, events: {} }}
+
+export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_partial(__sveltets_2_with_any_event(render()))) {
+}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/function-scope/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/function-scope/input.svelte
new file mode 100644
index 00000000..8637ec30
--- /dev/null
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/function-scope/input.svelte
@@ -0,0 +1,12 @@
+<script>
+    let callback = (id) => undefined;
+    class B {
+        constructor(id) { }
+
+        method(id) { }
+
+        set id(id) { }
+    }
+
+    $: ({ id } = { id: '' });
+</script>
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-function-type-scope/expectedv2.ts b/packages/svelte2tsx/test/svelte2tsx/samples/ts-function-type-scope/expectedv2.ts
new file mode 100644
index 00000000..e2f14bf2
--- /dev/null
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-function-type-scope/expectedv2.ts
@@ -0,0 +1,15 @@
+///<reference types="svelte" />
+;function render() {
+
+    let callback: (id: string) => void;
+    let callback2: {( id: string): void}
+    let constructor1: new (id: string) => { id: string };
+    let obj: { hi(id: string): void }
+
+    let  { id } = __sveltets_2_invalidate(() => ({ id: '' }));
+;
+async () => {};
+return { props: {} as Record<string, never>, slots: {}, events: {} }}
+
+export default class Input__SvelteComponent_ extends __sveltets_2_createSvelte2TsxComponent(__sveltets_2_with_any_event(render())) {
+}
\ No newline at end of file
diff --git a/packages/svelte2tsx/test/svelte2tsx/samples/ts-function-type-scope/input.svelte b/packages/svelte2tsx/test/svelte2tsx/samples/ts-function-type-scope/input.svelte
new file mode 100644
index 00000000..80dd60d2
--- /dev/null
+++ b/packages/svelte2tsx/test/svelte2tsx/samples/ts-function-type-scope/input.svelte
@@ -0,0 +1,8 @@
+<script lang="ts">
+    let callback: (id: string) => void;
+    let callback2: {( id: string): void}
+    let constructor1: new (id: string) => { id: string };
+    let obj: { hi(id: string): void }
+
+    $: ({ id } = { id: '' });
+</script>