Skip to content

Commit d265fbf

Browse files
Merge pull request #26192 from ajafff/createprogram-nochecker
createProgram: don't use TypeChecker
2 parents 5d65e86 + 3b022a4 commit d265fbf

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

src/compiler/program.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -953,25 +953,23 @@ namespace ts {
953953
// If we change our policy of rechecking failed lookups on each program create,
954954
// we should adjust the value returned here.
955955
function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string, oldProgramState: OldProgramState): boolean {
956+
if (!oldProgramState.program) {
957+
return false;
958+
}
956959
const resolutionToFile = getResolvedModule(oldProgramState.oldSourceFile!, moduleName); // TODO: GH#18217
957-
const resolvedFile = resolutionToFile && oldProgramState.program && oldProgramState.program.getSourceFile(resolutionToFile.resolvedFileName);
960+
const resolvedFile = resolutionToFile && oldProgramState.program.getSourceFile(resolutionToFile.resolvedFileName);
958961
if (resolutionToFile && resolvedFile && !resolvedFile.externalModuleIndicator) {
959962
// In the old program, we resolved to an ambient module that was in the same
960963
// place as we expected to find an actual module file.
961964
// We actually need to return 'false' here even though this seems like a 'true' case
962965
// because the normal module resolution algorithm will find this anyway.
963966
return false;
964967
}
965-
const ambientModule = oldProgramState.program && oldProgramState.program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(moduleName);
966-
if (!(ambientModule && ambientModule.declarations)) {
967-
return false;
968-
}
969968

970969
// at least one of declarations should come from non-modified source file
971-
const firstUnmodifiedFile = forEach(ambientModule.declarations, d => {
972-
const f = getSourceFileOfNode(d);
973-
return !contains(oldProgramState.modifiedFilePaths, f.path) && f;
974-
});
970+
const firstUnmodifiedFile = oldProgramState.program.getSourceFiles().find(
971+
f => !contains(oldProgramState.modifiedFilePaths, f.path) && contains(f.ambientModuleNames, moduleName)
972+
);
975973

976974
if (!firstUnmodifiedFile) {
977975
return false;

src/testRunner/unittests/reuseProgramStructure.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,30 @@ namespace ts {
399399
assert.isDefined(program2.getSourceFile("/a.ts")!.resolvedModules!.get("a"), "'a' is not an unresolved module after re-use");
400400
});
401401

402+
it("works with updated SourceFiles", () => {
403+
// adapted repro from https://github.com/Microsoft/TypeScript/issues/26166
404+
const files = [
405+
{ name: "/a.ts", text: SourceText.New("", "", 'import * as a from "a";a;') },
406+
{ name: "/types/zzz/index.d.ts", text: SourceText.New("", "", 'declare module "a" { }') },
407+
];
408+
const host = createTestCompilerHost(files, target);
409+
const options: CompilerOptions = { target, typeRoots: ["/types"] };
410+
const program1 = createProgram(["/a.ts"], options, host);
411+
let sourceFile = program1.getSourceFile("/a.ts")!;
412+
assert.isDefined(sourceFile, "'/a.ts' is included in the program");
413+
sourceFile = updateSourceFile(sourceFile, "'use strict';" + sourceFile.text, { newLength: "'use strict';".length, span: { start: 0, length: 0 } });
414+
assert.strictEqual(sourceFile.statements[2].getSourceFile(), sourceFile, "parent pointers are updated");
415+
const updateHost: TestCompilerHost = {
416+
...host,
417+
getSourceFile(fileName) {
418+
return fileName === sourceFile.fileName ? sourceFile : program1.getSourceFile(fileName);
419+
}
420+
};
421+
const program2 = createProgram(["/a.ts"], options, updateHost, program1);
422+
assert.isDefined(program2.getSourceFile("/a.ts")!.resolvedModules!.get("a"), "'a' is not an unresolved module after re-use");
423+
assert.strictEqual(sourceFile.statements[2].getSourceFile(), sourceFile, "parent pointers are not altered");
424+
});
425+
402426
it("resolved type directives cache follows type directives", () => {
403427
const files = [
404428
{ name: "/a.ts", text: SourceText.New("/// <reference types='typedefs'/>", "", "var x = $") },

0 commit comments

Comments
 (0)