mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-03 18:39:09 -05:00
Cache the latest source file from document registry so we can keep it alive when script info is orphan
This commit is contained in:
@@ -93,6 +93,12 @@ namespace ts {
|
||||
reportStats(): string;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface ExternalDocumentCache {
|
||||
setDocument(key: DocumentRegistryBucketKey, path: Path, sourceFile: SourceFile): void;
|
||||
getDocument(key: DocumentRegistryBucketKey, path: Path): SourceFile | undefined;
|
||||
}
|
||||
|
||||
export type DocumentRegistryBucketKey = string & { __bucketKey: any };
|
||||
|
||||
interface DocumentRegistryEntry {
|
||||
@@ -102,10 +108,14 @@ namespace ts {
|
||||
// language services are referencing the file, then the file can be removed from the
|
||||
// registry.
|
||||
languageServiceRefCount: number;
|
||||
owners: string[];
|
||||
}
|
||||
|
||||
export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory = ""): DocumentRegistry {
|
||||
export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean, currentDirectory?: string): DocumentRegistry {
|
||||
return createDocumentRegistryInternal(useCaseSensitiveFileNames, currentDirectory);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function createDocumentRegistryInternal(useCaseSensitiveFileNames?: boolean, currentDirectory = "", externalCache?: ExternalDocumentCache): DocumentRegistry {
|
||||
// Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
|
||||
// for those settings.
|
||||
const buckets = createMap<Map<DocumentRegistryEntry>>();
|
||||
@@ -126,12 +136,11 @@ namespace ts {
|
||||
function reportStats() {
|
||||
const bucketInfoArray = arrayFrom(buckets.keys()).filter(name => name && name.charAt(0) === "_").map(name => {
|
||||
const entries = buckets.get(name);
|
||||
const sourceFiles: { name: string; refCount: number; references: string[]; }[] = [];
|
||||
const sourceFiles: { name: string; refCount: number; }[] = [];
|
||||
entries.forEach((entry, name) => {
|
||||
sourceFiles.push({
|
||||
name,
|
||||
refCount: entry.languageServiceRefCount,
|
||||
references: entry.owners.slice(0)
|
||||
refCount: entry.languageServiceRefCount
|
||||
});
|
||||
});
|
||||
sourceFiles.sort((x, y) => y.refCount - x.refCount);
|
||||
@@ -176,14 +185,26 @@ namespace ts {
|
||||
const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true);
|
||||
let entry = bucket.get(path);
|
||||
const scriptTarget = scriptKind === ScriptKind.JSON ? ScriptTarget.JSON : compilationSettings.target;
|
||||
if (!entry && externalCache) {
|
||||
const sourceFile = externalCache.getDocument(key, path);
|
||||
if (sourceFile) {
|
||||
entry = {
|
||||
sourceFile,
|
||||
languageServiceRefCount: 1
|
||||
};
|
||||
bucket.set(path, entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
// Have never seen this file with these settings. Create a new source file for it.
|
||||
const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, /*setNodeParents*/ false, scriptKind);
|
||||
|
||||
if (externalCache) {
|
||||
externalCache.setDocument(key, path, sourceFile);
|
||||
}
|
||||
entry = {
|
||||
sourceFile,
|
||||
languageServiceRefCount: 1,
|
||||
owners: []
|
||||
};
|
||||
bucket.set(path, entry);
|
||||
}
|
||||
@@ -194,6 +215,9 @@ namespace ts {
|
||||
if (entry.sourceFile.version !== version) {
|
||||
entry.sourceFile = updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version,
|
||||
scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot));
|
||||
if (externalCache) {
|
||||
externalCache.setDocument(key, path, entry.sourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
// If we're acquiring, then this is the first time this LS is asking for this document.
|
||||
|
||||
Reference in New Issue
Block a user