Skip to content
Open
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
4 changes: 2 additions & 2 deletions tsc/internal/api/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -2031,7 +2031,7 @@ func (s *Session) handleParseJsonConfigFileContent(ctx context.Context, params *

parsedCommandLine := tsoptions.ParseJsonConfigFileContent(
jsonValueToAny(params.JSON),
s.snapshotHost.FS(),
tsoptions.NewDefaultParseConfigHost(s.snapshotHost.FS()),
basePath,
nil, /*existingOptions*/
configFileName,
Expand All @@ -2057,7 +2057,7 @@ func (s *Session) handleParseConfigFile(ctx context.Context, params *ParseConfig
)
parsedCommandLine := tsoptions.ParseJsonSourceFileConfigFileContent(
tsConfigSourceFile,
s.snapshotHost.FS(),
tsoptions.NewDefaultParseConfigHost(s.snapshotHost.FS()),
configDir,
nil, /*existingOptions*/
nil, /*existingOptionsRaw*/
Expand Down
10 changes: 5 additions & 5 deletions tsc/internal/checker/checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ foo.bar;`
fs = bundled.WrapFS(fs)

host := compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, nil, fs, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, nil, tsoptions.NewDefaultParseConfigHost(fs), nil)
assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line")

p := compiler.NewProgram(compiler.ProgramOptions{
Expand Down Expand Up @@ -87,7 +87,7 @@ export type E = D;`,

host := compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil)

parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, nil, fs, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, nil, tsoptions.NewDefaultParseConfigHost(fs), nil)
assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line")

p := compiler.NewProgram(compiler.ProgramOptions{
Expand Down Expand Up @@ -121,7 +121,7 @@ func BenchmarkNewChecker(b *testing.B) {
fs := bundled.WrapFS(osvfs.FS())
rootPath := tspath.RootedDirectoryPathFromAbsolute(filepath.Join(repo.TestDataPath(), "fixtures/compiler"))
host := compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(rootPath.ResolveFile("tsconfig.json"), &core.CompilerOptions{}, nil, fs, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(rootPath.ResolveFile("tsconfig.json"), &core.CompilerOptions{}, nil, tsoptions.NewDefaultParseConfigHost(fs), nil)
assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line")
program := compiler.NewProgram(compiler.ProgramOptions{
Config: parsed,
Expand All @@ -138,7 +138,7 @@ func BenchmarkCheck(b *testing.B) {
fs := bundled.WrapFS(osvfs.FS())
rootPath := tspath.RootedDirectoryPathFromAbsolute(filepath.Join(repo.TestDataPath(), "fixtures/compiler"))
host := compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(rootPath.ResolveFile("tsconfig.json"), &core.CompilerOptions{}, nil, fs, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(rootPath.ResolveFile("tsconfig.json"), &core.CompilerOptions{}, nil, tsoptions.NewDefaultParseConfigHost(fs), nil)
assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line")
program := compiler.NewProgram(compiler.ProgramOptions{
Config: parsed,
Expand All @@ -161,7 +161,7 @@ func BenchmarkCheckFreshProgram(b *testing.B) {
fs := bundled.WrapFS(osvfs.FS())
rootPath := tspath.RootedDirectoryPathFromAbsolute(filepath.Join(repo.TestDataPath(), "fixtures/compiler"))
host := compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(rootPath.ResolveFile("tsconfig.json"), &core.CompilerOptions{}, nil, fs, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(rootPath.ResolveFile("tsconfig.json"), &core.CompilerOptions{}, nil, tsoptions.NewDefaultParseConfigHost(fs), nil)
assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line")
ctx := b.Context()

Expand Down
2 changes: 1 addition & 1 deletion tsc/internal/compiler/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,6 @@ func (h *compilerHost) ContentMapperProject() contentmapper.Project {
}

func (h *compilerHost) GetResolvedProjectReference(fileName tspath.RootedFilePath, path tspath.PathKey) *tsoptions.ParsedCommandLine {
commandLine, _ := tsoptions.GetParsedCommandLineOfConfigFilePath(fileName, path, nil, nil /*optionsRaw*/, h.fs, h.extendedConfigCache)
commandLine, _ := tsoptions.GetParsedCommandLineOfConfigFilePath(fileName, path, nil, nil /*optionsRaw*/, tsoptions.NewDefaultParseConfigHost(h.fs), h.extendedConfigCache)
return commandLine
}
8 changes: 4 additions & 4 deletions tsc/internal/compiler/program_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ import { value } from "./dep.js"; export const result = value;`,
}
fs := vfstest.FromMap(files, tspath.CaseSensitive)
host := NewCompilerHost(fs, "/", nil, nil, nil)
config, diagnostics := tsoptions.GetParsedCommandLineOfConfigFile("/src/tsconfig.json", nil, nil, fs, nil)
config, diagnostics := tsoptions.GetParsedCommandLineOfConfigFile("/src/tsconfig.json", nil, nil, tsoptions.NewDefaultParseConfigHost(fs), nil)
assert.Equal(t, len(diagnostics), 0)
var pools, resolvers int
tr := new(tracing.Tracing)
Expand Down Expand Up @@ -209,7 +209,7 @@ func TestClonedProgramProjectReferenceResolution(t *testing.T) {
host := NewCompilerHost(fs, "/", nil, nil, nil)
config, diagnostics := tsoptions.GetParsedCommandLineOfConfigFile("/src/tsconfig.json", &core.CompilerOptions{
PreserveSymlinks: core.BoolToTristate(preserveSymlinks),
}, nil, fs, nil)
}, nil, tsoptions.NewDefaultParseConfigHost(fs), nil)
assert.Equal(t, len(diagnostics), 0)
p := NewProgram(ProgramOptions{Config: config, Host: host, UseSourceOfProjectReference: true})
assert.Assert(t, p.GetSourceFile("/reference/index.ts") != nil)
Expand Down Expand Up @@ -500,7 +500,7 @@ func TestImportSourceProgram(t *testing.T) {
}
fs := vfstest.FromMap(files, tspath.CaseSensitive)
host := NewCompilerHost(fs, "/", nil, nil, nil)
config, diagnostics := tsoptions.GetParsedCommandLineOfConfigFile("/src/tsconfig.json", nil, nil, fs, nil)
config, diagnostics := tsoptions.GetParsedCommandLineOfConfigFile("/src/tsconfig.json", nil, nil, tsoptions.NewDefaultParseConfigHost(fs), nil)
assert.Equal(t, len(diagnostics), 0)
program := NewProgram(ProgramOptions{Config: config, Host: host})
file := program.GetSourceFile("/src/index.ts")
Expand Down Expand Up @@ -609,7 +609,7 @@ func BenchmarkNewProgram(b *testing.B) {
rootPath := tspath.RootedDirectoryPathFromAbsolute(filepath.Join(repo.TestDataPath(), "fixtures/compiler"))
fs := bundled.WrapFS(osvfs.FS())
host := NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(rootPath.ResolveFile("tsconfig.json"), nil, nil, fs, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(rootPath.ResolveFile("tsconfig.json"), nil, nil, tsoptions.NewDefaultParseConfigHost(fs), nil)
assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line")
opts := ProgramOptions{
Config: parsed,
Expand Down
1 change: 1 addition & 0 deletions tsc/internal/diagnostics/diagnosticMessages.generated.json
Original file line number Diff line number Diff line change
Expand Up @@ -1957,6 +1957,7 @@
"The_typescript_contentMapper_outputExtensions_of_the_content_mapper_package_0_contains_an_invalid_ma_18121": "The 'typescript.contentMapper.outputExtensions' of the content mapper package '{0}' contains an invalid mapping from '{1}' to '{2}'. Extensions must be non-empty and begin with a '.'.",
"The_typescript_contentMapper_outputExtensions_of_the_content_mapper_package_0_must_be_an_object_with_18122": "The 'typescript.contentMapper.outputExtensions' of the content mapper package '{0}' must be an object with string values.",
"Content_mapper_extension_0_must_not_contain_path_separators_18123": "Content mapper extension '{0}' must not contain path separators.",
"The_content_mapper_package_0_is_outside_the_open_workspace_and_will_not_be_loaded_18124": "The content mapper package '{0}' is outside the open workspace and will not be loaded.",
"nodenext_if_module_is_nodenext_node16_if_module_is_node16_or_node18_otherwise_bundler_69010": "`nodenext` if `module` is `nodenext`; `node16` if `module` is `node16` or `node18`; otherwise, `bundler`.",
"File_is_a_CommonJS_module_it_may_be_converted_to_an_ES_module_80001": "File is a CommonJS module; it may be converted to an ES module.",
"This_constructor_function_may_be_converted_to_a_class_declaration_80002": "This constructor function may be converted to a class declaration.",
Expand Down
4 changes: 4 additions & 0 deletions tsc/internal/diagnostics/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -8728,6 +8728,10 @@
"category": "Error",
"code": 18068
},
"The content mapper package '{0}' is outside the open workspace and will not be loaded.": {
"category": "Error",
"code": 18124
},
"The content mapper '{0}' failed to transform this file.": {
"category": "Error",
"code": 18069
Expand Down
3 changes: 3 additions & 0 deletions tsc/internal/diagnostics/diagnostics_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tsc/internal/execute/build/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (h *host) GetResolvedProjectReference(fileName tspath.RootedFilePath, path
wrapped.Set("compilerOptions", raw)
commandLineRaw = wrapped
}
commandLine, _ := tsoptions.GetParsedCommandLineOfConfigFilePath(fileName, path, h.orchestrator.opts.Command.CompilerOptions, commandLineRaw, h.FS(), &h.extendedConfigCache)
commandLine, _ := tsoptions.GetParsedCommandLineOfConfigFilePath(fileName, path, h.orchestrator.opts.Command.CompilerOptions, commandLineRaw, tsoptions.NewDefaultParseConfigHost(h.FS()), &h.extendedConfigCache)
configTime := h.orchestrator.opts.Sys.Now().Sub(configStart)
h.configTimes.Store(path, configTime)
return commandLine
Expand Down
2 changes: 1 addition & 1 deletion tsc/internal/execute/tsc.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ func tscCompilation(ctx context.Context, sys tsc.System, commandLine *tsoptions.
commandLineRaw = wrapped
}
path := sys.FS().CaseSensitivity().PathKey(tspath.RootedPath(configFileName))
configParseResult, errors := tsoptions.GetParsedCommandLineOfConfigFilePath(configFileName, path, compilerOptionsFromCommandLine, commandLineRaw, sys.FS(), extendedConfigCache)
configParseResult, errors := tsoptions.GetParsedCommandLineOfConfigFilePath(configFileName, path, compilerOptionsFromCommandLine, commandLineRaw, tsoptions.NewDefaultParseConfigHost(sys.FS()), extendedConfigCache)
compileTimes.ConfigTime = sys.Now().Sub(configStart)
if len(errors) != 0 {
// these are unrecoverable errors--exit to report them as diagnostics
Expand Down
8 changes: 4 additions & 4 deletions tsc/internal/execute/tsc/extendedconfigcache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestExtendedConfigCacheExtendsCircularity(t *testing.T) {
fs := vfstest.FromMap(files, tspath.CaseInsensitive /*caseSensitivity*/)
cache := &tsc.ExtendedConfigCache{}

cmd, _ := tsoptions.GetParsedCommandLineOfConfigFile("/project/tsconfig.json", nil, nil, fs, cache)
cmd, _ := tsoptions.GetParsedCommandLineOfConfigFile("/project/tsconfig.json", nil, nil, tsoptions.NewDefaultParseConfigHost(fs), cache)
if cmd == nil {
t.Fatal("expected non-nil ParsedCommandLine")
}
Expand All @@ -46,7 +46,7 @@ func TestExtendedConfigCacheExtendsCircularity(t *testing.T) {
fs := vfstest.FromMap(files, tspath.CaseInsensitive /*caseSensitivity*/)
cache := &tsc.ExtendedConfigCache{}

cmd, _ := tsoptions.GetParsedCommandLineOfConfigFile("/project/tsconfig.json", nil, nil, fs, cache)
cmd, _ := tsoptions.GetParsedCommandLineOfConfigFile("/project/tsconfig.json", nil, nil, tsoptions.NewDefaultParseConfigHost(fs), cache)
if cmd == nil {
t.Fatal("expected non-nil ParsedCommandLine")
}
Expand All @@ -67,7 +67,7 @@ func TestExtendedConfigCacheExtendsCircularity(t *testing.T) {
fs := vfstest.FromMap(files, tspath.CaseInsensitive /*caseSensitivity*/)
cache := &tsc.ExtendedConfigCache{}

cmd, _ := tsoptions.GetParsedCommandLineOfConfigFile("/project/tsconfig.json", nil, nil, fs, cache)
cmd, _ := tsoptions.GetParsedCommandLineOfConfigFile("/project/tsconfig.json", nil, nil, tsoptions.NewDefaultParseConfigHost(fs), cache)
if cmd == nil {
t.Fatal("expected non-nil ParsedCommandLine")
}
Expand All @@ -86,7 +86,7 @@ func TestExtendedConfigCacheNullExtendsDoesNotPanic(t *testing.T) {
fs := vfstest.FromMap(files, tspath.CaseInsensitive /*caseSensitivity*/)
cache := &tsc.ExtendedConfigCache{}

cmd, _ := tsoptions.GetParsedCommandLineOfConfigFile("/project/tsconfig.json", nil, nil, fs, cache)
cmd, _ := tsoptions.GetParsedCommandLineOfConfigFile("/project/tsconfig.json", nil, nil, tsoptions.NewDefaultParseConfigHost(fs), cache)
if cmd == nil {
t.Fatal("expected non-nil ParsedCommandLine")
}
Expand Down
2 changes: 1 addition & 1 deletion tsc/internal/execute/tsctests/tscbuild_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2268,7 +2268,7 @@ func TestBuildOutputPaths(t *testing.T) {
t.Run("GetOutputFileNames/"+s.subScenario, func(t *testing.T) {
t.Parallel()
sys := newTestSys(input, false)
config, _ := tsoptions.GetParsedCommandLineOfConfigFile("/home/src/workspaces/project/tsconfig.json", &core.CompilerOptions{}, nil, sys.FS(), nil)
config, _ := tsoptions.GetParsedCommandLineOfConfigFile("/home/src/workspaces/project/tsconfig.json", &core.CompilerOptions{}, nil, tsoptions.NewDefaultParseConfigHost(sys.FS()), nil)
assert.DeepEqual(t, slices.Collect(config.GetOutputFileNames()), s.expectedDtsNames)
})
}
Expand Down
2 changes: 1 addition & 1 deletion tsc/internal/execute/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ func (w *Watcher) recheckTsConfig(force bool) bool {

func (w *Watcher) parseConfigFile() *tsoptions.ParsedCommandLine {
extendedConfigCache := &tsc.ExtendedConfigCache{}
configParseResult, errors := tsoptions.GetParsedCommandLineOfConfigFile(w.configFileName, w.compilerOptionsFromCommandLine, w.commandLineRaw, w.sys.FS(), extendedConfigCache)
configParseResult, errors := tsoptions.GetParsedCommandLineOfConfigFile(w.configFileName, w.compilerOptionsFromCommandLine, w.commandLineRaw, tsoptions.NewDefaultParseConfigHost(w.sys.FS()), extendedConfigCache)
if len(errors) > 0 {
for _, e := range errors {
w.reportDiagnostic(e)
Expand Down
3 changes: 3 additions & 0 deletions tsc/internal/fourslash/fourslash.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,9 @@ func (f *FourslashTest) initialize(t *testing.T, options *FourslashOptions) {
InitializationOptions: initializationOptions,
},
}
if options.RunExternalCode {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When does fourslash ever do this?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the content mapper fourslash tests do, in fact. I suppose it's not necessary, just kind of inherited from // @runExternalCode: true in compiler tests, which is useful for testing what the diagnostic looks like when it's not there.

params.RootUri = lsproto.DocumentUriOrNull{DocumentUri: new(lsproto.DocumentUri("file:///"))}
}
params.Capabilities = getCapabilitiesWithDefaults(options.Capabilities)
f.capabilities = params.Capabilities
resp, _, ok := f.client.SendRequest(t, lsproto.InitializeInfo, params)
Expand Down
2 changes: 1 addition & 1 deletion tsc/internal/ls/findallreferences_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func TestImplementationsWorklistDoesNotBlowUp(t *testing.T) {
fs = bundled.WrapFS(fs)

host := compiler.NewCompilerHost(fs, bundled.LibPath(), nil, nil, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, nil, fs, nil)
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, nil, tsoptions.NewDefaultParseConfigHost(fs), nil)
assert.Equal(t, len(errors), 0)
program := compiler.NewProgram(compiler.ProgramOptions{Config: parsed, Host: host})
program.BindSourceFiles()
Expand Down
20 changes: 20 additions & 0 deletions tsc/internal/lsp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1745,6 +1745,8 @@ func (s *Server) handleInitialized(ctx context.Context, params *lsproto.Initiali
s.logger.Logf("file watching: disabled (client lacks dynamic watch registration and builtin watcher backend is not fast-recursive)")
}

workspaceRoots := getInitialWorkspaceRoots(s.initializeParams)

cwd := s.cwd
if s.clientCapabilities.Workspace.WorkspaceFolders &&
s.initializeParams.WorkspaceFolders != nil &&
Expand Down Expand Up @@ -1778,6 +1780,7 @@ func (s *Server) handleInitialized(ctx context.Context, params *lsproto.Initiali
DebounceDelay: 500 * time.Millisecond,
PushDiagnosticsEnabled: !disablePushDiagnostics,
RunExternalCode: runExternalCode,
InitialWorkspaceRoots: workspaceRoots,

@andrewbranch Andrew Branch (andrewbranch) Oct 15, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⁠This was intentionally deferred because we just literally don't do anything correctly with workspace folders. I wasn't intending to add full support here, and "remove a folder from a workspace that was previously open in a trusted window" doesn't mean you stopped trusting it.

},
FS: s.fs,
Logger: s.logger,
Expand Down Expand Up @@ -1838,6 +1841,23 @@ func (s *Server) handleExit(ctx context.Context, _ lsproto.NoParams) error {
return io.EOF
}

func getInitialWorkspaceRoots(params *lsproto.InitializeParams) []tspath.RootedDirectoryPath {
workspaceRoots := []tspath.RootedDirectoryPath{}
if params.WorkspaceFolders != nil && params.WorkspaceFolders.WorkspaceFolders != nil {
for _, folder := range *params.WorkspaceFolders.WorkspaceFolders {
uri := lsproto.DocumentUri(folder.Uri)
if strings.HasPrefix(string(uri), "file://") {
workspaceRoots = append(workspaceRoots, tspath.RootedDirectoryPathFromPath(uri.Path()))
}
}
} else if params.RootUri.DocumentUri != nil && strings.HasPrefix(string(*params.RootUri.DocumentUri), "file://") {
workspaceRoots = append(workspaceRoots, tspath.RootedDirectoryPathFromPath(params.RootUri.DocumentUri.Path()))
} else if params.RootPath != nil && params.RootPath.String != nil && tspath.PathIsAbsolute(*params.RootPath.String) {
workspaceRoots = append(workspaceRoots, tspath.RootedDirectoryPathFromAbsolute(*params.RootPath.String))
}
return workspaceRoots
}

func (s *Server) handleDidChangeWorkspaceConfiguration(ctx context.Context, params *lsproto.DidChangeConfigurationParams) error {
if params.Settings == nil {
return nil
Expand Down
1 change: 1 addition & 0 deletions tsc/internal/lsp/server_contentmapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ export const title = "Profile";
}
initMsg, _, ok := client.SendRequest(t, lsproto.InitializeInfo, &lsproto.InitializeParams{
Capabilities: caps,
RootUri: lsproto.DocumentUriOrNull{DocumentUri: new(lsproto.DocumentUri("file:///home/project"))},
InitializationOptions: &lsproto.InitializationOptionsOrNull{InitializationOptions: &lsproto.InitializationOptions{
RunExternalCode: new(true),
}},
Expand Down
Loading
Loading