From 28f6a85c571262567f1e80c074d0ed4b2ed0b0ed Mon Sep 17 00:00:00 2001 From: Shun Wang <103867940+wangshunnn@users.noreply.github.com> Date: Sun, 7 Apr 2024 21:01:34 +0800 Subject: [PATCH] fix(typescript): transform source file for tsc without `incremental` (#162) * fix(typescript): transform source file for tsc without `incremental` refs https://github.com/vuejs/language-tools/issues/4099 --------- Co-authored-by: Johnson Chu --- packages/typescript/lib/node/decorateProgram.ts | 12 ++++-------- packages/typescript/lib/node/transform.ts | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/typescript/lib/node/decorateProgram.ts b/packages/typescript/lib/node/decorateProgram.ts index 3893b199..d3d3eaa0 100644 --- a/packages/typescript/lib/node/decorateProgram.ts +++ b/packages/typescript/lib/node/decorateProgram.ts @@ -1,7 +1,7 @@ import type { Language } from '@volar/language-core'; import type * as ts from 'typescript'; -import { getServiceScript, notEmpty } from './utils'; -import { transformDiagnostic } from './transform'; +import { notEmpty } from './utils'; +import { transformDiagnostic, fillSourceFileText } from './transform'; export function decorateProgram(language: Language, program: ts.Program) { @@ -48,15 +48,11 @@ export function decorateProgram(language: Language, program: ts.Program) { .filter(notEmpty); }; - // fix https://github.com/vuejs/language-tools/issues/4099 + // fix https://github.com/vuejs/language-tools/issues/4099 with `incremental` program.getSourceFileByPath = path => { const sourceFile = getSourceFileByPath(path); if (sourceFile) { - const [serviceScript, sourceScript] = getServiceScript(language, sourceFile.fileName); - if (serviceScript) { - sourceFile.text = sourceScript.snapshot.getText(0, sourceScript.snapshot.getLength()) - + sourceFile.text.substring(sourceScript.snapshot.getLength()); - } + fillSourceFileText(language, sourceFile); } return sourceFile; }; diff --git a/packages/typescript/lib/node/transform.ts b/packages/typescript/lib/node/transform.ts index 626a451d..514f69cc 100644 --- a/packages/typescript/lib/node/transform.ts +++ b/packages/typescript/lib/node/transform.ts @@ -3,6 +3,7 @@ import type * as ts from 'typescript'; import { getServiceScript, notEmpty } from './utils'; const transformedDiagnostics = new WeakMap(); +const transformedSourceFile = new WeakSet(); export function transformCallHierarchyItem(language: Language, item: ts.CallHierarchyItem, filter: (data: CodeInformation) => boolean): ts.CallHierarchyItem { const span = transformSpan(language, item.file, item.span, filter); @@ -34,6 +35,7 @@ export function transformDiagnostic(language: Language, if (serviceScript) { const sourceSpan = transformTextSpan(sourceScript, map, { start: diagnostic.start, length: diagnostic.length }, shouldReportDiagnostics); if (sourceSpan) { + fillSourceFileText(language, diagnostic.file); transformedDiagnostics.set(diagnostic, { ...diagnostic, start: sourceSpan.start, @@ -52,6 +54,20 @@ export function transformDiagnostic(language: Language, return transformedDiagnostics.get(diagnostic) as T | undefined; } +// fix https://github.com/vuejs/language-tools/issues/4099 without `incremental` +export function fillSourceFileText(language: Language, sourceFile: ts.SourceFile) { + if (transformedSourceFile.has(sourceFile)) { + return; + } + transformedSourceFile.add(sourceFile); + const [serviceScript, sourceScript] = getServiceScript(language, sourceFile.fileName); + if (serviceScript) { + sourceFile.text = sourceScript.snapshot.getText(0, sourceScript.snapshot.getLength()) + + sourceFile.text.substring(sourceScript.snapshot.getLength()); + } + return; +} + export function transformFileTextChanges(language: Language, changes: ts.FileTextChanges, filter: (data: CodeInformation) => boolean): ts.FileTextChanges | undefined { const [_, source] = getServiceScript(language, changes.fileName); if (source) {