Skip to content

Commit 48aecfa

Browse files
authored
Consider module augmentations in files referenced by imports in watch/incremental (#45156)
* Consider module augmentations in files referenced by importsin watch/incremental * Accept baselines * Accept other baseline * Hooray optional chaining * Delete outdated and unuseful comment
1 parent f029a82 commit 48aecfa

File tree

5 files changed

+632
-34
lines changed

5 files changed

+632
-34
lines changed

src/compiler/builderState.ts

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -178,22 +178,16 @@ namespace ts {
178178
*/
179179
export type ComputeHash = ((data: string) => string) | undefined;
180180

181-
/**
182-
* Get the referencedFile from the imported module symbol
183-
*/
184-
function getReferencedFileFromImportedModuleSymbol(symbol: Symbol) {
185-
if (symbol.declarations && symbol.declarations[0]) {
186-
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
187-
return declarationSourceFile && declarationSourceFile.resolvedPath;
188-
}
181+
function getReferencedFilesFromImportedModuleSymbol(symbol: Symbol): Path[] {
182+
return mapDefined(symbol.declarations, declaration => getSourceFileOfNode(declaration)?.resolvedPath);
189183
}
190184

191185
/**
192-
* Get the referencedFile from the import name node from file
186+
* Get the module source file and all augmenting files from the import name node from file
193187
*/
194-
function getReferencedFileFromImportLiteral(checker: TypeChecker, importName: StringLiteralLike) {
188+
function getReferencedFilesFromImportLiteral(checker: TypeChecker, importName: StringLiteralLike): Path[] | undefined {
195189
const symbol = checker.getSymbolAtLocation(importName);
196-
return symbol && getReferencedFileFromImportedModuleSymbol(symbol);
190+
return symbol && getReferencedFilesFromImportedModuleSymbol(symbol);
197191
}
198192

199193
/**
@@ -215,10 +209,8 @@ namespace ts {
215209
if (sourceFile.imports && sourceFile.imports.length > 0) {
216210
const checker: TypeChecker = program.getTypeChecker();
217211
for (const importName of sourceFile.imports) {
218-
const declarationSourceFilePath = getReferencedFileFromImportLiteral(checker, importName);
219-
if (declarationSourceFilePath) {
220-
addReferencedFile(declarationSourceFilePath);
221-
}
212+
const declarationSourceFilePaths = getReferencedFilesFromImportLiteral(checker, importName);
213+
declarationSourceFilePaths?.forEach(addReferencedFile);
222214
}
223215
}
224216

@@ -458,20 +450,20 @@ namespace ts {
458450
}
459451

460452
let exportedModules: Set<Path> | undefined;
461-
exportedModulesFromDeclarationEmit.forEach(symbol => addExportedModule(getReferencedFileFromImportedModuleSymbol(symbol)));
453+
exportedModulesFromDeclarationEmit.forEach(symbol => addExportedModule(getReferencedFilesFromImportedModuleSymbol(symbol)));
462454
if (exportedModules) {
463455
exportedModulesMapCache.set(sourceFile.resolvedPath, exportedModules);
464456
}
465457
else {
466458
exportedModulesMapCache.deleteKey(sourceFile.resolvedPath);
467459
}
468460

469-
function addExportedModule(exportedModulePath: Path | undefined) {
470-
if (exportedModulePath) {
461+
function addExportedModule(exportedModulePaths: Path[] | undefined) {
462+
if (exportedModulePaths?.length) {
471463
if (!exportedModules) {
472464
exportedModules = new Set();
473465
}
474-
exportedModules.add(exportedModulePath);
466+
exportedModulePaths.forEach(path => exportedModules!.add(path));
475467
}
476468
}
477469
}

src/testRunner/unittests/tscWatch/incremental.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,5 +355,22 @@ export const Fragment: unique symbol;
355355
}
356356
});
357357
});
358+
359+
describe("editing module augmentation", () => {
360+
verifyIncrementalWatchEmit({
361+
subScenario: "editing module augmentation",
362+
files: () => [
363+
{ path: libFile.path, content: libContent },
364+
{ path: `${project}/node_modules/classnames/index.d.ts`, content: `export interface Result {} export default function classNames(): Result;` },
365+
{ path: `${project}/src/types/classnames.d.ts`, content: `export {}; declare module "classnames" { interface Result { foo } }` },
366+
{ path: `${project}/src/index.ts`, content: `import classNames from "classnames"; classNames().foo;` },
367+
{ path: configFile.path, content: JSON.stringify({ compilerOptions: { module: "commonjs", incremental: true } }) },
368+
],
369+
modifyFs: host => {
370+
// delete 'foo'
371+
host.writeFile(`${project}/src/types/classnames.d.ts`, `export {}; declare module "classnames" { interface Result {} }`);
372+
},
373+
});
374+
});
358375
});
359376
}

tests/baselines/reference/tsbuild/lateBoundSymbol/initial-build/interface-is-merged-and-contains-late-bound-member.js

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ var x = 10;
7171

7272

7373
//// [/src/tsconfig.tsbuildinfo]
74-
{"program":{"fileNames":["../lib/lib.d.ts","./src/globals.d.ts","./src/hkt.ts","./src/main.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-1994196675-interface SymbolConstructor {\n (description?: string | number): symbol;\n}\ndeclare var Symbol: SymbolConstructor;","affectsGlobalScope":true},"675797797-export interface HKT<T> { }","-28387946490-import { HKT } from \"./hkt\";\r\n\r\nconst sym = Symbol();\r\n\r\ndeclare module \"./hkt\" {\r\n interface HKT<T> {\r\n [sym]: { a: T }\r\n }\r\n}\r\nconst x = 10;\r\ntype A = HKT<number>[typeof sym];"],"options":{"rootDir":"./src"},"fileIdsList":[[3]],"referencedMap":[[4,1]],"exportedModulesMap":[[4,1]],"semanticDiagnosticsPerFile":[1,2,3,4]},"version":"FakeTSVersion"}
74+
{"program":{"fileNames":["../lib/lib.d.ts","./src/globals.d.ts","./src/hkt.ts","./src/main.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-1994196675-interface SymbolConstructor {\n (description?: string | number): symbol;\n}\ndeclare var Symbol: SymbolConstructor;","affectsGlobalScope":true},"675797797-export interface HKT<T> { }","-28387946490-import { HKT } from \"./hkt\";\r\n\r\nconst sym = Symbol();\r\n\r\ndeclare module \"./hkt\" {\r\n interface HKT<T> {\r\n [sym]: { a: T }\r\n }\r\n}\r\nconst x = 10;\r\ntype A = HKT<number>[typeof sym];"],"options":{"rootDir":"./src"},"fileIdsList":[[3,4]],"referencedMap":[[4,1]],"exportedModulesMap":[[4,1]],"semanticDiagnosticsPerFile":[1,2,3,4]},"version":"FakeTSVersion"}
7575

7676
//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt]
7777
{
@@ -84,7 +84,8 @@ var x = 10;
8484
],
8585
"fileNamesList": [
8686
[
87-
"./src/hkt.ts"
87+
"./src/hkt.ts",
88+
"./src/main.ts"
8889
]
8990
],
9091
"fileInfos": {
@@ -112,12 +113,14 @@ var x = 10;
112113
},
113114
"referencedMap": {
114115
"./src/main.ts": [
115-
"./src/hkt.ts"
116+
"./src/hkt.ts",
117+
"./src/main.ts"
116118
]
117119
},
118120
"exportedModulesMap": {
119121
"./src/main.ts": [
120-
"./src/hkt.ts"
122+
"./src/hkt.ts",
123+
"./src/main.ts"
121124
]
122125
},
123126
"semanticDiagnosticsPerFile": [
@@ -128,7 +131,7 @@ var x = 10;
128131
]
129132
},
130133
"version": "FakeTSVersion",
131-
"size": 1191
134+
"size": 1193
132135
}
133136

134137

@@ -171,7 +174,7 @@ var sym = Symbol();
171174

172175

173176
//// [/src/tsconfig.tsbuildinfo]
174-
{"program":{"fileNames":["../lib/lib.d.ts","./src/globals.d.ts","./src/hkt.ts","./src/main.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-1994196675-interface SymbolConstructor {\n (description?: string | number): symbol;\n}\ndeclare var Symbol: SymbolConstructor;","affectsGlobalScope":true},"675797797-export interface HKT<T> { }",{"version":"-27494779858-import { HKT } from \"./hkt\";\r\n\r\nconst sym = Symbol();\r\n\r\ndeclare module \"./hkt\" {\r\n interface HKT<T> {\r\n [sym]: { a: T }\r\n }\r\n}\r\n\r\ntype A = HKT<number>[typeof sym];","signature":"-7779857705-declare const sym: unique symbol;\r\ndeclare module \"./hkt\" {\r\n interface HKT<T> {\r\n [sym]: {\r\n a: T;\r\n };\r\n }\r\n}\r\nexport {};\r\n"}],"options":{"rootDir":"./src"},"fileIdsList":[[3]],"referencedMap":[[4,1]],"exportedModulesMap":[[4,1]],"semanticDiagnosticsPerFile":[1,2,3,4]},"version":"FakeTSVersion"}
177+
{"program":{"fileNames":["../lib/lib.d.ts","./src/globals.d.ts","./src/hkt.ts","./src/main.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-1994196675-interface SymbolConstructor {\n (description?: string | number): symbol;\n}\ndeclare var Symbol: SymbolConstructor;","affectsGlobalScope":true},"675797797-export interface HKT<T> { }",{"version":"-27494779858-import { HKT } from \"./hkt\";\r\n\r\nconst sym = Symbol();\r\n\r\ndeclare module \"./hkt\" {\r\n interface HKT<T> {\r\n [sym]: { a: T }\r\n }\r\n}\r\n\r\ntype A = HKT<number>[typeof sym];","signature":"-7779857705-declare const sym: unique symbol;\r\ndeclare module \"./hkt\" {\r\n interface HKT<T> {\r\n [sym]: {\r\n a: T;\r\n };\r\n }\r\n}\r\nexport {};\r\n"}],"options":{"rootDir":"./src"},"fileIdsList":[[3,4]],"referencedMap":[[4,1]],"exportedModulesMap":[[4,1]],"semanticDiagnosticsPerFile":[1,2,3,4]},"version":"FakeTSVersion"}
175178

176179
//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt]
177180
{
@@ -184,7 +187,8 @@ var sym = Symbol();
184187
],
185188
"fileNamesList": [
186189
[
187-
"./src/hkt.ts"
190+
"./src/hkt.ts",
191+
"./src/main.ts"
188192
]
189193
],
190194
"fileInfos": {
@@ -212,12 +216,14 @@ var sym = Symbol();
212216
},
213217
"referencedMap": {
214218
"./src/main.ts": [
215-
"./src/hkt.ts"
219+
"./src/hkt.ts",
220+
"./src/main.ts"
216221
]
217222
},
218223
"exportedModulesMap": {
219224
"./src/main.ts": [
220-
"./src/hkt.ts"
225+
"./src/hkt.ts",
226+
"./src/main.ts"
221227
]
222228
},
223229
"semanticDiagnosticsPerFile": [
@@ -228,7 +234,7 @@ var sym = Symbol();
228234
]
229235
},
230236
"version": "FakeTSVersion",
231-
"size": 1393
237+
"size": 1395
232238
}
233239

234240

@@ -272,7 +278,7 @@ var x = 10;
272278

273279

274280
//// [/src/tsconfig.tsbuildinfo]
275-
{"program":{"fileNames":["../lib/lib.d.ts","./src/globals.d.ts","./src/hkt.ts","./src/main.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-1994196675-interface SymbolConstructor {\n (description?: string | number): symbol;\n}\ndeclare var Symbol: SymbolConstructor;","affectsGlobalScope":true},"675797797-export interface HKT<T> { }",{"version":"-20682988154-import { HKT } from \"./hkt\";\r\n\r\nconst sym = Symbol();\r\n\r\ndeclare module \"./hkt\" {\r\n interface HKT<T> {\r\n [sym]: { a: T }\r\n }\r\n}\r\n\r\ntype A = HKT<number>[typeof sym];const x = 10;","signature":"-7779857705-declare const sym: unique symbol;\r\ndeclare module \"./hkt\" {\r\n interface HKT<T> {\r\n [sym]: {\r\n a: T;\r\n };\r\n }\r\n}\r\nexport {};\r\n"}],"options":{"rootDir":"./src"},"fileIdsList":[[3]],"referencedMap":[[4,1]],"exportedModulesMap":[[4,1]],"semanticDiagnosticsPerFile":[1,2,3,4]},"version":"FakeTSVersion"}
281+
{"program":{"fileNames":["../lib/lib.d.ts","./src/globals.d.ts","./src/hkt.ts","./src/main.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-1994196675-interface SymbolConstructor {\n (description?: string | number): symbol;\n}\ndeclare var Symbol: SymbolConstructor;","affectsGlobalScope":true},"675797797-export interface HKT<T> { }",{"version":"-20682988154-import { HKT } from \"./hkt\";\r\n\r\nconst sym = Symbol();\r\n\r\ndeclare module \"./hkt\" {\r\n interface HKT<T> {\r\n [sym]: { a: T }\r\n }\r\n}\r\n\r\ntype A = HKT<number>[typeof sym];const x = 10;","signature":"-7779857705-declare const sym: unique symbol;\r\ndeclare module \"./hkt\" {\r\n interface HKT<T> {\r\n [sym]: {\r\n a: T;\r\n };\r\n }\r\n}\r\nexport {};\r\n"}],"options":{"rootDir":"./src"},"fileIdsList":[[3,4]],"referencedMap":[[4,1]],"exportedModulesMap":[[4,1]],"semanticDiagnosticsPerFile":[1,2,3,4]},"version":"FakeTSVersion"}
276282

277283
//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt]
278284
{
@@ -285,7 +291,8 @@ var x = 10;
285291
],
286292
"fileNamesList": [
287293
[
288-
"./src/hkt.ts"
294+
"./src/hkt.ts",
295+
"./src/main.ts"
289296
]
290297
],
291298
"fileInfos": {
@@ -313,12 +320,14 @@ var x = 10;
313320
},
314321
"referencedMap": {
315322
"./src/main.ts": [
316-
"./src/hkt.ts"
323+
"./src/hkt.ts",
324+
"./src/main.ts"
317325
]
318326
},
319327
"exportedModulesMap": {
320328
"./src/main.ts": [
321-
"./src/hkt.ts"
329+
"./src/hkt.ts",
330+
"./src/main.ts"
322331
]
323332
},
324333
"semanticDiagnosticsPerFile": [
@@ -329,6 +338,6 @@ var x = 10;
329338
]
330339
},
331340
"version": "FakeTSVersion",
332-
"size": 1406
341+
"size": 1408
333342
}
334343

0 commit comments

Comments
 (0)