Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package fourslash_test

import (
"testing"

"github.com/microsoft/TypeScript/tsc/internal/fourslash"
"github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto"
"github.com/microsoft/TypeScript/tsc/internal/testutil"
)

// workspace/symbol used to crash when an open file got kicked out of its tsconfig project
// and then another file from that project was opened. The orphaned file ends up in a fresh
// inferred project, and nothing was building a program for it. Before that, the orphaned
// file's symbols were missing because loading project trees didn't refresh the inferred project.
func TestWorkspaceSymbolNewInferredProject(t *testing.T) {
t.Parallel()
defer testutil.RecoverAndFail(t, "Panic on fourslash test")
const content = `
// @Filename: /home/src/projects/p/tsconfig.json
// @noOpen: true
{ "files": ["a.ts", "b.ts"] }

// @Filename: /home/src/projects/p/a.ts
import "./e";

// @Filename: /home/src/projects/p/b.ts
// @noOpen: true
export const b = 1;

// @Filename: /home/src/projects/p/e.ts
export const e = 1;
`
f, done := fourslash.NewFourslash(t, nil /*capabilities*/, content)
defer done()

// e.ts isn't listed in tsconfig.json, it only gets pulled in by the import in a.ts.
// Once that import is gone, e.ts should move to the inferred project.
f.GoToFile(t, "/home/src/projects/p/a.ts")
f.Replace(t, 0, len(`import "./e";`), "")
f.VerifyWorkspaceSymbol(t, []*fourslash.VerifyWorkspaceSymbolCase{
{Pattern: "b", Includes: new([]*lsproto.SymbolInformation{})},
{Pattern: "e", Includes: new([]*lsproto.SymbolInformation{{
Name: "e",
Kind: lsproto.SymbolKindVariable,
Location: lsproto.Location{
Uri: "file:///home/src/projects/p/e.ts",
Range: lsproto.Range{Start: lsproto.Position{Line: 0, Character: 13}, End: lsproto.Position{Line: 0, Character: 14}},
},
}})},
})

// The tsconfig project is already up to date, so opening b.ts takes the fast path.
f.GoToFile(t, "/home/src/projects/p/b.ts")
f.VerifyWorkspaceSymbol(t, []*fourslash.VerifyWorkspaceSymbolCase{
{Pattern: "b", Includes: new([]*lsproto.SymbolInformation{})},
})
}
7 changes: 7 additions & 0 deletions tsc/internal/project/projectcollectionbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,13 @@ func (b *ProjectCollectionBuilder) DidRequestProjectTrees(projectTreeRequest *Pr
}
wg.RunAndWait()

// Updated configured projects may have moved open files in or out of the inferred project.
// Callers iterate over all language service projects, so the inferred one needs a program too.
b.cleanupInferredProject(logger)
if b.inferredProject.Value() != nil {
b.updateProgram(b.inferredProject, logger)
}

if logger != nil {
elapsed := time.Since(startTime)
logger.Log(fmt.Sprintf("Completed project tree request for %v in %v", projectTreeRequest.Projects(), elapsed))
Expand Down
Loading