From 7f050a1adc5de1efacc8f90d9cf750da00b5818c Mon Sep 17 00:00:00 2001 From: johnsoncodehk Date: Mon, 19 Dec 2022 21:22:39 +0800 Subject: [PATCH] fix: virtual file version override source file version lead to TS plugin always read file text close #2228 --- packages/language-core/src/languageContext.ts | 29 +++++------ .../vue-language-core/src/sourceFile.ts | 49 +++++++++---------- 2 files changed, 38 insertions(+), 40 deletions(-) diff --git a/packages/language-core/src/languageContext.ts b/packages/language-core/src/languageContext.ts index 3f59878e6..287e273da 100644 --- a/packages/language-core/src/languageContext.ts +++ b/packages/language-core/src/languageContext.ts @@ -30,9 +30,10 @@ export function createEmbeddedLanguageServiceHost( const documentRegistry = createDocumentRegistry(); const ts = host.getTypeScriptModule(); - const tsFileVersions = new Map(); const scriptSnapshots = new Map(); - const fileVersions = new Map(); + const sourceTsFileVersions = new Map(); + const sourceVueFileVersions = new Map(); + const virtualFileVersions = new Map(); const _tsHost: Partial = { fileExists: host.fileExists ? fileName => { @@ -135,8 +136,8 @@ export function createEmbeddedLanguageServiceHost( for (const [sourceFile, languageModule] of documentRegistry.getAll()) { remainFileNames.delete(sourceFile.fileName); const newVersion = host.getScriptVersion(sourceFile.fileName); - if (fileVersions.get(sourceFile.fileName) !== newVersion) { - fileVersions.set(sourceFile.fileName, newVersion); + if (sourceVueFileVersions.get(sourceFile.fileName) !== newVersion) { + sourceVueFileVersions.set(sourceFile.fileName, newVersion); const snapshot = host.getScriptSnapshot(sourceFile.fileName); if (snapshot) { // update @@ -163,7 +164,7 @@ export function createEmbeddedLanguageServiceHost( for (const languageModule of languageModules) { const sourceFile = languageModule.createSourceFile(fileName, snapshot); if (sourceFile) { - fileVersions.set(sourceFile.fileName, host.getScriptVersion(fileName)); + sourceVueFileVersions.set(sourceFile.fileName, host.getScriptVersion(fileName)); documentRegistry.set(fileName, reactive(sourceFile), languageModule); remainFileNames.delete(fileName); break; @@ -173,26 +174,26 @@ export function createEmbeddedLanguageServiceHost( } // .ts / .js / .d.ts / .json ... - for (const [oldTsFileName, oldTsFileVersion] of [...tsFileVersions]) { + for (const [oldTsFileName, oldTsFileVersion] of [...sourceTsFileVersions]) { const newVersion = host.getScriptVersion(oldTsFileName); if (oldTsFileVersion !== newVersion) { if (!remainFileNames.has(oldTsFileName) && !host.getScriptSnapshot(oldTsFileName)) { // delete - tsFileVersions.delete(oldTsFileName); + sourceTsFileVersions.delete(oldTsFileName); } else { // update - tsFileVersions.set(oldTsFileName, newVersion); + sourceTsFileVersions.set(oldTsFileName, newVersion); } tsFileUpdated = true; } } for (const nowFileName of remainFileNames) { - if (!tsFileVersions.has(nowFileName)) { + if (!sourceTsFileVersions.has(nowFileName)) { // add const newVersion = host.getScriptVersion(nowFileName); - tsFileVersions.set(nowFileName, newVersion); + sourceTsFileVersions.set(nowFileName, newVersion); tsFileUpdated = true; } } @@ -200,7 +201,7 @@ export function createEmbeddedLanguageServiceHost( for (const [sourceFile, languageModule, snapshot] of sourceFilesToUpdate) { forEachEmbeddeds(sourceFile, embedded => { - fileVersions.delete(embedded.fileName); + virtualFileVersions.delete(embedded.fileName); }); const oldScripts: Record = {}; @@ -262,8 +263,8 @@ export function createEmbeddedLanguageServiceHost( function getScriptVersion(fileName: string) { let mapped = documentRegistry.fromEmbeddedFileName(fileName); if (mapped) { - if (fileVersions.has(mapped.embedded.fileName)) { - return fileVersions.get(mapped.embedded.fileName)!; + if (virtualFileVersions.has(mapped.embedded.fileName)) { + return virtualFileVersions.get(mapped.embedded.fileName)!; } else { let version = ts.sys?.createHash?.(mapped.embedded.text) ?? mapped.embedded.text; @@ -271,7 +272,7 @@ export function createEmbeddedLanguageServiceHost( // fix https://github.com/johnsoncodehk/volar/issues/1082 version = host.getScriptVersion(mapped.sourceFile.fileName) + ':' + version; } - fileVersions.set(mapped.embedded.fileName, version); + virtualFileVersions.set(mapped.embedded.fileName, version); return version; } } diff --git a/vue-language-tools/vue-language-core/src/sourceFile.ts b/vue-language-tools/vue-language-core/src/sourceFile.ts index cfc3bcedd..fd030c81e 100644 --- a/vue-language-tools/vue-language-core/src/sourceFile.ts +++ b/vue-language-tools/vue-language-core/src/sourceFile.ts @@ -349,35 +349,19 @@ export class VueSourceFile implements SourceFile { return blocks; }); - get kind(): EmbeddedFileKind { - return EmbeddedFileKind.TextFile; - } + kind = EmbeddedFileKind.TextFile; - get capabilities(): DocumentCapabilities { - return { - diagnostic: true, - foldingRange: true, - documentFormatting: true, - documentSymbol: true, - codeAction: true, - inlayHint: true, - }; - } + capabilities: DocumentCapabilities = { + diagnostic: true, + foldingRange: true, + documentFormatting: true, + documentSymbol: true, + codeAction: true, + inlayHint: true, + }; get mappings(): Mapping[] { - return [{ - sourceRange: [0, this._snapshot.value.getLength()], - generatedRange: [0, this._snapshot.value.getLength()], - data: { - hover: true, - references: true, - definition: true, - rename: true, - completion: true, - diagnostic: true, - semanticTokens: true, - }, - }]; + return this._mappings.value; } get text() { @@ -398,6 +382,19 @@ export class VueSourceFile implements SourceFile { // refs _snapshot: Ref; + _mappings = computed[]>(() => [{ + sourceRange: [0, this._snapshot.value.getLength()], + generatedRange: [0, this._snapshot.value.getLength()], + data: { + hover: true, + references: true, + definition: true, + rename: true, + completion: true, + diagnostic: true, + semanticTokens: true, + }, + }]); _allEmbeddeds = ref<{ file: VueEmbeddedFile; text: string;