From f0c242d08364098bad30c09b651aa46756488390 Mon Sep 17 00:00:00 2001 From: Justin Carrus Date: Sat, 1 Jun 2024 11:46:15 -0700 Subject: [PATCH 1/2] fix: Ensure removed extraLibs are not used in tsWorker --- src/language/typescript/tsWorker.ts | 36 +++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/language/typescript/tsWorker.ts b/src/language/typescript/tsWorker.ts index c4f7d3eb..750f4124 100644 --- a/src/language/typescript/tsWorker.ts +++ b/src/language/typescript/tsWorker.ts @@ -37,6 +37,8 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork private _ctx: worker.IWorkerContext; private _extraLibs: IExtraLibs = Object.create(null); + /** Extra libs may have been opened as models, so we track previously removed libs to ensure they are not considered */ + private _removedExtraLibs: { uri: string; version: number }[] = []; private _languageService = ts.createLanguageService(this); private _compilerOptions: ts.CompilerOptions; private _inlayHintsOptions?: ts.UserPreferences; @@ -63,8 +65,35 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork } getScriptFileNames(): string[] { - const allModels = this._ctx.getMirrorModels().map((model) => model.uri); - const models = allModels.filter((uri) => !fileNameIsLib(uri)).map((uri) => uri.toString()); + const allModels = this._ctx.getMirrorModels(); + const models = allModels + // remove default libs + .filter((model) => !fileNameIsLib(model.uri)) + // remove extra libs and previously removed libs + // Note that is is required for all model names to be unique, so + // while the logic here depends on the end user not creating extra + // libs with conflicting filenames, that is already a requirement. + .filter((model) => { + const uriAsString = model.uri.toString(); + // if the extra lib was not given a name, then it gets an autogenerated name prefixed with ts:extralib- + if (uriAsString.startsWith('ts:extralib-')) { + return false; + } + // Otherwise, the prefix will be file:/// and the name will be what the user provided to add/setExtraLibs + if ( + this._removedExtraLibs.some( + (removed) => + `file:///${removed.uri}` === uriAsString && removed.version === model.version + ) + ) { + return false; + } + if (this._extraLibs[uriAsString.replace(/^file:\/\/\//, '')]?.version === model.version) { + return false; + } + return true; + }) + .map((model) => model.uri.toString()); return models.concat(Object.keys(this._extraLibs)); } @@ -450,6 +479,9 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork } async updateExtraLibs(extraLibs: IExtraLibs): Promise { + this._removedExtraLibs.push( + ...Object.entries(this._extraLibs).map(([uri, lib]) => ({ uri, version: lib.version })) + ); this._extraLibs = extraLibs; } From 65058029d893ef15a829fc396b484c2b44038ca0 Mon Sep 17 00:00:00 2001 From: Justin Carrus Date: Fri, 27 Sep 2024 19:08:39 -0700 Subject: [PATCH 2/2] Rework based on PR feedback for schemas --- src/language/typescript/tsWorker.ts | 35 ++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/language/typescript/tsWorker.ts b/src/language/typescript/tsWorker.ts index 750f4124..3ec352b8 100644 --- a/src/language/typescript/tsWorker.ts +++ b/src/language/typescript/tsWorker.ts @@ -69,26 +69,39 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork const models = allModels // remove default libs .filter((model) => !fileNameIsLib(model.uri)) - // remove extra libs and previously removed libs - // Note that is is required for all model names to be unique, so - // while the logic here depends on the end user not creating extra - // libs with conflicting filenames, that is already a requirement. + // remove extra libs .filter((model) => { - const uriAsString = model.uri.toString(); - // if the extra lib was not given a name, then it gets an autogenerated name prefixed with ts:extralib- - if (uriAsString.startsWith('ts:extralib-')) { + const modelUri = model.uri.toString(); + if (this._extraLibs[modelUri]) { return false; } - // Otherwise, the prefix will be file:/// and the name will be what the user provided to add/setExtraLibs + // Extra libs passed with no schema get a file:/// prefix from the model but not in the _extraLibs map + if ( + modelUri.startsWith('file:///') && + this._extraLibs[modelUri.replace('file:///', '')]?.version + ) { + return false; + } + return true; + }) + // remove previously removed libs + .filter((model) => { + const modelUri = model.uri.toString(); if ( this._removedExtraLibs.some( - (removed) => - `file:///${removed.uri}` === uriAsString && removed.version === model.version + (removed) => removed.uri === modelUri && removed.version === model.version ) ) { return false; } - if (this._extraLibs[uriAsString.replace(/^file:\/\/\//, '')]?.version === model.version) { + // if the extra lib was passed with no schema, it gets a file:/// prefix from the model + if ( + modelUri.startsWith('file:///') && + this._removedExtraLibs.some( + (removed) => + removed.uri === modelUri.replace('file:///', '') && removed.version === model.version + ) + ) { return false; } return true;