Skip to content

Commit 5739b68

Browse files
committed
Do not create map just to store empty reference files. Also update file as changed if file text is same but it had invalidated resolution
1 parent de28d02 commit 5739b68

File tree

3 files changed

+76
-36
lines changed

3 files changed

+76
-36
lines changed

src/compiler/builder.ts

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ namespace ts {
4848
addScriptInfo(program: Program, sourceFile: SourceFile): void;
4949
removeScriptInfo(path: Path): void;
5050
updateScriptInfo(program: Program, sourceFile: SourceFile): void;
51+
updaterScriptInfoWithSameVersion(program: Program, sourceFile: SourceFile): boolean;
5152
/**
5253
* Gets the files affected by the script info which has updated shape from the known one
5354
*/
@@ -143,11 +144,15 @@ namespace ts {
143144
}
144145

145146
function updateExistingFileInfo(program: Program, existingInfo: FileInfo, sourceFile: SourceFile, hasInvalidatedResolution: HasInvalidatedResolution) {
146-
if (existingInfo.version !== sourceFile.version || hasInvalidatedResolution(sourceFile.path)) {
147+
if (existingInfo.version !== sourceFile.version) {
147148
registerChangedFile(sourceFile.path, sourceFile.fileName);
148149
existingInfo.version = sourceFile.version;
149150
emitHandler.updateScriptInfo(program, sourceFile);
150151
}
152+
else if (hasInvalidatedResolution(sourceFile.path) &&
153+
emitHandler.updaterScriptInfoWithSameVersion(program, sourceFile)) {
154+
registerChangedFile(sourceFile.path, sourceFile.fileName);
155+
}
151156
}
152157

153158
function ensureProgramGraph(program: Program) {
@@ -338,8 +343,8 @@ namespace ts {
338343
/**
339344
* Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
340345
*/
341-
function getReferencedFiles(program: Program, sourceFile: SourceFile): Map<true> {
342-
const referencedFiles = createMap<true>();
346+
function getReferencedFiles(program: Program, sourceFile: SourceFile): Map<true> | undefined {
347+
let referencedFiles: Map<true> | undefined;
343348

344349
// We need to use a set here since the code can contain the same import twice,
345350
// but that will only be one dependency.
@@ -351,7 +356,7 @@ namespace ts {
351356
if (symbol && symbol.declarations && symbol.declarations[0]) {
352357
const declarationSourceFile = getSourceFileOfNode(symbol.declarations[0]);
353358
if (declarationSourceFile) {
354-
referencedFiles.set(declarationSourceFile.path, true);
359+
addReferencedFile(declarationSourceFile.path);
355360
}
356361
}
357362
}
@@ -362,7 +367,7 @@ namespace ts {
362367
if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
363368
for (const referencedFile of sourceFile.referencedFiles) {
364369
const referencedPath = toPath(referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
365-
referencedFiles.set(referencedPath, true);
370+
addReferencedFile(referencedPath);
366371
}
367372
}
368373

@@ -375,11 +380,18 @@ namespace ts {
375380

376381
const fileName = resolvedTypeReferenceDirective.resolvedFileName;
377382
const typeFilePath = toPath(fileName, sourceFileDirectory, getCanonicalFileName);
378-
referencedFiles.set(typeFilePath, true);
383+
addReferencedFile(typeFilePath);
379384
});
380385
}
381386

382387
return referencedFiles;
388+
389+
function addReferencedFile(referencedPath: Path) {
390+
if (!referencedFiles) {
391+
referencedFiles = createMap<true>();
392+
}
393+
referencedFiles.set(referencedPath, true);
394+
}
383395
}
384396

385397
/**
@@ -402,6 +414,7 @@ namespace ts {
402414
addScriptInfo: noop,
403415
removeScriptInfo: noop,
404416
updateScriptInfo: noop,
417+
updaterScriptInfoWithSameVersion: returnFalse,
405418
getFilesAffectedByUpdatedShape
406419
};
407420

@@ -421,12 +434,45 @@ namespace ts {
421434
return {
422435
addScriptInfo: setReferences,
423436
removeScriptInfo,
424-
updateScriptInfo: setReferences,
437+
updateScriptInfo: updateReferences,
438+
updaterScriptInfoWithSameVersion: updateReferencesTrackingChangedReferences,
425439
getFilesAffectedByUpdatedShape
426440
};
427441

428442
function setReferences(program: Program, sourceFile: SourceFile) {
429-
references.set(sourceFile.path, getReferencedFiles(program, sourceFile));
443+
const newReferences = getReferencedFiles(program, sourceFile);
444+
if (newReferences) {
445+
references.set(sourceFile.path, getReferencedFiles(program, sourceFile));
446+
}
447+
}
448+
449+
function updateReferences(program: Program, sourceFile: SourceFile) {
450+
const newReferences = getReferencedFiles(program, sourceFile);
451+
if (newReferences) {
452+
references.set(sourceFile.path, newReferences);
453+
}
454+
else {
455+
references.delete(sourceFile.path);
456+
}
457+
}
458+
459+
function updateReferencesTrackingChangedReferences(program: Program, sourceFile: SourceFile) {
460+
const newReferences = getReferencedFiles(program, sourceFile);
461+
if (!newReferences) {
462+
// Changed if we had references
463+
return references.delete(sourceFile.path);
464+
}
465+
466+
const oldReferences = references.get(sourceFile.path);
467+
references.set(sourceFile.path, newReferences);
468+
if (!oldReferences || oldReferences.size !== newReferences.size) {
469+
return true;
470+
}
471+
472+
// If there are any new references that werent present previously there is change
473+
return forEachEntry(newReferences, (_true, referencedPath) => !oldReferences.delete(referencedPath)) ||
474+
// Otherwise its changed if there are more references previously than now
475+
!!oldReferences.size;
430476
}
431477

432478
function removeScriptInfo(removedFilePath: Path) {

src/compiler/utilities.ts

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3513,34 +3513,28 @@ namespace ts {
35133513
* Mutates the map with newMap such that keys in map will be same as newMap.
35143514
*/
35153515
export function mutateMap<T, U>(map: Map<T>, newMap: ReadonlyMap<U>, options: MutateMapOptions<T, U>) {
3516-
// If there are new values update them
3517-
if (newMap) {
3518-
const { createNewValue, onDeleteValue, onExistingValue } = options;
3519-
// Needs update
3520-
map.forEach((existingValue, key) => {
3521-
const valueInNewMap = newMap.get(key);
3522-
// Not present any more in new map, remove it
3523-
if (valueInNewMap === undefined) {
3524-
map.delete(key);
3525-
onDeleteValue(existingValue, key);
3526-
}
3527-
// If present notify about existing values
3528-
else if (onExistingValue) {
3529-
onExistingValue(existingValue, valueInNewMap, key);
3530-
}
3531-
});
3516+
const { createNewValue, onDeleteValue, onExistingValue } = options;
3517+
// Needs update
3518+
map.forEach((existingValue, key) => {
3519+
const valueInNewMap = newMap.get(key);
3520+
// Not present any more in new map, remove it
3521+
if (valueInNewMap === undefined) {
3522+
map.delete(key);
3523+
onDeleteValue(existingValue, key);
3524+
}
3525+
// If present notify about existing values
3526+
else if (onExistingValue) {
3527+
onExistingValue(existingValue, valueInNewMap, key);
3528+
}
3529+
});
35323530

3533-
// Add new values that are not already present
3534-
newMap.forEach((valueInNewMap, key) => {
3535-
if (!map.has(key)) {
3536-
// New values
3537-
map.set(key, createNewValue(key, valueInNewMap));
3538-
}
3539-
});
3540-
}
3541-
else {
3542-
clearMap(map, options.onDeleteValue);
3543-
}
3531+
// Add new values that are not already present
3532+
newMap.forEach((valueInNewMap, key) => {
3533+
if (!map.has(key)) {
3534+
// New values
3535+
map.set(key, createNewValue(key, valueInNewMap));
3536+
}
3537+
});
35443538
}
35453539

35463540
/**

src/harness/unittests/tsserverProjectSystem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5275,7 +5275,7 @@ namespace ts.projectSystem {
52755275
watchedRecursiveDirectories.length = 2;
52765276
verifyProject();
52775277

5278-
const changedFiles = limitHit ? [file1.path, file2.path, file3.path, libFile.path] : [file1.path, file2.path];
5278+
const changedFiles = [file1.path, file2.path];
52795279
verifyProjectChangedEventHandler([{
52805280
eventName: server.ProjectChangedEvent,
52815281
data: {

0 commit comments

Comments
 (0)