@@ -10,9 +10,11 @@ import { URITransformer, IRawURITransformer, transformOutgoingURIs } from "vs/ba
1010import { IServerChannel } from "vs/base/parts/ipc/common/ipc" ;
1111import { IDiagnosticInfo } from "vs/platform/diagnostics/common/diagnosticsService" ;
1212import { IEnvironmentService } from "vs/platform/environment/common/environment" ;
13+ import { IExtensionDescription , ExtensionIdentifier } from "vs/platform/extensions/common/extensions" ;
1314import { FileDeleteOptions , FileOverwriteOptions , FileType , IStat , IWatchOptions , FileOpenOptions } from "vs/platform/files/common/files" ;
1415import { ILogService } from "vs/platform/log/common/log" ;
1516import { IRemoteAgentEnvironment } from "vs/platform/remote/common/remoteAgentEnvironment" ;
17+ import { ExtensionScanner , ExtensionScannerInput } from "vs/workbench/services/extensions/node/extensionPoints" ;
1618import { DiskFileSystemProvider } from "vs/workbench/services/files/node/diskFileSystemProvider" ;
1719
1820/**
@@ -157,17 +159,20 @@ export class FileProviderChannel implements IServerChannel {
157159 * See: src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts.
158160 */
159161export class ExtensionEnvironmentChannel implements IServerChannel {
160- public constructor ( private readonly environment : IEnvironmentService ) { }
162+ public constructor (
163+ private readonly environment : IEnvironmentService ,
164+ private readonly log : ILogService ,
165+ ) { }
161166
162167 public listen ( _ : unknown , event : string ) : Event < any > {
163168 throw new Error ( `Invalid listen "${ event } "` ) ;
164169 }
165170
166- public async call ( context : any , command : string , _args ?: any ) : Promise < any > {
171+ public async call ( context : any , command : string , args ?: any ) : Promise < any > {
167172 switch ( command ) {
168173 case "getEnvironmentData" :
169174 return transformOutgoingURIs (
170- await this . getEnvironmentData ( ) ,
175+ await this . getEnvironmentData ( args . language ) ,
171176 getUriTransformer ( context . remoteAuthority ) ,
172177 ) ;
173178 case "getDiagnosticInfo" : return this . getDiagnosticInfo ( ) ;
@@ -176,22 +181,73 @@ export class ExtensionEnvironmentChannel implements IServerChannel {
176181 throw new Error ( `Invalid call "${ command } "` ) ;
177182 }
178183
179- private async getEnvironmentData ( ) : Promise < IRemoteAgentEnvironment > {
184+ private async getEnvironmentData ( locale : string ) : Promise < IRemoteAgentEnvironment > {
180185 return {
181186 pid : process . pid ,
182187 appRoot : URI . file ( this . environment . appRoot ) ,
183188 appSettingsHome : this . environment . appSettingsHome ,
184189 settingsPath : this . environment . machineSettingsHome ,
185190 logsPath : URI . file ( this . environment . logsPath ) ,
186191 extensionsPath : URI . file ( this . environment . extensionsPath ) ,
187- extensionHostLogsPath : URI . file ( path . join ( this . environment . logsPath , "extension-host" ) ) , // TODO
192+ extensionHostLogsPath : URI . file ( path . join ( this . environment . logsPath , "extension-host" ) ) ,
188193 globalStorageHome : URI . file ( this . environment . globalStorageHome ) ,
189194 userHome : URI . file ( this . environment . userHome ) ,
190- extensions : [ ] , // TODO
195+ extensions : await this . scanExtensions ( locale ) ,
191196 os : OS ,
192197 } ;
193198 }
194199
200+ private async scanExtensions ( locale : string ) : Promise < IExtensionDescription [ ] > {
201+ const root = getPathFromAmdModule ( require , "" ) ;
202+ const pkg = require . __$__nodeRequire ( path . resolve ( root , "../package.json" ) ) as any ;
203+
204+ const translations = { } ; // TODO: translations
205+
206+ // TODO: there is also this.environment.extensionDevelopmentLocationURI to look into.
207+ const scanBuiltin = async ( ) : Promise < IExtensionDescription [ ] > => {
208+ const input = new ExtensionScannerInput (
209+ pkg . version , pkg . commit , locale , ! ! process . env . VSCODE_DEV ,
210+ path . resolve ( root , "../extensions" ) ,
211+ true ,
212+ false ,
213+ translations ,
214+ ) ;
215+ const extensions = await ExtensionScanner . scanExtensions ( input , this . log ) ;
216+ // TODO: there is more to do if process.env.VSCODE_DEV is true.
217+ return extensions ;
218+ } ;
219+
220+ const scanInstalled = async ( ) : Promise < IExtensionDescription [ ] > => {
221+ const input = new ExtensionScannerInput (
222+ pkg . version , pkg . commit , locale , ! ! process . env . VSCODE_DEV ,
223+ this . environment . extensionsPath , false , true , translations ,
224+ ) ;
225+ return ExtensionScanner . scanExtensions ( input , this . log ) ;
226+ } ;
227+
228+ return Promise . all ( [ scanBuiltin ( ) , scanInstalled ( ) ] ) . then ( ( allExtensions ) => {
229+ // It's possible to get duplicates.
230+ const uniqueExtensions = new Map < string , IExtensionDescription > ( ) ;
231+ allExtensions . forEach ( ( extensions ) => {
232+ extensions . forEach ( ( extension ) => {
233+ const id = ExtensionIdentifier . toKey ( extension . identifier ) ;
234+ if ( uniqueExtensions . has ( id ) ) {
235+ const oldPath = uniqueExtensions . get ( id ) ! . extensionLocation . fsPath ;
236+ const newPath = extension . extensionLocation . fsPath ;
237+ this . log . warn (
238+ `Extension ${ id } in ${ oldPath } has been overridden ${ newPath } ` ,
239+ ) ;
240+ }
241+ uniqueExtensions . set ( id , extension ) ;
242+ } ) ;
243+ } ) ;
244+
245+ const finalExtensions = < IExtensionDescription [ ] > [ ] ;
246+ uniqueExtensions . forEach ( ( e ) => finalExtensions . push ( e ) ) ;
247+ return finalExtensions ;
248+ } ) ;
249+ }
250+
195251 private getDiagnosticInfo ( ) : Promise < IDiagnosticInfo > {
196252 throw new Error ( "not implemented" ) ;
197253 }
0 commit comments