diff --git a/internal/fourslash/tests/getEditsForFileRenameWithSolutionConfigFile_test.go b/internal/fourslash/tests/getEditsForFileRenameWithSolutionConfigFile_test.go new file mode 100644 index 00000000000..85baaf9c7c6 --- /dev/null +++ b/internal/fourslash/tests/getEditsForFileRenameWithSolutionConfigFile_test.go @@ -0,0 +1,48 @@ +package fourslash_test + +import ( + "testing" + + "github.com/microsoft/typescript-go/internal/fourslash" + "github.com/microsoft/typescript-go/internal/testutil" +) + +func TestGetEditsForFileRenameWithSolutionConfigFile(t *testing.T) { + t.Parallel() + defer testutil.RecoverAndFail(t, "Panic on fourslash test") + // The parent-directory solution tsconfig only references the composite child + // project, so when the child file is opened the solution is created as an + // ancestor project without ever building its program (it stays nil). Renaming + // a file in the child project must not crash when iterating that nil-program + // solution project. + const content = ` +// @Filename: /tsconfig.json +{ + "files": [], + "references": [ + { "path": "./src/tsconfig.json" } + ] +} + +// @Filename: /src/tsconfig.json +{ + "compilerOptions": { + "composite": true + }, + "files": ["./a.ts", "./b.ts"] +} + +// @Filename: /src/a.ts +import { b } from "./b"; +b; + +// @Filename: /src/b.ts +export const b = 0;` + f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content) + defer done() + f.VerifyWillRenameFilesEdits(t, "/src/b.ts", "/src/c.ts", map[string]string{ + "/src/a.ts": `import { b } from "./c"; +b; +`, + }, nil /*preferences*/) +} diff --git a/internal/project/session.go b/internal/project/session.go index 7c9d250f81e..bd037b1a051 100644 --- a/internal/project/session.go +++ b/internal/project/session.go @@ -1025,7 +1025,12 @@ func (s *Session) GetLanguageServicesForDocuments(ctx context.Context, uris []ls projects := snapshot.ProjectCollection.Projects() services := make([]*ls.LanguageService, 0, len(projects)) for _, project := range projects { - services = append(services, ls.NewLanguageService(project.configFilePath, project.GetProgram(), snapshot, activeFile)) + program := project.GetProgram() + if program == nil { + continue + } + + services = append(services, ls.NewLanguageService(project.configFilePath, program, snapshot, activeFile)) } return services }