Skip to content

Commit 7966c08

Browse files
author
Arthur Ozga
committed
make enum bitflag and add trace message
1 parent 044152e commit 7966c08

3 files changed

Lines changed: 87 additions & 22 deletions

File tree

src/compiler/diagnosticMessages.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3199,9 +3199,12 @@
31993199
},
32003200
"Scoped package detected, looking in '{0}'": {
32013201
"category": "Message",
3202-
"code": "6182"
3202+
"code": 6182
3203+
},
3204+
"Reusing module resolutions originating in '{0}' since this file was not modified.": {
3205+
"category": "Message",
3206+
"code": 6183
32033207
},
3204-
32053208
"Variable '{0}' implicitly has an '{1}' type.": {
32063209
"category": "Error",
32073210
"code": 7005

src/compiler/program.ts

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ namespace ts {
88

99

1010
const enum StructuralChangesFromOldProgram {
11-
None = 0,
12-
NoOldProgram = 1,
13-
ModuleResolutionOptions = 2,
14-
RootNames = 3,
15-
TypesOptions = 4,
16-
SourceFileRemoved = 5,
17-
HasNoDefaultLib = 6,
18-
TripleSlashReferences = 7,
19-
Imports = 8,
20-
ModuleAugmentations = 9,
21-
TripleSlashTypesReferences = 10,
11+
None = 0,
12+
NoOldProgram = 1 << 1,
13+
ModuleResolutionOptions = 1 << 2,
14+
RootNames = 1 << 3,
15+
TypesOptions = 1 << 4,
16+
SourceFileRemoved = 1 << 5,
17+
HasNoDefaultLib = 1 << 6,
18+
TripleSlashReferences = 1 << 7,
19+
Imports = 1 << 8,
20+
ModuleAugmentations = 1 << 9,
21+
TripleSlashTypesReferences = 1 << 10,
2222

2323
CannotReuseResolution = NoOldProgram | ModuleResolutionOptions | RootNames | TypesOptions | SourceFileRemoved
2424
}
@@ -520,6 +520,9 @@ namespace ts {
520520
const oldSourceFile = oldProgramState.program && oldProgramState.program.getSourceFile(containingFile);
521521
if (oldSourceFile === file) {
522522
// `file` is unchanged from the old program, so we can reuse old module resolutions.
523+
if (isTraceEnabled(options, host)) {
524+
trace(host, Diagnostics.Reusing_module_resolutions_originating_in_0_since_this_file_was_not_modified, file.path);
525+
}
523526
const oldSourceFileResult: ResolvedModuleFull[] = [];
524527
for (const moduleName of moduleNames) {
525528
const resolvedModule = oldSourceFile.resolvedModules.get(moduleName);
@@ -710,10 +713,6 @@ namespace ts {
710713
// tentatively approve the file
711714
modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
712715
}
713-
else {
714-
// file has no changes - use it as is
715-
newSourceFile = oldSourceFile;
716-
}
717716

718717
// if file has passed all checks it should be safe to reuse it
719718
newSourceFiles.push(newSourceFile);

src/harness/unittests/reuseProgramStructure.ts

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,7 @@ namespace ts {
140140
useCaseSensitiveFileNames(): boolean {
141141
return sys && sys.useCaseSensitiveFileNames;
142142
},
143-
getNewLine(): string {
144-
return sys ? sys.newLine : newLine;
145-
},
143+
getNewLine,
146144
fileExists: fileName => files.has(fileName),
147145
readFile: fileName => {
148146
const file = files.get(fileName);
@@ -217,7 +215,7 @@ namespace ts {
217215

218216
describe("Reuse program structure", () => {
219217
const target = ScriptTarget.Latest;
220-
const files = [
218+
const files: NamedSourceText[] = [
221219
{ name: "a.ts", text: SourceText.New(
222220
`
223221
/// <reference path='b.ts'/>
@@ -468,8 +466,73 @@ namespace ts {
468466
"File '/fs.jsx' does not exist.",
469467
"======== Module name 'fs' was not resolved. ========",
470468
], "should look for 'fs' again since node.d.ts was changed");
471-
472469
});
470+
471+
it("can reuse module resolutions from non-modified files", () => {
472+
const files = [
473+
{ name: "a1.ts", text: SourceText.New("", "", "let x = 1;") },
474+
{ name: "a2.ts", text: SourceText.New("", "", "let x = 1;") },
475+
{ name: "b1.ts", text: SourceText.New("", "export class B { x: number; }", "") },
476+
{ name: "b2.ts", text: SourceText.New("", "export class B { x: number; }", "") },
477+
{ name: "node_modules/@types/typerefs1/index.d.ts", text: SourceText.New("", "", "declare let z: string;") },
478+
{ name: "node_modules/@types/typerefs2/index.d.ts", text: SourceText.New("", "", "declare let z: string;") },
479+
{
480+
name: "f1.ts",
481+
text: SourceText.New(
482+
`/// <reference path="a1.ts"/>${newLine}/// <reference types="typerefs1"/>${newLine}/// <reference no-default-lib="true"/>`,
483+
`import { B } from './b1';${newLine}export let BB = B;`,
484+
"declare module './b1' { interface B { y: string; } }")
485+
},
486+
{
487+
name: "f2.ts",
488+
text: SourceText.New(
489+
`/// <reference path="a2.ts"/>${newLine}/// <reference types="typerefs2"/>`,
490+
`import { B } from './b2';${newLine}import { BB } from './f1';`,
491+
"(new BB).x; (new BB).y;")
492+
},
493+
];
494+
495+
const options = { target: ScriptTarget.ES2015, traceResolution: true };
496+
const program_1 = newProgram(files, files.map(f => f.name), options);
497+
assert.deepEqual(program_1.host.getTrace(),
498+
[
499+
"======== Resolving type reference directive 'typerefs1', containing file 'f1.ts', root directory 'node_modules/@types'. ========",
500+
"Resolving with primary search path 'node_modules/@types'.",
501+
"File 'node_modules/@types/typerefs1/package.json' does not exist.",
502+
"File 'node_modules/@types/typerefs1/index.d.ts' exist - use it as a name resolution result.",
503+
"======== Type reference directive 'typerefs1' was successfully resolved to 'node_modules/@types/typerefs1/index.d.ts', primary: true. ========",
504+
"======== Resolving module './b1' from 'f1.ts'. ========",
505+
"Module resolution kind is not specified, using 'Classic'.",
506+
"File 'b1.ts' exist - use it as a name resolution result.",
507+
"======== Module name './b1' was successfully resolved to 'b1.ts'. ========",
508+
"======== Resolving type reference directive 'typerefs2', containing file 'f2.ts', root directory 'node_modules/@types'. ========",
509+
"Resolving with primary search path 'node_modules/@types'.",
510+
"File 'node_modules/@types/typerefs2/package.json' does not exist.",
511+
"File 'node_modules/@types/typerefs2/index.d.ts' exist - use it as a name resolution result.",
512+
"======== Type reference directive 'typerefs2' was successfully resolved to 'node_modules/@types/typerefs2/index.d.ts', primary: true. ========",
513+
"======== Resolving module './b2' from 'f2.ts'. ========",
514+
"Module resolution kind is not specified, using 'Classic'.",
515+
"File 'b2.ts' exist - use it as a name resolution result.",
516+
"======== Module name './b2' was successfully resolved to 'b2.ts'. ========",
517+
"======== Resolving module './f1' from 'f2.ts'. ========",
518+
"Module resolution kind is not specified, using 'Classic'.",
519+
"File 'f1.ts' exist - use it as a name resolution result.",
520+
"======== Module name './f1' was successfully resolved to 'f1.ts'. ========"
521+
],
522+
"First program should execute module reoslution normally.");
523+
524+
// Create project. Edit file-exists to track disk accesses. Edit f1.ts, update project.
525+
// check that updating project "inherits" the fileexists implementation.
526+
const indexOfF1 = 6;
527+
function updateProgram_1(files: NamedSourceText[]): void {
528+
files[indexOfF1].text = SourceText.New("","","");
529+
}
530+
531+
const program_2 = updateProgram(program_1, program_1.getRootFileNames(), options, updateProgram_1);
532+
assert.deepEqual(program_2.host.getTrace(), [
533+
"Module 'fs' was resolved as ambient module declared in '/a/b/node.d.ts' since this file was not modified."
534+
], "should reuse module resolutions in f2 since it is unchanged");
535+
});
473536
});
474537

475538
describe("host is optional", () => {

0 commit comments

Comments
 (0)