From 448829a67bdd08efbbfb8d9a7e7e3f12b9c7e8fe Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 30 May 2025 15:26:19 -0700 Subject: [PATCH 1/2] Program to take ParsedCommandLine as config instead of separate options, root names, diagnostics etc --- internal/checker/checker_test.go | 15 +++- internal/compiler/program.go | 76 +++++++------------ internal/compiler/program_test.go | 24 ++++-- internal/execute/export_test.go | 5 +- internal/execute/tsc.go | 5 +- internal/execute/watch.go | 5 +- internal/project/project.go | 35 ++++++++- internal/testrunner/compiler_runner.go | 8 +- internal/testutil/harnessutil/harnessutil.go | 40 ++++++---- .../testutil/tsbaseline/js_emit_baseline.go | 3 +- internal/tsoptions/parsedcommandline.go | 1 - 11 files changed, 131 insertions(+), 86 deletions(-) diff --git a/internal/checker/checker_test.go b/internal/checker/checker_test.go index 8e101a750d..31db5a9ee6 100644 --- a/internal/checker/checker_test.go +++ b/internal/checker/checker_test.go @@ -41,7 +41,10 @@ foo.bar;` parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, host, nil) assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line") - p := compiler.NewProgramFromParsedCommandLine(parsed, host) + p := compiler.NewProgram(compiler.ProgramOptions{ + Config: parsed, + Host: host, + }) p.BindSourceFiles() c, done := p.GetTypeChecker(t.Context()) defer done() @@ -70,7 +73,10 @@ func TestCheckSrcCompiler(t *testing.T) { host := compiler.NewCompilerHost(nil, rootPath, fs, bundled.LibPath()) parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(tspath.CombinePaths(rootPath, "tsconfig.json"), &core.CompilerOptions{}, host, nil) assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line") - p := compiler.NewProgramFromParsedCommandLine(parsed, host) + p := compiler.NewProgram(compiler.ProgramOptions{ + Config: parsed, + Host: host, + }) p.CheckSourceFiles(t.Context()) } @@ -84,7 +90,10 @@ func BenchmarkNewChecker(b *testing.B) { host := compiler.NewCompilerHost(nil, rootPath, fs, bundled.LibPath()) parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(tspath.CombinePaths(rootPath, "tsconfig.json"), &core.CompilerOptions{}, host, nil) assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line") - p := compiler.NewProgramFromParsedCommandLine(parsed, host) + p := compiler.NewProgram(compiler.ProgramOptions{ + Config: parsed, + Host: host, + }) b.ReportAllocs() diff --git a/internal/compiler/program.go b/internal/compiler/program.go index 5bad0857c2..c9a7c619e2 100644 --- a/internal/compiler/program.go +++ b/internal/compiler/program.go @@ -21,27 +21,21 @@ import ( ) type ProgramOptions struct { - RootFiles []string - Host CompilerHost - Options *core.CompilerOptions - SingleThreaded core.Tristate - ProjectReference []core.ProjectReference - ConfigFileParsingDiagnostics []*ast.Diagnostic - CreateCheckerPool func(*Program) CheckerPool - - TypingsLocation string - ProjectName string + Host CompilerHost + Config *tsoptions.ParsedCommandLine + SingleThreaded core.Tristate + CreateCheckerPool func(*Program) CheckerPool + TypingsLocation string + ProjectName string } type Program struct { - host CompilerHost - programOptions ProgramOptions - compilerOptions *core.CompilerOptions - configFileName string - nodeModules map[string]*ast.SourceFile - checkerPool CheckerPool - currentDirectory string - configFileParsingDiagnostics []*ast.Diagnostic + host CompilerHost + programOptions ProgramOptions + compilerOptions *core.CompilerOptions + nodeModules map[string]*ast.SourceFile + checkerPool CheckerPool + currentDirectory string sourceAffectingCompilerOptionsOnce sync.Once sourceAffectingCompilerOptions *core.SourceFileAffectingCompilerOptions @@ -175,8 +169,7 @@ func (p *Program) GetSourceFileFromReference(origin *ast.SourceFile, ref *ast.Fi func NewProgram(options ProgramOptions) *Program { p := &Program{} p.programOptions = options - p.compilerOptions = options.Options - p.configFileParsingDiagnostics = slices.Clip(options.ConfigFileParsingDiagnostics) + p.compilerOptions = options.Config.CompilerOptions() if p.compilerOptions == nil { panic("compiler options required") } @@ -211,7 +204,7 @@ func NewProgram(options ProgramOptions) *Program { } } - p.processedFiles = processAllProgramFiles(p.host, p.programOptions, p.compilerOptions, p.resolver, options.RootFiles, libs, p.singleThreaded()) + p.processedFiles = processAllProgramFiles(p.host, p.programOptions, p.compilerOptions, p.resolver, options.Config.FileNames(), libs, p.singleThreaded()) p.filesByPath = make(map[tspath.Path]*ast.SourceFile, len(p.files)) for _, file := range p.files { p.filesByPath[file.Path()] = file @@ -236,20 +229,18 @@ func (p *Program) UpdateProgram(changedFilePath tspath.Path) (*Program, bool) { return NewProgram(p.programOptions), false } result := &Program{ - host: p.host, - programOptions: p.programOptions, - compilerOptions: p.compilerOptions, - configFileName: p.configFileName, - nodeModules: p.nodeModules, - currentDirectory: p.currentDirectory, - configFileParsingDiagnostics: p.configFileParsingDiagnostics, - resolver: p.resolver, - comparePathsOptions: p.comparePathsOptions, - processedFiles: p.processedFiles, - filesByPath: p.filesByPath, - currentNodeModulesDepth: p.currentNodeModulesDepth, - usesUriStyleNodeCoreModules: p.usesUriStyleNodeCoreModules, - unsupportedExtensions: p.unsupportedExtensions, + host: p.host, + programOptions: p.programOptions, + compilerOptions: p.compilerOptions, + nodeModules: p.nodeModules, + currentDirectory: p.currentDirectory, + resolver: p.resolver, + comparePathsOptions: p.comparePathsOptions, + processedFiles: p.processedFiles, + filesByPath: p.filesByPath, + currentNodeModulesDepth: p.currentNodeModulesDepth, + usesUriStyleNodeCoreModules: p.usesUriStyleNodeCoreModules, + unsupportedExtensions: p.unsupportedExtensions, } result.initCheckerPool() index := core.FindIndex(result.files, func(file *ast.SourceFile) bool { return file.Path() == newFile.Path() }) @@ -302,22 +293,11 @@ func equalCheckJSDirectives(d1 *ast.CheckJsDirective, d2 *ast.CheckJsDirective) return d1 == nil && d2 == nil || d1 != nil && d2 != nil && d1.Enabled == d2.Enabled } -func NewProgramFromParsedCommandLine(config *tsoptions.ParsedCommandLine, host CompilerHost) *Program { - programOptions := ProgramOptions{ - RootFiles: config.FileNames(), - Options: config.CompilerOptions(), - Host: host, - // todo: ProjectReferences - ConfigFileParsingDiagnostics: config.GetConfigFileParsingDiagnostics(), - } - return NewProgram(programOptions) -} - func (p *Program) SourceFiles() []*ast.SourceFile { return p.files } func (p *Program) Options() *core.CompilerOptions { return p.compilerOptions } func (p *Program) Host() CompilerHost { return p.host } func (p *Program) GetConfigFileParsingDiagnostics() []*ast.Diagnostic { - return slices.Clip(p.configFileParsingDiagnostics) + return slices.Clip(p.programOptions.Config.GetConfigFileParsingDiagnostics()) } func (p *Program) singleThreaded() bool { @@ -432,7 +412,7 @@ func (p *Program) getOptionsDiagnosticsOfConfigFile() []*ast.Diagnostic { if p.Options() == nil || p.Options().ConfigFilePath == "" { return nil } - return p.configFileParsingDiagnostics // TODO: actually call getDiagnosticsHelper on config path + return p.GetConfigFileParsingDiagnostics() // TODO: actually call getDiagnosticsHelper on config path } func (p *Program) getSyntacticDiagnosticsForFile(ctx context.Context, sourceFile *ast.SourceFile) []*ast.Diagnostic { diff --git a/internal/compiler/program_test.go b/internal/compiler/program_test.go index 53fb7a8881..7eac6bdd6c 100644 --- a/internal/compiler/program_test.go +++ b/internal/compiler/program_test.go @@ -232,9 +232,13 @@ func TestProgram(t *testing.T) { opts := core.CompilerOptions{Target: testCase.target} program := NewProgram(ProgramOptions{ - RootFiles: []string{"c:/dev/src/index.ts"}, - Host: NewCompilerHost(&opts, "c:/dev/src", fs, bundled.LibPath()), - Options: &opts, + Config: &tsoptions.ParsedCommandLine{ + ParsedConfig: &core.ParsedOptions{ + FileNames: []string{"c:/dev/src/index.ts"}, + CompilerOptions: &opts, + }, + }, + Host: NewCompilerHost(&opts, "c:/dev/src", fs, bundled.LibPath()), }) actualFiles := []string{} @@ -265,9 +269,13 @@ func BenchmarkNewProgram(b *testing.B) { opts := core.CompilerOptions{Target: testCase.target} programOpts := ProgramOptions{ - RootFiles: []string{"c:/dev/src/index.ts"}, - Host: NewCompilerHost(&opts, "c:/dev/src", fs, bundled.LibPath()), - Options: &opts, + Config: &tsoptions.ParsedCommandLine{ + ParsedConfig: &core.ParsedOptions{ + FileNames: []string{"c:/dev/src/index.ts"}, + CompilerOptions: &opts, + }, + }, + Host: NewCompilerHost(&opts, "c:/dev/src", fs, bundled.LibPath()), } for b.Loop() { @@ -290,8 +298,8 @@ func BenchmarkNewProgram(b *testing.B) { assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line") opts := ProgramOptions{ - Host: host, - Options: parsed.CompilerOptions(), + Config: parsed, + Host: host, } for b.Loop() { diff --git a/internal/execute/export_test.go b/internal/execute/export_test.go index 8c47763060..665e0fbc18 100644 --- a/internal/execute/export_test.go +++ b/internal/execute/export_test.go @@ -29,7 +29,10 @@ func RunWatchCycle(w *watcher) { return } // todo: updateProgram() - w.program = compiler.NewProgramFromParsedCommandLine(w.options, w.host) + w.program = compiler.NewProgram(compiler.ProgramOptions{ + Config: w.options, + Host: w.host, + }) if w.hasBeenModified(w.program) { w.compileAndEmit() } diff --git a/internal/execute/tsc.go b/internal/execute/tsc.go index 712e562192..d2294af38a 100644 --- a/internal/execute/tsc.go +++ b/internal/execute/tsc.go @@ -176,7 +176,10 @@ func performCompilation(sys System, cb cbType, config *tsoptions.ParsedCommandLi host := compiler.NewCachedFSCompilerHost(config.CompilerOptions(), sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath()) // todo: cache, statistics, tracing parseStart := time.Now() - program := compiler.NewProgramFromParsedCommandLine(config, host) + program := compiler.NewProgram(compiler.ProgramOptions{ + Config: config, + Host: host, + }) parseTime := time.Since(parseStart) result := emitFilesAndReportErrors(sys, program, reportDiagnostic) diff --git a/internal/execute/watch.go b/internal/execute/watch.go index 392ab13de9..d02689680e 100644 --- a/internal/execute/watch.go +++ b/internal/execute/watch.go @@ -35,7 +35,10 @@ func (w *watcher) doCycle() { return } // updateProgram() - w.program = compiler.NewProgramFromParsedCommandLine(w.options, w.host) + w.program = compiler.NewProgram(compiler.ProgramOptions{ + Config: w.options, + Host: w.host, + }) if w.hasBeenModified(w.program) { fmt.Fprint(w.sys.Writer(), "build starting at ", w.sys.Now(), w.sys.NewLine()) timeStart := w.sys.Now() diff --git a/internal/project/project.go b/internal/project/project.go index 0b9827a0c7..0e7c60a11f 100644 --- a/internal/project/project.go +++ b/internal/project/project.go @@ -147,6 +147,7 @@ type Project struct { compilerOptions *core.CompilerOptions typeAcquisition *core.TypeAcquisition parsedCommandLine *tsoptions.ParsedCommandLine + programConfig *tsoptions.ParsedCommandLine program *compiler.Program checkerPool *checkerPool @@ -471,6 +472,7 @@ func (p *Project) updateGraph() bool { case PendingReloadFileNames: p.parsedCommandLine = tsoptions.ReloadFileNamesOfParsedCommandLine(p.parsedCommandLine, p.host.FS()) writeFileNames = p.setRootFiles(p.parsedCommandLine.FileNames()) + p.programConfig = nil case PendingReloadFull: if err := p.loadConfig(); err != nil { panic(fmt.Sprintf("failed to reload config: %v", err)) @@ -512,16 +514,37 @@ func (p *Project) updateProgram() bool { } var oldProgramReused bool if p.program == nil || p.dirtyFilePath == "" { - rootFileNames := p.GetRootFileNames() - compilerOptions := p.compilerOptions + if p.programConfig == nil { + if p.parsedCommandLine != nil { + if len(p.typingFiles) == 0 { + p.programConfig = p.parsedCommandLine + } else { + parsedConfig := *p.parsedCommandLine.ParsedConfig + parsedConfig.FileNames = p.GetRootFileNames() + p.programConfig = &tsoptions.ParsedCommandLine{ + ParsedConfig: &parsedConfig, + ConfigFile: p.parsedCommandLine.ConfigFile, + Errors: p.parsedCommandLine.Errors, + } + } + } else { + rootFileNames := p.GetRootFileNames() + compilerOptions := p.compilerOptions + p.programConfig = &tsoptions.ParsedCommandLine{ + ParsedConfig: &core.ParsedOptions{ + CompilerOptions: compilerOptions, + FileNames: rootFileNames, + }, + } + } + } var typingsLocation string if typeAcquisition := p.getTypeAcquisition(); typeAcquisition != nil && typeAcquisition.Enable.IsTrue() { typingsLocation = p.host.TypingsInstaller().TypingsLocation } p.program = compiler.NewProgram(compiler.ProgramOptions{ - RootFiles: rootFileNames, + Config: p.programConfig, Host: p, - Options: compilerOptions, TypingsLocation: typingsLocation, CreateCheckerPool: func(program *compiler.Program) compiler.CheckerPool { p.checkerPool = newCheckerPool(4, program, p.Log) @@ -694,6 +717,7 @@ func (p *Project) UpdateTypingFiles(typingsInfo *TypingsInfo, typingFiles []stri if !slices.Equal(typingFiles, p.typingFiles) { // If typing files changed, then only schedule project update p.typingFiles = typingFiles + p.programConfig = nil // // Invalidate files with unresolved imports // this.resolutionCache.setFilesWithInvalidatedNonRelativeUnresolvedImports(this.cachedUnresolvedImportsPerFile); @@ -790,6 +814,7 @@ func (p *Project) removeFile(info *ScriptInfo, fileExists bool, detachFromProjec case KindInferred: p.rootFileNames.Delete(info.path) p.typeAcquisition = nil + p.programConfig = nil case KindConfigured: p.pendingReload = PendingReloadFileNames } @@ -813,6 +838,7 @@ func (p *Project) AddRoot(info *ScriptInfo) { p.mu.Lock() defer p.mu.Unlock() p.addRoot(info) + p.programConfig = nil p.markAsDirtyLocked() } @@ -845,6 +871,7 @@ func (p *Project) loadConfig() error { panic("loadConfig called on non-configured project") } + p.programConfig = nil if configFileContent, ok := p.host.FS().ReadFile(p.configFileName); ok { configDir := tspath.GetDirectoryPath(p.configFileName) tsConfigSourceFile := tsoptions.NewTsconfigSourceFileFromFilePath(p.configFileName, p.configFilePath, configFileContent) diff --git a/internal/testrunner/compiler_runner.go b/internal/testrunner/compiler_runner.go index f09a987296..06a1d0c467 100644 --- a/internal/testrunner/compiler_runner.go +++ b/internal/testrunner/compiler_runner.go @@ -255,19 +255,19 @@ func newCompilerTest( units := testCaseContentWithConfig.testUnitData var toBeCompiled []*harnessutil.TestFile var otherFiles []*harnessutil.TestFile - var tsConfigOptions core.CompilerOptions + var tsConfig *tsoptions.ParsedCommandLine hasNonDtsFiles := core.Some( units, func(unit *testUnit) bool { return !tspath.FileExtensionIs(unit.name, tspath.ExtensionDts) }) var tsConfigFiles []*harnessutil.TestFile if testCaseContentWithConfig.tsConfig != nil { - tsConfigOptions = *testCaseContentWithConfig.tsConfig.ParsedConfig.CompilerOptions + tsConfig = testCaseContentWithConfig.tsConfig tsConfigFiles = []*harnessutil.TestFile{ createHarnessTestFile(testCaseContentWithConfig.tsConfigFileUnitData, currentDirectory), } for _, unit := range units { if slices.Contains( - testCaseContentWithConfig.tsConfig.ParsedConfig.FileNames, + tsConfig.ParsedConfig.FileNames, tspath.GetNormalizedAbsolutePath(unit.name, currentDirectory), ) { toBeCompiled = append(toBeCompiled, createHarnessTestFile(unit, currentDirectory)) @@ -303,7 +303,7 @@ func newCompilerTest( toBeCompiled, otherFiles, harnessConfig, - &tsConfigOptions, + tsConfig, currentDirectory, testCaseContentWithConfig.symlinks, ) diff --git a/internal/testutil/harnessutil/harnessutil.go b/internal/testutil/harnessutil/harnessutil.go index b7d391bf31..fa00224ab5 100644 --- a/internal/testutil/harnessutil/harnessutil.go +++ b/internal/testutil/harnessutil/harnessutil.go @@ -79,13 +79,13 @@ func CompileFiles( inputFiles []*TestFile, otherFiles []*TestFile, testConfig TestConfiguration, - tsconfigOptions *core.CompilerOptions, + tsconfig *tsoptions.ParsedCommandLine, currentDirectory string, symlinks map[string]string, ) *CompilationResult { var compilerOptions core.CompilerOptions - if tsconfigOptions != nil { - compilerOptions = *tsconfigOptions + if tsconfig != nil { + compilerOptions = *tsconfig.ParsedConfig.CompilerOptions } // Set default options for tests if compilerOptions.NewLine == core.NewLineKindNone { @@ -102,7 +102,7 @@ func CompileFiles( setOptionsFromTestConfig(t, testConfig, &compilerOptions, &harnessOptions) } - return CompileFilesEx(t, inputFiles, otherFiles, &harnessOptions, &compilerOptions, currentDirectory, symlinks) + return CompileFilesEx(t, inputFiles, otherFiles, &harnessOptions, &compilerOptions, currentDirectory, symlinks, tsconfig) } func CompileFilesEx( @@ -113,6 +113,7 @@ func CompileFilesEx( compilerOptions *core.CompilerOptions, currentDirectory string, symlinks map[string]string, + tsconfig *tsoptions.ParsedCommandLine, ) *CompilationResult { var programFileNames []string for _, file := range inputFiles { @@ -206,13 +207,26 @@ func CompileFilesEx( fs = NewOutputRecorderFS(fs) host := createCompilerHost(fs, bundled.LibPath(), compilerOptions, currentDirectory) - result := compileFilesWithHost(host, programFileNames, compilerOptions, harnessOptions) + var configFile *tsoptions.TsConfigSourceFile + var errors []*ast.Diagnostic + if tsconfig != nil { + configFile = tsconfig.ConfigFile + errors = tsconfig.Errors + } + result := compileFilesWithHost(host, &tsoptions.ParsedCommandLine{ + ParsedConfig: &core.ParsedOptions{ + CompilerOptions: compilerOptions, + FileNames: programFileNames, + }, + ConfigFile: configFile, + Errors: errors, + }, harnessOptions) result.Symlinks = symlinks result.Repeat = func(testConfig TestConfiguration) *CompilationResult { newHarnessOptions := *harnessOptions newCompilerOptions := *compilerOptions setOptionsFromTestConfig(t, testConfig, &newCompilerOptions, &newHarnessOptions) - return CompileFilesEx(t, inputFiles, otherFiles, &newHarnessOptions, &newCompilerOptions, currentDirectory, symlinks) + return CompileFilesEx(t, inputFiles, otherFiles, &newHarnessOptions, &newCompilerOptions, currentDirectory, symlinks, tsconfig) } return result } @@ -482,8 +496,7 @@ func createCompilerHost(fs vfs.FS, defaultLibraryPath string, options *core.Comp func compileFilesWithHost( host compiler.CompilerHost, - rootFiles []string, - options *core.CompilerOptions, + config *tsoptions.ParsedCommandLine, harnessOptions *HarnessOptions, ) *CompilationResult { // !!! @@ -542,17 +555,17 @@ func compileFilesWithHost( // ), // ] : postErrors; ctx := context.Background() - program := createProgram(host, options, rootFiles) + program := createProgram(host, config) var diagnostics []*ast.Diagnostic diagnostics = append(diagnostics, program.GetSyntacticDiagnostics(ctx, nil)...) diagnostics = append(diagnostics, program.GetSemanticDiagnostics(ctx, nil)...) diagnostics = append(diagnostics, program.GetGlobalDiagnostics(ctx)...) - if options.GetEmitDeclarations() { + if config.CompilerOptions().GetEmitDeclarations() { diagnostics = append(diagnostics, program.GetDeclarationDiagnostics(ctx, nil)...) } emitResult := program.Emit(compiler.EmitOptions{}) - return newCompilationResult(options, program, emitResult, diagnostics, harnessOptions) + return newCompilationResult(config.CompilerOptions(), program, emitResult, diagnostics, harnessOptions) } type CompilationResult struct { @@ -787,16 +800,15 @@ func (c *CompilationResult) GetSourceMapRecord() string { return sourceMapRecorder.String() } -func createProgram(host compiler.CompilerHost, options *core.CompilerOptions, rootFiles []string) *compiler.Program { +func createProgram(host compiler.CompilerHost, config *tsoptions.ParsedCommandLine) *compiler.Program { var singleThreaded core.Tristate if testutil.TestProgramIsSingleThreaded() { singleThreaded = core.TSTrue } programOptions := compiler.ProgramOptions{ - RootFiles: rootFiles, + Config: config, Host: host, - Options: options, SingleThreaded: singleThreaded, } program := compiler.NewProgram(programOptions) diff --git a/internal/testutil/tsbaseline/js_emit_baseline.go b/internal/testutil/tsbaseline/js_emit_baseline.go index b377233b72..0c9e533980 100644 --- a/internal/testutil/tsbaseline/js_emit_baseline.go +++ b/internal/testutil/tsbaseline/js_emit_baseline.go @@ -281,7 +281,8 @@ func compileDeclarationFiles(t *testing.T, context *declarationCompilationContex context.harnessSettings, context.options, context.currentDirectory, - symlinks) + symlinks, + nil) return &declarationCompilationResult{ context.declInputFiles, context.declOtherFiles, diff --git a/internal/tsoptions/parsedcommandline.go b/internal/tsoptions/parsedcommandline.go index 02978664cf..373bfe0f27 100644 --- a/internal/tsoptions/parsedcommandline.go +++ b/internal/tsoptions/parsedcommandline.go @@ -17,7 +17,6 @@ type ParsedCommandLine struct { Errors []*ast.Diagnostic `json:"errors"` Raw any `json:"raw"` CompileOnSave *bool `json:"compileOnSave"` - // TypeAquisition *core.TypeAcquisition comparePathsOptions tspath.ComparePathsOptions wildcardDirectoriesOnce sync.Once From 89a9034ef5038d58fe380024c5f8d057eb255b9d Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 30 May 2025 16:17:28 -0700 Subject: [PATCH 2/2] Comments --- internal/project/project.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/project/project.go b/internal/project/project.go index 0e7c60a11f..3ca92ccb29 100644 --- a/internal/project/project.go +++ b/internal/project/project.go @@ -515,12 +515,15 @@ func (p *Project) updateProgram() bool { var oldProgramReused bool if p.program == nil || p.dirtyFilePath == "" { if p.programConfig == nil { + // Get from config file = config file root files + typings files if p.parsedCommandLine != nil { + // There are no typing files so use the parsed command line as is if len(p.typingFiles) == 0 { p.programConfig = p.parsedCommandLine } else { + // Update the fileNames parsedConfig := *p.parsedCommandLine.ParsedConfig - parsedConfig.FileNames = p.GetRootFileNames() + parsedConfig.FileNames = append(p.parsedCommandLine.FileNames(), p.typingFiles...) p.programConfig = &tsoptions.ParsedCommandLine{ ParsedConfig: &parsedConfig, ConfigFile: p.parsedCommandLine.ConfigFile,