Skip to content

Commit 9a506f9

Browse files
committed
Fix incremental updates
1 parent 5a187de commit 9a506f9

16 files changed

+93
-536
lines changed

internal/execute/tsc.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func CommandLine(sys System, commandLineArgs []string, testing bool) (ExitStatus
5656

5757
parsedCommandLine := tsoptions.ParseCommandLine(commandLineArgs, sys)
5858
status, incrementalProgram, watcher := tscCompilation(sys, parsedCommandLine, testing)
59-
if watcher == nil {
59+
if watcher != nil {
6060
watcher.start()
6161
}
6262
return status, parsedCommandLine, incrementalProgram, watcher
@@ -371,7 +371,7 @@ func emitFilesAndReportErrors(
371371

372372
if sys.Writer() != nil {
373373
for _, file := range emitResult.EmittedFiles {
374-
fmt.Fprint(sys.Writer(), "TSFILE: ", tspath.GetNormalizedAbsolutePath(file, sys.GetCurrentDirectory()))
374+
fmt.Fprint(sys.Writer(), "TSFILE: ", tspath.GetNormalizedAbsolutePath(file, sys.GetCurrentDirectory()), sys.NewLine())
375375
}
376376
listFiles(sys, program)
377377
}

internal/execute/tscincremental_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func TestIncremental(t *testing.T) {
3333
<div />
3434
</Component>)`,
3535
}, "/home/src/workspaces/project"),
36+
edits: noChangeOnlyEdit,
3637
},
3738
{
3839
subScenario: "serializing composite project",

internal/execute/tsctestrunner_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ var noChange = &testTscEdit{
2525
edit: func(sys *testSys) {},
2626
}
2727

28+
var noChangeOnlyEdit = []*testTscEdit{
29+
noChange,
30+
}
31+
2832
type tscInput struct {
2933
subScenario string
3034
commandLineArgs []string

internal/execute/tscwatch_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func noEmitWatchTestInput(
6363
commandLineArgs: commandLineArgs,
6464
sys: sys,
6565
edits: []*testTscEdit{
66-
newTscEdit("fix syntax error", func(sys *testSys) {
66+
newTscEdit("fix error", func(sys *testSys) {
6767
sys.WriteFileNoError("/home/src/workspaces/project/a.ts", `const a = "hello";`, false)
6868
}),
6969
newTscEdit("emit after fixing error", func(sys *testSys) {

internal/incremental/emitfileshandler.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -97,26 +97,26 @@ func (h *emitFilesHandler) emitAllAffectedFiles(options compiler.EmitOptions) *c
9797
if h.ctx.Err() != nil {
9898
return nil
9999
}
100+
}
100101

101-
// Get updated errors that were not included in affected files emit
102-
for path, diagnostics := range h.program.snapshot.emitDiagnosticsPerFile {
103-
if _, ok := h.emitUpdates.Load(path); !ok {
104-
affectedFile := h.program.program.GetSourceFileByPath(path)
105-
if affectedFile == nil || !h.program.program.SourceFileMayBeEmitted(affectedFile, false) {
106-
h.deletedPendingKinds.Add(path)
107-
continue
108-
}
109-
pendingKind := h.program.snapshot.affectedFilesPendingEmit[path]
110-
h.emitUpdates.Store(path, &emitUpdate{pendingKind: pendingKind, result: &compiler.EmitResult{
111-
EmitSkipped: true,
112-
Diagnostics: diagnostics.getDiagnostics(h.program.program, affectedFile),
113-
}})
102+
// Get updated errors that were not included in affected files emit
103+
for path, diagnostics := range h.program.snapshot.emitDiagnosticsPerFile {
104+
if _, ok := h.emitUpdates.Load(path); !ok {
105+
affectedFile := h.program.program.GetSourceFileByPath(path)
106+
if affectedFile == nil || !h.program.program.SourceFileMayBeEmitted(affectedFile, false) {
107+
h.deletedPendingKinds.Add(path)
108+
continue
114109
}
110+
pendingKind := h.program.snapshot.affectedFilesPendingEmit[path]
111+
h.emitUpdates.Store(path, &emitUpdate{pendingKind: pendingKind, result: &compiler.EmitResult{
112+
EmitSkipped: true,
113+
Diagnostics: diagnostics.getDiagnostics(h.program.program, affectedFile),
114+
}})
115115
}
116-
117-
results = h.updateSnapshot()
118116
}
119117

118+
results = h.updateSnapshot()
119+
120120
// Combine results and update buildInfo
121121
if h.isForDtsErrors && options.TargetSourceFile != nil {
122122
// Result from cache

internal/incremental/program.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,15 @@ func (h *Program) emitBuildInfo(ctx context.Context, options compiler.EmitOption
230230
if buildInfoFileName == "" {
231231
return nil
232232
}
233-
234-
hasErrors := h.ensureHasErrorsForState(ctx, h.program)
235-
if !h.snapshot.buildInfoEmitPending && h.snapshot.hasErrors == hasErrors {
233+
if h.snapshot.hasErrors == core.TSUnknown {
234+
h.snapshot.hasErrors = h.ensureHasErrorsForState(ctx, h.program)
235+
if h.snapshot.hasErrors != h.snapshot.hasErrorsFromOldState {
236+
h.snapshot.buildInfoEmitPending = true
237+
}
238+
}
239+
if !h.snapshot.buildInfoEmitPending {
236240
return nil
237241
}
238-
h.snapshot.hasErrors = hasErrors
239-
h.snapshot.buildInfoEmitPending = true
240242
if ctx.Err() != nil {
241243
return nil
242244
}
@@ -273,10 +275,6 @@ func (h *Program) emitBuildInfo(ctx context.Context, options compiler.EmitOption
273275
}
274276

275277
func (h *Program) ensureHasErrorsForState(ctx context.Context, program *compiler.Program) core.Tristate {
276-
if h.snapshot.hasErrors != core.TSUnknown {
277-
return h.snapshot.hasErrors
278-
}
279-
280278
// Check semantic and emit diagnostics first as we dont need to ask program about it
281279
if slices.ContainsFunc(program.GetSourceFiles(), func(file *ast.SourceFile) bool {
282280
semanticDiagnostics := h.snapshot.semanticDiagnosticsPerFile[file.Path()]

internal/incremental/snapshot.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ type snapshot struct {
209209

210210
// true if build info emit is pending
211211
buildInfoEmitPending bool
212+
hasErrorsFromOldState core.Tristate
212213
allFilesExcludingDefaultLibraryFileOnce sync.Once
213214
// Cache of all files excluding default library file for the current program
214215
allFilesExcludingDefaultLibraryFile []*ast.SourceFile
@@ -232,6 +233,7 @@ func (s *snapshot) addFileToAffectedFilesPendingEmit(filePath tspath.Path, emitK
232233
}
233234
s.affectedFilesPendingEmit[filePath] = existingKind | emitKind
234235
delete(s.emitDiagnosticsPerFile, filePath)
236+
s.buildInfoEmitPending = true
235237
}
236238

237239
func (s *snapshot) getAllFilesExcludingDefaultLibraryFile(program *compiler.Program, firstSourceFile *ast.SourceFile) []*ast.SourceFile {
@@ -278,6 +280,7 @@ func newSnapshotForProgram(program *compiler.Program, oldProgram *Program) *snap
278280
snapshot.affectedFilesPendingEmit = maps.Clone(oldProgram.snapshot.affectedFilesPendingEmit)
279281
}
280282
snapshot.buildInfoEmitPending = oldProgram.snapshot.buildInfoEmitPending
283+
snapshot.hasErrorsFromOldState = oldProgram.snapshot.hasErrors
281284
} else {
282285
snapshot.changedFilesSet = &collections.Set[tspath.Path]{}
283286
snapshot.buildInfoEmitPending = snapshot.options.IsIncremental()
@@ -312,7 +315,7 @@ func newSnapshotForProgram(program *compiler.Program, oldProgram *Program) *snap
312315
if oldProgram != nil {
313316
if oldFileInfo, ok := oldProgram.snapshot.fileInfos[file.Path()]; ok {
314317
signature = oldFileInfo.signature
315-
if oldFileInfo.version == version || oldFileInfo.affectsGlobalScope != affectsGlobalScope || oldFileInfo.impliedNodeFormat != impliedNodeFormat {
318+
if oldFileInfo.version != version || oldFileInfo.affectsGlobalScope != affectsGlobalScope || oldFileInfo.impliedNodeFormat != impliedNodeFormat {
316319
snapshot.addFileToChangeSet(file.Path())
317320
} else if oldReferences, _ := oldProgram.snapshot.referencedMap.GetValues(file.Path()); !newReferences.Equals(oldReferences) {
318321
// Referenced files changed

internal/tsoptions/declscompiler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,7 @@ func optionsHaveChanges(oldOptions *core.CompilerOptions, newOptions *core.Compi
12491249
}
12501250
oldOptionsValue := reflect.ValueOf(oldOptions).Elem()
12511251
return ForEachCompilerOptionValue(newOptions, declFilter, func(option *CommandLineOption, value reflect.Value, i int) bool {
1252-
return !reflect.DeepEqual(value, oldOptionsValue.Field(i))
1252+
return !reflect.DeepEqual(value.Interface(), oldOptionsValue.Field(i).Interface())
12531253
})
12541254
}
12551255

internal/tsoptions/parsinghelpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ func parseCompilerOptions(key string, value any, allOptions *core.CompilerOption
262262
case "isolatedDeclarations":
263263
allOptions.IsolatedDeclarations = parseTristate(value)
264264
case "jsx":
265-
allOptions.Jsx = value.(core.JsxEmit)
265+
allOptions.Jsx = floatOrInt32ToFlag[core.JsxEmit](value)
266266
case "jsxFactory":
267267
allOptions.JsxFactory = parseString(value)
268268
case "jsxFragmentFactory":

0 commit comments

Comments
 (0)