diff --git a/cmd/tsgo/main.go b/cmd/tsgo/main.go index fbc694c2df..5eabc96df9 100644 --- a/cmd/tsgo/main.go +++ b/cmd/tsgo/main.go @@ -20,6 +20,6 @@ func runMain() int { return runAPI(args[1:]) } } - result := execute.CommandLine(newSystem(), args, false) + result := execute.CommandLine(newSystem(), args, nil) return int(result.Status) } diff --git a/cmd/tsgo/sys.go b/cmd/tsgo/sys.go index 741a48bac3..6f28371e77 100644 --- a/cmd/tsgo/sys.go +++ b/cmd/tsgo/sys.go @@ -46,11 +46,6 @@ func (s *osSys) Writer() io.Writer { return s.writer } -func (s *osSys) EndWrite() { - // do nothing, this is needed in the interface for testing - // todo: revisit if improving tsc/build/watch unittest baselines -} - func (s *osSys) WriteOutputIsTTY() bool { return term.IsTerminal(int(os.Stdout.Fd())) } diff --git a/internal/diagnosticwriter/diagnosticwriter.go b/internal/diagnosticwriter/diagnosticwriter.go index 797e447a44..7001bed49e 100644 --- a/internal/diagnosticwriter/diagnosticwriter.go +++ b/internal/diagnosticwriter/diagnosticwriter.go @@ -44,38 +44,41 @@ func FormatDiagnosticsWithColorAndContext(output io.Writer, diags []*ast.Diagnos if i > 0 { fmt.Fprint(output, formatOpts.NewLine) } + FormatDiagnosticWithColorAndContext(output, diagnostic, formatOpts) + } +} - if diagnostic.File() != nil { - file := diagnostic.File() - pos := diagnostic.Loc().Pos() - WriteLocation(output, file, pos, formatOpts, writeWithStyleAndReset) - fmt.Fprint(output, " - ") - } +func FormatDiagnosticWithColorAndContext(output io.Writer, diagnostic *ast.Diagnostic, formatOpts *FormattingOptions) { + if diagnostic.File() != nil { + file := diagnostic.File() + pos := diagnostic.Loc().Pos() + WriteLocation(output, file, pos, formatOpts, writeWithStyleAndReset) + fmt.Fprint(output, " - ") + } - writeWithStyleAndReset(output, diagnostic.Category().Name(), getCategoryFormat(diagnostic.Category())) - fmt.Fprintf(output, "%s TS%d: %s", foregroundColorEscapeGrey, diagnostic.Code(), resetEscapeSequence) - WriteFlattenedDiagnosticMessage(output, diagnostic, formatOpts.NewLine) + writeWithStyleAndReset(output, diagnostic.Category().Name(), getCategoryFormat(diagnostic.Category())) + fmt.Fprintf(output, "%s TS%d: %s", foregroundColorEscapeGrey, diagnostic.Code(), resetEscapeSequence) + WriteFlattenedDiagnosticMessage(output, diagnostic, formatOpts.NewLine) - if diagnostic.File() != nil && diagnostic.Code() != diagnostics.File_appears_to_be_binary.Code() { - fmt.Fprint(output, formatOpts.NewLine) - writeCodeSnippet(output, diagnostic.File(), diagnostic.Pos(), diagnostic.Len(), getCategoryFormat(diagnostic.Category()), "", formatOpts) - fmt.Fprint(output, formatOpts.NewLine) - } + if diagnostic.File() != nil && diagnostic.Code() != diagnostics.File_appears_to_be_binary.Code() { + fmt.Fprint(output, formatOpts.NewLine) + writeCodeSnippet(output, diagnostic.File(), diagnostic.Pos(), diagnostic.Len(), getCategoryFormat(diagnostic.Category()), "", formatOpts) + fmt.Fprint(output, formatOpts.NewLine) + } - if (diagnostic.RelatedInformation() != nil) && (len(diagnostic.RelatedInformation()) > 0) { - for _, relatedInformation := range diagnostic.RelatedInformation() { - file := relatedInformation.File() - if file != nil { - fmt.Fprint(output, formatOpts.NewLine) - fmt.Fprint(output, " ") - pos := relatedInformation.Pos() - WriteLocation(output, file, pos, formatOpts, writeWithStyleAndReset) - fmt.Fprint(output, " - ") - WriteFlattenedDiagnosticMessage(output, relatedInformation, formatOpts.NewLine) - writeCodeSnippet(output, file, pos, relatedInformation.Len(), foregroundColorEscapeCyan, " ", formatOpts) - } + if (diagnostic.RelatedInformation() != nil) && (len(diagnostic.RelatedInformation()) > 0) { + for _, relatedInformation := range diagnostic.RelatedInformation() { + file := relatedInformation.File() + if file != nil { fmt.Fprint(output, formatOpts.NewLine) + fmt.Fprint(output, " ") + pos := relatedInformation.Pos() + WriteLocation(output, file, pos, formatOpts, writeWithStyleAndReset) + fmt.Fprint(output, " - ") + WriteFlattenedDiagnosticMessage(output, relatedInformation, formatOpts.NewLine) + writeCodeSnippet(output, file, pos, relatedInformation.Len(), foregroundColorEscapeCyan, " ", formatOpts) } + fmt.Fprint(output, formatOpts.NewLine) } } } diff --git a/internal/execute/outputs.go b/internal/execute/outputs.go index 4094e3a468..29b1e4c825 100644 --- a/internal/execute/outputs.go +++ b/internal/execute/outputs.go @@ -31,21 +31,18 @@ func getFormatOptsOfSys(sys System) *diagnosticwriter.FormattingOptions { type diagnosticReporter = func(*ast.Diagnostic) +func quietDiagnosticReporter(diagnostic *ast.Diagnostic) {} func createDiagnosticReporter(sys System, options *core.CompilerOptions) diagnosticReporter { if options.Quiet.IsTrue() { - return func(diagnostic *ast.Diagnostic) {} + return quietDiagnosticReporter } formatOpts := getFormatOptsOfSys(sys) - if !shouldBePretty(sys, options) { - return func(diagnostic *ast.Diagnostic) { - diagnosticwriter.WriteFormatDiagnostic(sys.Writer(), diagnostic, formatOpts) - sys.EndWrite() - } - } + writeDiagnostic := core.IfElse(shouldBePretty(sys, options), diagnosticwriter.FormatDiagnosticWithColorAndContext, diagnosticwriter.WriteFormatDiagnostic) + return func(diagnostic *ast.Diagnostic) { - diagnosticwriter.FormatDiagnosticsWithColorAndContext(sys.Writer(), []*ast.Diagnostic{diagnostic}, formatOpts) - sys.EndWrite() + writeDiagnostic(sys.Writer(), diagnostic, formatOpts) + fmt.Fprint(sys.Writer(), formatOpts.NewLine) } } @@ -132,15 +129,18 @@ func createReportErrorSummary(sys System, options *core.CompilerOptions) func(di formatOpts := getFormatOptsOfSys(sys) return func(diagnostics []*ast.Diagnostic) { diagnosticwriter.WriteErrorSummaryText(sys.Writer(), diagnostics, formatOpts) - sys.EndWrite() } } return func(diagnostics []*ast.Diagnostic) {} } -func reportStatistics(sys System, program *compiler.Program, result compileAndEmitResult, memStats *runtime.MemStats) { +func reportStatistics(sys System, program *compiler.Program, result compileAndEmitResult, memStats *runtime.MemStats, testing CommandLineTesting) { var stats table + if testing != nil { + testing.OnStatisticsStart() + defer testing.OnStatisticsEnd() + } stats.add("Files", len(program.SourceFiles())) stats.add("Lines", program.LineCount()) stats.add("Identifiers", program.IdentifierCount()) @@ -175,7 +175,6 @@ func reportStatistics(sys System, program *compiler.Program, result compileAndEm func printVersion(sys System) { fmt.Fprintln(sys.Writer(), diagnostics.Version_0.Format(core.Version())) - sys.EndWrite() } func printHelp(sys System, commandLine *tsoptions.ParsedCommandLine) { @@ -268,7 +267,6 @@ func printEasyHelp(sys System, simpleOptions []*tsoptions.CommandLineOption) { for _, chunk := range output { fmt.Fprint(sys.Writer(), chunk) } - sys.EndWrite() } func generateSectionOptionsOutput( diff --git a/internal/execute/system.go b/internal/execute/system.go index ad6816db15..db7a40907b 100644 --- a/internal/execute/system.go +++ b/internal/execute/system.go @@ -9,7 +9,6 @@ import ( type System interface { Writer() io.Writer - EndWrite() // needed for testing FS() vfs.FS DefaultLibraryPath() string GetCurrentDirectory() string diff --git a/internal/execute/testsys_test.go b/internal/execute/testsys_test.go index 8bba8ff082..44875635a9 100644 --- a/internal/execute/testsys_test.go +++ b/internal/execute/testsys_test.go @@ -1,7 +1,6 @@ package execute_test import ( - "errors" "fmt" "io" "io/fs" @@ -9,6 +8,7 @@ import ( "slices" "strconv" "strings" + "sync" "time" "github.com/microsoft/typescript-go/internal/collections" @@ -19,7 +19,9 @@ import ( "github.com/microsoft/typescript-go/internal/testutil/incrementaltestutil" "github.com/microsoft/typescript-go/internal/testutil/stringtestutil" "github.com/microsoft/typescript-go/internal/tsoptions" + "github.com/microsoft/typescript-go/internal/tspath" "github.com/microsoft/typescript-go/internal/vfs" + "github.com/microsoft/typescript-go/internal/vfs/iovfs" "github.com/microsoft/typescript-go/internal/vfs/vfstest" ) @@ -52,23 +54,52 @@ interface Symbol { declare const console: { log(msg: any): void; }; `) -func newTestSys(fileOrFolderList FileMap, cwd string, env map[string]string) *testSys { +type TestClock struct { + start time.Time + now time.Time + nowMu sync.Mutex +} + +func (t *TestClock) Now() time.Time { + t.nowMu.Lock() + defer t.nowMu.Unlock() + if t.now.IsZero() { + t.now = t.start + } + t.now = t.now.Add(1 * time.Second) // Simulate some time passing + return t.now +} + +func (t *TestClock) SinceStart() time.Duration { + return t.Now().Sub(t.start) +} + +func newTestSys(tscInput *tscInput) *testSys { + cwd := tscInput.cwd if cwd == "" { cwd = "/home/src/workspaces/project" } + libPath := tscLibPath + if tscInput.windowsStyleRoot != "" { + libPath = tscInput.windowsStyleRoot + libPath[1:] + } + currentWrite := &strings.Builder{} + clock := &TestClock{start: time.Now()} sys := &testSys{ fs: &incrementaltestutil.FsHandlingBuildInfo{ FS: &testFs{ - FS: vfstest.FromMap(fileOrFolderList, true /*useCaseSensitiveFileNames*/), + FS: vfstest.FromMapWithClock(tscInput.files, !tscInput.ignoreCase, clock), }, }, - defaultLibraryPath: tscLibPath, + defaultLibraryPath: libPath, cwd: cwd, - files: slices.Collect(maps.Keys(fileOrFolderList)), - output: []string{}, - currentWrite: &strings.Builder{}, - start: time.Now(), - env: env, + currentWrite: currentWrite, + tracer: harnessutil.NewTracerForBaselining(tspath.ComparePathsOptions{ + UseCaseSensitiveFileNames: !tscInput.ignoreCase, + CurrentDirectory: cwd, + }, currentWrite), + clock: clock, + env: tscInput.env, } // Ensure the default library file is present @@ -83,8 +114,10 @@ func newTestSys(fileOrFolderList FileMap, cwd string, env map[string]string) *te } type diffEntry struct { - content string - isWritten bool + content string + mTime time.Time + isWritten bool + symlinkTarget string } type snapshot struct { @@ -93,29 +126,28 @@ type snapshot struct { } type testSys struct { - // todo: original has write to output as a string[] because the separations are needed for baselining - output []string currentWrite *strings.Builder + tracer *harnessutil.TracerForBaselining serializedDiff *snapshot fs *incrementaltestutil.FsHandlingBuildInfo defaultLibraryPath string cwd string - files []string env map[string]string - - start time.Time + clock *TestClock } -var _ execute.System = (*testSys)(nil) +var ( + _ execute.System = (*testSys)(nil) + _ execute.CommandLineTesting = (*testSys)(nil) +) func (s *testSys) Now() time.Time { - // todo: make a "test time" structure - return time.Now() + return s.clock.Now() } func (s *testSys) SinceStart() time.Duration { - return time.Since(s.start) + return s.clock.SinceStart() } func (s *testSys) FS() vfs.FS { @@ -126,12 +158,16 @@ func (s *testSys) testFs() *testFs { return s.fs.FS.(*testFs) } -func (s *testSys) fsFromFileMap() vfs.FS { - return s.testFs().FS +func (s *testSys) fsFromFileMap() iovfs.FsWithSys { + return s.testFs().FS.(iovfs.FsWithSys) +} + +func (s *testSys) mapFs() *vfstest.MapFS { + return s.fsFromFileMap().FSys().(*vfstest.MapFS) } func (s *testSys) ensureLibPathExists(path string) { - path = tscLibPath + "/" + path + path = s.defaultLibraryPath + "/" + path if _, ok := s.fsFromFileMap().ReadFile(path); !ok { if s.testFs().defaultLibs == nil { s.testFs().defaultLibs = &collections.SyncSet[string]{} @@ -171,24 +207,28 @@ func (s *testSys) GetEnvironmentVariable(name string) string { return s.env[name] } -func sanitizeSysOutput(output string, prefixLine string, replaceString string) string { - if index := strings.Index(output, prefixLine); index != -1 { - indexOfNewLine := strings.Index(output[index:], "\n") - if indexOfNewLine != -1 { - output = output[:index] + replaceString + output[index+indexOfNewLine+1:] - } - } - return output +func (s *testSys) OnListFilesStart() { + fmt.Fprintln(s.Writer(), listFileStart) } -func (s *testSys) EndWrite() { - // todo: revisit if improving tsc/build/watch unittest baselines - output := s.currentWrite.String() - s.currentWrite.Reset() - output = sanitizeSysOutput(output, "Version "+core.Version(), "Version "+harnessutil.FakeTSVersion+"\n") - output = sanitizeSysOutput(output, "build starting at ", "") - output = sanitizeSysOutput(output, "build finished in ", "") - s.output = append(s.output, output) +func (s *testSys) OnListFilesEnd() { + fmt.Fprintln(s.Writer(), listFileEnd) +} + +func (s *testSys) OnStatisticsStart() { + fmt.Fprintln(s.Writer(), statisticsStart) +} + +func (s *testSys) OnStatisticsEnd() { + fmt.Fprintln(s.Writer(), statisticsEnd) +} + +func (s *testSys) GetTrace() func(str string) { + return func(str string) { + fmt.Fprintln(s.currentWrite, traceStart) + defer fmt.Fprintln(s.currentWrite, traceEnd) + s.tracer.Trace(str) + } } func (s *testSys) baselineProgram(baseline *strings.Builder, program *incremental.Program, watcher *execute.Watcher) { @@ -199,8 +239,14 @@ func (s *testSys) baselineProgram(baseline *strings.Builder, program *incrementa return } - baseline.WriteString("SemanticDiagnostics::\n") testingData := program.GetTestingData(program.GetProgram()) + if testingData.ConfigFilePath != "" { + baseline.WriteString(tspath.GetRelativePathFromDirectory(s.cwd, testingData.ConfigFilePath, tspath.ComparePathsOptions{ + UseCaseSensitiveFileNames: s.FS().UseCaseSensitiveFileNames(), + CurrentDirectory: s.GetCurrentDirectory(), + }) + "::\n") + } + baseline.WriteString("SemanticDiagnostics::\n") for _, file := range program.GetProgram().GetSourceFiles() { if diagnostics, ok := testingData.SemanticDiagnosticsPerFile.Load(file.Path()); ok { if oldDiagnostics, ok := testingData.OldProgramSemanticDiagnosticsPerFile.Load(file.Path()); !ok || oldDiagnostics != diagnostics { @@ -238,18 +284,98 @@ func (s *testSys) serializeState(baseline *strings.Builder) { // this.service?.baseline(); } +var ( + fakeTimeStamp = "HH:MM:SS AM" + fakeDuration = "d.ddds" + + buildStartingAt = "build starting at " + buildFinishedIn = "build finished in " + listFileStart = "!!! List files start" + listFileEnd = "!!! List files end" + statisticsStart = "!!! Statistics start" + statisticsEnd = "!!! Statistics end" + traceStart = "!!! Trace start" + traceEnd = "!!! Trace end" +) + func (s *testSys) baselineOutput(baseline io.Writer) { fmt.Fprint(baseline, "\nOutput::\n") - if len(s.output) == 0 { - fmt.Fprint(baseline, "No output\n") - return + output := s.getOutput(false) + fmt.Fprint(baseline, output) +} + +type outputSanitizer struct { + forComparing bool + lines []string + index int + outputLines []string +} + +func (o *outputSanitizer) addOutputLine(s string) { + o.outputLines = append(o.outputLines, s) +} + +func (o *outputSanitizer) transformLines() string { + for ; o.index < len(o.lines); o.index++ { + line := o.lines[o.index] + if change := strings.Replace(line, "Version "+core.Version(), "Version "+harnessutil.FakeTSVersion, 1); change != line { + o.addOutputLine(change) + continue + } + if strings.HasPrefix(line, buildStartingAt) { + if !o.forComparing { + o.addOutputLine(buildStartingAt + fakeTimeStamp) + } + continue + } + if strings.HasPrefix(line, buildFinishedIn) { + if !o.forComparing { + o.addOutputLine(buildFinishedIn + fakeDuration) + } + continue + } + if !o.addOrSkipLinesForComparing(listFileStart, listFileEnd, false) && + !o.addOrSkipLinesForComparing(statisticsStart, statisticsEnd, true) && + !o.addOrSkipLinesForComparing(traceStart, traceEnd, false) { + o.addOutputLine(line) + } + } + return strings.Join(o.outputLines, "\n") +} + +func (o *outputSanitizer) addOrSkipLinesForComparing( + lineStart string, + lineEnd string, + skipEvenIfNotComparing bool, +) bool { + if o.lines[o.index] != lineStart { + return false + } + o.index++ + for ; o.index < len(o.lines); o.index++ { + if o.lines[o.index] == lineEnd { + return true + } + if !o.forComparing && !skipEvenIfNotComparing { + o.addOutputLine(o.lines[o.index]) + } + } + panic("Expected lineEnd" + lineEnd + " not found after " + lineStart) +} + +func (s *testSys) getOutput(forComparing bool) string { + lines := strings.Split(s.currentWrite.String(), "\n") + transformer := &outputSanitizer{ + forComparing: forComparing, + lines: lines, + outputLines: make([]string, 0, len(lines)), } - // todo screen clears - s.printOutputs(baseline) + return transformer.transformLines() } func (s *testSys) clearOutput() { - s.output = []string{} + s.currentWrite.Reset() + s.tracer.Reset() } func (s *testSys) baselineFSwithDiff(baseline io.Writer) { @@ -258,27 +384,22 @@ func (s *testSys) baselineFSwithDiff(baseline io.Writer) { testFs := s.testFs() diffs := map[string]string{} - err := s.fsFromFileMap().WalkDir("/", func(path string, d vfs.DirEntry, e error) error { - if e != nil { - return e - } - if !d.Type().IsRegular() { - return nil - } - - newContents, ok := s.fsFromFileMap().ReadFile(path) - if !ok { - return nil + for path, file := range s.mapFs().Entries() { + if file.Mode&fs.ModeSymlink != 0 { + target, ok := s.mapFs().GetTargetOfSymlink(path) + if !ok { + panic("Failed to resolve symlink target: " + path) + } + newEntry := &diffEntry{symlinkTarget: target} + snap[path] = newEntry + s.addFsEntryDiff(diffs, newEntry, path) + continue + } else if file.Mode.IsRegular() { + newEntry := &diffEntry{content: string(file.Data), mTime: file.ModTime, isWritten: testFs.writtenFiles.Has(path)} + snap[path] = newEntry + s.addFsEntryDiff(diffs, newEntry, path) } - newEntry := &diffEntry{content: newContents, isWritten: testFs.writtenFiles.Has(path)} - snap[path] = newEntry - s.addFsEntryDiff(diffs, newEntry, path) - - return nil - }) - if err != nil && !errors.Is(err, fs.ErrNotExist) { - panic("walkdir error during diff: " + err.Error()) } if s.serializedDiff != nil { for path := range s.serializedDiff.snap { @@ -319,7 +440,11 @@ func (s *testSys) addFsEntryDiff(diffs map[string]string, newDirContent *diffEnt // todo handle more cases of fs changes if oldDirContent == nil { if s.testFs().defaultLibs == nil || !s.testFs().defaultLibs.Has(path) { - diffs[path] = "*new* \n" + newDirContent.content + if newDirContent.symlinkTarget != "" { + diffs[path] = "-> " + newDirContent.symlinkTarget + " *new*" + } else { + diffs[path] = "*new* \n" + newDirContent.content + } } } else if newDirContent == nil { diffs[path] = "*deleted*" @@ -327,17 +452,14 @@ func (s *testSys) addFsEntryDiff(diffs map[string]string, newDirContent *diffEnt diffs[path] = "*modified* \n" + newDirContent.content } else if newDirContent.isWritten { diffs[path] = "*rewrite with same content*" + } else if newDirContent.mTime != oldDirContent.mTime { + diffs[path] = "*mTime changed*" } else if defaultLibs != nil && defaultLibs.Has(path) && s.testFs().defaultLibs != nil && !s.testFs().defaultLibs.Has(path) { // Lib file that was read diffs[path] = "*Lib*\n" + newDirContent.content } } -func (s *testSys) printOutputs(baseline io.Writer) { - // todo sanitize sys output - fmt.Fprint(baseline, strings.Join(s.output, "\n")) -} - func (s *testSys) writeFileNoError(path string, content string, writeByteOrderMark bool) { if err := s.fsFromFileMap().WriteFile(path, content, writeByteOrderMark); err != nil { panic(err) diff --git a/internal/execute/tsc.go b/internal/execute/tsc.go index cb633671f2..066685a34e 100644 --- a/internal/execute/tsc.go +++ b/internal/execute/tsc.go @@ -21,8 +21,6 @@ import ( "github.com/microsoft/typescript-go/internal/tspath" ) -type cbType = func(p any) any - func applyBulkEdits(text string, edits []core.TextChange) string { b := strings.Builder{} b.Grow(len(text)) @@ -47,13 +45,20 @@ type CommandLineResult struct { Watcher *Watcher } -func CommandLine(sys System, commandLineArgs []string, testing bool) CommandLineResult { +type CommandLineTesting interface { + OnListFilesStart() + OnListFilesEnd() + OnStatisticsStart() + OnStatisticsEnd() + GetTrace() func(str string) +} + +func CommandLine(sys System, commandLineArgs []string, testing CommandLineTesting) CommandLineResult { if len(commandLineArgs) > 0 { // !!! build mode switch strings.ToLower(commandLineArgs[0]) { case "-b", "--b", "-build", "--build": fmt.Fprintln(sys.Writer(), "Build mode is currently unsupported.") - sys.EndWrite() return CommandLineResult{Status: ExitStatusNotImplemented} // case "-f": // return fmtMain(sys, commandLineArgs[1], commandLineArgs[1]) @@ -89,7 +94,7 @@ func fmtMain(sys System, input, output string) ExitStatus { return ExitStatusSuccess } -func tscCompilation(sys System, commandLine *tsoptions.ParsedCommandLine, testing bool) CommandLineResult { +func tscCompilation(sys System, commandLine *tsoptions.ParsedCommandLine, testing CommandLineTesting) CommandLineResult { configFileName := "" reportDiagnostic := createDiagnosticReporter(sys, commandLine.CompilerOptions()) // if commandLine.Options().Locale != nil @@ -206,6 +211,7 @@ func tscCompilation(sys System, commandLine *tsoptions.ParsedCommandLine, testin reportDiagnostic, &extendedConfigCache, configTime, + testing, ) } @@ -223,9 +229,13 @@ func findConfigFile(searchPath string, fileExists func(string) bool, configName return result } -func getTraceFromSys(sys System) func(msg string) { - return func(msg string) { - fmt.Fprintln(sys.Writer(), msg) +func getTraceFromSys(sys System, testing CommandLineTesting) func(msg string) { + if testing == nil { + return func(msg string) { + fmt.Fprintln(sys.Writer(), msg) + } + } else { + return testing.GetTrace() } } @@ -235,9 +245,9 @@ func performIncrementalCompilation( reportDiagnostic diagnosticReporter, extendedConfigCache *collections.SyncMap[tspath.Path, *tsoptions.ExtendedConfigCacheEntry], configTime time.Duration, - testing bool, + testing CommandLineTesting, ) CommandLineResult { - host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache, getTraceFromSys(sys)) + host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache, getTraceFromSys(sys, testing)) buildInfoReadStart := sys.Now() oldProgram := incremental.ReadBuildInfoProgram(config, incremental.NewBuildInfoReader(host), host) buildInfoReadTime := sys.Now().Sub(buildInfoReadStart) @@ -250,7 +260,7 @@ func performIncrementalCompilation( }) parseTime := sys.Now().Sub(parseStart) changesComputeStart := sys.Now() - incrementalProgram := incremental.NewProgram(program, oldProgram, testing) + incrementalProgram := incremental.NewProgram(program, oldProgram, testing != nil) changesComputeTime := sys.Now().Sub(changesComputeStart) return CommandLineResult{ Status: emitAndReportStatistics( @@ -264,6 +274,7 @@ func performIncrementalCompilation( buildInfoReadTime, changesComputeTime, + testing, ), IncrementalProgram: incrementalProgram, } @@ -275,8 +286,9 @@ func performCompilation( reportDiagnostic diagnosticReporter, extendedConfigCache *collections.SyncMap[tspath.Path, *tsoptions.ExtendedConfigCacheEntry], configTime time.Duration, + testing CommandLineTesting, ) CommandLineResult { - host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache, getTraceFromSys(sys)) + host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache, getTraceFromSys(sys, testing)) // todo: cache, statistics, tracing parseStart := sys.Now() program := compiler.NewProgram(compiler.ProgramOptions{ @@ -296,6 +308,7 @@ func performCompilation( parseTime, 0, 0, + testing, ), } } @@ -310,8 +323,9 @@ func emitAndReportStatistics( parseTime time.Duration, buildInfoReadTime time.Duration, changesComputeTime time.Duration, + testing CommandLineTesting, ) ExitStatus { - result := emitFilesAndReportErrors(sys, programLike, program, reportDiagnostic) + result := emitFilesAndReportErrors(sys, programLike, program, reportDiagnostic, testing) if result.status != ExitStatusSuccess { // compile exited early return result.status @@ -330,7 +344,7 @@ func emitAndReportStatistics( runtime.GC() runtime.ReadMemStats(&memStats) - reportStatistics(sys, program, result, &memStats) + reportStatistics(sys, program, result, &memStats, testing) } if result.emitResult.EmitSkipped && len(result.diagnostics) > 0 { @@ -360,6 +374,7 @@ func emitFilesAndReportErrors( programLike compiler.ProgramLike, program *compiler.Program, reportDiagnostic diagnosticReporter, + testing CommandLineTesting, ) (result compileAndEmitResult) { ctx := context.Background() @@ -400,12 +415,7 @@ func emitFilesAndReportErrors( reportDiagnostic(diagnostic) } - if sys.Writer() != nil { - for _, file := range emitResult.EmittedFiles { - fmt.Fprintln(sys.Writer(), "TSFILE: ", tspath.GetNormalizedAbsolutePath(file, sys.GetCurrentDirectory())) - } - listFiles(sys, program) - } + listFiles(sys, program, emitResult, testing) createReportErrorSummary(sys, programLike.Options())(allDiagnostics) result.diagnostics = allDiagnostics @@ -423,7 +433,14 @@ func showConfig(sys System, config *core.CompilerOptions) { _ = jsonutil.MarshalIndentWrite(sys.Writer(), config, "", " ") } -func listFiles(sys System, program *compiler.Program) { +func listFiles(sys System, program *compiler.Program, emitResult *compiler.EmitResult, testing CommandLineTesting) { + if testing != nil { + testing.OnListFilesStart() + defer testing.OnListFilesEnd() + } + for _, file := range emitResult.EmittedFiles { + fmt.Fprintln(sys.Writer(), "TSFILE: ", tspath.GetNormalizedAbsolutePath(file, sys.GetCurrentDirectory())) + } options := program.Options() if options.ExplainFiles.IsTrue() { program.ExplainFiles(sys.Writer()) diff --git a/internal/execute/tscincremental_test.go b/internal/execute/tscincremental_test.go index 1b277e0bb7..76fe263bbc 100644 --- a/internal/execute/tscincremental_test.go +++ b/internal/execute/tscincremental_test.go @@ -82,7 +82,7 @@ func TestIncremental(t *testing.T) { type InstanceType any> = T extends abstract new (...args: any) => infer R ? R : any;`), }, commandLineArgs: []string{"--incremental"}, - edits: []*testTscEdit{ + edits: []*tscEdit{ noChange, { caption: "modify public to protected", @@ -128,7 +128,7 @@ func TestIncremental(t *testing.T) { type InstanceType any> = T extends abstract new (...args: any) => infer R ? R : any;`), }, commandLineArgs: []string{"--incremental"}, - edits: []*testTscEdit{ + edits: []*tscEdit{ noChange, { caption: "modify public to protected", @@ -187,7 +187,7 @@ func TestIncremental(t *testing.T) { "/home/src/workspaces/project/tsconfig.json": "{}", }, commandLineArgs: []string{"--incremental"}, - edits: []*testTscEdit{ + edits: []*tscEdit{ noChange, { caption: "modify d.ts file", @@ -220,7 +220,7 @@ func TestIncremental(t *testing.T) { "/home/src/workspaces/project/tsconfig.tsbuildinfo": "Some random string", }, commandLineArgs: []string{"-i"}, - edits: []*testTscEdit{ + edits: []*tscEdit{ { caption: "tsbuildinfo written has error", edit: func(sys *testSys) { @@ -250,7 +250,7 @@ func TestIncremental(t *testing.T) { }`), }, commandLineArgs: []string{}, - edits: []*testTscEdit{ + edits: []*tscEdit{ noChange, { caption: "Modify main file", @@ -362,7 +362,7 @@ func TestIncremental(t *testing.T) { "/home/src/workspaces/project/constants.ts": "export default 1;", "/home/src/workspaces/project/types.d.ts": `type MagicNumber = typeof import('./constants').default`, }, - edits: []*testTscEdit{ + edits: []*tscEdit{ { caption: "Modify imports used in global file", edit: func(sys *testSys) { @@ -388,7 +388,7 @@ func TestIncremental(t *testing.T) { "/home/src/workspaces/project/reexport.ts": `export { default as ConstantNumber } from "./constants"`, "/home/src/workspaces/project/types.d.ts": `type MagicNumber = typeof import('./reexport').ConstantNumber`, }, - edits: []*testTscEdit{ + edits: []*tscEdit{ { caption: "Modify imports used in global file", edit: func(sys *testSys) { @@ -411,7 +411,7 @@ func TestIncremental(t *testing.T) { "/home/src/workspaces/project/file1.ts": `export class C { }`, "/home/src/workspaces/project/file2.ts": `export class D { }`, }, - edits: []*testTscEdit{ + edits: []*tscEdit{ { caption: "delete file with imports", edit: func(sys *testSys) { @@ -466,7 +466,7 @@ func TestIncremental(t *testing.T) { } `), }, - edits: []*testTscEdit{ + edits: []*tscEdit{ { caption: "modify js file", edit: func(sys *testSys) { @@ -501,7 +501,7 @@ func TestIncremental(t *testing.T) { "/home/src/workspaces/project/c.ts": `import { a } from "./a";export const c = a;`, "/home/src/workspaces/project/d.ts": `import { b } from "./b";export const d = b;`, }, - edits: []*testTscEdit{ + edits: []*tscEdit{ { caption: "with sourceMap", commandLineArgs: []string{"--sourceMap"}, @@ -582,7 +582,7 @@ func TestIncremental(t *testing.T) { "/home/src/workspaces/project/c.ts": `import { a } from "./a";export const c = a;`, "/home/src/workspaces/project/d.ts": `import { b } from "./b";export const d = b;`, }, - edits: []*testTscEdit{ + edits: []*tscEdit{ { caption: "with sourceMap", commandLineArgs: []string{"--sourceMap"}, @@ -671,7 +671,7 @@ func getConstEnumTest(bdsContents string, changeEnumFile string, testSuffix stri `), }, commandLineArgs: []string{"-i", `a.ts`, "--tsbuildinfofile", "a.tsbuildinfo"}, - edits: []*testTscEdit{ + edits: []*tscEdit{ { caption: "change enum value", edit: func(sys *testSys) { diff --git a/internal/execute/tsctestrunner_test.go b/internal/execute/tsctestrunner_test.go index 1e04a68231..d6546c7e06 100644 --- a/internal/execute/tsctestrunner_test.go +++ b/internal/execute/tsctestrunner_test.go @@ -13,33 +13,35 @@ import ( "github.com/microsoft/typescript-go/internal/tspath" ) -type testTscEdit struct { +type tscEdit struct { caption string commandLineArgs []string edit func(*testSys) expectedDiff string } -var noChange = &testTscEdit{ +var noChange = &tscEdit{ caption: "no change", } -var noChangeOnlyEdit = []*testTscEdit{ +var noChangeOnlyEdit = []*tscEdit{ noChange, } type tscInput struct { - subScenario string - commandLineArgs []string - files FileMap - cwd string - edits []*testTscEdit - env map[string]string + subScenario string + commandLineArgs []string + files FileMap + cwd string + edits []*tscEdit + env map[string]string + ignoreCase bool + windowsStyleRoot string } func (test *tscInput) executeCommand(sys *testSys, baselineBuilder *strings.Builder, commandLineArgs []string) execute.CommandLineResult { fmt.Fprint(baselineBuilder, "tsgo ", strings.Join(commandLineArgs, " "), "\n") - result := execute.CommandLine(sys, commandLineArgs, true) + result := execute.CommandLine(sys, commandLineArgs, sys) switch result.Status { case execute.ExitStatusSuccess: baselineBuilder.WriteString("ExitStatus:: Success") @@ -61,11 +63,11 @@ func (test *tscInput) executeCommand(sys *testSys, baselineBuilder *strings.Buil func (test *tscInput) run(t *testing.T, scenario string) { t.Helper() - t.Run(test.subScenario+" tsc baseline", func(t *testing.T) { + t.Run(test.subScenario, func(t *testing.T) { t.Parallel() // initial test tsc compile baselineBuilder := &strings.Builder{} - sys := newTestSys(test.files, test.cwd, test.env) + sys := newTestSys(test) fmt.Fprint( baselineBuilder, "currentDirectory::", @@ -78,6 +80,7 @@ func (test *tscInput) run(t *testing.T, scenario string) { result := test.executeCommand(sys, baselineBuilder, test.commandLineArgs) sys.serializeState(baselineBuilder) sys.baselineProgram(baselineBuilder, result.IncrementalProgram, result.Watcher) + var unexpectedDiff string for index, do := range test.edits { sys.clearOutput() @@ -102,13 +105,13 @@ func (test *tscInput) run(t *testing.T, scenario string) { }) wg.Queue(func() { // Compute build with all the edits - nonIncrementalSys = newTestSys(test.files, test.cwd, test.env) + nonIncrementalSys = newTestSys(test) for i := range index + 1 { if test.edits[i].edit != nil { test.edits[i].edit(nonIncrementalSys) } } - execute.CommandLine(nonIncrementalSys, commandLineArgs, true) + execute.CommandLine(nonIncrementalSys, commandLineArgs, nonIncrementalSys) }) wg.RunAndWait() @@ -116,11 +119,18 @@ func (test *tscInput) run(t *testing.T, scenario string) { if diff != "" { baselineBuilder.WriteString(fmt.Sprintf("\n\nDiff:: %s\n", core.IfElse(do.expectedDiff == "", "!!! Unexpected diff, please review and either fix or write explanation as expectedDiff !!!", do.expectedDiff))) baselineBuilder.WriteString(diff) + if do.expectedDiff == "" { + unexpectedDiff += fmt.Sprintf("Edit [%d]:: %s\n!!! Unexpected diff, please review and either fix or write explanation as expectedDiff !!!\n%s\n", index, do.caption, diff) + } } else if do.expectedDiff != "" { baselineBuilder.WriteString(fmt.Sprintf("\n\nDiff:: %s !!! Diff not found but explanation present, please review and remove the explanation !!!\n", do.expectedDiff)) + unexpectedDiff += fmt.Sprintf("Edit [%d]:: %s\n!!! Diff not found but explanation present, please review and remove the explanation !!!\n", index, do.caption) } } baseline.Run(t, strings.ReplaceAll(test.subScenario, " ", "-")+".js", baselineBuilder.String(), baseline.Options{Subfolder: filepath.Join(test.getBaselineSubFolder(), scenario)}) + if unexpectedDiff != "" { + t.Errorf("Test %s has unexpected diff %s with incremental build, please review the baseline file", test.subScenario, unexpectedDiff) + } }) } @@ -150,10 +160,10 @@ func getDiffForIncremental(incrementalSys *testSys, nonIncrementalSys *testSys) } } - incrementalErrors := strings.Join(incrementalSys.output, "") - nonIncrementalErrors := strings.Join(nonIncrementalSys.output, "") - if incrementalErrors != nonIncrementalErrors { - diffBuilder.WriteString(baseline.DiffText("nonIncremental errors.txt", "incremental errors.txt", nonIncrementalErrors, incrementalErrors)) + incrementalOutput := incrementalSys.getOutput(true) + nonIncrementalOutput := nonIncrementalSys.getOutput(true) + if incrementalOutput != nonIncrementalOutput { + diffBuilder.WriteString(baseline.DiffText("nonIncremental.output.txt", "incremental.output.txt", nonIncrementalOutput, incrementalOutput)) } return diffBuilder.String() } @@ -161,13 +171,21 @@ func getDiffForIncremental(incrementalSys *testSys, nonIncrementalSys *testSys) func (test *tscInput) getBaselineSubFolder() string { commandName := "tsc" if slices.ContainsFunc(test.commandLineArgs, func(arg string) bool { - return arg == "--build" || arg == "-b" + switch arg { + case "-b", "--b", "-build", "--build": + return true + } + return false }) { commandName = "tsbuild" } w := "" if slices.ContainsFunc(test.commandLineArgs, func(arg string) bool { - return arg == "--watch" || arg == "-w" + switch arg { + case "-w", "--w", "-watch", "--watch": + return true + } + return false }) { w = "Watch" } diff --git a/internal/execute/tscwatch_test.go b/internal/execute/tscwatch_test.go index c7ce9719c4..eabb675791 100644 --- a/internal/execute/tscwatch_test.go +++ b/internal/execute/tscwatch_test.go @@ -69,7 +69,7 @@ func noEmitWatchTestInput( "/home/src/workspaces/project/a.ts": aText, "/home/src/workspaces/project/tsconfig.json": tsconfigText, }, - edits: []*testTscEdit{ + edits: []*tscEdit{ newTscEdit("fix error", func(sys *testSys) { sys.writeFileNoError("/home/src/workspaces/project/a.ts", `const a = "hello";`, false) }), @@ -92,8 +92,8 @@ func noEmitWatchTestInput( } } -func newTscEdit(name string, edit func(sys *testSys)) *testTscEdit { - return &testTscEdit{name, []string{}, edit, ""} +func newTscEdit(name string, edit func(sys *testSys)) *tscEdit { + return &tscEdit{name, []string{}, edit, ""} } func TestTscNoEmitWatch(t *testing.T) { diff --git a/internal/execute/watcher.go b/internal/execute/watcher.go index fddd321389..738c24ae17 100644 --- a/internal/execute/watcher.go +++ b/internal/execute/watcher.go @@ -19,7 +19,7 @@ type Watcher struct { configFileName string options *tsoptions.ParsedCommandLine reportDiagnostic diagnosticReporter - testing bool + testing CommandLineTesting host compiler.CompilerHost program *incremental.Program @@ -27,7 +27,7 @@ type Watcher struct { configModified bool } -func createWatcher(sys System, configParseResult *tsoptions.ParsedCommandLine, reportDiagnostic diagnosticReporter, testing bool) *Watcher { +func createWatcher(sys System, configParseResult *tsoptions.ParsedCommandLine, reportDiagnostic diagnosticReporter, testing CommandLineTesting) *Watcher { w := &Watcher{ sys: sys, options: configParseResult, @@ -42,10 +42,10 @@ func createWatcher(sys System, configParseResult *tsoptions.ParsedCommandLine, r } func (w *Watcher) start() { - w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), nil, getTraceFromSys(w.sys)) + w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), nil, getTraceFromSys(w.sys, w.testing)) w.program = incremental.ReadBuildInfoProgram(w.options, incremental.NewBuildInfoReader(w.host), w.host) - if !w.testing { + if w.testing == nil { watchInterval := 1000 * time.Millisecond if w.options.ParsedConfig.WatchOptions != nil { watchInterval = time.Duration(*w.options.ParsedConfig.WatchOptions.Interval) * time.Millisecond @@ -72,7 +72,7 @@ func (w *Watcher) DoCycle() { Config: w.options, Host: w.host, JSDocParsingMode: ast.JSDocParsingModeParseForTypeErrors, - }), w.program, w.testing) + }), w.program, w.testing != nil) if w.hasBeenModified(w.program.GetProgram()) { fmt.Fprintln(w.sys.Writer(), "build starting at ", w.sys.Now()) @@ -88,13 +88,13 @@ func (w *Watcher) DoCycle() { func (w *Watcher) compileAndEmit() { // !!! output/error reporting is currently the same as non-watch mode // diagnostics, emitResult, exitStatus := - emitFilesAndReportErrors(w.sys, w.program, w.program.GetProgram(), w.reportDiagnostic) + emitFilesAndReportErrors(w.sys, w.program, w.program.GetProgram(), w.reportDiagnostic, w.testing) } func (w *Watcher) hasErrorsInTsConfig() bool { // only need to check and reparse tsconfig options/update host if we are watching a config file + extendedConfigCache := collections.SyncMap[tspath.Path, *tsoptions.ExtendedConfigCacheEntry]{} if w.configFileName != "" { - extendedConfigCache := collections.SyncMap[tspath.Path, *tsoptions.ExtendedConfigCacheEntry]{} // !!! need to check that this merges compileroptions correctly. This differs from non-watch, since we allow overriding of previous options configParseResult, errors := tsoptions.GetParsedCommandLineOfConfigFile(w.configFileName, &core.CompilerOptions{}, w.sys, &extendedConfigCache) if len(errors) > 0 { @@ -109,8 +109,8 @@ func (w *Watcher) hasErrorsInTsConfig() bool { w.configModified = true } w.options = configParseResult - w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), &extendedConfigCache, getTraceFromSys(w.sys)) } + w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), &extendedConfigCache, getTraceFromSys(w.sys, w.testing)) return false } diff --git a/internal/incremental/program.go b/internal/incremental/program.go index 8750c214e6..362cea8a3c 100644 --- a/internal/incremental/program.go +++ b/internal/incremental/program.go @@ -53,6 +53,7 @@ type TestingData struct { SemanticDiagnosticsPerFile *collections.SyncMap[tspath.Path, *diagnosticsOrBuildInfoDiagnosticsWithFileName] OldProgramSemanticDiagnosticsPerFile *collections.SyncMap[tspath.Path, *diagnosticsOrBuildInfoDiagnosticsWithFileName] UpdatedSignatureKinds map[tspath.Path]SignatureUpdateKind + ConfigFilePath string } func (p *Program) GetTestingData(program *compiler.Program) TestingData { @@ -60,6 +61,7 @@ func (p *Program) GetTestingData(program *compiler.Program) TestingData { SemanticDiagnosticsPerFile: &p.snapshot.semanticDiagnosticsPerFile, OldProgramSemanticDiagnosticsPerFile: p.semanticDiagnosticsPerFile, UpdatedSignatureKinds: p.updatedSignatureKinds, + ConfigFilePath: p.snapshot.options.ConfigFilePath, } } diff --git a/internal/testutil/harnessutil/harnessutil.go b/internal/testutil/harnessutil/harnessutil.go index 804a18e137..b885996dea 100644 --- a/internal/testutil/harnessutil/harnessutil.go +++ b/internal/testutil/harnessutil/harnessutil.go @@ -223,7 +223,7 @@ func CompileFilesEx( Errors: errors, }, harnessOptions) result.Symlinks = symlinks - result.Trace = host.tracer.string() + result.Trace = host.tracer.String() result.Repeat = func(testConfig TestConfiguration) *CompilationResult { newHarnessOptions := *harnessOptions newCompilerOptions := compilerOptions.Clone() @@ -474,7 +474,7 @@ func getOptionValue(t *testing.T, option *tsoptions.CommandLineOption, value str type cachedCompilerHost struct { compiler.CompilerHost - tracer *tracer + tracer *TracerForBaselining } var sourceFileCache collections.SyncMap[SourceFileCacheKey, *ast.SourceFile] @@ -515,18 +515,25 @@ func (h *cachedCompilerHost) GetSourceFile(opts ast.SourceFileParseOptions) *ast return result } -type tracer struct { - fs vfs.FS - currentDirectory string +type TracerForBaselining struct { + opts tspath.ComparePathsOptions packageJsonCache map[tspath.Path]bool - builder strings.Builder + builder *strings.Builder } -func (t *tracer) trace(msg string) { - fmt.Fprintln(&t.builder, t.sanitizeTrace(msg)) +func NewTracerForBaselining(opts tspath.ComparePathsOptions, builder *strings.Builder) *TracerForBaselining { + return &TracerForBaselining{ + opts: opts, + packageJsonCache: make(map[tspath.Path]bool), + builder: builder, + } +} + +func (t *TracerForBaselining) Trace(msg string) { + fmt.Fprintln(t.builder, t.sanitizeTrace(msg)) } -func (t *tracer) sanitizeTrace(msg string) string { +func (t *TracerForBaselining) sanitizeTrace(msg string) string { // Version if str := strings.Replace(msg, "'"+core.Version()+"'", "'"+FakeTSVersion+"'", 1); str != msg { return str @@ -534,7 +541,7 @@ func (t *tracer) sanitizeTrace(msg string) string { // caching of fs in trace to be replaces with non caching version if str := strings.TrimSuffix(msg, "' does not exist according to earlier cached lookups."); str != msg { file := strings.TrimPrefix(str, "File '") - filePath := tspath.ToPath(file, t.currentDirectory, t.fs.UseCaseSensitiveFileNames()) + filePath := tspath.ToPath(file, t.opts.CurrentDirectory, t.opts.UseCaseSensitiveFileNames) if _, has := t.packageJsonCache[filePath]; has { return msg } else { @@ -544,7 +551,7 @@ func (t *tracer) sanitizeTrace(msg string) string { } if str := strings.TrimSuffix(msg, "' does not exist."); str != msg { file := strings.TrimPrefix(str, "File '") - filePath := tspath.ToPath(file, t.currentDirectory, t.fs.UseCaseSensitiveFileNames()) + filePath := tspath.ToPath(file, t.opts.CurrentDirectory, t.opts.UseCaseSensitiveFileNames) if _, has := t.packageJsonCache[filePath]; !has { t.packageJsonCache[filePath] = false return msg @@ -554,7 +561,7 @@ func (t *tracer) sanitizeTrace(msg string) string { } if str := strings.TrimSuffix(msg, "' exists according to earlier cached lookups."); str != msg { file := strings.TrimPrefix(str, "File '") - filePath := tspath.ToPath(file, t.currentDirectory, t.fs.UseCaseSensitiveFileNames()) + filePath := tspath.ToPath(file, t.opts.CurrentDirectory, t.opts.UseCaseSensitiveFileNames) if _, has := t.packageJsonCache[filePath]; has { return msg } else { @@ -564,7 +571,7 @@ func (t *tracer) sanitizeTrace(msg string) string { } if str := strings.TrimPrefix(msg, "Found 'package.json' at '"); str != msg { file := strings.TrimSuffix(str, "'.") - filePath := tspath.ToPath(file, t.currentDirectory, t.fs.UseCaseSensitiveFileNames()) + filePath := tspath.ToPath(file, t.opts.CurrentDirectory, t.opts.UseCaseSensitiveFileNames) if _, has := t.packageJsonCache[filePath]; !has { t.packageJsonCache[filePath] = true return msg @@ -575,15 +582,22 @@ func (t *tracer) sanitizeTrace(msg string) string { return msg } -func (t *tracer) string() string { +func (t *TracerForBaselining) String() string { return t.builder.String() } +func (t *TracerForBaselining) Reset() { + t.packageJsonCache = make(map[tspath.Path]bool) +} + func createCompilerHost(fs vfs.FS, defaultLibraryPath string, currentDirectory string) *cachedCompilerHost { - tracer := tracer{fs: fs, currentDirectory: currentDirectory, packageJsonCache: make(map[tspath.Path]bool)} + tracer := NewTracerForBaselining(tspath.ComparePathsOptions{ + UseCaseSensitiveFileNames: fs.UseCaseSensitiveFileNames(), + CurrentDirectory: currentDirectory, + }, &strings.Builder{}) return &cachedCompilerHost{ - CompilerHost: compiler.NewCompilerHost(currentDirectory, fs, defaultLibraryPath, nil, tracer.trace), - tracer: &tracer, + CompilerHost: compiler.NewCompilerHost(currentDirectory, fs, defaultLibraryPath, nil, tracer.Trace), + tracer: tracer, } } diff --git a/internal/vfs/iovfs/iofs.go b/internal/vfs/iovfs/iofs.go index 8b4fd5777d..a5289d4f0b 100644 --- a/internal/vfs/iovfs/iofs.go +++ b/internal/vfs/iovfs/iofs.go @@ -24,6 +24,11 @@ type WritableFS interface { Remove(path string) error } +type FsWithSys interface { + vfs.FS + FSys() fs.FS +} + // From creates a new FS from an [fs.FS]. // // For paths like `c:/foo/bar`, fsys will be used as though it's rooted at `/` and the path is `/c:/foo/bar`. @@ -33,7 +38,7 @@ type WritableFS interface { // // From does not actually handle case-insensitivity; ensure the passed in [fs.FS] // respects case-insensitive file names if needed. Consider using [vfstest.FromMap] for testing. -func From(fsys fs.FS, useCaseSensitiveFileNames bool) vfs.FS { +func From(fsys fs.FS, useCaseSensitiveFileNames bool) FsWithSys { var realpath func(path string) (string, error) if fsys, ok := fsys.(RealpathFS); ok { realpath = func(path string) (string, error) { @@ -107,6 +112,7 @@ func From(fsys fs.FS, useCaseSensitiveFileNames bool) vfs.FS { writeFile: writeFile, mkdirAll: mkdirAll, remove: remove, + fsys: fsys, } } @@ -118,9 +124,10 @@ type ioFS struct { writeFile func(path string, content string, writeByteOrderMark bool) error mkdirAll func(path string) error remove func(path string) error + fsys fs.FS } -var _ vfs.FS = (*ioFS)(nil) +var _ FsWithSys = (*ioFS)(nil) func (vfs *ioFS) UseCaseSensitiveFileNames() bool { return vfs.useCaseSensitiveFileNames @@ -177,3 +184,7 @@ func (vfs *ioFS) WriteFile(path string, content string, writeByteOrderMark bool) } return vfs.writeFile(path, content, writeByteOrderMark) } + +func (vfs *ioFS) FSys() fs.FS { + return vfs.fsys +} diff --git a/internal/vfs/vfstest/vfstest.go b/internal/vfs/vfstest/vfstest.go index 861a8c4212..e051b0c347 100644 --- a/internal/vfs/vfstest/vfstest.go +++ b/internal/vfs/vfstest/vfstest.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "io/fs" + "iter" "maps" "path" "slices" @@ -17,7 +18,7 @@ import ( "github.com/microsoft/typescript-go/internal/vfs/iovfs" ) -type mapFS struct { +type MapFS struct { // mu protects m. // A single mutex is sufficient as we only use fstest.Map's Open method. mu sync.RWMutex @@ -28,11 +29,30 @@ type mapFS struct { useCaseSensitiveFileNames bool symlinks map[canonicalPath]canonicalPath + + clock Clock +} + +type Clock interface { + Now() time.Time + SinceStart() time.Duration +} + +type clockImpl struct { + start time.Time +} + +func (c *clockImpl) Now() time.Time { + return time.Now() +} + +func (c *clockImpl) SinceStart() time.Duration { + return time.Since(c.start) } var ( - _ iovfs.RealpathFS = (*mapFS)(nil) - _ iovfs.WritableFS = (*mapFS)(nil) + _ iovfs.RealpathFS = (*MapFS)(nil) + _ iovfs.WritableFS = (*MapFS)(nil) ) type sys struct { @@ -47,6 +67,16 @@ type sys struct { // without trailing directory separators. // The paths must be all POSIX-style or all Windows-style, but not both. func FromMap[File any](m map[string]File, useCaseSensitiveFileNames bool) vfs.FS { + return FromMapWithClock(m, useCaseSensitiveFileNames, &clockImpl{start: time.Now()}) +} + +// FromMapWithClock creates a new [vfs.FS] from a map of paths to file contents. +// Those file contents may be strings, byte slices, or [fstest.MapFile]s. +// +// The paths must be normalized absolute paths according to the tspath package, +// without trailing directory separators. +// The paths must be all POSIX-style or all Windows-style, but not both. +func FromMapWithClock[File any](m map[string]File, useCaseSensitiveFileNames bool, clock Clock) vfs.FS { posix := false windows := false @@ -67,17 +97,23 @@ func FromMap[File any](m map[string]File, useCaseSensitiveFileNames bool) vfs.FS } mfs := make(fstest.MapFS, len(m)) - for p, f := range m { + // Sorted creation to ensure times are always guaranteed to be in order. + keys := slices.Collect(maps.Keys(m)) + slices.SortFunc(keys, comparePathsByParts) + for _, p := range keys { + f := m[p] checkPath(p) var file *fstest.MapFile switch f := any(f).(type) { case string: - file = &fstest.MapFile{Data: []byte(f)} + file = &fstest.MapFile{Data: []byte(f), ModTime: clock.Now()} case []byte: - file = &fstest.MapFile{Data: f} + file = &fstest.MapFile{Data: f, ModTime: clock.Now()} case *fstest.MapFile: - file = f + fCopy := *f + fCopy.ModTime = clock.Now() + file = &fCopy default: panic(fmt.Sprintf("invalid file type %T", f)) } @@ -100,13 +136,17 @@ func FromMap[File any](m map[string]File, useCaseSensitiveFileNames bool) vfs.FS panic("mixed posix and windows paths") } - return iovfs.From(convertMapFS(mfs, useCaseSensitiveFileNames), useCaseSensitiveFileNames) + return iovfs.From(convertMapFS(mfs, useCaseSensitiveFileNames, clock), useCaseSensitiveFileNames) } -func convertMapFS(input fstest.MapFS, useCaseSensitiveFileNames bool) *mapFS { - m := &mapFS{ +func convertMapFS(input fstest.MapFS, useCaseSensitiveFileNames bool, clock Clock) *MapFS { + if clock == nil { + clock = &clockImpl{start: time.Now()} + } + m := &MapFS{ m: make(fstest.MapFS, len(input)), useCaseSensitiveFileNames: useCaseSensitiveFileNames, + clock: clock, } // Verify that the input is well-formed. @@ -162,15 +202,15 @@ func comparePathsByParts(a, b string) int { type canonicalPath string -func (m *mapFS) getCanonicalPath(p string) canonicalPath { +func (m *MapFS) getCanonicalPath(p string) canonicalPath { return canonicalPath(tspath.GetCanonicalFileName(p, m.useCaseSensitiveFileNames)) } -func (m *mapFS) open(p canonicalPath) (fs.File, error) { +func (m *MapFS) open(p canonicalPath) (fs.File, error) { return m.m.Open(string(p)) } -func (m *mapFS) remove(path string) error { +func (m *MapFS) remove(path string) error { canonical := m.getCanonicalPath(path) canonicalString := string(canonical) fileInfo := m.m[canonicalString] @@ -200,7 +240,7 @@ func Symlink(target string) *fstest.MapFile { } } -func (m *mapFS) getFollowingSymlinks(p canonicalPath) (*fstest.MapFile, canonicalPath, error) { +func (m *MapFS) getFollowingSymlinks(p canonicalPath) (*fstest.MapFile, canonicalPath, error) { return m.getFollowingSymlinksWorker(p, "", "") } @@ -212,7 +252,7 @@ func (e *brokenSymlinkError) Error() string { return fmt.Sprintf("broken symlink %q -> %q", e.from, e.to) } -func (m *mapFS) getFollowingSymlinksWorker(p canonicalPath, symlinkFrom, symlinkTo canonicalPath) (*fstest.MapFile, canonicalPath, error) { +func (m *MapFS) getFollowingSymlinksWorker(p canonicalPath, symlinkFrom, symlinkTo canonicalPath) (*fstest.MapFile, canonicalPath, error) { if file, ok := m.m[string(p)]; ok && file.Mode&fs.ModeSymlink == 0 { return file, p, nil } @@ -235,11 +275,11 @@ func (m *mapFS) getFollowingSymlinksWorker(p canonicalPath, symlinkFrom, symlink return nil, p, err } -func (m *mapFS) set(p canonicalPath, file *fstest.MapFile) { +func (m *MapFS) set(p canonicalPath, file *fstest.MapFile) { m.m[string(p)] = file } -func (m *mapFS) setEntry(realpath string, canonical canonicalPath, file fstest.MapFile) { +func (m *MapFS) setEntry(realpath string, canonical canonicalPath, file fstest.MapFile) { if realpath == "" || canonical == "" { panic("empty path") } @@ -276,7 +316,7 @@ func baseName(p string) string { return file } -func (m *mapFS) mkdirAll(p string, perm fs.FileMode) error { +func (m *MapFS) mkdirAll(p string, perm fs.FileMode) error { if p == "" { panic("empty path") } @@ -320,7 +360,8 @@ func (m *mapFS) mkdirAll(p string, perm fs.FileMode) error { for _, dir := range toCreate { m.setEntry(dir, m.getCanonicalPath(dir), fstest.MapFile{ - Mode: fs.ModeDir | perm&^umask, + Mode: fs.ModeDir | perm&^umask, + ModTime: m.clock.Now(), }) } @@ -378,7 +419,7 @@ func (f *readDirFile) ReadDir(n int) ([]fs.DirEntry, error) { return entries, nil } -func (m *mapFS) Open(name string) (fs.File, error) { +func (m *MapFS) Open(name string) (fs.File, error) { m.mu.RLock() defer m.mu.RUnlock() @@ -420,7 +461,7 @@ func (m *mapFS) Open(name string) (fs.File, error) { }, nil } -func (m *mapFS) Realpath(name string) (string, error) { +func (m *MapFS) Realpath(name string) (string, error) { m.mu.RLock() defer m.mu.RUnlock() @@ -445,14 +486,14 @@ func convertInfo(info fs.FileInfo) (*fileInfo, bool) { const umask = 0o022 -func (m *mapFS) MkdirAll(path string, perm fs.FileMode) error { +func (m *MapFS) MkdirAll(path string, perm fs.FileMode) error { m.mu.Lock() defer m.mu.Unlock() return m.mkdirAll(path, perm) } -func (m *mapFS) WriteFile(path string, data []byte, perm fs.FileMode) error { +func (m *MapFS) WriteFile(path string, data []byte, perm fs.FileMode) error { m.mu.Lock() defer m.mu.Unlock() @@ -482,20 +523,54 @@ func (m *mapFS) WriteFile(path string, data []byte, perm fs.FileMode) error { m.setEntry(path, cp, fstest.MapFile{ Data: data, - ModTime: time.Now(), + ModTime: m.clock.Now(), Mode: perm &^ umask, }) return nil } -func (m *mapFS) Remove(path string) error { +func (m *MapFS) Remove(path string) error { m.mu.Lock() defer m.mu.Unlock() return m.remove(path) } +func (m *MapFS) GetTargetOfSymlink(path string) (string, bool) { + path, _ = strings.CutPrefix(path, "/") + m.mu.RLock() + defer m.mu.RUnlock() + canonical := m.getCanonicalPath(path) + canonicalString := string(canonical) + if fileInfo, ok := m.m[canonicalString]; ok { + if fileInfo.Mode&fs.ModeSymlink != 0 { + return "/" + string(fileInfo.Data), true + } + } + return "", false +} + +func (m *MapFS) Entries() iter.Seq2[string, *fstest.MapFile] { + return func(yield func(string, *fstest.MapFile) bool) { + m.mu.RLock() + defer m.mu.RUnlock() + inputKeys := slices.Collect(maps.Keys(m.m)) + slices.SortFunc(inputKeys, comparePathsByParts) + + for _, p := range inputKeys { + file := m.m[p] + path := file.Sys.(*sys).realpath + if !tspath.PathIsAbsolute(path) { + path = "/" + path + } + if !yield(path, file) { + break + } + } + } +} + func must[T any](v T, err error) T { if err != nil { panic(err) diff --git a/internal/vfs/vfstest/vfstest_test.go b/internal/vfs/vfstest/vfstest_test.go index a0c0da026a..0e2337fb84 100644 --- a/internal/vfs/vfstest/vfstest_test.go +++ b/internal/vfs/vfstest/vfstest_test.go @@ -34,7 +34,7 @@ func TestInsensitive(t *testing.T) { Data: contents, Sys: 1234, }, - }, false /*useCaseSensitiveFileNames*/) + }, false /*useCaseSensitiveFileNames*/, nil) sensitive, err := fs.ReadFile(vfs, "foo/bar/baz") assert.NilError(t, err) @@ -97,7 +97,7 @@ func TestInsensitiveUpper(t *testing.T) { Data: contents, Sys: 1234, }, - }, false /*useCaseSensitiveFileNames*/) + }, false /*useCaseSensitiveFileNames*/, nil) sensitive, err := fs.ReadFile(vfs, "foo/bar/baz") assert.NilError(t, err) @@ -142,7 +142,7 @@ func TestSensitive(t *testing.T) { Data: contents, Sys: 1234, }, - }, true /*useCaseSensitiveFileNames*/) + }, true /*useCaseSensitiveFileNames*/, nil) sensitive, err := fs.ReadFile(vfs, "foo/bar/baz") assert.NilError(t, err) @@ -170,7 +170,7 @@ func TestSensitiveDuplicatePath(t *testing.T) { } testutil.AssertPanics(t, func() { - convertMapFS(testfs, false /*useCaseSensitiveFileNames*/) + convertMapFS(testfs, false /*useCaseSensitiveFileNames*/, nil) }, `duplicate path: "Foo" and "foo" have the same canonical path`) } @@ -186,7 +186,7 @@ func TestInsensitiveDuplicatePath(t *testing.T) { }, } - convertMapFS(testfs, true /*useCaseSensitiveFileNames*/) + convertMapFS(testfs, true /*useCaseSensitiveFileNames*/, nil) } func dirEntriesToNames(entries []fs.DirEntry) []string { @@ -303,7 +303,7 @@ func TestParentDirFile(t *testing.T) { } testutil.AssertPanics(t, func() { - convertMapFS(testfs, false /*useCaseSensitiveFileNames*/) + convertMapFS(testfs, false /*useCaseSensitiveFileNames*/, nil) }, `failed to create intermediate directories for "foo/oops": mkdir "foo": path exists but is not a directory`) } diff --git a/testdata/baselines/reference/tsbuild/commandLine/when-build-not-first-argument.js b/testdata/baselines/reference/tsbuild/commandLine/when-build-not-first-argument.js index 608553534e..d44964311b 100644 --- a/testdata/baselines/reference/tsbuild/commandLine/when-build-not-first-argument.js +++ b/testdata/baselines/reference/tsbuild/commandLine/when-build-not-first-argument.js @@ -7,3 +7,4 @@ ExitStatus:: DiagnosticsPresent_OutputsSkipped Output:: error TS5093: Compiler option '--verbose' may only be used with '--build'. error TS6369: Option '--build' must be the first command line argument. + diff --git a/testdata/baselines/reference/tsc/commandLine/does-not-add-color-when-NO_COLOR-is-set.js b/testdata/baselines/reference/tsc/commandLine/does-not-add-color-when-NO_COLOR-is-set.js index d5682e767f..466c49d180 100644 --- a/testdata/baselines/reference/tsc/commandLine/does-not-add-color-when-NO_COLOR-is-set.js +++ b/testdata/baselines/reference/tsc/commandLine/does-not-add-color-when-NO_COLOR-is-set.js @@ -6,7 +6,6 @@ tsgo ExitStatus:: DiagnosticsPresent_OutputsSkipped Output:: Version FakeTSVersion - tsc: The TypeScript Compiler - Version FakeTSVersion COMMON COMMANDS diff --git a/testdata/baselines/reference/tsc/commandLine/help-all.js b/testdata/baselines/reference/tsc/commandLine/help-all.js index ece14ddbf0..b96905a0a7 100644 --- a/testdata/baselines/reference/tsc/commandLine/help-all.js +++ b/testdata/baselines/reference/tsc/commandLine/help-all.js @@ -5,5 +5,4 @@ Input:: tsgo --help --all ExitStatus:: Success Output:: -No output diff --git a/testdata/baselines/reference/tsc/commandLine/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped-when-host-cannot-provide-terminal-width.js b/testdata/baselines/reference/tsc/commandLine/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped-when-host-cannot-provide-terminal-width.js index 2985d6a3fa..617b39a1ac 100644 --- a/testdata/baselines/reference/tsc/commandLine/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped-when-host-cannot-provide-terminal-width.js +++ b/testdata/baselines/reference/tsc/commandLine/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped-when-host-cannot-provide-terminal-width.js @@ -6,7 +6,6 @@ tsgo ExitStatus:: DiagnosticsPresent_OutputsSkipped Output:: Version FakeTSVersion - tsc: The TypeScript Compiler - Version FakeTSVersion COMMON COMMANDS diff --git a/testdata/baselines/reference/tsc/commandLine/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js b/testdata/baselines/reference/tsc/commandLine/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js index 5092b85eee..9bbaffbc42 100644 --- a/testdata/baselines/reference/tsc/commandLine/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js +++ b/testdata/baselines/reference/tsc/commandLine/show-help-with-ExitStatus.DiagnosticsPresent_OutputsSkipped.js @@ -6,8 +6,7 @@ tsgo ExitStatus:: DiagnosticsPresent_OutputsSkipped Output:: Version FakeTSVersion - -tsc: The TypeScript Compiler - Version FakeTSVersion +tsc: The TypeScript Compiler - Version FakeTSVersion    TS  COMMON COMMANDS diff --git a/testdata/baselines/reference/tsc/extends/configDir-template-showConfig.js b/testdata/baselines/reference/tsc/extends/configDir-template-showConfig.js index b32d38fcc4..6e13d50e15 100644 --- a/testdata/baselines/reference/tsc/extends/configDir-template-showConfig.js +++ b/testdata/baselines/reference/tsc/extends/configDir-template-showConfig.js @@ -51,5 +51,27 @@ export const x = 10; tsgo --showConfig ExitStatus:: Success Output:: -No output - +{ + "declaration": true, + "declarationDir": "/home/src/projects/myproject/decls", + "outDir": "/home/src/projects/myproject/outDir", + "paths": { + "@myscope/*": [ + "/home/src/projects/myproject/types/*" + ], + "other/*": [ + "other/*" + ] + }, + "traceResolution": true, + "typeRoots": [ + "/home/src/projects/configs/first/root1", + "/home/src/projects/myproject/root2", + "/home/src/projects/configs/first/root3" + ], + "types": [], + "baseUrl": "/home/src/projects/myproject", + "configFilePath": "/home/src/projects/myproject/tsconfig.json", + "pathsBasePath": "/home/src/projects/configs/second", + "showConfig": true +} diff --git a/testdata/baselines/reference/tsc/incremental/change-to-modifier-of-class-expression-field-with-declaration-emit-enabled.js b/testdata/baselines/reference/tsc/incremental/change-to-modifier-of-class-expression-field-with-declaration-emit-enabled.js index b06f24a4fe..d3f3690594 100644 --- a/testdata/baselines/reference/tsc/incremental/change-to-modifier-of-class-expression-field-with-declaration-emit-enabled.js +++ b/testdata/baselines/reference/tsc/incremental/change-to-modifier-of-class-expression-field-with-declaration-emit-enabled.js @@ -141,6 +141,7 @@ export {}; "size": 2019 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/MessageablePerson.ts @@ -156,6 +157,7 @@ tsgo --incremental ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -299,6 +301,7 @@ Errors Files "size": 2702 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/MessageablePerson.ts *refresh* /home/src/workspaces/project/main.ts @@ -336,6 +339,7 @@ Errors Files //// [/home/src/workspaces/project/tsconfig.tsbuildinfo] *rewrite with same content* //// [/home/src/workspaces/project/tsconfig.tsbuildinfo.readable.baseline.txt] *rewrite with same content* +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -421,6 +425,7 @@ Output:: "size": 2019 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/MessageablePerson.ts *refresh* /home/src/workspaces/project/main.ts @@ -435,5 +440,6 @@ tsgo --incremental ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/change-to-modifier-of-class-expression-field.js b/testdata/baselines/reference/tsc/incremental/change-to-modifier-of-class-expression-field.js index de5b5b24a4..44cd75b955 100644 --- a/testdata/baselines/reference/tsc/incremental/change-to-modifier-of-class-expression-field.js +++ b/testdata/baselines/reference/tsc/incremental/change-to-modifier-of-class-expression-field.js @@ -117,6 +117,7 @@ export {}; "size": 1636 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/MessageablePerson.ts @@ -130,6 +131,7 @@ tsgo --incremental ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -234,6 +236,7 @@ Found 1 error in main.ts:3 "size": 2377 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/MessageablePerson.ts *refresh* /home/src/workspaces/project/main.ts @@ -256,6 +259,7 @@ Output:: Found 1 error in main.ts:3 +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -338,6 +342,7 @@ Output:: "size": 2000 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/MessageablePerson.ts *refresh* /home/src/workspaces/project/main.ts @@ -352,5 +357,6 @@ tsgo --incremental ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/change-to-type-that-gets-used-as-global-through-export-in-another-file-through-indirect-import.js b/testdata/baselines/reference/tsc/incremental/change-to-type-that-gets-used-as-global-through-export-in-another-file-through-indirect-import.js index 557e27d2a1..0c78cd54c2 100644 --- a/testdata/baselines/reference/tsc/incremental/change-to-type-that-gets-used-as-global-through-export-in-another-file-through-indirect-import.js +++ b/testdata/baselines/reference/tsc/incremental/change-to-type-that-gets-used-as-global-through-export-in-another-file-through-indirect-import.js @@ -165,6 +165,7 @@ Object.defineProperty(exports, "ConstantNumber", { enumerable: true, get: functi "size": 1816 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/class1.ts @@ -285,6 +286,7 @@ exports.default = 2; "size": 1816 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/constants.ts Signatures:: @@ -297,13 +299,14 @@ Diff:: Currently there is issue with d.ts emit for export default = 1 to widen i @@ -1,1 +1,1 @@ -declare const a = 2; +declare const a = 1; ---- nonIncremental errors.txt -+++ incremental errors.txt -@@ -1,7 +0,0 @@ +--- nonIncremental.output.txt ++++ incremental.output.txt +@@ -1,8 +0,0 @@ -class1.ts:1:7 - error TS2322: Type '1' is not assignable to type '2'. - -1 const a: MagicNumber = 1; -   ~ - +- -Found 1 error in class1.ts:1 - \ No newline at end of file diff --git a/testdata/baselines/reference/tsc/incremental/change-to-type-that-gets-used-as-global-through-export-in-another-file.js b/testdata/baselines/reference/tsc/incremental/change-to-type-that-gets-used-as-global-through-export-in-another-file.js index 2eed40cb53..4350dc09ed 100644 --- a/testdata/baselines/reference/tsc/incremental/change-to-type-that-gets-used-as-global-through-export-in-another-file.js +++ b/testdata/baselines/reference/tsc/incremental/change-to-type-that-gets-used-as-global-through-export-in-another-file.js @@ -135,6 +135,7 @@ exports.default = 1; "size": 1550 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/class1.ts @@ -235,6 +236,7 @@ exports.default = 2; "size": 1550 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/constants.ts Signatures:: @@ -247,13 +249,14 @@ Diff:: Currently there is issue with d.ts emit for export default = 1 to widen i @@ -1,1 +1,1 @@ -declare const a = 2; +declare const a = 1; ---- nonIncremental errors.txt -+++ incremental errors.txt -@@ -1,7 +0,0 @@ +--- nonIncremental.output.txt ++++ incremental.output.txt +@@ -1,8 +0,0 @@ -class1.ts:1:7 - error TS2322: Type '1' is not assignable to type '2'. - -1 const a: MagicNumber = 1; -   ~ - +- -Found 1 error in class1.ts:1 - \ No newline at end of file diff --git a/testdata/baselines/reference/tsc/incremental/generates-typerefs-correctly.js b/testdata/baselines/reference/tsc/incremental/generates-typerefs-correctly.js index e43878d4ef..e0407c36f9 100644 --- a/testdata/baselines/reference/tsc/incremental/generates-typerefs-correctly.js +++ b/testdata/baselines/reference/tsc/incremental/generates-typerefs-correctly.js @@ -190,6 +190,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); "size": 2078 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/src/box.ts @@ -333,6 +334,7 @@ exports.something = 1; "size": 2141 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/src/bug.js Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/option-changes-with-composite.js b/testdata/baselines/reference/tsc/incremental/option-changes-with-composite.js index 39aadf17e7..d84dcad4b8 100644 --- a/testdata/baselines/reference/tsc/incremental/option-changes-with-composite.js +++ b/testdata/baselines/reference/tsc/incremental/option-changes-with-composite.js @@ -175,6 +175,7 @@ exports.d = b_1.b; "size": 1747 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -323,6 +324,7 @@ exports.d = b_1.b; "size": 1764 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -453,6 +455,7 @@ exports.d = b_1.b; "size": 1747 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -463,6 +466,7 @@ tsgo --declaration ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -473,6 +477,7 @@ tsgo ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -597,6 +602,7 @@ export declare const d = 10; "size": 1788 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -711,6 +717,7 @@ export declare const d = 10; "size": 1747 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -721,6 +728,7 @@ tsgo --emitDeclarationOnly ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -731,6 +739,7 @@ tsgo ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -842,6 +851,7 @@ const aLocal = 100; "size": 1748 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/a.ts Signatures:: @@ -854,6 +864,7 @@ tsgo --declaration ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -985,6 +996,7 @@ exports.d = b_1.b; "size": 1771 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -1121,6 +1133,7 @@ exports.d = b_1.b; "size": 1765 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -1274,6 +1287,7 @@ exports.d = b_1.b; "size": 1770 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -1410,5 +1424,6 @@ exports.d = b_1.b; "size": 1787 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/option-changes-with-incremental.js b/testdata/baselines/reference/tsc/incremental/option-changes-with-incremental.js index ae80d67f90..e0329f64f4 100644 --- a/testdata/baselines/reference/tsc/incremental/option-changes-with-incremental.js +++ b/testdata/baselines/reference/tsc/incremental/option-changes-with-incremental.js @@ -139,6 +139,7 @@ exports.d = b_1.b; "size": 1236 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -261,6 +262,7 @@ exports.d = b_1.b; "size": 1265 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -367,6 +369,7 @@ exports.d = b_1.b; "size": 1236 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -480,6 +483,7 @@ export declare const d = 10; "size": 1715 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: (stored at emit) /home/src/workspaces/project/a.ts @@ -606,6 +610,7 @@ export declare const d = 10; "size": 1737 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -616,6 +621,7 @@ tsgo ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -723,6 +729,7 @@ const aLocal = 100; "size": 1685 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/a.ts Signatures:: @@ -835,6 +842,7 @@ Output:: "size": 1738 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -845,6 +853,7 @@ tsgo ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -974,6 +983,7 @@ exports.d = b_1.b; "size": 1720 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -1108,6 +1118,7 @@ exports.d = b_1.b; "size": 1714 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -1234,6 +1245,7 @@ exports.d = b_1.b; "size": 1685 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -1344,6 +1356,7 @@ Output:: "size": 1738 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -1354,5 +1367,6 @@ tsgo --declaration --declarationMap ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/react-jsx-emit-mode-with-no-backing-types-found-doesnt-crash-under---strict.js b/testdata/baselines/reference/tsc/incremental/react-jsx-emit-mode-with-no-backing-types-found-doesnt-crash-under---strict.js index 08093ca69c..d50ad32e52 100644 --- a/testdata/baselines/reference/tsc/incremental/react-jsx-emit-mode-with-no-backing-types-found-doesnt-crash-under---strict.js +++ b/testdata/baselines/reference/tsc/incremental/react-jsx-emit-mode-with-no-backing-types-found-doesnt-crash-under---strict.js @@ -134,6 +134,7 @@ exports.App = App; "size": 1612 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/src/index.tsx diff --git a/testdata/baselines/reference/tsc/incremental/react-jsx-emit-mode-with-no-backing-types-found-doesnt-crash.js b/testdata/baselines/reference/tsc/incremental/react-jsx-emit-mode-with-no-backing-types-found-doesnt-crash.js index 6c23a7e822..04165b519c 100644 --- a/testdata/baselines/reference/tsc/incremental/react-jsx-emit-mode-with-no-backing-types-found-doesnt-crash.js +++ b/testdata/baselines/reference/tsc/incremental/react-jsx-emit-mode-with-no-backing-types-found-doesnt-crash.js @@ -111,6 +111,7 @@ exports.App = App; "size": 1343 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/src/index.tsx diff --git a/testdata/baselines/reference/tsc/incremental/serializing-composite-project.js b/testdata/baselines/reference/tsc/incremental/serializing-composite-project.js index 05fa2d66da..ac61ce49b9 100644 --- a/testdata/baselines/reference/tsc/incremental/serializing-composite-project.js +++ b/testdata/baselines/reference/tsc/incremental/serializing-composite-project.js @@ -107,6 +107,7 @@ export const b = 2; "size": 1288 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/index.tsx diff --git a/testdata/baselines/reference/tsc/incremental/serializing-error-chain.js b/testdata/baselines/reference/tsc/incremental/serializing-error-chain.js index 9475e70c60..907e86ee11 100644 --- a/testdata/baselines/reference/tsc/incremental/serializing-error-chain.js +++ b/testdata/baselines/reference/tsc/incremental/serializing-error-chain.js @@ -172,6 +172,7 @@ declare const console: { log(msg: any): void; }; "size": 2098 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/index.tsx @@ -200,5 +201,6 @@ Output:: Found 1 error in index.tsx:10 +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/tsbuildinfo-has-error.js b/testdata/baselines/reference/tsc/incremental/tsbuildinfo-has-error.js index fca82548b5..08d10bcd2c 100644 --- a/testdata/baselines/reference/tsc/incremental/tsbuildinfo-has-error.js +++ b/testdata/baselines/reference/tsc/incremental/tsbuildinfo-has-error.js @@ -72,6 +72,7 @@ exports.x = 10; "size": 904 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/main.ts @@ -90,6 +91,7 @@ Output:: {"version":"FakeTSVersion","fileNames":["lib.d.ts","./main.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},"28e8748a7acd58f4f59388926e914f86-export const x = 10;"]} //// [/home/src/workspaces/project/tsconfig.tsbuildinfo.readable.baseline.txt] *rewrite with same content* +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/main.ts diff --git a/testdata/baselines/reference/tsc/incremental/when-file-is-deleted.js b/testdata/baselines/reference/tsc/incremental/when-file-is-deleted.js index 6b9d8e9163..2a9453f868 100644 --- a/testdata/baselines/reference/tsc/incremental/when-file-is-deleted.js +++ b/testdata/baselines/reference/tsc/incremental/when-file-is-deleted.js @@ -117,6 +117,7 @@ exports.D = D; "size": 1276 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/file1.ts @@ -174,5 +175,6 @@ Output:: "size": 1097 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/when-global-file-is-added,-the-signatures-are-updated.js b/testdata/baselines/reference/tsc/incremental/when-global-file-is-added,-the-signatures-are-updated.js index 8890070ee2..c23d894001 100644 --- a/testdata/baselines/reference/tsc/incremental/when-global-file-is-added,-the-signatures-are-updated.js +++ b/testdata/baselines/reference/tsc/incremental/when-global-file-is-added,-the-signatures-are-updated.js @@ -153,6 +153,7 @@ function main() { } "size": 1895 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/src/filePresent.ts @@ -170,6 +171,7 @@ tsgo ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -277,6 +279,7 @@ something(); "size": 1907 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/src/main.ts Signatures:: @@ -387,6 +390,7 @@ something(); "size": 1919 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/src/main.ts Signatures:: @@ -528,6 +532,7 @@ function foo() { return 20; } "size": 2201 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/src/newFile.ts @@ -673,6 +678,7 @@ function something2() { return 20; } "size": 2426 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/src/fileNotFound.ts @@ -825,6 +831,7 @@ something(); "size": 2438 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/src/main.ts Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/when-passing-filename-for-buildinfo-on-commandline.js b/testdata/baselines/reference/tsc/incremental/when-passing-filename-for-buildinfo-on-commandline.js index 99ad44a329..ffcb32f40a 100644 --- a/testdata/baselines/reference/tsc/incremental/when-passing-filename-for-buildinfo-on-commandline.js +++ b/testdata/baselines/reference/tsc/incremental/when-passing-filename-for-buildinfo-on-commandline.js @@ -87,6 +87,7 @@ exports.x = void 0; exports.x = 10; +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/src/main.ts @@ -103,5 +104,6 @@ Output:: src/main.ts Matched by include pattern 'src/**/*.ts' in 'tsconfig.json' +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/when-passing-rootDir-from-commandline.js b/testdata/baselines/reference/tsc/incremental/when-passing-rootDir-from-commandline.js index b38e03c510..06eef5bdc8 100644 --- a/testdata/baselines/reference/tsc/incremental/when-passing-rootDir-from-commandline.js +++ b/testdata/baselines/reference/tsc/incremental/when-passing-rootDir-from-commandline.js @@ -79,6 +79,7 @@ exports.x = 10; "size": 956 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/src/main.ts @@ -91,5 +92,6 @@ tsgo --rootDir src ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/when-passing-rootDir-is-in-the-tsconfig.js b/testdata/baselines/reference/tsc/incremental/when-passing-rootDir-is-in-the-tsconfig.js index e80df2ee46..4737fef775 100644 --- a/testdata/baselines/reference/tsc/incremental/when-passing-rootDir-is-in-the-tsconfig.js +++ b/testdata/baselines/reference/tsc/incremental/when-passing-rootDir-is-in-the-tsconfig.js @@ -80,6 +80,7 @@ exports.x = 10; "size": 950 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/src/main.ts @@ -92,5 +93,6 @@ tsgo ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tsc/incremental/with-only-dts-files.js b/testdata/baselines/reference/tsc/incremental/with-only-dts-files.js index ec5b0308e9..9c9887d283 100644 --- a/testdata/baselines/reference/tsc/incremental/with-only-dts-files.js +++ b/testdata/baselines/reference/tsc/incremental/with-only-dts-files.js @@ -73,6 +73,7 @@ declare const console: { log(msg: any): void; }; "size": 987 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/src/another.d.ts @@ -86,6 +87,7 @@ tsgo --incremental ExitStatus:: Success Output:: +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -136,6 +138,7 @@ Output:: "size": 1009 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/workspaces/project/src/main.d.ts Signatures:: diff --git a/testdata/baselines/reference/tsc/noEmit/when-project-has-strict-true.js b/testdata/baselines/reference/tsc/noEmit/when-project-has-strict-true.js index 330b9bf419..e9e50e8693 100644 --- a/testdata/baselines/reference/tsc/noEmit/when-project-has-strict-true.js +++ b/testdata/baselines/reference/tsc/noEmit/when-project-has-strict-true.js @@ -79,6 +79,7 @@ declare const console: { log(msg: any): void; }; "size": 965 } +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/class1.ts diff --git a/testdata/baselines/reference/tsc/projectReferences/default-import-interop-uses-referenced-project-settings.js b/testdata/baselines/reference/tsc/projectReferences/default-import-interop-uses-referenced-project-settings.js index abc2590be1..6c55de0c02 100644 --- a/testdata/baselines/reference/tsc/projectReferences/default-import-interop-uses-referenced-project-settings.js +++ b/testdata/baselines/reference/tsc/projectReferences/default-import-interop-uses-referenced-project-settings.js @@ -58,6 +58,7 @@ Output:: app/src/index.ts(1,8): error TS2613: Module '"/home/src/workspaces/project/app/src/local"' has no default export. Did you mean to use 'import { local } from "/home/src/workspaces/project/app/src/local"' instead? app/src/index.ts(2,8): error TS2613: Module '"/home/src/workspaces/project/node_modules/esm-package/index"' has no default export. Did you mean to use 'import { esm } from "/home/src/workspaces/project/node_modules/esm-package/index"' instead? + //// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib* /// interface Boolean {} diff --git a/testdata/baselines/reference/tsc/projectReferences/importing-const-enum-from-referenced-project-with-preserveConstEnums-and-verbatimModuleSyntax.js b/testdata/baselines/reference/tsc/projectReferences/importing-const-enum-from-referenced-project-with-preserveConstEnums-and-verbatimModuleSyntax.js index 1bb030b983..9d78b51615 100644 --- a/testdata/baselines/reference/tsc/projectReferences/importing-const-enum-from-referenced-project-with-preserveConstEnums-and-verbatimModuleSyntax.js +++ b/testdata/baselines/reference/tsc/projectReferences/importing-const-enum-from-referenced-project-with-preserveConstEnums-and-verbatimModuleSyntax.js @@ -46,6 +46,7 @@ tsgo --p project --pretty false ExitStatus:: DiagnosticsPresent_OutputsGenerated Output:: project/index.ts(2,10): error TS2748: Cannot access ambient const enums when 'verbatimModuleSyntax' is enabled. + //// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib* /// interface Boolean {} diff --git a/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences1.js b/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences1.js index b0b402f89e..b30f0e41f5 100644 --- a/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences1.js +++ b/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences1.js @@ -49,6 +49,7 @@ tsgo -p packages/main --pretty false ExitStatus:: DiagnosticsPresent_OutputsGenerated Output:: packages/main/src/index.ts(1,16): error TS2878: This import path is unsafe to rewrite because it resolves to another project, and the relative path between the projects' output files is not the same as the relative path between its input files. + //// [/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts] *Lib* /// interface Boolean {} diff --git a/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences2.js b/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences2.js index e87b5efa7c..fec014724b 100644 --- a/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences2.js +++ b/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences2.js @@ -34,7 +34,6 @@ import {} from "../compiler/parser.ts"; tsgo --p src/services --pretty false ExitStatus:: Success Output:: -No output //// [/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts] *Lib* /// interface Boolean {} @@ -127,6 +126,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); "size": 1326 } +src/services/tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.esnext.full.d.ts *refresh* /home/src/workspaces/solution/dist/compiler/parser.d.ts diff --git a/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences3.js b/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences3.js index 2256197ade..8297da6f3f 100644 --- a/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences3.js +++ b/testdata/baselines/reference/tsc/projectReferences/rewriteRelativeImportExtensionsProjectReferences3.js @@ -38,7 +38,6 @@ import {} from "../compiler/parser.ts"; tsgo --p src/services --pretty false ExitStatus:: Success Output:: -No output //// [/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts] *Lib* /// interface Boolean {} @@ -131,6 +130,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); "size": 1335 } +src/services/tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.esnext.full.d.ts *refresh* /home/src/workspaces/solution/dist/compiler/parser.d.ts diff --git a/testdata/baselines/reference/tsc/typeAcquisition/parse-tsconfig-with-typeAcquisition.js b/testdata/baselines/reference/tsc/typeAcquisition/parse-tsconfig-with-typeAcquisition.js index 33a17e206c..0a7f765952 100644 --- a/testdata/baselines/reference/tsc/typeAcquisition/parse-tsconfig-with-typeAcquisition.js +++ b/testdata/baselines/reference/tsc/typeAcquisition/parse-tsconfig-with-typeAcquisition.js @@ -35,5 +35,6 @@ Found 1 error. "size": 85 } +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option-without-tsconfig.json.js b/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option-without-tsconfig.json.js index caa5ad3c2f..25c01cba5c 100644 --- a/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option-without-tsconfig.json.js +++ b/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option-without-tsconfig.json.js @@ -6,7 +6,6 @@ tsgo -w --watchInterval 1000 ExitStatus:: DiagnosticsPresent_OutputsSkipped Output:: Version FakeTSVersion - tsc: The TypeScript Compiler - Version FakeTSVersion COMMON COMMANDS diff --git a/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option.js b/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option.js index fbff1dd2bb..ee2b9ae875 100644 --- a/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option.js +++ b/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option.js @@ -14,6 +14,8 @@ export const a = 1 tsgo -w --watchInterval 1000 ExitStatus:: Success Output:: +build starting at HH:MM:SS AM +build finished in d.ddds //// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib* /// interface Boolean {} @@ -38,6 +40,7 @@ interface Symbol { } declare const console: { log(msg: any): void; }; +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/first.ts diff --git a/testdata/baselines/reference/tscWatch/commandLineWatch/watch-with-no-tsconfig.js b/testdata/baselines/reference/tscWatch/commandLineWatch/watch-with-no-tsconfig.js index fcf71f7645..522610da63 100644 --- a/testdata/baselines/reference/tscWatch/commandLineWatch/watch-with-no-tsconfig.js +++ b/testdata/baselines/reference/tscWatch/commandLineWatch/watch-with-no-tsconfig.js @@ -7,6 +7,8 @@ Input:: tsgo index.ts --watch ExitStatus:: Success Output:: +build starting at HH:MM:SS AM +build finished in d.ddds //// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib* /// interface Boolean {} diff --git a/testdata/baselines/reference/tscWatch/commandLineWatch/watch-with-tsconfig-and-incremental.js b/testdata/baselines/reference/tscWatch/commandLineWatch/watch-with-tsconfig-and-incremental.js index 408993b951..67055b1897 100644 --- a/testdata/baselines/reference/tscWatch/commandLineWatch/watch-with-tsconfig-and-incremental.js +++ b/testdata/baselines/reference/tscWatch/commandLineWatch/watch-with-tsconfig-and-incremental.js @@ -9,6 +9,8 @@ Input:: tsgo --watch --incremental ExitStatus:: Success Output:: +build starting at HH:MM:SS AM +build finished in d.ddds //// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib* /// interface Boolean {} @@ -35,6 +37,7 @@ declare const console: { log(msg: any): void; }; //// [/home/src/workspaces/project/index.js] *new* +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/index.ts diff --git a/testdata/baselines/reference/tscWatch/noEmit/dts-errors-without-dts-enabled.js b/testdata/baselines/reference/tscWatch/noEmit/dts-errors-without-dts-enabled.js index a426806d75..44b0893a86 100644 --- a/testdata/baselines/reference/tscWatch/noEmit/dts-errors-without-dts-enabled.js +++ b/testdata/baselines/reference/tscWatch/noEmit/dts-errors-without-dts-enabled.js @@ -13,6 +13,8 @@ const a = class { private p = 10; }; tsgo -w ExitStatus:: Success Output:: +build starting at HH:MM:SS AM +build finished in d.ddds //// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib* /// interface Boolean {} @@ -37,6 +39,7 @@ interface Symbol { } declare const console: { log(msg: any): void; }; +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -49,7 +52,10 @@ const a = "hello"; Output:: +build starting at HH:MM:SS AM +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -67,10 +73,13 @@ Edit [1]:: emit after fixing error Output:: +build starting at HH:MM:SS AM +build finished in d.ddds //// [/home/src/workspaces/project/a.js] *new* const a = "hello"; +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -86,7 +95,10 @@ Edit [2]:: no emit run after fixing error Output:: +build starting at HH:MM:SS AM +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -97,7 +109,10 @@ const a = class { private p = 10; }; Output:: +build starting at HH:MM:SS AM +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -115,12 +130,15 @@ Edit [4]:: emit when error Output:: +build starting at HH:MM:SS AM +build finished in d.ddds //// [/home/src/workspaces/project/a.js] *modified* const a = class { p = 10; }; +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -136,6 +154,9 @@ Edit [5]:: no emit run when error Output:: +build starting at HH:MM:SS AM +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tscWatch/noEmit/dts-errors.js b/testdata/baselines/reference/tscWatch/noEmit/dts-errors.js index 633939b3e4..7b11ad2b8d 100644 --- a/testdata/baselines/reference/tscWatch/noEmit/dts-errors.js +++ b/testdata/baselines/reference/tscWatch/noEmit/dts-errors.js @@ -14,6 +14,7 @@ const a = class { private p = 10; }; tsgo -w ExitStatus:: Success Output:: +build starting at HH:MM:SS AM a.ts:1:7 - error TS4094: Property 'p' of exported anonymous class type may not be private or protected. 1 const a = class { private p = 10; }; @@ -26,6 +27,7 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds //// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib* /// interface Boolean {} @@ -50,6 +52,7 @@ interface Symbol { } declare const console: { log(msg: any): void; }; +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -62,7 +65,10 @@ const a = "hello"; Output:: +build starting at HH:MM:SS AM +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -80,6 +86,8 @@ Edit [1]:: emit after fixing error Output:: +build starting at HH:MM:SS AM +build finished in d.ddds //// [/home/src/workspaces/project/a.d.ts] *new* declare const a = "hello"; @@ -87,6 +95,7 @@ declare const a = "hello"; const a = "hello"; +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -102,7 +111,10 @@ Edit [2]:: no emit run after fixing error Output:: +build starting at HH:MM:SS AM +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -113,6 +125,7 @@ const a = class { private p = 10; }; Output:: +build starting at HH:MM:SS AM a.ts:1:7 - error TS4094: Property 'p' of exported anonymous class type may not be private or protected. 1 const a = class { private p = 10; }; @@ -125,7 +138,9 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -143,6 +158,7 @@ Edit [4]:: emit when error Output:: +build starting at HH:MM:SS AM a.ts:1:7 - error TS4094: Property 'p' of exported anonymous class type may not be private or protected. 1 const a = class { private p = 10; }; @@ -155,6 +171,7 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds //// [/home/src/workspaces/project/a.d.ts] *modified* declare const a: { new (): { @@ -168,6 +185,7 @@ const a = class { }; +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -183,6 +201,7 @@ Edit [5]:: no emit run when error Output:: +build starting at HH:MM:SS AM a.ts:1:7 - error TS4094: Property 'p' of exported anonymous class type may not be private or protected. 1 const a = class { private p = 10; }; @@ -195,6 +214,8 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tscWatch/noEmit/semantic-errors.js b/testdata/baselines/reference/tscWatch/noEmit/semantic-errors.js index 931f63d408..2fbce1bdd8 100644 --- a/testdata/baselines/reference/tscWatch/noEmit/semantic-errors.js +++ b/testdata/baselines/reference/tscWatch/noEmit/semantic-errors.js @@ -13,6 +13,7 @@ const a: number = "hello" tsgo -w ExitStatus:: Success Output:: +build starting at HH:MM:SS AM a.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'. 1 const a: number = "hello" @@ -21,6 +22,7 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds //// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib* /// interface Boolean {} @@ -45,6 +47,7 @@ interface Symbol { } declare const console: { log(msg: any): void; }; +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -57,7 +60,10 @@ const a = "hello"; Output:: +build starting at HH:MM:SS AM +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -75,10 +81,13 @@ Edit [1]:: emit after fixing error Output:: +build starting at HH:MM:SS AM +build finished in d.ddds //// [/home/src/workspaces/project/a.js] *new* const a = "hello"; +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -94,7 +103,10 @@ Edit [2]:: no emit run after fixing error Output:: +build starting at HH:MM:SS AM +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -105,6 +117,7 @@ const a: number = "hello" Output:: +build starting at HH:MM:SS AM a.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'. 1 const a: number = "hello" @@ -113,7 +126,9 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -131,6 +146,7 @@ Edit [4]:: emit when error Output:: +build starting at HH:MM:SS AM a.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'. 1 const a: number = "hello" @@ -139,8 +155,10 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds //// [/home/src/workspaces/project/a.js] *rewrite with same content* +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -156,6 +174,7 @@ Edit [5]:: no emit run when error Output:: +build starting at HH:MM:SS AM a.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'. 1 const a: number = "hello" @@ -164,6 +183,8 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: Signatures:: diff --git a/testdata/baselines/reference/tscWatch/noEmit/syntax-errors.js b/testdata/baselines/reference/tscWatch/noEmit/syntax-errors.js index ce5b5071b0..7139f74304 100644 --- a/testdata/baselines/reference/tscWatch/noEmit/syntax-errors.js +++ b/testdata/baselines/reference/tscWatch/noEmit/syntax-errors.js @@ -13,6 +13,7 @@ const a = "hello tsgo -w ExitStatus:: Success Output:: +build starting at HH:MM:SS AM a.ts:1:17 - error TS1002: Unterminated string literal. 1 const a = "hello @@ -21,6 +22,7 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds //// [/home/src/tslibs/TS/Lib/lib.d.ts] *Lib* /// interface Boolean {} @@ -45,6 +47,7 @@ interface Symbol { } declare const console: { log(msg: any): void; }; +tsconfig.json:: SemanticDiagnostics:: *not cached* /home/src/tslibs/TS/Lib/lib.d.ts *not cached* /home/src/workspaces/project/a.ts @@ -57,7 +60,10 @@ const a = "hello"; Output:: +build starting at HH:MM:SS AM +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: *refresh* /home/src/tslibs/TS/Lib/lib.d.ts *refresh* /home/src/workspaces/project/a.ts @@ -75,10 +81,13 @@ Edit [1]:: emit after fixing error Output:: +build starting at HH:MM:SS AM +build finished in d.ddds //// [/home/src/workspaces/project/a.js] *new* const a = "hello"; +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -94,7 +103,10 @@ Edit [2]:: no emit run after fixing error Output:: +build starting at HH:MM:SS AM +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: Signatures:: @@ -105,6 +117,7 @@ const a = "hello Output:: +build starting at HH:MM:SS AM a.ts:1:17 - error TS1002: Unterminated string literal. 1 const a = "hello @@ -113,7 +126,9 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: *not cached* /home/src/workspaces/project/a.ts Signatures:: @@ -129,6 +144,7 @@ Edit [4]:: emit when error Output:: +build starting at HH:MM:SS AM a.ts:1:17 - error TS1002: Unterminated string literal. 1 const a = "hello @@ -137,10 +153,12 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds //// [/home/src/workspaces/project/a.js] *modified* const a = "hello; +tsconfig.json:: SemanticDiagnostics:: *not cached* /home/src/workspaces/project/a.ts Signatures:: @@ -158,6 +176,7 @@ Edit [5]:: no emit run when error Output:: +build starting at HH:MM:SS AM a.ts:1:17 - error TS1002: Unterminated string literal. 1 const a = "hello @@ -166,7 +185,9 @@ Output:: Found 1 error in a.ts:1 +build finished in d.ddds +tsconfig.json:: SemanticDiagnostics:: *not cached* /home/src/workspaces/project/a.ts Signatures::