diff --git a/internal/compiler/fileloader.go b/internal/compiler/fileloader.go
index ef866d1921..c1122f44ce 100644
--- a/internal/compiler/fileloader.go
+++ b/internal/compiler/fileloader.go
@@ -129,128 +129,12 @@ func processAllProgramFiles(
}
loader.filesParser.parse(&loader, loader.rootTasks)
+
// Clear out loader and host to ensure its not used post program creation
loader.projectReferenceFileMapper.loader = nil
loader.projectReferenceFileMapper.host = nil
- totalFileCount := int(loader.totalFileCount.Load())
- libFileCount := int(loader.libFileCount.Load())
-
- var missingFiles []string
- 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
-
- filesByPath := make(map[tspath.Path]*ast.SourceFile, totalFileCount)
- loader.includeProcessor.fileIncludeReasons = make(map[tspath.Path][]*FileIncludeReason, totalFileCount)
- var outputFileToProjectReferenceSource map[tspath.Path]string
- if !opts.canUseProjectReferenceSource() {
- outputFileToProjectReferenceSource = make(map[tspath.Path]string, totalFileCount)
- }
- resolvedModules := make(map[tspath.Path]module.ModeAwareCache[*module.ResolvedModule], totalFileCount+1)
- typeResolutionsInFile := make(map[tspath.Path]module.ModeAwareCache[*module.ResolvedTypeReferenceDirective], totalFileCount)
- sourceFileMetaDatas := make(map[tspath.Path]ast.SourceFileMetaData, totalFileCount)
- var jsxRuntimeImportSpecifiers map[tspath.Path]*jsxRuntimeImportSpecifier
- var importHelpersImportSpecifiers map[tspath.Path]*ast.Node
- var sourceFilesFoundSearchingNodeModules collections.Set[tspath.Path]
- libFilesMap := make(map[tspath.Path]*LibFile, libFileCount)
-
- loader.filesParser.collect(&loader, loader.rootTasks, func(task *parseTask) {
- if task.redirectedParseTask != nil {
- if !opts.canUseProjectReferenceSource() {
- outputFileToProjectReferenceSource[task.redirectedParseTask.path] = task.FileName()
- }
- return
- }
-
- if task.isForAutomaticTypeDirective {
- typeResolutionsInFile[task.path] = task.typeResolutionsInFile
- return
- }
- file := task.file
- path := task.path
- if file == nil {
- // !!! sheetal file preprocessing diagnostic explaining getSourceFileFromReferenceWorker
- missingFiles = append(missingFiles, task.normalizedFilePath)
- return
- }
-
- // !!! sheetal todo porting file case errors
- // if _, ok := filesByPath[path]; ok {
- // Check if it differs only in drive letters its ok to ignore that error:
- // const checkedAbsolutePath = getNormalizedAbsolutePathWithoutRoot(checkedName, currentDirectory);
- // const inputAbsolutePath = getNormalizedAbsolutePathWithoutRoot(fileName, currentDirectory);
- // if (checkedAbsolutePath !== inputAbsolutePath) {
- // reportFileNamesDifferOnlyInCasingError(fileName, file, reason);
- // }
- // } else if loader.comparePathsOptions.UseCaseSensitiveFileNames {
- // pathIgnoreCase := tspath.ToPath(file.FileName(), loader.comparePathsOptions.CurrentDirectory, false)
- // // for case-sensitsive file systems check if we've already seen some file with similar filename ignoring case
- // if _, ok := filesByNameIgnoreCase[pathIgnoreCase]; ok {
- // reportFileNamesDifferOnlyInCasingError(fileName, existingFile, reason);
- // } else {
- // filesByNameIgnoreCase[pathIgnoreCase] = file
- // }
- // }
-
- if task.libFile != nil {
- libFiles = append(libFiles, file)
- libFilesMap[path] = task.libFile
- } else {
- files = append(files, file)
- }
- filesByPath[path] = file
- resolvedModules[path] = task.resolutionsInFile
- typeResolutionsInFile[path] = task.typeResolutionsInFile
- sourceFileMetaDatas[path] = task.metadata
-
- if task.jsxRuntimeImportSpecifier != nil {
- if jsxRuntimeImportSpecifiers == nil {
- jsxRuntimeImportSpecifiers = make(map[tspath.Path]*jsxRuntimeImportSpecifier, totalFileCount)
- }
- jsxRuntimeImportSpecifiers[path] = task.jsxRuntimeImportSpecifier
- }
- if task.importHelpersImportSpecifier != nil {
- if importHelpersImportSpecifiers == nil {
- importHelpersImportSpecifiers = make(map[tspath.Path]*ast.Node, totalFileCount)
- }
- importHelpersImportSpecifiers[path] = task.importHelpersImportSpecifier
- }
- if task.fromExternalLibrary {
- sourceFilesFoundSearchingNodeModules.Add(path)
- }
- })
- loader.sortLibs(libFiles)
-
- allFiles := append(libFiles, files...)
-
- keys := slices.Collect(loader.pathForLibFileResolutions.Keys())
- slices.Sort(keys)
- for _, key := range keys {
- value, _ := loader.pathForLibFileResolutions.Load(key)
- resolvedModules[key] = module.ModeAwareCache[*module.ResolvedModule]{
- module.ModeAwareCacheKey{Name: value.libraryName, Mode: core.ModuleKindCommonJS}: value.resolution,
- }
- for _, trace := range value.trace {
- opts.Host.Trace(trace.Message, trace.Args...)
- }
- }
-
- return processedFiles{
- resolver: loader.resolver,
- files: allFiles,
- filesByPath: filesByPath,
- projectReferenceFileMapper: loader.projectReferenceFileMapper,
- resolvedModules: resolvedModules,
- typeResolutionsInFile: typeResolutionsInFile,
- sourceFileMetaDatas: sourceFileMetaDatas,
- jsxRuntimeImportSpecifiers: jsxRuntimeImportSpecifiers,
- importHelpersImportSpecifiers: importHelpersImportSpecifiers,
- sourceFilesFoundSearchingNodeModules: sourceFilesFoundSearchingNodeModules,
- libFiles: libFilesMap,
- missingFiles: missingFiles,
- includeProcessor: loader.includeProcessor,
- outputFileToProjectReferenceSource: outputFileToProjectReferenceSource,
- }
+ return loader.filesParser.getProcessedFiles(&loader)
}
func (p *fileLoader) toPath(file string) tspath.Path {
@@ -466,11 +350,10 @@ func (p *fileLoader) resolveTypeReferenceDirectives(t *parseTask) {
if resolved.IsResolved() {
t.addSubTask(resolvedRef{
- fileName: resolved.ResolvedFileName,
- increaseDepth: resolved.IsExternalLibraryImport,
- elideOnDepth: false,
- isFromExternalLibrary: resolved.IsExternalLibraryImport,
- includeReason: includeReason,
+ fileName: resolved.ResolvedFileName,
+ increaseDepth: resolved.IsExternalLibraryImport,
+ elideOnDepth: false,
+ includeReason: includeReason,
}, nil)
} else {
p.includeProcessor.addProcessingDiagnostic(&processingDiagnostic{
@@ -566,10 +449,9 @@ func (p *fileLoader) resolveImportsAndModuleAugmentations(t *parseTask) {
if shouldAddFile {
t.addSubTask(resolvedRef{
- fileName: resolvedFileName,
- increaseDepth: resolvedModule.IsExternalLibraryImport,
- elideOnDepth: isJsFileFromNodeModules,
- isFromExternalLibrary: resolvedModule.IsExternalLibraryImport,
+ fileName: resolvedFileName,
+ increaseDepth: resolvedModule.IsExternalLibraryImport,
+ elideOnDepth: isJsFileFromNodeModules,
includeReason: &FileIncludeReason{
kind: fileIncludeKindImport,
data: &referencedFileData{
diff --git a/internal/compiler/filesparser.go b/internal/compiler/filesparser.go
index 554ca47327..0aa19b024a 100644
--- a/internal/compiler/filesparser.go
+++ b/internal/compiler/filesparser.go
@@ -2,6 +2,7 @@ package compiler
import (
"math"
+ "slices"
"sync"
"github.com/microsoft/typescript-go/internal/ast"
@@ -20,6 +21,7 @@ type parseTask struct {
redirectedParseTask *parseTask
subTasks []*parseTask
loaded bool
+ startedSubTasks bool
isForAutomaticTypeDirective bool
includeReason *FileIncludeReason
@@ -31,12 +33,9 @@ type parseTask struct {
resolutionDiagnostics []*ast.Diagnostic
importHelpersImportSpecifier *ast.Node
jsxRuntimeImportSpecifier *jsxRuntimeImportSpecifier
- increaseDepth bool
- elideOnDepth bool
- // Track if this file is from an external library (node_modules)
- // This mirrors the TypeScript currentNodeModulesDepth > 0 check
- fromExternalLibrary bool
+ increaseDepth bool
+ elideOnDepth bool
loadedTask *parseTask
allIncludeReasons []*FileIncludeReason
@@ -50,14 +49,8 @@ func (t *parseTask) Path() tspath.Path {
return t.path
}
-func (t *parseTask) isRoot() bool {
- // Intentionally not checking t.includeReason != nil to ensure we can catch cases for missing include reason
- return !t.isForAutomaticTypeDirective && (t.includeReason.kind == fileIncludeKindRootFile || t.includeReason.kind == fileIncludeKindLibFile)
-}
-
func (t *parseTask) load(loader *fileLoader) {
t.loaded = true
- t.path = loader.toPath(t.normalizedFilePath)
if t.isForAutomaticTypeDirective {
t.loadAutomaticTypeDirectives(loader)
return
@@ -119,10 +112,9 @@ func (t *parseTask) load(loader *fileLoader) {
func (t *parseTask) redirect(loader *fileLoader, fileName string) {
t.redirectedParseTask = &parseTask{
- normalizedFilePath: tspath.NormalizePath(fileName),
- libFile: t.libFile,
- fromExternalLibrary: t.fromExternalLibrary,
- includeReason: t.includeReason,
+ normalizedFilePath: tspath.NormalizePath(fileName),
+ libFile: t.libFile,
+ includeReason: t.includeReason,
}
// increaseDepth and elideOnDepth are not copied to redirects, otherwise their depth would be double counted.
t.subTasks = []*parseTask{t.redirectedParseTask}
@@ -138,132 +130,262 @@ func (t *parseTask) loadAutomaticTypeDirectives(loader *fileLoader) {
}
type resolvedRef struct {
- fileName string
- increaseDepth bool
- elideOnDepth bool
- isFromExternalLibrary bool
- includeReason *FileIncludeReason
+ fileName string
+ increaseDepth bool
+ elideOnDepth bool
+ includeReason *FileIncludeReason
}
func (t *parseTask) addSubTask(ref resolvedRef, libFile *LibFile) {
normalizedFilePath := tspath.NormalizePath(ref.fileName)
subTask := &parseTask{
- normalizedFilePath: normalizedFilePath,
- libFile: libFile,
- increaseDepth: ref.increaseDepth,
- elideOnDepth: ref.elideOnDepth,
- fromExternalLibrary: ref.isFromExternalLibrary,
- includeReason: ref.includeReason,
+ normalizedFilePath: normalizedFilePath,
+ libFile: libFile,
+ increaseDepth: ref.increaseDepth,
+ elideOnDepth: ref.elideOnDepth,
+ includeReason: ref.includeReason,
}
t.subTasks = append(t.subTasks, subTask)
}
type filesParser struct {
- wg core.WorkGroup
- tasksByFileName collections.SyncMap[string, *queuedParseTask]
- maxDepth int
+ wg core.WorkGroup
+ taskDataByPath collections.SyncMap[tspath.Path, *parseTaskData]
+ maxDepth int
}
-type queuedParseTask struct {
- task *parseTask
- mu sync.Mutex
- lowestDepth int
- fromExternalLibrary bool
+type parseTaskData struct {
+ // map of tasks by file casing
+ tasks map[string]*parseTask
+ mu sync.Mutex
+ lowestDepth int
+ startedSubTasks bool
}
func (w *filesParser) parse(loader *fileLoader, tasks []*parseTask) {
- w.start(loader, tasks, 0, false)
+ w.start(loader, tasks, 0)
w.wg.RunAndWait()
}
-func (w *filesParser) start(loader *fileLoader, tasks []*parseTask, depth int, isFromExternalLibrary bool) {
+func (w *filesParser) start(loader *fileLoader, tasks []*parseTask, depth int) {
for i, task := range tasks {
- taskIsFromExternalLibrary := isFromExternalLibrary || task.fromExternalLibrary
- newTask := &queuedParseTask{task: task, lowestDepth: math.MaxInt}
- loadedTask, loaded := w.tasksByFileName.LoadOrStore(task.FileName(), newTask)
- task = loadedTask.task
- if loaded {
- tasks[i].loadedTask = task
- // Add in the loaded task's external-ness.
- taskIsFromExternalLibrary = taskIsFromExternalLibrary || task.fromExternalLibrary
- }
+ task.path = loader.toPath(task.normalizedFilePath)
+ data, loaded := w.taskDataByPath.LoadOrStore(task.path, &parseTaskData{
+ tasks: map[string]*parseTask{task.normalizedFilePath: task},
+ lowestDepth: math.MaxInt,
+ })
w.wg.Queue(func() {
- loadedTask.mu.Lock()
- defer loadedTask.mu.Unlock()
+ data.mu.Lock()
+ defer data.mu.Unlock()
startSubtasks := false
-
- currentDepth := depth
- if task.increaseDepth {
- currentDepth++
+ if loaded {
+ if existingTask, ok := data.tasks[task.normalizedFilePath]; ok {
+ tasks[i].loadedTask = existingTask
+ } else {
+ data.tasks[task.normalizedFilePath] = task
+ // This is new task for file name - so load subtasks if there was loading for any other casing
+ startSubtasks = data.startedSubTasks
+ }
}
- if currentDepth < loadedTask.lowestDepth {
+
+ currentDepth := core.IfElse(task.increaseDepth, depth+1, depth)
+ if currentDepth < data.lowestDepth {
// If we're seeing this task at a lower depth than before,
// reprocess its subtasks to ensure they are loaded.
- loadedTask.lowestDepth = currentDepth
- startSubtasks = true
- }
-
- if !task.isRoot() && taskIsFromExternalLibrary && !loadedTask.fromExternalLibrary {
- // If we're seeing this task now as an external library,
- // reprocess its subtasks to ensure they are also marked as external.
- loadedTask.fromExternalLibrary = true
+ data.lowestDepth = currentDepth
startSubtasks = true
+ data.startedSubTasks = true
}
if task.elideOnDepth && currentDepth > w.maxDepth {
return
}
- if !task.loaded {
- task.load(loader)
- }
-
- if startSubtasks {
- w.start(loader, task.subTasks, loadedTask.lowestDepth, loadedTask.fromExternalLibrary)
+ for _, taskByFileName := range data.tasks {
+ loadSubTasks := startSubtasks
+ if !taskByFileName.loaded {
+ taskByFileName.load(loader)
+ if taskByFileName.redirectedParseTask != nil {
+ // Always load redirected task
+ loadSubTasks = true
+ data.startedSubTasks = true
+ }
+ }
+ if !taskByFileName.startedSubTasks && loadSubTasks {
+ taskByFileName.startedSubTasks = true
+ w.start(loader, taskByFileName.subTasks, data.lowestDepth)
+ }
}
})
}
}
-func (w *filesParser) collect(loader *fileLoader, tasks []*parseTask, iterate func(*parseTask)) {
- // Mark all tasks we saw as external after the fact.
- w.tasksByFileName.Range(func(key string, value *queuedParseTask) bool {
- if value.fromExternalLibrary {
- value.task.fromExternalLibrary = true
- }
- return true
- })
- w.collectWorker(loader, tasks, iterate, collections.Set[*parseTask]{})
-}
+func (w *filesParser) getProcessedFiles(loader *fileLoader) processedFiles {
+ totalFileCount := int(loader.totalFileCount.Load())
+ libFileCount := int(loader.libFileCount.Load())
+
+ var missingFiles []string
+ 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
+
+ filesByPath := make(map[tspath.Path]*ast.SourceFile, totalFileCount)
+ // stores 'filename -> file association' ignoring case
+ // used to track cases when two file names differ only in casing
+ var tasksSeenByNameIgnoreCase map[string]*parseTask
+ if loader.comparePathsOptions.UseCaseSensitiveFileNames {
+ tasksSeenByNameIgnoreCase = make(map[string]*parseTask, totalFileCount)
+ }
-func (w *filesParser) collectWorker(loader *fileLoader, tasks []*parseTask, iterate func(*parseTask), seen collections.Set[*parseTask]) {
- for _, task := range tasks {
- // Exclude automatic type directive tasks from include reason processing,
- // as these are internal implementation details and should not contribute
- // to the reasons for including files.
- if task.redirectedParseTask == nil && !task.isForAutomaticTypeDirective {
+ loader.includeProcessor.fileIncludeReasons = make(map[tspath.Path][]*FileIncludeReason, totalFileCount)
+ var outputFileToProjectReferenceSource map[tspath.Path]string
+ if !loader.opts.canUseProjectReferenceSource() {
+ outputFileToProjectReferenceSource = make(map[tspath.Path]string, totalFileCount)
+ }
+ resolvedModules := make(map[tspath.Path]module.ModeAwareCache[*module.ResolvedModule], totalFileCount+1)
+ typeResolutionsInFile := make(map[tspath.Path]module.ModeAwareCache[*module.ResolvedTypeReferenceDirective], totalFileCount)
+ sourceFileMetaDatas := make(map[tspath.Path]ast.SourceFileMetaData, totalFileCount)
+ var jsxRuntimeImportSpecifiers map[tspath.Path]*jsxRuntimeImportSpecifier
+ var importHelpersImportSpecifiers map[tspath.Path]*ast.Node
+ var sourceFilesFoundSearchingNodeModules collections.Set[tspath.Path]
+ libFilesMap := make(map[tspath.Path]*LibFile, libFileCount)
+
+ var collectFiles func(tasks []*parseTask, seen map[*parseTaskData]string)
+ collectFiles = func(tasks []*parseTask, seen map[*parseTaskData]string) {
+ for _, task := range tasks {
includeReason := task.includeReason
- if task.loadedTask != nil {
- task = task.loadedTask
+ // Exclude automatic type directive tasks from include reason processing,
+ // as these are internal implementation details and should not contribute
+ // to the reasons for including files.
+ if task.redirectedParseTask == nil && !task.isForAutomaticTypeDirective {
+ if task.loadedTask != nil {
+ task = task.loadedTask
+ }
+ w.addIncludeReason(loader, task, includeReason)
+ }
+ data, _ := w.taskDataByPath.Load(task.path)
+ if !task.loaded {
+ continue
+ }
+
+ // ensure we only walk each task once
+ if checkedName, ok := seen[data]; ok {
+ if !loader.opts.Config.CompilerOptions().ForceConsistentCasingInFileNames.IsFalse() {
+ // Check if it differs only in drive letters its ok to ignore that error:
+ checkedAbsolutePath := tspath.GetNormalizedAbsolutePathWithoutRoot(checkedName, loader.comparePathsOptions.CurrentDirectory)
+ inputAbsolutePath := tspath.GetNormalizedAbsolutePathWithoutRoot(task.normalizedFilePath, loader.comparePathsOptions.CurrentDirectory)
+ if checkedAbsolutePath != inputAbsolutePath {
+ loader.includeProcessor.addProcessingDiagnosticsForFileCasing(task.path, checkedName, task.normalizedFilePath, includeReason)
+ }
+ }
+ continue
+ } else {
+ seen[data] = task.normalizedFilePath
+ }
+
+ if tasksSeenByNameIgnoreCase != nil {
+ pathLowerCase := tspath.ToFileNameLowerCase(string(task.path))
+ if taskByIgnoreCase, ok := tasksSeenByNameIgnoreCase[pathLowerCase]; ok {
+ loader.includeProcessor.addProcessingDiagnosticsForFileCasing(taskByIgnoreCase.path, taskByIgnoreCase.normalizedFilePath, task.normalizedFilePath, includeReason)
+ } else {
+ tasksSeenByNameIgnoreCase[pathLowerCase] = task
+ }
+ }
+
+ for _, trace := range task.typeResolutionsTrace {
+ loader.opts.Host.Trace(trace.Message, trace.Args...)
+ }
+ for _, trace := range task.resolutionsTrace {
+ loader.opts.Host.Trace(trace.Message, trace.Args...)
+ }
+ if subTasks := task.subTasks; len(subTasks) > 0 {
+ collectFiles(subTasks, seen)
+ }
+
+ // Exclude automatic type directive tasks from include reason processing,
+ // as these are internal implementation details and should not contribute
+ // to the reasons for including files.
+ if task.redirectedParseTask != nil {
+ if !loader.opts.canUseProjectReferenceSource() {
+ outputFileToProjectReferenceSource[task.redirectedParseTask.path] = task.FileName()
+ }
+ continue
+ }
+
+ if task.isForAutomaticTypeDirective {
+ typeResolutionsInFile[task.path] = task.typeResolutionsInFile
+ continue
+ }
+ file := task.file
+ path := task.path
+ if file == nil {
+ // !!! sheetal file preprocessing diagnostic explaining getSourceFileFromReferenceWorker
+ missingFiles = append(missingFiles, task.normalizedFilePath)
+ continue
+ }
+
+ if task.libFile != nil {
+ libFiles = append(libFiles, file)
+ libFilesMap[path] = task.libFile
+ } else {
+ files = append(files, file)
+ }
+ filesByPath[path] = file
+ resolvedModules[path] = task.resolutionsInFile
+ typeResolutionsInFile[path] = task.typeResolutionsInFile
+ sourceFileMetaDatas[path] = task.metadata
+
+ if task.jsxRuntimeImportSpecifier != nil {
+ if jsxRuntimeImportSpecifiers == nil {
+ jsxRuntimeImportSpecifiers = make(map[tspath.Path]*jsxRuntimeImportSpecifier, totalFileCount)
+ }
+ jsxRuntimeImportSpecifiers[path] = task.jsxRuntimeImportSpecifier
+ }
+ if task.importHelpersImportSpecifier != nil {
+ if importHelpersImportSpecifiers == nil {
+ importHelpersImportSpecifiers = make(map[tspath.Path]*ast.Node, totalFileCount)
+ }
+ importHelpersImportSpecifiers[path] = task.importHelpersImportSpecifier
+ }
+ if data.lowestDepth > 0 {
+ sourceFilesFoundSearchingNodeModules.Add(path)
}
- w.addIncludeReason(loader, task, includeReason)
- }
- // ensure we only walk each task once
- if !task.loaded || !seen.AddIfAbsent(task) {
- continue
}
- for _, trace := range task.typeResolutionsTrace {
- loader.opts.Host.Trace(trace.Message, trace.Args...)
+ }
+
+ collectFiles(loader.rootTasks, make(map[*parseTaskData]string, totalFileCount))
+ loader.sortLibs(libFiles)
+
+ allFiles := append(libFiles, files...)
+
+ keys := slices.Collect(loader.pathForLibFileResolutions.Keys())
+ slices.Sort(keys)
+ for _, key := range keys {
+ value, _ := loader.pathForLibFileResolutions.Load(key)
+ resolvedModules[key] = module.ModeAwareCache[*module.ResolvedModule]{
+ module.ModeAwareCacheKey{Name: value.libraryName, Mode: core.ModuleKindCommonJS}: value.resolution,
}
- for _, trace := range task.resolutionsTrace {
+ for _, trace := range value.trace {
loader.opts.Host.Trace(trace.Message, trace.Args...)
}
- if subTasks := task.subTasks; len(subTasks) > 0 {
- w.collectWorker(loader, subTasks, iterate, seen)
- }
- iterate(task)
+ }
+
+ return processedFiles{
+ resolver: loader.resolver,
+ files: allFiles,
+ filesByPath: filesByPath,
+ projectReferenceFileMapper: loader.projectReferenceFileMapper,
+ resolvedModules: resolvedModules,
+ typeResolutionsInFile: typeResolutionsInFile,
+ sourceFileMetaDatas: sourceFileMetaDatas,
+ jsxRuntimeImportSpecifiers: jsxRuntimeImportSpecifiers,
+ importHelpersImportSpecifiers: importHelpersImportSpecifiers,
+ sourceFilesFoundSearchingNodeModules: sourceFilesFoundSearchingNodeModules,
+ libFiles: libFilesMap,
+ missingFiles: missingFiles,
+ includeProcessor: loader.includeProcessor,
+ outputFileToProjectReferenceSource: outputFileToProjectReferenceSource,
}
}
diff --git a/internal/compiler/includeprocessor.go b/internal/compiler/includeprocessor.go
index 83691f45a1..a40534bbde 100644
--- a/internal/compiler/includeprocessor.go
+++ b/internal/compiler/includeprocessor.go
@@ -1,6 +1,7 @@
package compiler
import (
+ "slices"
"sync"
"github.com/microsoft/typescript-go/internal/ast"
@@ -59,6 +60,32 @@ func (i *includeProcessor) addProcessingDiagnostic(d ...*processingDiagnostic) {
i.processingDiagnostics = append(i.processingDiagnostics, d...)
}
+func (i *includeProcessor) addProcessingDiagnosticsForFileCasing(file tspath.Path, existingCasing string, currentCasing string, reason *FileIncludeReason) {
+ if !reason.isReferencedFile() && slices.ContainsFunc(i.fileIncludeReasons[file], func(r *FileIncludeReason) bool {
+ return r.isReferencedFile()
+ }) {
+ i.addProcessingDiagnostic(&processingDiagnostic{
+ kind: processingDiagnosticKindExplainingFileInclude,
+ data: &includeExplainingDiagnostic{
+ file: file,
+ diagnosticReason: reason,
+ message: diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing,
+ args: []any{existingCasing, currentCasing},
+ },
+ })
+ } else {
+ i.addProcessingDiagnostic(&processingDiagnostic{
+ kind: processingDiagnosticKindExplainingFileInclude,
+ data: &includeExplainingDiagnostic{
+ file: file,
+ diagnosticReason: reason,
+ message: diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing,
+ args: []any{currentCasing, existingCasing},
+ },
+ })
+ }
+}
+
func (i *includeProcessor) getReferenceLocation(r *FileIncludeReason, program *Program) *referenceFileLocation {
if existing, ok := i.reasonToReferenceLocation.Load(r); ok {
return existing
diff --git a/internal/compiler/processingDiagnostic.go b/internal/compiler/processingDiagnostic.go
index 20e5c8d18c..a2f7d89e90 100644
--- a/internal/compiler/processingDiagnostic.go
+++ b/internal/compiler/processingDiagnostic.go
@@ -79,7 +79,7 @@ func (d *processingDiagnostic) createDiagnosticExplainingFile(program *Program)
processRelatedInfo := func(includeReason *FileIncludeReason) {
if preferredLocation == nil && includeReason.isReferencedFile() && !program.includeProcessor.getReferenceLocation(includeReason, program).isSynthetic {
preferredLocation = includeReason
- } else {
+ } else if preferredLocation != includeReason {
info := program.includeProcessor.getRelatedInfo(includeReason, program)
if info != nil {
relatedInfo = append(relatedInfo, info)
diff --git a/internal/execute/incremental/snapshottobuildinfo.go b/internal/execute/incremental/snapshottobuildinfo.go
index fc83153362..528097d564 100644
--- a/internal/execute/incremental/snapshottobuildinfo.go
+++ b/internal/execute/incremental/snapshottobuildinfo.go
@@ -197,7 +197,7 @@ func (t *toBuildInfo) collectRootFiles() {
}
func (t *toBuildInfo) setFileInfoAndEmitSignatures() {
- t.buildInfo.FileInfos = core.MapNonNil(t.program.GetSourceFiles(), func(file *ast.SourceFile) *BuildInfoFileInfo {
+ t.buildInfo.FileInfos = core.Map(t.program.GetSourceFiles(), func(file *ast.SourceFile) *BuildInfoFileInfo {
info, _ := t.snapshot.fileInfos.Load(file.Path())
fileId := t.toFileId(file.Path())
// tryAddRoot(key, fileId);
@@ -206,11 +206,6 @@ func (t *toBuildInfo) setFileInfoAndEmitSignatures() {
panic(fmt.Sprintf("File name at index %d does not match expected relative path or libName: %s != %s", fileId-1, t.buildInfo.FileNames[fileId-1], t.relativeToBuildInfo(string(file.Path()))))
}
}
- if int(fileId) != len(t.buildInfo.FileNames) {
- // Duplicate - for now ignore
- return nil
- }
-
if t.snapshot.options.Composite.IsTrue() {
if !ast.IsJsonSourceFile(file) && t.program.SourceFileMayBeEmitted(file, false) {
if emitSignature, loaded := t.snapshot.emitSignatures.Load(file.Path()); !loaded {
@@ -235,9 +230,6 @@ func (t *toBuildInfo) setFileInfoAndEmitSignatures() {
}
return newBuildInfoFileInfo(info)
})
- if t.buildInfo.FileInfos == nil {
- t.buildInfo.FileInfos = []*BuildInfoFileInfo{}
- }
}
func (t *toBuildInfo) setRootOfIncrementalProgram() {
diff --git a/internal/execute/tsctests/tsc_test.go b/internal/execute/tsctests/tsc_test.go
index e618ce7829..87fca6fdca 100644
--- a/internal/execute/tsctests/tsc_test.go
+++ b/internal/execute/tsctests/tsc_test.go
@@ -981,6 +981,93 @@ func TestTscExtends(t *testing.T) {
}
}
+func TestForceConsistentCasingInFileNames(t *testing.T) {
+ t.Parallel()
+ testCases := []*tscInput{
+ {
+ subScenario: "with relative and non relative file resolutions",
+ files: FileMap{
+ "/user/username/projects/myproject/src/struct.d.ts": stringtestutil.Dedent(`
+ import * as xs1 from "fp-ts/lib/Struct";
+ import * as xs2 from "fp-ts/lib/struct";
+ import * as xs3 from "./Struct";
+ import * as xs4 from "./struct";
+ `),
+ "/user/username/projects/myproject/node_modules/fp-ts/lib/struct.d.ts": `export function foo(): void`,
+ },
+ cwd: "/user/username/projects/myproject",
+ commandLineArgs: []string{"/user/username/projects/myproject/src/struct.d.ts", "--forceConsistentCasingInFileNames", "--explainFiles"},
+ ignoreCase: true,
+ },
+ {
+ subScenario: "when file is included from multiple places with different casing",
+ files: FileMap{
+ "/home/src/projects/project/src/struct.d.ts": stringtestutil.Dedent(`
+ import * as xs1 from "fp-ts/lib/Struct";
+ import * as xs2 from "fp-ts/lib/struct";
+ import * as xs3 from "./Struct";
+ import * as xs4 from "./struct";
+ `),
+ "/home/src/projects/project/src/anotherFile.ts": stringtestutil.Dedent(`
+ import * as xs1 from "fp-ts/lib/Struct";
+ import * as xs2 from "fp-ts/lib/struct";
+ import * as xs3 from "./Struct";
+ import * as xs4 from "./struct";
+ `),
+ "/home/src/projects/project/src/oneMore.ts": stringtestutil.Dedent(`
+ import * as xs1 from "fp-ts/lib/Struct";
+ import * as xs2 from "fp-ts/lib/struct";
+ import * as xs3 from "./Struct";
+ import * as xs4 from "./struct";
+ `),
+ "/home/src/projects/project/tsconfig.json": `{}`,
+ "/home/src/projects/project/node_modules/fp-ts/lib/struct.d.ts": `export function foo(): void`,
+ },
+ cwd: "/home/src/projects/project",
+ commandLineArgs: []string{"--explainFiles"},
+ ignoreCase: true,
+ },
+ {
+ subScenario: "with type ref from file",
+ files: FileMap{
+ "/user/username/projects/myproject/src/fileOne.d.ts": `declare class c { }`,
+ "/user/username/projects/myproject/src/file2.d.ts": stringtestutil.Dedent(`
+ ///
+ declare const y: c;
+ `),
+ "/user/username/projects/myproject/tsconfig.json": "{ }",
+ },
+ cwd: "/user/username/projects/myproject",
+ commandLineArgs: []string{"-p", "/user/username/projects/myproject", "--explainFiles", "--traceResolution"},
+ ignoreCase: true,
+ },
+ {
+ subScenario: "with triple slash ref from file",
+ files: FileMap{
+ "/home/src/workspaces/project/src/c.ts": `/// `,
+ "/home/src/workspaces/project/src/d.ts": `declare class c { }`,
+ "/home/src/workspaces/project/tsconfig.json": "{ }",
+ },
+ ignoreCase: true,
+ },
+ {
+ subScenario: "two files exist on disk that differs only in casing",
+ files: FileMap{
+ "/home/src/workspaces/project/c.ts": `import {x} from "./D"`,
+ "/home/src/workspaces/project/D.ts": `export const x = 10;`,
+ "/home/src/workspaces/project/d.ts": `export const y = 20;`,
+ "/home/src/workspaces/project/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "files": ["c.ts", "d.ts"]
+ }`),
+ },
+ },
+ }
+ for _, test := range testCases {
+ test.run(t, "forceConsistentCasingInFileNames")
+ }
+}
+
func TestTscIgnoreConfig(t *testing.T) {
t.Parallel()
filesWithoutConfig := func() FileMap {
@@ -1745,6 +1832,54 @@ func TestTscIncremental(t *testing.T) {
},
},
},
+ {
+ subScenario: "Compile incremental with case insensitive file names",
+ commandLineArgs: []string{"-p", "."},
+ files: FileMap{
+ "/home/project/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "incremental": true
+ },
+ }`),
+ "/home/project/src/index.ts": stringtestutil.Dedent(`
+ import type { Foo1 } from 'lib1';
+ import type { Foo2 } from 'lib2';
+ export const foo1: Foo1 = { foo: "a" };
+ export const foo2: Foo2 = { foo: "b" };`),
+ "/home/node_modules/lib1/index.d.ts": stringtestutil.Dedent(`
+ import type { Foo } from 'someLib';
+ export type { Foo as Foo1 };`),
+ "/home/node_modules/lib1/package.json": stringtestutil.Dedent(`
+ {
+ "name": "lib1"
+ }`),
+ "/home/node_modules/lib2/index.d.ts": stringtestutil.Dedent(`
+ import type { Foo } from 'somelib';
+ export type { Foo as Foo2 };
+ export declare const foo2: Foo;`),
+ "/home/node_modules/lib2/package.json": stringtestutil.Dedent(`
+ {
+ "name": "lib2"
+ }
+ `),
+ "/home/node_modules/someLib/index.d.ts": stringtestutil.Dedent(`
+ import type { Str } from 'otherLib';
+ export type Foo = { foo: Str; };`),
+ "/home/node_modules/someLib/package.json": stringtestutil.Dedent(`
+ {
+ "name": "somelib"
+ }`),
+ "/home/node_modules/otherLib/index.d.ts": stringtestutil.Dedent(`
+ export type Str = string;`),
+ "/home/node_modules/otherLib/package.json": stringtestutil.Dedent(`
+ {
+ "name": "otherlib"
+ }`),
+ },
+ cwd: "/home/project",
+ ignoreCase: true,
+ },
}
for _, test := range testCases {
diff --git a/internal/tspath/path.go b/internal/tspath/path.go
index de09221507..26abe6778d 100644
--- a/internal/tspath/path.go
+++ b/internal/tspath/path.go
@@ -334,6 +334,12 @@ func GetNormalizedPathComponents(path string, currentDirectory string) []string
return reducePathComponents(GetPathComponents(path, currentDirectory))
}
+func GetNormalizedAbsolutePathWithoutRoot(fileName string, currentDirectory string) string {
+ absolutePath := GetNormalizedAbsolutePath(fileName, currentDirectory)
+ rootLength := GetRootLength(absolutePath)
+ return absolutePath[rootLength:]
+}
+
func GetNormalizedAbsolutePath(fileName string, currentDirectory string) string {
rootLength := GetRootLength(fileName)
if rootLength == 0 && currentDirectory != "" {
diff --git a/internal/tspath/path_test.go b/internal/tspath/path_test.go
index 85d7829de6..711030a1cd 100644
--- a/internal/tspath/path_test.go
+++ b/internal/tspath/path_test.go
@@ -417,6 +417,14 @@ func TestGetNormalizedAbsolutePath(t *testing.T) {
assert.Equal(t, GetNormalizedAbsolutePath("\\\\a\\b\\\\c", ""), "//a/b/c")
}
+func TestGetNormalizedAbsolutePathWithoutRoot(t *testing.T) {
+ t.Parallel()
+
+ assert.Equal(t, GetNormalizedAbsolutePathWithoutRoot("/a/b/c.txt", "/a/b"), "a/b/c.txt")
+ assert.Equal(t, GetNormalizedAbsolutePathWithoutRoot("c:/work/hello.txt", "c:/work"), "work/hello.txt")
+ assert.Equal(t, GetNormalizedAbsolutePathWithoutRoot("c:/work/hello.txt", "d:/worspaces"), "work/hello.txt")
+}
+
var getNormalizedAbsolutePathTests = map[string][][]string{
"non-normalized inputs": {
{"/.", ""},
diff --git a/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/two-files-exist-on-disk-that-differs-only-in-casing.js b/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/two-files-exist-on-disk-that-differs-only-in-casing.js
new file mode 100644
index 0000000000..cf19f856c1
--- /dev/null
+++ b/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/two-files-exist-on-disk-that-differs-only-in-casing.js
@@ -0,0 +1,72 @@
+currentDirectory::/home/src/workspaces/project
+useCaseSensitiveFileNames::true
+Input::
+//// [/home/src/workspaces/project/D.ts] *new*
+export const x = 10;
+//// [/home/src/workspaces/project/c.ts] *new*
+import {x} from "./D"
+//// [/home/src/workspaces/project/d.ts] *new*
+export const y = 20;
+//// [/home/src/workspaces/project/tsconfig.json] *new*
+{
+ "files": ["c.ts", "d.ts"]
+}
+
+tsgo
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
+Output::
+[96mc.ts[0m:[93m1[0m:[93m17[0m - [91merror[0m[90m TS1261: [0mAlready included file name '/home/src/workspaces/project/D.ts' differs from file name '/home/src/workspaces/project/d.ts' only in casing.
+ The file is in the program because:
+ Imported via "./D" from file '/home/src/workspaces/project/c.ts'
+ Part of 'files' list in tsconfig.json
+
+[7m1[0m import {x} from "./D"
+[7m [0m [91m ~~~~~[0m
+
+ [96mtsconfig.json[0m:[93m2[0m:[93m23[0m - File is matched by 'files' list specified here.
+ [7m2[0m "files": ["c.ts", "d.ts"]
+ [7m [0m [96m ~~~~~~[0m
+
+
+Found 1 error in c.ts[90m:1[0m
+
+//// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib*
+///
+interface Boolean {}
+interface Function {}
+interface CallableFunction {}
+interface NewableFunction {}
+interface IArguments {}
+interface Number { toExponential: any; }
+interface Object {}
+interface RegExp {}
+interface String { charAt: any; }
+interface Array { length: number; [n: number]: T; }
+interface ReadonlyArray {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+//// [/home/src/workspaces/project/D.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.x = void 0;
+exports.x = 10;
+
+//// [/home/src/workspaces/project/c.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+
+//// [/home/src/workspaces/project/d.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.y = void 0;
+exports.y = 20;
+
+
diff --git a/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/when-file-is-included-from-multiple-places-with-different-casing.js b/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/when-file-is-included-from-multiple-places-with-different-casing.js
new file mode 100644
index 0000000000..2c5f0bfa46
--- /dev/null
+++ b/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/when-file-is-included-from-multiple-places-with-different-casing.js
@@ -0,0 +1,315 @@
+currentDirectory::/home/src/projects/project
+useCaseSensitiveFileNames::false
+Input::
+//// [/home/src/projects/project/node_modules/fp-ts/lib/struct.d.ts] *new*
+export function foo(): void
+//// [/home/src/projects/project/src/anotherFile.ts] *new*
+import * as xs1 from "fp-ts/lib/Struct";
+import * as xs2 from "fp-ts/lib/struct";
+import * as xs3 from "./Struct";
+import * as xs4 from "./struct";
+//// [/home/src/projects/project/src/oneMore.ts] *new*
+import * as xs1 from "fp-ts/lib/Struct";
+import * as xs2 from "fp-ts/lib/struct";
+import * as xs3 from "./Struct";
+import * as xs4 from "./struct";
+//// [/home/src/projects/project/src/struct.d.ts] *new*
+import * as xs1 from "fp-ts/lib/Struct";
+import * as xs2 from "fp-ts/lib/struct";
+import * as xs3 from "./Struct";
+import * as xs4 from "./struct";
+//// [/home/src/projects/project/tsconfig.json] *new*
+{}
+
+tsgo --explainFiles
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
+Output::
+[96msrc/Struct.d.ts[0m:[93m2[0m:[93m22[0m - [91merror[0m[90m TS1149: [0mFile name '/home/src/projects/project/node_modules/fp-ts/lib/struct.d.ts' differs from already included file name '/home/src/projects/project/node_modules/fp-ts/lib/Struct.d.ts' only in casing.
+ The file is in the program because:
+ Imported via "fp-ts/lib/Struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "fp-ts/lib/struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "fp-ts/lib/Struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "fp-ts/lib/struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "fp-ts/lib/Struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Imported via "fp-ts/lib/struct" from file '/home/src/projects/project/src/oneMore.ts'
+
+[7m2[0m import * as xs2 from "fp-ts/lib/struct";
+[7m [0m [91m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m1[0m:[93m22[0m - File is included via import here.
+ [7m1[0m import * as xs1 from "fp-ts/lib/Struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m2[0m:[93m22[0m - File is included via import here.
+ [7m2[0m import * as xs2 from "fp-ts/lib/struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m1[0m:[93m22[0m - File is included via import here.
+ [7m1[0m import * as xs1 from "fp-ts/lib/Struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m1[0m:[93m22[0m - File is included via import here.
+ [7m1[0m import * as xs1 from "fp-ts/lib/Struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m2[0m:[93m22[0m - File is included via import here.
+ [7m2[0m import * as xs2 from "fp-ts/lib/struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+[96msrc/Struct.d.ts[0m:[93m4[0m:[93m22[0m - [91merror[0m[90m TS1149: [0mFile name '/home/src/projects/project/src/struct.d.ts' differs from already included file name '/home/src/projects/project/src/Struct.d.ts' only in casing.
+ The file is in the program because:
+ Imported via "./Struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "./Struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "./Struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Matched by default include pattern '**/*'
+
+[7m4[0m import * as xs4 from "./struct";
+[7m [0m [91m ~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m4[0m:[93m22[0m - File is included via import here.
+ [7m4[0m import * as xs4 from "./struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m4[0m:[93m22[0m - File is included via import here.
+ [7m4[0m import * as xs4 from "./struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+[96msrc/anotherFile.ts[0m:[93m2[0m:[93m22[0m - [91merror[0m[90m TS1149: [0mFile name '/home/src/projects/project/node_modules/fp-ts/lib/struct.d.ts' differs from already included file name '/home/src/projects/project/node_modules/fp-ts/lib/Struct.d.ts' only in casing.
+ The file is in the program because:
+ Imported via "fp-ts/lib/Struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "fp-ts/lib/struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "fp-ts/lib/Struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "fp-ts/lib/struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "fp-ts/lib/Struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Imported via "fp-ts/lib/struct" from file '/home/src/projects/project/src/oneMore.ts'
+
+[7m2[0m import * as xs2 from "fp-ts/lib/struct";
+[7m [0m [91m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m1[0m:[93m22[0m - File is included via import here.
+ [7m1[0m import * as xs1 from "fp-ts/lib/Struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m1[0m:[93m22[0m - File is included via import here.
+ [7m1[0m import * as xs1 from "fp-ts/lib/Struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m2[0m:[93m22[0m - File is included via import here.
+ [7m2[0m import * as xs2 from "fp-ts/lib/struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m1[0m:[93m22[0m - File is included via import here.
+ [7m1[0m import * as xs1 from "fp-ts/lib/Struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m2[0m:[93m22[0m - File is included via import here.
+ [7m2[0m import * as xs2 from "fp-ts/lib/struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+[96msrc/anotherFile.ts[0m:[93m3[0m:[93m22[0m - [91merror[0m[90m TS1261: [0mAlready included file name '/home/src/projects/project/src/Struct.d.ts' differs from file name '/home/src/projects/project/src/struct.d.ts' only in casing.
+ The file is in the program because:
+ Imported via "./Struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "./Struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "./Struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Matched by default include pattern '**/*'
+
+[7m3[0m import * as xs3 from "./Struct";
+[7m [0m [91m ~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m4[0m:[93m22[0m - File is included via import here.
+ [7m4[0m import * as xs4 from "./struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m4[0m:[93m22[0m - File is included via import here.
+ [7m4[0m import * as xs4 from "./struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m4[0m:[93m22[0m - File is included via import here.
+ [7m4[0m import * as xs4 from "./struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+[96msrc/anotherFile.ts[0m:[93m4[0m:[93m22[0m - [91merror[0m[90m TS1149: [0mFile name '/home/src/projects/project/src/struct.d.ts' differs from already included file name '/home/src/projects/project/src/Struct.d.ts' only in casing.
+ The file is in the program because:
+ Imported via "./Struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "./Struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "./Struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Matched by default include pattern '**/*'
+
+[7m4[0m import * as xs4 from "./struct";
+[7m [0m [91m ~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m4[0m:[93m22[0m - File is included via import here.
+ [7m4[0m import * as xs4 from "./struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m4[0m:[93m22[0m - File is included via import here.
+ [7m4[0m import * as xs4 from "./struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+[96msrc/oneMore.ts[0m:[93m2[0m:[93m22[0m - [91merror[0m[90m TS1149: [0mFile name '/home/src/projects/project/node_modules/fp-ts/lib/struct.d.ts' differs from already included file name '/home/src/projects/project/node_modules/fp-ts/lib/Struct.d.ts' only in casing.
+ The file is in the program because:
+ Imported via "fp-ts/lib/Struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "fp-ts/lib/struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "fp-ts/lib/Struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "fp-ts/lib/struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "fp-ts/lib/Struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Imported via "fp-ts/lib/struct" from file '/home/src/projects/project/src/oneMore.ts'
+
+[7m2[0m import * as xs2 from "fp-ts/lib/struct";
+[7m [0m [91m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m1[0m:[93m22[0m - File is included via import here.
+ [7m1[0m import * as xs1 from "fp-ts/lib/Struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m2[0m:[93m22[0m - File is included via import here.
+ [7m2[0m import * as xs2 from "fp-ts/lib/struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m1[0m:[93m22[0m - File is included via import here.
+ [7m1[0m import * as xs1 from "fp-ts/lib/Struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m2[0m:[93m22[0m - File is included via import here.
+ [7m2[0m import * as xs2 from "fp-ts/lib/struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m1[0m:[93m22[0m - File is included via import here.
+ [7m1[0m import * as xs1 from "fp-ts/lib/Struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+[96msrc/oneMore.ts[0m:[93m4[0m:[93m22[0m - [91merror[0m[90m TS1149: [0mFile name '/home/src/projects/project/src/struct.d.ts' differs from already included file name '/home/src/projects/project/src/Struct.d.ts' only in casing.
+ The file is in the program because:
+ Imported via "./Struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "./Struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/Struct.d.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/anotherFile.ts'
+ Imported via "./Struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Imported via "./struct" from file '/home/src/projects/project/src/oneMore.ts'
+ Matched by default include pattern '**/*'
+
+[7m4[0m import * as xs4 from "./struct";
+[7m [0m [91m ~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/Struct.d.ts[0m:[93m4[0m:[93m22[0m - File is included via import here.
+ [7m4[0m import * as xs4 from "./struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/anotherFile.ts[0m:[93m4[0m:[93m22[0m - File is included via import here.
+ [7m4[0m import * as xs4 from "./struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+ [96msrc/oneMore.ts[0m:[93m3[0m:[93m22[0m - File is included via import here.
+ [7m3[0m import * as xs3 from "./Struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+../../tslibs/TS/Lib/lib.d.ts
+ Default library for target 'ES5'
+node_modules/fp-ts/lib/Struct.d.ts
+ Imported via "fp-ts/lib/Struct" from file 'src/anotherFile.ts'
+ Imported via "fp-ts/lib/struct" from file 'src/anotherFile.ts'
+ Imported via "fp-ts/lib/Struct" from file 'src/Struct.d.ts'
+ Imported via "fp-ts/lib/struct" from file 'src/Struct.d.ts'
+ Imported via "fp-ts/lib/Struct" from file 'src/oneMore.ts'
+ Imported via "fp-ts/lib/struct" from file 'src/oneMore.ts'
+src/Struct.d.ts
+ Imported via "./Struct" from file 'src/anotherFile.ts'
+ Imported via "./Struct" from file 'src/Struct.d.ts'
+ Imported via "./struct" from file 'src/Struct.d.ts'
+ Imported via "./struct" from file 'src/anotherFile.ts'
+ Imported via "./Struct" from file 'src/oneMore.ts'
+ Imported via "./struct" from file 'src/oneMore.ts'
+ Matched by default include pattern '**/*'
+src/anotherFile.ts
+ Matched by default include pattern '**/*'
+src/oneMore.ts
+ Matched by default include pattern '**/*'
+
+Found 7 errors in 3 files.
+
+Errors Files
+ 2 src/Struct.d.ts[90m:2[0m
+ 3 src/anotherFile.ts[90m:2[0m
+ 2 src/oneMore.ts[90m:2[0m
+
+//// [/home/src/projects/project/src/anotherFile.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+
+//// [/home/src/projects/project/src/oneMore.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+
+//// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib*
+///
+interface Boolean {}
+interface Function {}
+interface CallableFunction {}
+interface NewableFunction {}
+interface IArguments {}
+interface Number { toExponential: any; }
+interface Object {}
+interface RegExp {}
+interface String { charAt: any; }
+interface Array { length: number; [n: number]: T; }
+interface ReadonlyArray {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+
diff --git a/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/with-relative-and-non-relative-file-resolutions.js b/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/with-relative-and-non-relative-file-resolutions.js
new file mode 100644
index 0000000000..19ce089f68
--- /dev/null
+++ b/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/with-relative-and-non-relative-file-resolutions.js
@@ -0,0 +1,75 @@
+currentDirectory::/user/username/projects/myproject
+useCaseSensitiveFileNames::false
+Input::
+//// [/user/username/projects/myproject/node_modules/fp-ts/lib/struct.d.ts] *new*
+export function foo(): void
+//// [/user/username/projects/myproject/src/struct.d.ts] *new*
+import * as xs1 from "fp-ts/lib/Struct";
+import * as xs2 from "fp-ts/lib/struct";
+import * as xs3 from "./Struct";
+import * as xs4 from "./struct";
+
+tsgo /user/username/projects/myproject/src/struct.d.ts --forceConsistentCasingInFileNames --explainFiles
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
+Output::
+[96msrc/struct.d.ts[0m:[93m2[0m:[93m22[0m - [91merror[0m[90m TS1149: [0mFile name '/user/username/projects/myproject/node_modules/fp-ts/lib/struct.d.ts' differs from already included file name '/user/username/projects/myproject/node_modules/fp-ts/lib/Struct.d.ts' only in casing.
+ The file is in the program because:
+ Imported via "fp-ts/lib/Struct" from file '/user/username/projects/myproject/src/struct.d.ts'
+ Imported via "fp-ts/lib/struct" from file '/user/username/projects/myproject/src/struct.d.ts'
+
+[7m2[0m import * as xs2 from "fp-ts/lib/struct";
+[7m [0m [91m ~~~~~~~~~~~~~~~~~~[0m
+
+ [96msrc/struct.d.ts[0m:[93m1[0m:[93m22[0m - File is included via import here.
+ [7m1[0m import * as xs1 from "fp-ts/lib/Struct";
+ [7m [0m [96m ~~~~~~~~~~~~~~~~~~[0m
+
+[96msrc/struct.d.ts[0m:[93m3[0m:[93m22[0m - [91merror[0m[90m TS1149: [0mFile name '/user/username/projects/myproject/src/Struct.d.ts' differs from already included file name '/user/username/projects/myproject/src/struct.d.ts' only in casing.
+ The file is in the program because:
+ Root file specified for compilation
+ Imported via "./Struct" from file '/user/username/projects/myproject/src/struct.d.ts'
+ Imported via "./struct" from file '/user/username/projects/myproject/src/struct.d.ts'
+
+[7m3[0m import * as xs3 from "./Struct";
+[7m [0m [91m ~~~~~~~~~~[0m
+
+ [96msrc/struct.d.ts[0m:[93m4[0m:[93m22[0m - File is included via import here.
+ [7m4[0m import * as xs4 from "./struct";
+ [7m [0m [96m ~~~~~~~~~~[0m
+
+../../../../home/src/tslibs/TS/Lib/lib.d.ts
+ Default library for target 'ES5'
+node_modules/fp-ts/lib/Struct.d.ts
+ Imported via "fp-ts/lib/Struct" from file 'src/struct.d.ts'
+ Imported via "fp-ts/lib/struct" from file 'src/struct.d.ts'
+src/struct.d.ts
+ Root file specified for compilation
+ Imported via "./Struct" from file 'src/struct.d.ts'
+ Imported via "./struct" from file 'src/struct.d.ts'
+
+Found 2 errors in the same file, starting at: src/struct.d.ts[90m:2[0m
+
+//// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib*
+///
+interface Boolean {}
+interface Function {}
+interface CallableFunction {}
+interface NewableFunction {}
+interface IArguments {}
+interface Number { toExponential: any; }
+interface Object {}
+interface RegExp {}
+interface String { charAt: any; }
+interface Array { length: number; [n: number]: T; }
+interface ReadonlyArray {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+
diff --git a/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/with-triple-slash-ref-from-file.js b/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/with-triple-slash-ref-from-file.js
new file mode 100644
index 0000000000..1d16927567
--- /dev/null
+++ b/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/with-triple-slash-ref-from-file.js
@@ -0,0 +1,53 @@
+currentDirectory::/home/src/workspaces/project
+useCaseSensitiveFileNames::false
+Input::
+//// [/home/src/workspaces/project/src/c.ts] *new*
+///
+//// [/home/src/workspaces/project/src/d.ts] *new*
+declare class c { }
+//// [/home/src/workspaces/project/tsconfig.json] *new*
+{ }
+
+tsgo
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
+Output::
+[96msrc/c.ts[0m:[93m1[0m:[93m22[0m - [91merror[0m[90m TS1261: [0mAlready included file name '/home/src/workspaces/project/src/D.ts' differs from file name '/home/src/workspaces/project/src/d.ts' only in casing.
+ The file is in the program because:
+ Referenced via './D.ts' from file '/home/src/workspaces/project/src/c.ts'
+ Matched by default include pattern '**/*'
+
+[7m1[0m ///
+[7m [0m [91m ~~~~~~[0m
+
+
+Found 1 error in src/c.ts[90m:1[0m
+
+//// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib*
+///
+interface Boolean {}
+interface Function {}
+interface CallableFunction {}
+interface NewableFunction {}
+interface IArguments {}
+interface Number { toExponential: any; }
+interface Object {}
+interface RegExp {}
+interface String { charAt: any; }
+interface Array { length: number; [n: number]: T; }
+interface ReadonlyArray {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+//// [/home/src/workspaces/project/src/D.js] *new*
+
+//// [/home/src/workspaces/project/src/c.js] *new*
+///
+
+
diff --git a/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/with-type-ref-from-file.js b/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/with-type-ref-from-file.js
new file mode 100644
index 0000000000..2f55514b08
--- /dev/null
+++ b/testdata/baselines/reference/tsc/forceConsistentCasingInFileNames/with-type-ref-from-file.js
@@ -0,0 +1,58 @@
+currentDirectory::/user/username/projects/myproject
+useCaseSensitiveFileNames::false
+Input::
+//// [/user/username/projects/myproject/src/file2.d.ts] *new*
+///
+declare const y: c;
+//// [/user/username/projects/myproject/src/fileOne.d.ts] *new*
+declare class c { }
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{ }
+
+tsgo -p /user/username/projects/myproject --explainFiles --traceResolution
+ExitStatus:: Success
+Output::
+======== Resolving type reference directive './fileOne.d.ts', containing file '/user/username/projects/myproject/src/file2.d.ts', root directory '/user/username/projects/myproject/node_modules/@types,/user/username/projects/node_modules/@types,/user/username/node_modules/@types,/user/node_modules/@types,/node_modules/@types'. ========
+Resolving with primary search path '/user/username/projects/myproject/node_modules/@types, /user/username/projects/node_modules/@types, /user/username/node_modules/@types, /user/node_modules/@types, /node_modules/@types'.
+Directory '/user/username/projects/myproject/node_modules/@types' does not exist, skipping all lookups in it.
+Directory '/user/username/projects/node_modules/@types' does not exist, skipping all lookups in it.
+Directory '/user/username/node_modules/@types' does not exist, skipping all lookups in it.
+Directory '/user/node_modules/@types' does not exist, skipping all lookups in it.
+Directory '/node_modules/@types' does not exist, skipping all lookups in it.
+Looking up in 'node_modules' folder, initial location '/user/username/projects/myproject/src'.
+Loading module as file / folder, candidate module location '/user/username/projects/myproject/src/fileOne.d.ts', target file types: Declaration.
+File name '/user/username/projects/myproject/src/fileOne.d.ts' has a '.d.ts' extension - stripping it.
+File '/user/username/projects/myproject/src/fileOne.d.ts' exists - use it as a name resolution result.
+Resolving real path for '/user/username/projects/myproject/src/fileOne.d.ts', result '/user/username/projects/myproject/src/fileOne.d.ts'.
+======== Type reference directive './fileOne.d.ts' was successfully resolved to '/user/username/projects/myproject/src/fileOne.d.ts', primary: false. ========
+../../../../home/src/tslibs/TS/Lib/lib.d.ts
+ Default library for target 'ES5'
+src/fileOne.d.ts
+ Type library referenced via './fileOne.d.ts' from file 'src/file2.d.ts'
+ Matched by default include pattern '**/*'
+src/file2.d.ts
+ Matched by default include pattern '**/*'
+//// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib*
+///
+interface Boolean {}
+interface Function {}
+interface CallableFunction {}
+interface NewableFunction {}
+interface IArguments {}
+interface Number { toExponential: any; }
+interface Object {}
+interface RegExp {}
+interface String { charAt: any; }
+interface Array { length: number; [n: number]: T; }
+interface ReadonlyArray {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+
diff --git a/testdata/baselines/reference/tsc/incremental/Compile-incremental-with-case-insensitive-file-names.js b/testdata/baselines/reference/tsc/incremental/Compile-incremental-with-case-insensitive-file-names.js
new file mode 100644
index 0000000000..416b8b8923
--- /dev/null
+++ b/testdata/baselines/reference/tsc/incremental/Compile-incremental-with-case-insensitive-file-names.js
@@ -0,0 +1,196 @@
+currentDirectory::/home/project
+useCaseSensitiveFileNames::false
+Input::
+//// [/home/node_modules/lib1/index.d.ts] *new*
+import type { Foo } from 'someLib';
+export type { Foo as Foo1 };
+//// [/home/node_modules/lib1/package.json] *new*
+{
+ "name": "lib1"
+}
+//// [/home/node_modules/lib2/index.d.ts] *new*
+import type { Foo } from 'somelib';
+export type { Foo as Foo2 };
+export declare const foo2: Foo;
+//// [/home/node_modules/lib2/package.json] *new*
+{
+ "name": "lib2"
+}
+//// [/home/node_modules/otherLib/index.d.ts] *new*
+export type Str = string;
+//// [/home/node_modules/otherLib/package.json] *new*
+{
+ "name": "otherlib"
+}
+//// [/home/node_modules/someLib/index.d.ts] *new*
+import type { Str } from 'otherLib';
+export type Foo = { foo: Str; };
+//// [/home/node_modules/someLib/package.json] *new*
+{
+ "name": "somelib"
+}
+//// [/home/project/src/index.ts] *new*
+import type { Foo1 } from 'lib1';
+import type { Foo2 } from 'lib2';
+export const foo1: Foo1 = { foo: "a" };
+export const foo2: Foo2 = { foo: "b" };
+//// [/home/project/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "incremental": true
+ },
+}
+
+tsgo -p .
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
+Output::
+[96m../node_modules/lib2/index.d.ts[0m:[93m1[0m:[93m26[0m - [91merror[0m[90m TS1149: [0mFile name '/home/node_modules/somelib/index.d.ts' differs from already included file name '/home/node_modules/someLib/index.d.ts' only in casing.
+ The file is in the program because:
+ Imported via 'someLib' from file '/home/node_modules/lib1/index.d.ts'
+ Imported via 'somelib' from file '/home/node_modules/lib2/index.d.ts'
+
+[7m1[0m import type { Foo } from 'somelib';
+[7m [0m [91m ~~~~~~~~~[0m
+
+ [96m../node_modules/lib1/index.d.ts[0m:[93m1[0m:[93m26[0m - File is included via import here.
+ [7m1[0m import type { Foo } from 'someLib';
+ [7m [0m [96m ~~~~~~~~~[0m
+
+
+Found 1 error in ../node_modules/lib2/index.d.ts[90m:1[0m
+
+//// [/home/project/src/index.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.foo2 = exports.foo1 = void 0;
+exports.foo1 = { foo: "a" };
+exports.foo2 = { foo: "b" };
+
+//// [/home/project/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","errors":true,"root":[6],"fileNames":["lib.d.ts","../node_modules/otherlib/index.d.ts","../node_modules/somelib/index.d.ts","../node_modules/lib1/index.d.ts","../node_modules/lib2/index.d.ts","./src/index.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"1fe659ed0634bb57b6dc25e9062f1162-export type Str = string;","12e112ff6e2744bb42d8e0b511e44117-import type { Str } from 'otherLib';\nexport type Foo = { foo: Str; };","b6305455d920a6729c435e6acf45eff6-import type { Foo } from 'someLib';\nexport type { Foo as Foo1 };","a5393e550a9c20a242a120bf6410db48-import type { Foo } from 'somelib';\nexport type { Foo as Foo2 };\nexport declare const foo2: Foo;","42aef197ff5f079223e2c29fb2e77cc5-import type { Foo1 } from 'lib1';\nimport type { Foo2 } from 'lib2';\nexport const foo1: Foo1 = { foo: \"a\" };\nexport const foo2: Foo2 = { foo: \"b\" };"],"fileIdsList":[[3],[2],[4,5]],"referencedMap":[[4,1],[5,1],[3,2],[6,3]]}
+//// [/home/project/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "errors": true,
+ "root": [
+ {
+ "files": [
+ "./src/index.ts"
+ ],
+ "original": 6
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../node_modules/otherlib/index.d.ts",
+ "../node_modules/somelib/index.d.ts",
+ "../node_modules/lib1/index.d.ts",
+ "../node_modules/lib2/index.d.ts",
+ "./src/index.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../node_modules/otherlib/index.d.ts",
+ "version": "1fe659ed0634bb57b6dc25e9062f1162-export type Str = string;",
+ "signature": "1fe659ed0634bb57b6dc25e9062f1162-export type Str = string;",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "../node_modules/somelib/index.d.ts",
+ "version": "12e112ff6e2744bb42d8e0b511e44117-import type { Str } from 'otherLib';\nexport type Foo = { foo: Str; };",
+ "signature": "12e112ff6e2744bb42d8e0b511e44117-import type { Str } from 'otherLib';\nexport type Foo = { foo: Str; };",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "../node_modules/lib1/index.d.ts",
+ "version": "b6305455d920a6729c435e6acf45eff6-import type { Foo } from 'someLib';\nexport type { Foo as Foo1 };",
+ "signature": "b6305455d920a6729c435e6acf45eff6-import type { Foo } from 'someLib';\nexport type { Foo as Foo1 };",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "../node_modules/lib2/index.d.ts",
+ "version": "a5393e550a9c20a242a120bf6410db48-import type { Foo } from 'somelib';\nexport type { Foo as Foo2 };\nexport declare const foo2: Foo;",
+ "signature": "a5393e550a9c20a242a120bf6410db48-import type { Foo } from 'somelib';\nexport type { Foo as Foo2 };\nexport declare const foo2: Foo;",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "./src/index.ts",
+ "version": "42aef197ff5f079223e2c29fb2e77cc5-import type { Foo1 } from 'lib1';\nimport type { Foo2 } from 'lib2';\nexport const foo1: Foo1 = { foo: \"a\" };\nexport const foo2: Foo2 = { foo: \"b\" };",
+ "signature": "42aef197ff5f079223e2c29fb2e77cc5-import type { Foo1 } from 'lib1';\nimport type { Foo2 } from 'lib2';\nexport const foo1: Foo1 = { foo: \"a\" };\nexport const foo2: Foo2 = { foo: \"b\" };",
+ "impliedNodeFormat": "CommonJS"
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../node_modules/somelib/index.d.ts"
+ ],
+ [
+ "../node_modules/otherlib/index.d.ts"
+ ],
+ [
+ "../node_modules/lib1/index.d.ts",
+ "../node_modules/lib2/index.d.ts"
+ ]
+ ],
+ "referencedMap": {
+ "../node_modules/lib1/index.d.ts": [
+ "../node_modules/somelib/index.d.ts"
+ ],
+ "../node_modules/lib2/index.d.ts": [
+ "../node_modules/somelib/index.d.ts"
+ ],
+ "../node_modules/somelib/index.d.ts": [
+ "../node_modules/otherlib/index.d.ts"
+ ],
+ "./src/index.ts": [
+ "../node_modules/lib1/index.d.ts",
+ "../node_modules/lib2/index.d.ts"
+ ]
+ },
+ "size": 1685
+}
+//// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib*
+///
+interface Boolean {}
+interface Function {}
+interface CallableFunction {}
+interface NewableFunction {}
+interface IArguments {}
+interface Number { toExponential: any; }
+interface Object {}
+interface RegExp {}
+interface String { charAt: any; }
+interface Array { length: number; [n: number]: T; }
+interface ReadonlyArray {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+
+tsconfig.json::
+SemanticDiagnostics::
+*refresh* /home/src/tslibs/TS/Lib/lib.d.ts
+*refresh* /home/node_modules/otherLib/index.d.ts
+*refresh* /home/node_modules/someLib/index.d.ts
+*refresh* /home/node_modules/lib1/index.d.ts
+*refresh* /home/node_modules/lib2/index.d.ts
+*refresh* /home/project/src/index.ts
+Signatures::