Make sure we pass TS server the transformed project root (#173096)

When opening a file, we pass TS Server a project root to prevent it from scanning too many files. On web, we need to pass the transformed project root, not the original uri

This PR also removes some confusingly duplicated methods and renames them to make their behavior more clear
This commit is contained in:
Matt Bierner
2023-02-02 03:30:04 -08:00
committed by GitHub
parent 86b34fdd9e
commit 69b6f978f6
36 changed files with 76 additions and 96 deletions

View File

@@ -26,7 +26,7 @@ class TypeScriptCallHierarchySupport implements vscode.CallHierarchyProvider {
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.CallHierarchyItem | vscode.CallHierarchyItem[] | undefined> {
const filepath = this.client.toOpenedFilePath(document);
const filepath = this.client.toOpenTsFilePath(document);
if (!filepath) {
return undefined;
}
@@ -43,7 +43,7 @@ class TypeScriptCallHierarchySupport implements vscode.CallHierarchyProvider {
}
public async provideCallHierarchyIncomingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyIncomingCall[] | undefined> {
const filepath = this.client.toPath(item.uri);
const filepath = this.client.toTsFilePath(item.uri);
if (!filepath) {
return undefined;
}
@@ -58,7 +58,7 @@ class TypeScriptCallHierarchySupport implements vscode.CallHierarchyProvider {
}
public async provideCallHierarchyOutgoingCalls(item: vscode.CallHierarchyItem, token: vscode.CancellationToken): Promise<vscode.CallHierarchyOutgoingCall[] | undefined> {
const filepath = this.client.toPath(item.uri);
const filepath = this.client.toTsFilePath(item.uri);
if (!filepath) {
return undefined;
}

View File

@@ -41,7 +41,7 @@ export abstract class TypeScriptBaseCodeLensProvider implements vscode.CodeLensP
async provideCodeLenses(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<ReferencesCodeLens[]> {
const filepath = this.client.toOpenedFilePath(document);
const filepath = this.client.toOpenTsFilePath(document);
if (!filepath) {
return [];
}

View File

@@ -171,7 +171,7 @@ class MyCompletionItem extends vscode.CompletionItem {
const requestToken = new vscode.CancellationTokenSource();
const promise = (async (): Promise<ResolvedCompletionItem | undefined> => {
const filepath = client.toOpenedFilePath(this.document);
const filepath = client.toOpenTsFilePath(this.document);
if (!filepath) {
return undefined;
}
@@ -701,7 +701,7 @@ class TypeScriptCompletionItemProvider implements vscode.CompletionItemProvider<
});
}
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return undefined;
}

View File

@@ -19,7 +19,7 @@ export default class TypeScriptDefinitionProviderBase {
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.Location[] | undefined> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return undefined;
}

View File

@@ -17,7 +17,7 @@ export default class TypeScriptDefinitionProvider extends DefinitionProviderBase
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.DefinitionLink[] | vscode.Definition | undefined> {
const filepath = this.client.toOpenedFilePath(document);
const filepath = this.client.toOpenTsFilePath(document);
if (!filepath) {
return undefined;
}

View File

@@ -46,7 +46,7 @@ class DirectiveCommentCompletionProvider implements vscode.CompletionItemProvide
position: vscode.Position,
_token: vscode.CancellationToken
): vscode.CompletionItem[] {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return [];
}

View File

@@ -19,7 +19,7 @@ class TypeScriptDocumentHighlightProvider implements vscode.DocumentHighlightPro
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.DocumentHighlight[]> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return [];
}

View File

@@ -41,7 +41,7 @@ class TypeScriptDocumentSymbolProvider implements vscode.DocumentSymbolProvider
) { }
public async provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentSymbol[] | undefined> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return undefined;
}

View File

@@ -68,7 +68,7 @@ export default class FileConfigurationManager extends Disposable {
options: vscode.FormattingOptions,
token: vscode.CancellationToken
): Promise<void> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return;
}

View File

@@ -40,7 +40,7 @@ class FileReferencesCommand implements Command {
return;
}
const openedFiledPath = this.client.toOpenedFilePath(document);
const openedFiledPath = this.client.toOpenTsFilePath(document);
if (!openedFiledPath) {
vscode.window.showErrorMessage(vscode.l10n.t("Find file references failed. Unknown file type."));
return;

View File

@@ -213,7 +213,7 @@ class TypeScriptAutoFixProvider implements vscode.CodeActionProvider {
return undefined;
}
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return undefined;
}

View File

@@ -21,7 +21,7 @@ class TypeScriptFoldingProvider implements vscode.FoldingRangeProvider {
_context: vscode.FoldingContext,
token: vscode.CancellationToken
): Promise<vscode.FoldingRange[] | undefined> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return;
}

View File

@@ -24,7 +24,7 @@ class TypeScriptFormattingProvider implements vscode.DocumentRangeFormattingEdit
options: vscode.FormattingOptions,
token: vscode.CancellationToken
): Promise<vscode.TextEdit[] | undefined> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return undefined;
}
@@ -47,7 +47,7 @@ class TypeScriptFormattingProvider implements vscode.DocumentRangeFormattingEdit
options: vscode.FormattingOptions,
token: vscode.CancellationToken
): Promise<vscode.TextEdit[]> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return [];
}

