Skip to content

Commit ba402e6

Browse files
authored
Allow structure reuse if a declaration file within a package is updated (#47472)
* Allow structure reuse if a declaration file within a package is updated Closes #47471 * Use correct program to obtain source file in structure reuse test
1 parent a9efe2b commit ba402e6

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

src/compiler/program.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2829,14 +2829,14 @@ namespace ts {
28292829
redirectTargetsMap.add(fileFromPackageId.path, fileName);
28302830
addFileToFilesByName(dupFile, path, redirectedPath);
28312831
addFileIncludeReason(dupFile, reason);
2832-
sourceFileToPackageName.set(path, packageId.name);
2832+
sourceFileToPackageName.set(path, packageIdToPackageName(packageId));
28332833
processingOtherFiles!.push(dupFile);
28342834
return dupFile;
28352835
}
28362836
else if (file) {
28372837
// This is the first source file to have this packageId.
28382838
packageIdToSourceFile.set(packageIdKey, file);
2839-
sourceFileToPackageName.set(path, packageId.name);
2839+
sourceFileToPackageName.set(path, packageIdToPackageName(packageId));
28402840
}
28412841
}
28422842
addFileToFilesByName(file, path, redirectedPath);

src/compiler/utilities.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,12 @@ namespace ts {
192192
return a === b || !!a && !!b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version;
193193
}
194194

195-
export function packageIdToString({ name, subModuleName, version }: PackageId): string {
196-
const fullName = subModuleName ? `${name}/${subModuleName}` : name;
197-
return `${fullName}@${version}`;
195+
export function packageIdToPackageName({ name, subModuleName }: PackageId): string {
196+
return subModuleName ? `${name}/${subModuleName}` : name;
197+
}
198+
199+
export function packageIdToString(packageId: PackageId): string {
200+
return `${packageIdToPackageName(packageId)}@${packageId.version}`;
198201
}
199202

200203
export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirective, newResolution: ResolvedTypeReferenceDirective): boolean {

src/testRunner/unittests/reuseProgramStructure.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ namespace ts {
234234
});
235235
assert.equal(program2.structureIsReused, StructureIsReused.Completely);
236236
const program1Diagnostics = program1.getSemanticDiagnostics(program1.getSourceFile("a.ts"));
237-
const program2Diagnostics = program2.getSemanticDiagnostics(program1.getSourceFile("a.ts"));
237+
const program2Diagnostics = program2.getSemanticDiagnostics(program2.getSourceFile("a.ts"));
238238
assert.equal(program1Diagnostics.length, program2Diagnostics.length);
239239
});
240240

@@ -245,7 +245,26 @@ namespace ts {
245245
});
246246
assert.equal(program2.structureIsReused, StructureIsReused.Completely);
247247
const program1Diagnostics = program1.getSemanticDiagnostics(program1.getSourceFile("a.ts"));
248-
const program2Diagnostics = program2.getSemanticDiagnostics(program1.getSourceFile("a.ts"));
248+
const program2Diagnostics = program2.getSemanticDiagnostics(program2.getSourceFile("a.ts"));
249+
assert.equal(program1Diagnostics.length, program2Diagnostics.length);
250+
});
251+
252+
it("successful if change affects a single module of a package", () => {
253+
const files = [
254+
{ name: "/a.ts", text: SourceText.New("", "import {b} from 'b'", "var a = b;") },
255+
{ name: "/node_modules/b/index.d.ts", text: SourceText.New("", "export * from './internal';", "") },
256+
{ name: "/node_modules/b/internal.d.ts", text: SourceText.New("", "", "export const b = 1;") },
257+
{ name: "/node_modules/b/package.json", text: SourceText.New("", "", JSON.stringify({ name: "b", version: "1.2.3" })) },
258+
];
259+
260+
const options: CompilerOptions = { target, moduleResolution: ModuleResolutionKind.NodeJs };
261+
const program1 = newProgram(files, ["/a.ts"], options);
262+
const program2 = updateProgram(program1, ["/a.ts"], options, files => {
263+
files[2].text = files[2].text.updateProgram("export const b = 2;");
264+
});
265+
assert.equal(program2.structureIsReused, StructureIsReused.Completely);
266+
const program1Diagnostics = program1.getSemanticDiagnostics(program1.getSourceFile("a.ts"));
267+
const program2Diagnostics = program2.getSemanticDiagnostics(program2.getSourceFile("a.ts"));
249268
assert.equal(program1Diagnostics.length, program2Diagnostics.length);
250269
});
251270

0 commit comments

Comments
 (0)