11// Copyright (c) Microsoft Corporation. All rights reserved.
22// Licensed under the MIT License.
33import { inject , injectable } from 'inversify' ;
4+ import * as path from 'path' ;
5+ import { IFileSystem } from '../common/platform/types' ;
46import { IExtensions } from '../common/types' ;
57import * as localize from '../common/utils/localize' ;
8+ import { EXTENSION_ROOT_DIR } from '../constants' ;
9+ import { JupyterUriProviderWrapper } from './jupyterUriProviderWrapper' ;
610import {
711 IJupyterServerUri ,
812 IJupyterUriProvider ,
@@ -13,20 +17,23 @@ import {
1317@injectable ( )
1418export class JupyterUriProviderRegistration implements IJupyterUriProviderRegistration {
1519 private loadedOtherExtensionsPromise : Promise < void > | undefined ;
16- private providers = new Map < string , IJupyterUriProvider > ( ) ;
20+ private providers = new Map < string , Promise < IJupyterUriProvider > > ( ) ;
1721
18- constructor ( @inject ( IExtensions ) private readonly extensions : IExtensions ) { }
22+ constructor (
23+ @inject ( IExtensions ) private readonly extensions : IExtensions ,
24+ @inject ( IFileSystem ) private readonly fileSystem : IFileSystem
25+ ) { }
1926
2027 public async getProviders ( ) : Promise < ReadonlyArray < IJupyterUriProvider > > {
2128 await this . checkOtherExtensions ( ) ;
2229
2330 // Other extensions should have registered in their activate callback
24- return [ ...this . providers . values ( ) ] ;
31+ return Promise . all ( [ ...this . providers . values ( ) ] ) ;
2532 }
2633
2734 public registerProvider ( provider : IJupyterUriProvider ) {
2835 if ( ! this . providers . has ( provider . id ) ) {
29- this . providers . set ( provider . id , provider ) ;
36+ this . providers . set ( provider . id , this . createProvider ( provider ) ) ;
3037 } else {
3138 throw new Error ( `IJupyterUriProvider already exists with id ${ provider . id } ` ) ;
3239 }
@@ -35,8 +42,9 @@ export class JupyterUriProviderRegistration implements IJupyterUriProviderRegist
3542 public async getJupyterServerUri ( id : string , handle : JupyterServerUriHandle ) : Promise < IJupyterServerUri > {
3643 await this . checkOtherExtensions ( ) ;
3744
38- const provider = this . providers . get ( id ) ;
39- if ( provider ) {
45+ const providerPromise = this . providers . get ( id ) ;
46+ if ( providerPromise ) {
47+ const provider = await providerPromise ;
4048 return provider . getServerUri ( handle ) ;
4149 }
4250 throw new Error ( localize . DataScience . unknownServerUri ( ) ) ;
@@ -55,4 +63,44 @@ export class JupyterUriProviderRegistration implements IJupyterUriProviderRegist
5563 . map ( ( e ) => ( e . isActive ? Promise . resolve ( ) : e . activate ( ) ) ) ;
5664 await Promise . all ( list ) ;
5765 }
66+
67+ private async createProvider ( provider : IJupyterUriProvider ) : Promise < IJupyterUriProvider > {
68+ const packageName = await this . determineExtensionFromCallstack ( ) ;
69+ return new JupyterUriProviderWrapper ( provider , packageName ) ;
70+ }
71+
72+ private async determineExtensionFromCallstack ( ) : Promise < string > {
73+ const stack = new Error ( ) . stack ;
74+ if ( stack ) {
75+ const root = EXTENSION_ROOT_DIR . toLowerCase ( ) ;
76+ const frames = stack . split ( '\n' ) . map ( ( f ) => {
77+ const result = / \( ( .* ) \) / . exec ( f ) ;
78+ if ( result ) {
79+ return result [ 1 ] ;
80+ }
81+ } ) ;
82+ for ( const frame of frames ) {
83+ if ( frame && ! frame . startsWith ( root ) ) {
84+ // This file is from a different extension. Try to find its package.json
85+ let dirName = path . dirname ( frame ) ;
86+ let last = frame ;
87+ while ( dirName && dirName . length < last . length ) {
88+ const possiblePackageJson = path . join ( dirName , 'package.json' ) ;
89+ if ( await this . fileSystem . fileExists ( possiblePackageJson ) ) {
90+ const text = await this . fileSystem . readFile ( possiblePackageJson ) ;
91+ try {
92+ const json = JSON . parse ( text ) ;
93+ return `${ json . publisher } .${ json . name } ` ;
94+ } catch {
95+ // If parse fails, then not the extension
96+ }
97+ }
98+ last = dirName ;
99+ dirName = path . dirname ( dirName ) ;
100+ }
101+ }
102+ }
103+ }
104+ return localize . DataScience . unknownPackage ( ) ;
105+ }
58106}
0 commit comments