Skip to content

Commit 01cac67

Browse files
sheetalkamatCopilotDanielRosenwasser
authored
Incremental fixes (#2532)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
1 parent f4ae2af commit 01cac67

3 files changed

Lines changed: 588 additions & 9 deletions

File tree

internal/execute/incremental/affectedfileshandler.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type affectedFilesHandler struct {
3535
dtsMayChange []dtsMayChange
3636
filesToRemoveDiagnostics collections.SyncSet[tspath.Path]
3737
cleanedDiagnosticsOfLibFiles sync.Once
38-
seenFileAndExportsOfFile collections.SyncMap[tspath.Path, bool]
38+
seenFileAndReferences collections.SyncMap[tspath.Path, bool]
3939
}
4040

4141
func (h *affectedFilesHandler) getDtsMayChange(affectedFilePath tspath.Path, affectedFileEmitKind FileEmitKind) dtsMayChange {
@@ -200,6 +200,9 @@ func (h *affectedFilesHandler) handleDtsMayChangeOfAffectedFile(dtsMayChange dts
200200
return
201201
}
202202

203+
// At this point affectedFile is actually one of the changed files
204+
// that has some change in its .d.ts signature.
205+
203206
// Since isolated modules dont change js files, files affected by change in signature is itself
204207
// But we need to cleanup semantic diagnostics and queue dts emit for affected files
205208
if h.program.snapshot.options.IsolatedModules.IsTrue() {
@@ -250,30 +253,36 @@ func (h *affectedFilesHandler) handleDtsMayChangeOfAffectedFile(dtsMayChange dts
250253
}
251254

252255
// Go through files that reference affected file and handle dts emit and semantic diagnostics for them and their references
253-
for exportedFromPath := range h.program.snapshot.referencedMap.getReferencedBy(affectedFile.Path()) {
254-
if h.handleDtsMayChangeOfGlobalScope(dtsMayChange, exportedFromPath, invalidateJsFiles) {
256+
for fileReferencingChangedFile := range h.program.snapshot.referencedMap.getReferencedBy(affectedFile.Path()) {
257+
if h.handleDtsMayChangeOfGlobalScope(dtsMayChange, fileReferencingChangedFile, invalidateJsFiles) {
255258
return
256259
}
257-
for filePath := range h.program.snapshot.referencedMap.getReferencedBy(exportedFromPath) {
258-
if h.handleDtsMayChangeOfFileAndExportsOfFile(dtsMayChange, filePath, invalidateJsFiles) {
260+
// Since references of changed file = affected files - we would have already handled d.ts emit and semantic diagnostics
261+
// for those files. Now we need to handle files referencing those affected files to ensure correctness.
262+
for fileReferencingAffectedFile := range h.program.snapshot.referencedMap.getReferencedBy(fileReferencingChangedFile) {
263+
if h.handleDtsMayChangeOfFileAndReferences(dtsMayChange, fileReferencingAffectedFile, invalidateJsFiles) {
259264
return
260265
}
261266
}
262267
}
263268
}
264269

265-
func (h *affectedFilesHandler) handleDtsMayChangeOfFileAndExportsOfFile(dtsMayChange dtsMayChange, filePath tspath.Path, invalidateJsFiles bool) bool {
266-
if existing, loaded := h.seenFileAndExportsOfFile.LoadOrStore(filePath, invalidateJsFiles); loaded && (existing || !invalidateJsFiles) {
270+
func (h *affectedFilesHandler) handleDtsMayChangeOfFileAndReferences(dtsMayChange dtsMayChange, filePath tspath.Path, invalidateJsFiles bool) bool {
271+
if existing, loaded := h.seenFileAndReferences.LoadOrStore(filePath, invalidateJsFiles); loaded && (existing || !invalidateJsFiles) {
267272
return false
273+
} else if loaded && invalidateJsFiles {
274+
h.seenFileAndReferences.Store(filePath, true)
268275
}
276+
269277
if h.handleDtsMayChangeOfGlobalScope(dtsMayChange, filePath, invalidateJsFiles) {
270278
return true
271279
}
272280
h.handleDtsMayChangeOf(dtsMayChange, filePath, invalidateJsFiles)
273281

274-
// Remove the diagnostics of files that import this file and handle all its exports too
282+
// Remove the diagnostics of files that import this file and
283+
// any files that are referenced by it (directly or indirectly)
275284
for referencingFilePath := range h.program.snapshot.referencedMap.getReferencedBy(filePath) {
276-
if h.handleDtsMayChangeOfFileAndExportsOfFile(dtsMayChange, referencingFilePath, invalidateJsFiles) {
285+
if h.handleDtsMayChangeOfFileAndReferences(dtsMayChange, referencingFilePath, invalidateJsFiles) {
277286
return true
278287
}
279288
}

internal/execute/tsctests/tsc_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,6 +1880,52 @@ func TestTscIncremental(t *testing.T) {
18801880
cwd: "/home/project",
18811881
ignoreCase: true,
18821882
},
1883+
{
1884+
subScenario: "const enums with refCycle",
1885+
files: FileMap{
1886+
"/home/src/workspaces/project/file.ts": stringtestutil.Dedent(`
1887+
import {A} from "./c"
1888+
let a = A.ONE
1889+
`),
1890+
"/home/src/workspaces/project/b.ts": stringtestutil.Dedent(`
1891+
import { AWorker } from "./aworker"
1892+
import { A as ACycle } from "./c"
1893+
export const enum A {
1894+
ONE = 1
1895+
}
1896+
`),
1897+
"/home/src/workspaces/project/c.ts": stringtestutil.Dedent(`
1898+
import {A} from "./b"
1899+
let b = A.ONE
1900+
export {A}
1901+
`),
1902+
"/home/src/workspaces/project/aworker.ts": stringtestutil.Dedent(`
1903+
export const AWorker = 10
1904+
`),
1905+
"/home/src/workspaces/project/tsconfig.json": stringtestutil.Dedent(`
1906+
{
1907+
"compilerOptions": {
1908+
"composite": true,
1909+
}
1910+
}`),
1911+
},
1912+
commandLineArgs: []string{},
1913+
edits: []*tscEdit{
1914+
{
1915+
caption: "change aworker",
1916+
edit: func(sys *TestSys) {
1917+
sys.replaceFileText("/home/src/workspaces/project/aworker.ts", "10", "20")
1918+
},
1919+
},
1920+
{
1921+
caption: "change aworker and enum value",
1922+
edit: func(sys *TestSys) {
1923+
sys.replaceFileText("/home/src/workspaces/project/aworker.ts", "20", "30")
1924+
sys.replaceFileText("/home/src/workspaces/project/b.ts", "1", "2")
1925+
},
1926+
},
1927+
},
1928+
},
18831929
}
18841930

18851931
for _, test := range testCases {

0 commit comments

Comments
 (0)