Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure removed extraLibs are not used in tsWorker #4544

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions src/language/typescript/tsWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the prefix will always be file://. I think you can pass any URI (as a string) to addExtraLib, including with a different scheme, or with file as a scheme, but with a hostname (i.e. file://some-host/some/path.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the catch @tomprince , sorry it took so long for me to revisit this.

I've made changes in 6505802 to address your comment

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));
}

Expand Down Expand Up @@ -450,6 +479,9 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork
}

async updateExtraLibs(extraLibs: IExtraLibs): Promise<void> {
this._removedExtraLibs.push(
...Object.entries(this._extraLibs).map(([uri, lib]) => ({ uri, version: lib.version }))
);
this._extraLibs = extraLibs;
}

Expand Down
Loading