diff --git a/internal/compiler/fileloader.go b/internal/compiler/fileloader.go index e1e84650d3..62e696315a 100644 --- a/internal/compiler/fileloader.go +++ b/internal/compiler/fileloader.go @@ -51,12 +51,17 @@ type fileLoader struct { pathForLibFileResolutions collections.SyncMap[tspath.Path, *libResolution] } +type missingFile struct { + path string + reason *FileIncludeReason +} + type processedFiles struct { resolver *module.Resolver files []*ast.SourceFile filesByPath map[tspath.Path]*ast.SourceFile projectReferenceFileMapper *projectReferenceFileMapper - missingFiles []string + missingFiles []missingFile resolvedModules map[tspath.Path]module.ModeAwareCache[*module.ResolvedModule] typeResolutionsInFile map[tspath.Path]module.ModeAwareCache[*module.ResolvedTypeReferenceDirective] sourceFileMetaDatas map[tspath.Path]ast.SourceFileMetaData @@ -136,7 +141,7 @@ func processAllProgramFiles( totalFileCount := int(loader.totalFileCount.Load()) libFileCount := int(loader.libFileCount.Load()) - var missingFiles []string + var missingFiles []missingFile files := make([]*ast.SourceFile, 0, totalFileCount-libFileCount) libFiles := make([]*ast.SourceFile, 0, totalFileCount) // totalFileCount here since we append files to it later to construct the final list @@ -168,9 +173,13 @@ func processAllProgramFiles( } file := task.file path := task.path + + // !!! sheetal file preprocessing diagnostic explaining getSourceFileFromReferenceWorker if file == nil { - // !!! sheetal file preprocessing diagnostic explaining getSourceFileFromReferenceWorker - missingFiles = append(missingFiles, task.normalizedFilePath) + missingFiles = append(missingFiles, missingFile{ + path: task.normalizedFilePath, + reason: task.includeReason, + }) return } diff --git a/internal/compiler/program.go b/internal/compiler/program.go index 2dbe96c47e..c512ca4b09 100644 --- a/internal/compiler/program.go +++ b/internal/compiler/program.go @@ -59,6 +59,7 @@ type Program struct { declarationDiagnosticCache collections.SyncMap[*ast.SourceFile, []*ast.Diagnostic] programDiagnostics []*ast.Diagnostic + programDiagnosticsOnce sync.Once hasEmitBlockingDiagnostics collections.Set[tspath.Path] sourceFilesToEmitOnce sync.Once @@ -211,6 +212,7 @@ func NewProgram(opts ProgramOptions) *Program { p.initCheckerPool() p.processedFiles = processAllProgramFiles(p.opts, p.SingleThreaded()) p.verifyCompilerOptions() + p.addProgramDiagnostics() return p } @@ -1222,6 +1224,33 @@ func (p *Program) getDiagnosticsHelper(ctx context.Context, sourceFile *ast.Sour return SortAndDeduplicateDiagnostics(result) } +func (p *Program) addProgramDiagnostics() { + for _, missingFile := range p.missingFiles { + missingFileReason := missingFile.reason + refData, ok := missingFileReason.data.(*referencedFileData) + if !ok { + continue + } + + parentFile := p.filesByPath[refData.file] + if parentFile == nil { + continue + } + + for _, ref := range parentFile.ReferencedFiles { + if tspath.GetNormalizedAbsolutePath(ref.FileName, tspath.GetDirectoryPath(parentFile.FileName())) == missingFile.path { + diagnostic := ast.NewDiagnostic( + parentFile, + ref.TextRange, + diagnostics.File_0_not_found, + ref.FileName, + ) + p.programDiagnostics = append(p.programDiagnostics, diagnostic) + } + } + } +} + func (p *Program) LineCount() int { var count int for _, file := range p.files { @@ -1553,8 +1582,8 @@ func (p *Program) GetIncludeReasons() map[tspath.Path][]*FileIncludeReason { // Testing only func (p *Program) IsMissingPath(path tspath.Path) bool { - return slices.ContainsFunc(p.missingFiles, func(missingPath string) bool { - return p.toPath(missingPath) == path + return slices.ContainsFunc(p.missingFiles, func(missingPath missingFile) bool { + return missingPath.path == string(path) }) }