View File

@@ -26,7 +26,7 @@ class TypeScriptHoverProvider implements vscode.HoverProvider {
position: vscode.Position,
token: vscode.CancellationToken
): Promise<vscode.Hover | undefined> {
const filepath = this.client.toOpenedFilePath(document);
const filepath = this.client.toOpenTsFilePath(document);
if (!filepath) {
return undefined;
}

View File

@@ -55,7 +55,7 @@ class TypeScriptInlayHintsProvider extends Disposable implements vscode.InlayHin
}
async provideInlayHints(model: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise<vscode.InlayHint[]> {
const filepath = this.client.toOpenedFilePath(model);
const filepath = this.client.toOpenTsFilePath(model);
if (!filepath) {
return [];
}

View File

@@ -49,7 +49,7 @@ class JsDocCompletionProvider implements vscode.CompletionItemProvider {
return undefined;
}
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return undefined;
}

View File

@@ -76,7 +76,7 @@ class OrganizeImportsCommand implements Command {
const resource = activeEditor.document.uri;
const document = await vscode.workspace.openTextDocument(resource);
const openedFiledPath = this.client.toOpenedFilePath(document);
const openedFiledPath = this.client.toOpenTsFilePath(document);
if (!openedFiledPath) {
vscode.window.showErrorMessage(vscode.l10n.t("Organize Imports failed. Unknown file type."));
return;
@@ -128,7 +128,7 @@ class ImportsCodeActionProvider implements vscode.CodeActionProvider {
context: vscode.CodeActionContext,
token: vscode.CancellationToken
): vscode.CodeAction[] {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return [];
}

View File

@@ -228,7 +228,7 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider<VsCodeCode
context: vscode.CodeActionContext,
token: vscode.CancellationToken
): Promise<VsCodeCodeAction[] | undefined> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return;
}

View File

@@ -80,7 +80,7 @@ class SelectRefactorCommand implements Command {
) { }
public async execute(args: SelectRefactorCommand_Args): Promise<void> {
const file = this.client.toOpenedFilePath(args.document);
const file = this.client.toOpenTsFilePath(args.document);
if (!file) {
return;
}
@@ -192,7 +192,7 @@ class InlinedCodeAction extends vscode.CodeAction {
public renameLocation?: Proto.Location;
public async resolve(token: vscode.CancellationToken): Promise<undefined> {
const file = this.client.toOpenedFilePath(this.document);
const file = this.client.toOpenTsFilePath(this.document);
if (!file) {
return;
}
@@ -285,12 +285,12 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider<TsCodeActi
if (!this.shouldTrigger(context, rangeOrSelection)) {
return undefined;
}
if (!this.client.toOpenedFilePath(document)) {
if (!this.client.toOpenTsFilePath(document)) {
return undefined;
}
const response = await this.client.interruptGetErr(() => {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return undefined;
}

View File

@@ -19,7 +19,7 @@ class TypeScriptReferenceSupport implements vscode.ReferenceProvider {
options: vscode.ReferenceContext,
token: vscode.CancellationToken
): Promise<vscode.Location[]> {
const filepath = this.client.toOpenedFilePath(document);
const filepath = this.client.toOpenTsFilePath(document);
if (!filepath) {
return [];
}

View File

@@ -75,7 +75,7 @@ class TypeScriptRenameProvider implements vscode.RenameProvider {
position: vscode.Position,
token: vscode.CancellationToken
): Promise<ServerResponse.Response<Proto.RenameResponse> | undefined> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return undefined;
}

View File

@@ -37,7 +37,7 @@ class DocumentSemanticTokensProvider implements vscode.DocumentSemanticTokensPro
}
public async provideDocumentSemanticTokens(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.SemanticTokens | null> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file || document.getText().length > CONTENT_LENGTH_LIMIT) {
return null;
}
@@ -45,7 +45,7 @@ class DocumentSemanticTokensProvider implements vscode.DocumentSemanticTokensPro
}
public async provideDocumentRangeSemanticTokens(document: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): Promise<vscode.SemanticTokens | null> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file || (document.offsetAt(range.end) - document.offsetAt(range.start) > CONTENT_LENGTH_LIMIT)) {
return null;
}
@@ -56,7 +56,7 @@ class DocumentSemanticTokensProvider implements vscode.DocumentSemanticTokensPro
}
private async provideSemanticTokens(document: vscode.TextDocument, requestArg: Proto.EncodedSemanticClassificationsRequestArgs, token: vscode.CancellationToken): Promise<vscode.SemanticTokens | null> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return null;
}

View File

@@ -26,7 +26,7 @@ class TypeScriptSignatureHelpProvider implements vscode.SignatureHelpProvider {
token: vscode.CancellationToken,
context: vscode.SignatureHelpContext,
): Promise<vscode.SignatureHelp | undefined> {
const filepath = this.client.toOpenedFilePath(document);
const filepath = this.client.toOpenTsFilePath(document);
if (!filepath) {
return undefined;
}

View File

@@ -23,7 +23,7 @@ class SmartSelection implements vscode.SelectionRangeProvider {
positions: vscode.Position[],
token: vscode.CancellationToken,
): Promise<vscode.SelectionRange[] | undefined> {
const file = this.client.toOpenedFilePath(document);
const file = this.client.toOpenTsFilePath(document);
if (!file) {
return undefined;
}

View File

@@ -41,7 +41,7 @@ class SourceDefinitionCommand implements Command {
return;
}
const openedFiledPath = this.client.toOpenedFilePath(document);
const openedFiledPath = this.client.toOpenTsFilePath(document);
if (!openedFiledPath) {
vscode.window.showErrorMessage(vscode.l10n.t("Go to Source Definition failed. Unknown file type."));
return;

View File

@@ -58,7 +58,7 @@ class TagClosing extends Disposable {
return;
}
const filepath = this.client.toOpenedFilePath(document);
const filepath = this.client.toOpenTsFilePath(document);
if (!filepath) {
return;
}

View File

@@ -57,12 +57,12 @@ class UpdateImportsOnFileRenameHandler extends Disposable {
this._register(vscode.workspace.onDidRenameFiles(async (e) => {
const [{ newUri, oldUri }] = e.files;
const newFilePath = this.client.toPath(newUri);
const newFilePath = this.client.toTsFilePath(newUri);
if (!newFilePath) {
return;
}
const oldFilePath = this.client.toPath(oldUri);
const oldFilePath = this.client.toTsFilePath(oldUri);
if (!oldFilePath) {
return;
}
@@ -76,7 +76,7 @@ class UpdateImportsOnFileRenameHandler extends Disposable {
// Try to get a js/ts file that is being moved
// For directory moves, this returns a js/ts file under the directory.
const jsTsFileThatIsBeingMoved = await this.getJsTsFileBeingMoved(newUri);
if (!jsTsFileThatIsBeingMoved || !this.client.toPath(jsTsFileThatIsBeingMoved)) {
if (!jsTsFileThatIsBeingMoved || !this.client.toTsFilePath(jsTsFileThatIsBeingMoved)) {
return;
}

View File

@@ -80,13 +80,13 @@ class TypeScriptWorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvide
const path = vscode.Uri.file(JSON.parse(document.uri.query)?.path);
if (doesResourceLookLikeATypeScriptFile(path) || doesResourceLookLikeAJavaScriptFile(path)) {
const document = await vscode.workspace.openTextDocument(path);
return this.client.toOpenedFilePath(document);
return this.client.toOpenTsFilePath(document);
}
} catch {
// noop
}
}
return this.client.toOpenedFilePath(document);
return this.client.toOpenTsFilePath(document);
}
private toSymbolInformation(item: Proto.NavtoItem) {

View File

@@ -73,9 +73,7 @@ export function lazilyActivateClient(
// Force activation
void lazyClientHost.value;
disposables.push(new ManagedFileContextManager(activeJsTsEditorTracker, resource => {
return lazyClientHost.value.serviceClient.toPath(resource);
}));
disposables.push(new ManagedFileContextManager(activeJsTsEditorTracker));
});
return true;

View File

@@ -198,7 +198,7 @@ class TscTaskProvider extends Disposable implements vscode.TaskProvider {
if (editor) {
const document = editor.document;
if (document && (document.languageId === 'typescript' || document.languageId === 'typescriptreact')) {
return this.client.value.toPath(document.uri);
return this.client.value.toTsFilePath(document.uri);
}
}
return undefined;

View File

@@ -316,7 +316,7 @@ class GetErrRequest {
const supportsSyntaxGetErr = this.client.apiVersion.gte(API.v440);
const allFiles = coalesce(Array.from(files.entries)
.filter(entry => supportsSyntaxGetErr || client.hasCapabilityForResource(entry.resource, ClientCapability.Semantic))
.map(entry => client.normalizedPath(entry.resource)));
.map(entry => client.toTsFilePath(entry.resource)));
if (!allFiles.length) {
this._done = true;
@@ -479,7 +479,7 @@ export default class BufferSyncSupport extends Disposable {
this.diagnosticDelayer = new Delayer<any>(300);
const pathNormalizer = (path: vscode.Uri) => this.client.normalizedPath(path);
const pathNormalizer = (path: vscode.Uri) => this.client.toTsFilePath(path);
this.syncedBuffers = new SyncedBufferMap(pathNormalizer, { onCaseInsensitiveFileSystem });
this.pendingDiagnostics = new PendingDiagnostics(pathNormalizer, { onCaseInsensitiveFileSystem });
this.synchronizer = new BufferSynchronizer(client, pathNormalizer, onCaseInsensitiveFileSystem);
@@ -553,7 +553,7 @@ export default class BufferSyncSupport extends Disposable {
}
public toVsCodeResource(resource: vscode.Uri): vscode.Uri {
const filepath = this.client.normalizedPath(resource);
const filepath = this.client.toTsFilePath(resource);
for (const buffer of this.syncedBuffers.allBuffers) {
if (buffer.filepath === filepath) {
return buffer.resource;
@@ -588,7 +588,7 @@ export default class BufferSyncSupport extends Disposable {
return false;
}
const resource = document.uri;
const filepath = this.client.normalizedPath(resource);
const filepath = this.client.toTsFilePath(resource);
if (!filepath) {
return false;
}

View File

@@ -129,19 +129,11 @@ export class ClientCapabilities {
}
export interface ITypeScriptServiceClient {
/**
* Convert a resource (VS Code) to a normalized path (TypeScript).
*
* Does not try handling case insensitivity.
*/
normalizedPath(resource: vscode.Uri): string | undefined;
/**
* Map a resource to a normalized path
*
* This will attempt to handle case insensitivity.
* Convert a (VS Code) resource to a path that TypeScript server understands.
*/
toPath(resource: vscode.Uri): string | undefined;
toTsFilePath(resource: vscode.Uri): string | undefined;
/**
* Convert a path to a resource.
@@ -153,7 +145,7 @@ export interface ITypeScriptServiceClient {
*
* @return The normalized path or `undefined` if the document is not open on the server.
*/
toOpenedFilePath(document: vscode.TextDocument, options?: {
toOpenTsFilePath(document: vscode.TextDocument, options?: {
suppressAlertOnFailure?: boolean;
}): string | undefined;

View File

@@ -93,7 +93,6 @@ namespace ServerState {
export default class TypeScriptServiceClient extends Disposable implements ITypeScriptServiceClient {
private readonly pathSeparator: string;
private readonly emptyAuthority = 'ts-nul-authority';
private readonly inMemoryResourcePrefix = '^';
@@ -150,7 +149,6 @@ export default class TypeScriptServiceClient extends Disposable implements IType
this.versionProvider = services.versionProvider;
this.processFactory = services.processFactory;
this.pathSeparator = path.sep;
this.lastStart = Date.now();
let resolve: () => void;
@@ -678,20 +676,18 @@ export default class TypeScriptServiceClient extends Disposable implements IType
}
}
public normalizedPath(resource: vscode.Uri): string | undefined {
public toTsFilePath(resource: vscode.Uri): string | undefined {
if (fileSchemes.disabledSchemes.has(resource.scheme)) {
return undefined;
}
if (resource.scheme === fileSchemes.file && !isWeb()) {
let result = resource.fsPath;
if (!result) {
if (!resource.fsPath) {
return undefined;
}
result = path.normalize(result);
// Both \ and / must be escaped in regular expressions
return result.replace(new RegExp('\\' + this.pathSeparator, 'g'), '/');
// Convert to posix style path
return path.posix.normalize(resource.fsPath.split(path.sep).join(path.posix.sep));
}
return (this.isProjectWideIntellisenseOnWebEnabled() ? '' : this.inMemoryResourcePrefix)
@@ -701,18 +697,15 @@ export default class TypeScriptServiceClient extends Disposable implements IType
+ (resource.fragment ? '#' + resource.fragment : '');
}
public toPath(resource: vscode.Uri): string | undefined {
return this.normalizedPath(resource);
}
public toOpenedFilePath(document: vscode.TextDocument, options: { suppressAlertOnFailure?: boolean } = {}): string | undefined {
public toOpenTsFilePath(document: vscode.TextDocument, options: { suppressAlertOnFailure?: boolean } = {}): string | undefined {
if (!this.bufferSyncSupport.ensureHasBuffer(document.uri)) {
if (!options.suppressAlertOnFailure && !fileSchemes.disabledSchemes.has(document.uri.scheme)) {
console.error(`Unexpected resource ${document.uri}`);
}
return undefined;
}
return this.toPath(document.uri);
return this.toTsFilePath(document.uri);
}
public hasCapabilityForResource(resource: vscode.Uri, capability: ClientCapability): boolean {
@@ -767,23 +760,22 @@ export default class TypeScriptServiceClient extends Disposable implements IType
return undefined;
}
switch (resource.scheme) {
case fileSchemes.file:
case fileSchemes.untitled:
case fileSchemes.vscodeNotebookCell:
case fileSchemes.memFs:
case fileSchemes.vscodeVfs:
case fileSchemes.officeScript:
for (const root of roots.sort((a, b) => a.uri.fsPath.length - b.uri.fsPath.length)) {
if (resource.fsPath.startsWith(root.uri.fsPath + path.sep)) {
return root.uri.fsPath;
}
let tsRootPath: string | undefined;
for (const root of roots.sort((a, b) => a.uri.fsPath.length - b.uri.fsPath.length)) {
if (root.uri.scheme === resource.scheme && root.uri.authority === resource.authority) {
if (resource.fsPath.startsWith(root.uri.fsPath + path.sep)) {
tsRootPath = this.toTsFilePath(root.uri);
break;
}
return roots[0].uri.fsPath;
default:
return undefined;
}
}
tsRootPath ??= this.toTsFilePath(roots[0].uri);
if (!tsRootPath || tsRootPath.startsWith(this.inMemoryResourcePrefix)) {
return undefined;
}
return tsRootPath;
}
public execute(command: keyof TypeScriptRequests, args: any, token: vscode.CancellationToken, config?: ExecConfig): Promise<ServerResponse.Response<Proto.Response>> {

View File

@@ -102,7 +102,7 @@ export class IntellisenseStatus extends Disposable {
return;
}
const file = this._client.toOpenedFilePath(doc, { suppressAlertOnFailure: true });
const file = this._client.toOpenTsFilePath(doc, { suppressAlertOnFailure: true });
if (!file) {
this.updateState(IntellisenseState.None);
return;

View File

@@ -6,6 +6,7 @@
import * as vscode from 'vscode';
import { ActiveJsTsEditorTracker } from './activeJsTsEditorTracker';
import { Disposable } from './dispose';
import { disabledSchemes } from './fileSchemes';
import { isJsConfigOrTsConfigFileName } from './languageDescription';
import { isSupportedLanguageMode } from './languageIds';
@@ -17,10 +18,7 @@ export default class ManagedFileContextManager extends Disposable {
private isInManagedFileContext: boolean = false;
public constructor(
activeJsTsEditorTracker: ActiveJsTsEditorTracker,
private readonly normalizePath: (resource: vscode.Uri) => string | undefined,
) {
public constructor(activeJsTsEditorTracker: ActiveJsTsEditorTracker) {
super();
activeJsTsEditorTracker.onDidChangeActiveJsTsEditor(this.onDidChangeActiveTextEditor, this, this._disposables);
@@ -49,7 +47,7 @@ export default class ManagedFileContextManager extends Disposable {
}
private isManagedScriptFile(editor: vscode.TextEditor): boolean {
return isSupportedLanguageMode(editor.document) && this.normalizePath(editor.document.uri) !== null;
return isSupportedLanguageMode(editor.document) && !disabledSchemes.has(editor.document.uri.scheme);
}
private isManagedConfigFile(editor: vscode.TextEditor): boolean {

View File

@@ -149,9 +149,9 @@ export async function openProjectConfigForFile(
return;
}
const file = client.toPath(resource);
const file = client.toTsFilePath(resource);
// TSServer errors when 'projectInfo' is invoked on a non js/ts file
if (!file || !await client.toPath(resource)) {
if (!file || !client.toTsFilePath(resource)) {
vscode.window.showWarningMessage(
vscode.l10n.t("Could not determine TypeScript or JavaScript project. Unsupported file type"));
return;