From 648066b1c32f0aaa5e98cd67c0de0e2ebd7bdffa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Sep 2026 02:54:47 +0000 Subject: [PATCH 1/7] Initial plan From 0ab173127dca2c02c96bef88a9c31f2ee6762128 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Sep 2026 03:00:52 +0000 Subject: [PATCH 2/7] Avoid JSX runtime panic in auto-import checker Co-authored-by: DanielRosenwasser <972891+DanielRosenwasser@users.noreply.github.com> --- tsc/internal/ls/autoimport/aliasresolver.go | 2 +- .../ls/autoimport/aliasresolver_crash_test.go | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/tsc/internal/ls/autoimport/aliasresolver.go b/tsc/internal/ls/autoimport/aliasresolver.go index 62882eef2e5f7..df0a798245f50 100644 --- a/tsc/internal/ls/autoimport/aliasresolver.go +++ b/tsc/internal/ls/autoimport/aliasresolver.go @@ -176,7 +176,7 @@ func (r *aliasResolver) GetImportHelpersImportSpecifier(path tspath.Path) *ast.N // GetJSXRuntimeImportSpecifier implements checker.Program. func (r *aliasResolver) GetJSXRuntimeImportSpecifier(path tspath.Path) (moduleReference string, specifier *ast.Node) { - panic("unimplemented") + return "", nil } // GetNearestAncestorDirectoryWithPackageJson implements checker.Program. diff --git a/tsc/internal/ls/autoimport/aliasresolver_crash_test.go b/tsc/internal/ls/autoimport/aliasresolver_crash_test.go index 1043d9a6f8111..6b311d6729618 100644 --- a/tsc/internal/ls/autoimport/aliasresolver_crash_test.go +++ b/tsc/internal/ls/autoimport/aliasresolver_crash_test.go @@ -48,14 +48,25 @@ func TestAliasResolverGetDiagnosticsDoesNotPanic(t *testing.T) { const fileName = "/pkg/index.ts" text := "declare function f(arg: { a: string }): () => void;\nexport const x = f({ a: 1 });\n" + testAliasResolverGetDiagnostics(t, fileName, text, core.ScriptKindTS) +} + +func TestAliasResolverGetDiagnosticsWithAutomaticJSXRuntimeDoesNotPanic(t *testing.T) { + t.Parallel() + + const fileName = "/pkg/index.tsx" + text := "/** @jsxRuntime automatic */\nexport const x = { value:
} satisfies {};\n" + testAliasResolverGetDiagnostics(t, fileName, text, core.ScriptKindTSX) +} +func testAliasResolverGetDiagnostics(t *testing.T, fileName string, text string, scriptKind core.ScriptKind) { fs := vfstest.FromMap(map[string]string{fileName: text}, true /*useCaseSensitiveFileNames*/) host := &fakeCloneHost{fs: fs} sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{ FileName: fileName, Path: tspath.Path(fileName), - }, text, core.ScriptKindTS) + }, text, scriptKind) binder.BindSourceFile(sourceFile) resolver := module.NewResolver(module.ResolverOptions{Host: host, CompilerOptions: core.EmptyCompilerOptions}) From 2c7a5a2b0e1fa3221e49a8a33bf92e14a9b3cd8c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Sep 2026 14:58:58 +0000 Subject: [PATCH 3/7] Changes before error encountered Agent-Logs-Url: https://github.com/microsoft/TypeScript/sessions/329b044e-bd60-452c-87bd-720058c69ed0 Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com> --- .../autoImportAutomaticJsxRuntime_test.go | 31 +++++++++++++++++++ tsc/internal/ls/autoimport/aliasresolver.go | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntime_test.go diff --git a/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntime_test.go b/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntime_test.go new file mode 100644 index 0000000000000..d956a196339ac --- /dev/null +++ b/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntime_test.go @@ -0,0 +1,31 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/fourslash" + "github.com/microsoft/TypeScript/tsc/internal/testutil" +) + +func TestAutoImportAutomaticJsxRuntime(t *testing.T) { + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /node_modules/pkg/package.json + { "name": "pkg", "version": "1.0.0", "main": "index.jsx" } + // @Filename: /node_modules/pkg/index.jsx +/** @jsxRuntime automatic */ +module.exports = { + x() { + return { value:
} satisfies {}; + }, +}; +// @Filename: /tsconfig.json +{ "compilerOptions": { "allowJs": true, "checkJs": true, "jsx": "react-jsx" } } +// @Filename: /package.json +{ "dependencies": { "pkg": "*" } } +// @Filename: /index.ts +x/**/` + f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) + defer done() + f.BaselineAutoImportsCompletions(t, []string{""}) +} diff --git a/tsc/internal/ls/autoimport/aliasresolver.go b/tsc/internal/ls/autoimport/aliasresolver.go index df0a798245f50..62882eef2e5f7 100644 --- a/tsc/internal/ls/autoimport/aliasresolver.go +++ b/tsc/internal/ls/autoimport/aliasresolver.go @@ -176,7 +176,7 @@ func (r *aliasResolver) GetImportHelpersImportSpecifier(path tspath.Path) *ast.N // GetJSXRuntimeImportSpecifier implements checker.Program. func (r *aliasResolver) GetJSXRuntimeImportSpecifier(path tspath.Path) (moduleReference string, specifier *ast.Node) { - return "", nil + panic("unimplemented") } // GetNearestAncestorDirectoryWithPackageJson implements checker.Program. From 5c3daaf42e77ae3415540725ef72b9c417bd0868 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Sep 2026 15:03:32 +0000 Subject: [PATCH 4/7] Exercise JSX crash through auto-import completion Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com> --- ...autoImportAutomaticJsxRuntimeCrash_test.go | 45 +++++++++++++++++++ .../ls/autoimport/aliasresolver_crash_test.go | 13 +----- 2 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go diff --git a/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go b/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go new file mode 100644 index 0000000000000..68aad5ac9b5ca --- /dev/null +++ b/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go @@ -0,0 +1,45 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/fourslash" + . "github.com/microsoft/TypeScript/tsc/internal/fourslash/tests/util" + "github.com/microsoft/TypeScript/tsc/internal/ls/lsutil" + "github.com/microsoft/TypeScript/tsc/internal/testutil" +) + +func TestAutoImportAutomaticJsxRuntimeCrash(t *testing.T) { + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = `// @Filename: /project/node_modules/pkg/package.json +{ "name": "pkg", "types": "index.tsx" } +// @Filename: /project/node_modules/pkg/index.tsx +/** @jsxRuntime automatic */ +const container = { Widget: { value:
} satisfies {} }; +export default container.Widget; +// @Filename: /project/package.json +{ "dependencies": { "pkg": "*" } } +// @Filename: /project/tsconfig.json +{ "compilerOptions": { "jsx": "react-jsx" } } +// @Filename: /project/index.ts +Widg/**/` + f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) + defer done() + f.MarkTestAsStradaServer() + f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{ + UserPreferences: &lsutil.UserPreferences{ + IncludeCompletionsForModuleExports: core.TSTrue, + IncludeCompletionsForImportStatements: core.TSTrue, + }, + IsIncomplete: false, + ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{ + CommitCharacters: &DefaultCommitCharacters, + EditRange: Ignored, + }, + Items: &fourslash.CompletionsExpectedItems{ + Includes: []fourslash.CompletionsExpectedItem{"Widget"}, + }, + }) +} diff --git a/tsc/internal/ls/autoimport/aliasresolver_crash_test.go b/tsc/internal/ls/autoimport/aliasresolver_crash_test.go index 6b311d6729618..1043d9a6f8111 100644 --- a/tsc/internal/ls/autoimport/aliasresolver_crash_test.go +++ b/tsc/internal/ls/autoimport/aliasresolver_crash_test.go @@ -48,25 +48,14 @@ func TestAliasResolverGetDiagnosticsDoesNotPanic(t *testing.T) { const fileName = "/pkg/index.ts" text := "declare function f(arg: { a: string }): () => void;\nexport const x = f({ a: 1 });\n" - testAliasResolverGetDiagnostics(t, fileName, text, core.ScriptKindTS) -} - -func TestAliasResolverGetDiagnosticsWithAutomaticJSXRuntimeDoesNotPanic(t *testing.T) { - t.Parallel() - - const fileName = "/pkg/index.tsx" - text := "/** @jsxRuntime automatic */\nexport const x = { value:
} satisfies {};\n" - testAliasResolverGetDiagnostics(t, fileName, text, core.ScriptKindTSX) -} -func testAliasResolverGetDiagnostics(t *testing.T, fileName string, text string, scriptKind core.ScriptKind) { fs := vfstest.FromMap(map[string]string{fileName: text}, true /*useCaseSensitiveFileNames*/) host := &fakeCloneHost{fs: fs} sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{ FileName: fileName, Path: tspath.Path(fileName), - }, text, scriptKind) + }, text, core.ScriptKindTS) binder.BindSourceFile(sourceFile) resolver := module.NewResolver(module.ResolverOptions{Host: host, CompilerOptions: core.EmptyCompilerOptions}) From a785796b938e51e5a6611b46b85fdc2a80d73235 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Sep 2026 15:15:31 +0000 Subject: [PATCH 5/7] Keep focused auto-import JSX regression Co-authored-by: andrewbranch <3277153+andrewbranch@users.noreply.github.com> --- .../autoImportAutomaticJsxRuntime_test.go | 31 ------------------- tsc/internal/ls/autoimport/aliasresolver.go | 2 +- 2 files changed, 1 insertion(+), 32 deletions(-) delete mode 100644 tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntime_test.go diff --git a/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntime_test.go b/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntime_test.go deleted file mode 100644 index d956a196339ac..0000000000000 --- a/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntime_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package fourslash_test - -import ( - "testing" - - "github.com/microsoft/TypeScript/tsc/internal/fourslash" - "github.com/microsoft/TypeScript/tsc/internal/testutil" -) - -func TestAutoImportAutomaticJsxRuntime(t *testing.T) { - t.Parallel() - defer testutil.RecoverAndFail(t, "Panic on fourslash test") - const content = `// @Filename: /node_modules/pkg/package.json - { "name": "pkg", "version": "1.0.0", "main": "index.jsx" } - // @Filename: /node_modules/pkg/index.jsx -/** @jsxRuntime automatic */ -module.exports = { - x() { - return { value:
} satisfies {}; - }, -}; -// @Filename: /tsconfig.json -{ "compilerOptions": { "allowJs": true, "checkJs": true, "jsx": "react-jsx" } } -// @Filename: /package.json -{ "dependencies": { "pkg": "*" } } -// @Filename: /index.ts -x/**/` - f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) - defer done() - f.BaselineAutoImportsCompletions(t, []string{""}) -} diff --git a/tsc/internal/ls/autoimport/aliasresolver.go b/tsc/internal/ls/autoimport/aliasresolver.go index 62882eef2e5f7..df0a798245f50 100644 --- a/tsc/internal/ls/autoimport/aliasresolver.go +++ b/tsc/internal/ls/autoimport/aliasresolver.go @@ -176,7 +176,7 @@ func (r *aliasResolver) GetImportHelpersImportSpecifier(path tspath.Path) *ast.N // GetJSXRuntimeImportSpecifier implements checker.Program. func (r *aliasResolver) GetJSXRuntimeImportSpecifier(path tspath.Path) (moduleReference string, specifier *ast.Node) { - panic("unimplemented") + return "", nil } // GetNearestAncestorDirectoryWithPackageJson implements checker.Program. From 1995e1d7e78f71d3e66c51ac9e42da9364dec5c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Sep 2026 17:53:14 +0000 Subject: [PATCH 6/7] Add project-reference JSX auto-import regression Co-authored-by: DanielRosenwasser <972891+DanielRosenwasser@users.noreply.github.com> --- ...autoImportAutomaticJsxRuntimeCrash_test.go | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go b/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go index 68aad5ac9b5ca..83d11a481fed6 100644 --- a/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go +++ b/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go @@ -43,3 +43,48 @@ Widg/**/` }, }) } + +func TestAutoImportAutomaticJsxRuntimeProjectReferenceCrash(t *testing.T) { + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + const content = ` +// @Filename: /packages/lib/package.json +{ "name": "lib", "types": "out/index.d.ts" } + +// @Filename: /packages/lib/tsconfig.json +{ "compilerOptions": { "composite": true, "jsx": "react-jsx", "outDir": "out" } } + +// @Filename: /packages/lib/index.tsx +/** @jsxRuntime automatic */ +const container = { Widget: { value:
} satisfies {} }; +export default container.Widget; + +// @Filename: /packages/app/package.json +{ "dependencies": { "lib": "*" } } + +// @Filename: /packages/app/tsconfig.json +{ "references": [{ "path": "../lib" }] } + +// @Filename: /packages/app/index.ts +Widg/**/ + +// @link: /packages/lib -> /packages/app/node_modules/lib +` + f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) + defer done() + f.MarkTestAsStradaServer() + f.VerifyCompletions(t, "", &fourslash.CompletionsExpectedList{ + UserPreferences: &lsutil.UserPreferences{ + IncludeCompletionsForModuleExports: core.TSTrue, + IncludeCompletionsForImportStatements: core.TSTrue, + }, + IsIncomplete: false, + ItemDefaults: &fourslash.CompletionsExpectedItemDefaults{ + CommitCharacters: &DefaultCommitCharacters, + EditRange: Ignored, + }, + Items: &fourslash.CompletionsExpectedItems{ + Includes: []fourslash.CompletionsExpectedItem{"Widget"}, + }, + }) +} From 95d6238e72a50edb9c69f1f7d8bddbb07defa598 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 24 Sep 2026 13:19:31 -0700 Subject: [PATCH 7/7] Apply suggestion from @DanielRosenwasser --- .../tests/autoImportAutomaticJsxRuntimeCrash_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go b/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go index 83d11a481fed6..bf17cd59ce51c 100644 --- a/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go +++ b/tsc/internal/fourslash/tests/autoImportAutomaticJsxRuntimeCrash_test.go @@ -13,18 +13,24 @@ import ( func TestAutoImportAutomaticJsxRuntimeCrash(t *testing.T) { t.Parallel() defer testutil.RecoverAndFail(t, "Panic on fourslash test") - const content = `// @Filename: /project/node_modules/pkg/package.json + const content = ` +// @Filename: /project/node_modules/pkg/package.json { "name": "pkg", "types": "index.tsx" } + // @Filename: /project/node_modules/pkg/index.tsx /** @jsxRuntime automatic */ const container = { Widget: { value:
} satisfies {} }; export default container.Widget; + // @Filename: /project/package.json { "dependencies": { "pkg": "*" } } + // @Filename: /project/tsconfig.json { "compilerOptions": { "jsx": "react-jsx" } } + // @Filename: /project/index.ts -Widg/**/` +Widg/**/ +` f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) defer done() f.MarkTestAsStradaServer()