From 547d92631e968463ea828fa7033ce496ae3c352a Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Mon, 11 Oct 2021 11:39:12 +0200 Subject: [PATCH] getExtensionPathIndex indexes extensions by URI, not just fsPath, fixes https://github.com/microsoft/vscode/issues/134602 --- .../api/common/extHostExtensionService.ts | 39 ++++++++++++------- .../api/common/extHostRequireInterceptor.ts | 10 ++--- .../extensions/common/extensionHostMain.ts | 2 +- .../services/extensions/node/proxyResolver.ts | 2 +- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index 6694151cd09..ad89e7f0f3d 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -37,6 +37,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { IExtensionActivationHost, checkActivateWorkspaceContainsExtension } from 'vs/workbench/api/common/shared/workspaceContains'; import { ExtHostSecretState, IExtHostSecretState } from 'vs/workbench/api/common/exHostSecretState'; import { ExtensionSecrets } from 'vs/workbench/api/common/extHostSecrets'; +import { Schemas } from 'vs/base/common/network'; interface ITestRunner { /** Old test runner API, as exported from `vscode/lib/testrunner` */ @@ -101,7 +102,7 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme private readonly _secretState: ExtHostSecretState; private readonly _storagePath: IExtensionStoragePaths; private readonly _activator: ExtensionsActivator; - private _extensionPathIndex: Promise> | null; + private _extensionPathIndex: Promise> | null; private readonly _resolvers: { [authorityPrefix: string]: vscode.RemoteAuthorityResolver; }; @@ -259,17 +260,29 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme } } + /** + * Applies realpath to file-uris and returns all others uris unmodified + */ + private async _realPathExtensionUri(uri: URI): Promise { + if (uri.scheme !== Schemas.file) { + return uri; + } + const realpathValue = await this._hostUtils.realpath(uri.fsPath); + return URI.file(realpathValue); + } + // create trie to enable fast 'filename -> extension id' look up - public getExtensionPathIndex(): Promise> { + public getExtensionPathIndex(): Promise> { if (!this._extensionPathIndex) { - const tree = TernarySearchTree.forPaths(); - const extensions = this._registry.getAllExtensionDescriptions().map(ext => { + const tst = TernarySearchTree.forUris(); + const extensions = this._registry.getAllExtensionDescriptions().map(async ext => { if (!this._getEntryPoint(ext)) { - return undefined; + return; } - return this._hostUtils.realpath(ext.extensionLocation.fsPath).then(value => tree.set(URI.file(value).fsPath, ext)); + const uri = await this._realPathExtensionUri(ext.extensionLocation); + tst.set(uri, ext); }); - this._extensionPathIndex = Promise.all(extensions).then(() => tree); + this._extensionPathIndex = Promise.all(extensions).then(() => tst); } return this._extensionPathIndex; } @@ -757,16 +770,14 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme await Promise.all(toRemove.map(async (extensionId) => { const extensionDescription = this._registry.getExtensionDescription(extensionId); - if (!extensionDescription) { - return; + if (extensionDescription) { + trie.delete(await this._realPathExtensionUri(extensionDescription.extensionLocation)); } - const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath); - trie.delete(URI.file(realpathValue).fsPath); })); await Promise.all(toAdd.map(async (extensionDescription) => { - const realpathValue = await this._hostUtils.realpath(extensionDescription.extensionLocation.fsPath); - trie.set(URI.file(realpathValue).fsPath, extensionDescription); + const realpathUri = await this._realPathExtensionUri(extensionDescription.extensionLocation); + trie.set(realpathUri, extensionDescription); })); this._registry.deltaExtensions(toAdd, toRemove); @@ -839,7 +850,7 @@ export interface IExtHostExtensionService extends AbstractExtHostExtensionServic deactivateAll(): Promise; getExtensionExports(extensionId: ExtensionIdentifier): IExtensionAPI | null | undefined; getExtensionRegistry(): Promise; - getExtensionPathIndex(): Promise>; + getExtensionPathIndex(): Promise>; registerRemoteAuthorityResolver(authorityPrefix: string, resolver: vscode.RemoteAuthorityResolver): vscode.Disposable; onDidChangeRemoteConnectionData: Event; diff --git a/src/vs/workbench/api/common/extHostRequireInterceptor.ts b/src/vs/workbench/api/common/extHostRequireInterceptor.ts index f59d41ce891..b6609ed24a7 100644 --- a/src/vs/workbench/api/common/extHostRequireInterceptor.ts +++ b/src/vs/workbench/api/common/extHostRequireInterceptor.ts @@ -93,7 +93,7 @@ class VSCodeNodeModuleFactory implements INodeModuleFactory { constructor( private readonly _apiFactory: IExtensionApiFactory, - private readonly _extensionPaths: TernarySearchTree, + private readonly _extensionPaths: TernarySearchTree, private readonly _extensionRegistry: ExtensionDescriptionRegistry, private readonly _configProvider: ExtHostConfigProvider, private readonly _logService: ILogService, @@ -103,7 +103,7 @@ class VSCodeNodeModuleFactory implements INodeModuleFactory { public load(_request: string, parent: URI): any { // get extension id from filename and api for extension - const ext = this._extensionPaths.findSubstr(parent.fsPath); + const ext = this._extensionPaths.findSubstr(parent); if (ext) { let apiImpl = this._extApiImpl.get(ExtensionIdentifier.toKey(ext.identifier)); if (!apiImpl) { @@ -117,7 +117,7 @@ class VSCodeNodeModuleFactory implements INodeModuleFactory { if (!this._defaultApiImpl) { let extensionPathsPretty = ''; this._extensionPaths.forEach((value, index) => extensionPathsPretty += `\t${index} -> ${value.identifier.value}\n`); - this._logService.warn(`Could not identify extension for 'vscode' require call from ${parent.fsPath}. These are the extension path mappings: \n${extensionPathsPretty}`); + this._logService.warn(`Could not identify extension for 'vscode' require call from ${parent}. These are the extension path mappings: \n${extensionPathsPretty}`); this._defaultApiImpl = this._apiFactory(nullExtensionDescription, this._extensionRegistry, this._configProvider); } return this._defaultApiImpl; @@ -232,7 +232,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory { private _mainThreadTelemetry: MainThreadTelemetryShape; constructor( - private readonly _extensionPaths: TernarySearchTree, + private readonly _extensionPaths: TernarySearchTree, private readonly _appUriScheme: string, @IExtHostRpcService rpcService: IExtHostRpcService, ) { @@ -257,7 +257,7 @@ class OpenNodeModuleFactory implements INodeModuleFactory { public load(request: string, parent: URI, original: LoadFunction): any { // get extension id from filename and api for extension - const extension = this._extensionPaths.findSubstr(parent.fsPath); + const extension = this._extensionPaths.findSubstr(parent); if (extension) { this._extensionId = extension.identifier.value; this.sendShimmingTelemetry(); diff --git a/src/vs/workbench/services/extensions/common/extensionHostMain.ts b/src/vs/workbench/services/extensions/common/extensionHostMain.ts index 0120d4dcdd9..9e5551bccb4 100644 --- a/src/vs/workbench/services/extensions/common/extensionHostMain.ts +++ b/src/vs/workbench/services/extensions/common/extensionHostMain.ts @@ -91,7 +91,7 @@ export class ExtensionHostMain { stackTraceMessage += `\n\tat ${call.toString()}`; fileName = call.getFileName(); if (!extension && fileName) { - extension = map.findSubstr(fileName); + extension = map.findSubstr(URI.file(fileName)); } } diff --git a/src/vs/workbench/services/extensions/node/proxyResolver.ts b/src/vs/workbench/services/extensions/node/proxyResolver.ts index 23ece190437..e4b4985aa02 100644 --- a/src/vs/workbench/services/extensions/node/proxyResolver.ts +++ b/src/vs/workbench/services/extensions/node/proxyResolver.ts @@ -122,7 +122,7 @@ function configureModuleLoading(extensionService: ExtHostExtensionService, looku } const modules = lookup[request]; - const ext = extensionPaths.findSubstr(URI.file(parent.filename).fsPath); + const ext = extensionPaths.findSubstr(URI.file(parent.filename)); let cache = modulesCache.get(ext); if (!cache) { modulesCache.set(ext, cache = {});