From 3b8a68a6898a464918e666c471e11308117adbc9 Mon Sep 17 00:00:00 2001 From: liyancheng2 Date: Sun, 17 Aug 2025 17:33:50 +0800 Subject: [PATCH] handle already released source files that don't match scriptKind Issue: https://gitee.com/openharmony/third_party_typescript/issues/ICTBZU Signed-off-by: liyancheng2 Change-Id: I84f329a6823561b8c9c1d85da66f2938f4a8b836 --- lib/tsserver.js | 8 +++++++- lib/tsserverlibrary.js | 8 +++++++- lib/typescript.js | 8 +++++++- src/services/services.ts | 8 +++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/tsserver.js b/lib/tsserver.js index 3ae3145064..f94d186b67 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -126699,9 +126699,13 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h onUnRecoverableConfigFileDiagnostic: noop }; const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings); + let releasedScriptKinds = new Set2(); PerformanceDotting.start("isProgramUptoDate"); if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), (fileName) => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { PerformanceDotting.stop("isProgramUptoDate"); + compilerHost = void 0; + parsedCommandLines = void 0; + releasedScriptKinds = void 0; host.clearFileCache && host.clearFileCache(); return; } @@ -126731,6 +126735,7 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h } compilerHost = void 0; parsedCommandLines = void 0; + releasedScriptKinds = void 0; sourceMapper.clearCache(); program.getTypeChecker(); host.clearFileCache && host.clearFileCache(); @@ -126784,10 +126789,11 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h if (!shouldCreateNewSourceFile) { const oldSourceFile = program && program.getSourceFileByPath(path); if (oldSourceFile) { - if (scriptKind === oldSourceFile.scriptKind) { + if (scriptKind === oldSourceFile.scriptKind || releasedScriptKinds.has(oldSourceFile.resolvedPath)) { return documentRegistry.updateDocumentWithKey(fileName, path, host, documentRegistryBucketKey, scriptSnapshot, scriptVersion, scriptKind, languageVersionOrOptions); } else { documentRegistry.releaseDocumentWithKey(oldSourceFile.resolvedPath, documentRegistry.getKeyForCompilationSettings(program.getCompilerOptions()), oldSourceFile.scriptKind, oldSourceFile.impliedNodeFormat); + releasedScriptKinds.add(oldSourceFile.resolvedPath); } } } diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 96d913c93d..205a60d1a0 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -123921,9 +123921,13 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h onUnRecoverableConfigFileDiagnostic: noop }; const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings); + let releasedScriptKinds = new Set2(); PerformanceDotting.start("isProgramUptoDate"); if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), (fileName) => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { PerformanceDotting.stop("isProgramUptoDate"); + compilerHost = void 0; + parsedCommandLines = void 0; + releasedScriptKinds = void 0; host.clearFileCache && host.clearFileCache(); return; } @@ -123953,6 +123957,7 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h } compilerHost = void 0; parsedCommandLines = void 0; + releasedScriptKinds = void 0; sourceMapper.clearCache(); program.getTypeChecker(); host.clearFileCache && host.clearFileCache(); @@ -124006,10 +124011,11 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h if (!shouldCreateNewSourceFile) { const oldSourceFile = program && program.getSourceFileByPath(path); if (oldSourceFile) { - if (scriptKind === oldSourceFile.scriptKind) { + if (scriptKind === oldSourceFile.scriptKind || releasedScriptKinds.has(oldSourceFile.resolvedPath)) { return documentRegistry.updateDocumentWithKey(fileName, path, host, documentRegistryBucketKey, scriptSnapshot, scriptVersion, scriptKind, languageVersionOrOptions); } else { documentRegistry.releaseDocumentWithKey(oldSourceFile.resolvedPath, documentRegistry.getKeyForCompilationSettings(program.getCompilerOptions()), oldSourceFile.scriptKind, oldSourceFile.impliedNodeFormat); + releasedScriptKinds.add(oldSourceFile.resolvedPath); } } } diff --git a/lib/typescript.js b/lib/typescript.js index 68ffd2ed23..51f4b9ed69 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -124323,9 +124323,13 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h onUnRecoverableConfigFileDiagnostic: noop }; const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings); + let releasedScriptKinds = new Set2(); PerformanceDotting.start("isProgramUptoDate"); if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), (fileName) => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { PerformanceDotting.stop("isProgramUptoDate"); + compilerHost = void 0; + parsedCommandLines = void 0; + releasedScriptKinds = void 0; host.clearFileCache && host.clearFileCache(); return; } @@ -124355,6 +124359,7 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h } compilerHost = void 0; parsedCommandLines = void 0; + releasedScriptKinds = void 0; sourceMapper.clearCache(); program.getTypeChecker(); host.clearFileCache && host.clearFileCache(); @@ -124408,10 +124413,11 @@ function createLanguageService(host, documentRegistry = createDocumentRegistry(h if (!shouldCreateNewSourceFile) { const oldSourceFile = program && program.getSourceFileByPath(path); if (oldSourceFile) { - if (scriptKind === oldSourceFile.scriptKind) { + if (scriptKind === oldSourceFile.scriptKind || releasedScriptKinds.has(oldSourceFile.resolvedPath)) { return documentRegistry.updateDocumentWithKey(fileName, path, host, documentRegistryBucketKey, scriptSnapshot, scriptVersion, scriptKind, languageVersionOrOptions); } else { documentRegistry.releaseDocumentWithKey(oldSourceFile.resolvedPath, documentRegistry.getKeyForCompilationSettings(program.getCompilerOptions()), oldSourceFile.scriptKind, oldSourceFile.impliedNodeFormat); + releasedScriptKinds.add(oldSourceFile.resolvedPath); } } } diff --git a/src/services/services.ts b/src/services/services.ts index e1c70f6393..dd9b9f72a7 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1727,11 +1727,15 @@ export function createLanguageService( // calculate this early so it's not undefined if downleveled to a var (or, if emitted // as a const variable without downleveling, doesn't crash). const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings); + let releasedScriptKinds: Set | undefined = new Set(); // If the program is already up-to-date, we can reuse it PerformanceDotting.start("isProgramUptoDate"); if (isProgramUptoDate(program, rootFileNames, newSettings, (_path, fileName) => host.getScriptVersion(fileName), fileName => compilerHost!.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) { PerformanceDotting.stop("isProgramUptoDate"); + compilerHost = undefined; + parsedCommandLines = undefined; + releasedScriptKinds = undefined; // During incremental compilation, executing isProgramUptoDate to check for program updates generates file caches; // clear these caches to avoid affecting future compilations. host.clearFileCache && host.clearFileCache(); @@ -1775,6 +1779,7 @@ export function createLanguageService( // After this point, the cache needs to be cleared to allow all collected snapshots to be released compilerHost = undefined; parsedCommandLines = undefined; + releasedScriptKinds = undefined; // We reset this cache on structure invalidation so we don't hold on to outdated files for long; however we can't use the `compilerHost` above, // Because it only functions until `hostCache` is cleared, while we'll potentially need the functionality to lazily read sourcemap files during @@ -1881,12 +1886,13 @@ export function createLanguageService( // We do not support the scenario where a host can modify a registered // file's script kind, i.e. in one project some file is treated as ".ts" // and in another as ".js" - if (scriptKind === oldSourceFile.scriptKind) { + if (scriptKind === oldSourceFile.scriptKind || releasedScriptKinds!.has(oldSourceFile.resolvedPath)) { return documentRegistry.updateDocumentWithKey(fileName, path, host, documentRegistryBucketKey, scriptSnapshot, scriptVersion, scriptKind, languageVersionOrOptions); } else { // Release old source file and fall through to aquire new file with new script kind documentRegistry.releaseDocumentWithKey(oldSourceFile.resolvedPath, documentRegistry.getKeyForCompilationSettings(program.getCompilerOptions()), oldSourceFile.scriptKind, oldSourceFile.impliedNodeFormat); + releasedScriptKinds!.add(oldSourceFile.resolvedPath); } } -- Gitee