77import * as nls from 'vs/nls' ;
88import Severity from 'vs/base/common/severity' ;
99import { TPromise } from 'vs/base/common/winjs.base' ;
10- import { IExtensionDescription , IExtensionService , IExtensionsStatus , ExtensionPointContribution } from 'vs/platform/extensions/common/extensions' ;
11- import { IExtensionPoint } from 'vs/platform/extensions/common/extensionsRegistry' ;
10+ import { IExtensionDescription , IExtensionsStatus } from 'vs/platform/extensions/common/extensions' ;
1211
1312const hasOwnProperty = Object . hasOwnProperty ;
1413
@@ -30,107 +29,65 @@ interface IActivatingExtensionMap {
3029
3130const NO_OP_VOID_PROMISE = TPromise . as < void > ( void 0 ) ;
3231
33- export abstract class AbstractExtensionService < T extends ActivatedExtension > implements IExtensionService {
34- public _serviceBrand : any ;
32+ export interface IExtensionsManagerHost < T extends ActivatedExtension > {
33+ showMessage ( severity : Severity , message : string ) : void ;
3534
36- private _activatingExtensions : IActivatingExtensionMap ;
37- protected _activatedExtensions : IActivatedExtensionMap < T > ;
38- private _onReady : TPromise < boolean > ;
39- private _onReadyC : ( v : boolean ) => void ;
40- private _isReady : boolean ;
41- protected _registry : ExtensionDescriptionRegistry ;
35+ createFailedExtension ( ) : T ;
36+
37+ actualActivateExtension ( extensionDescription : IExtensionDescription ) : TPromise < T > ;
38+ }
4239
40+ export class ExtensionsManager < T extends ActivatedExtension > {
41+
42+ private readonly _registry : ExtensionDescriptionRegistry ;
43+ private readonly _host : IExtensionsManagerHost < T > ;
44+ private readonly _activatingExtensions : IActivatingExtensionMap ;
45+ private readonly _activatedExtensions : IActivatedExtensionMap < T > ;
4346 /**
4447 * A map of already activated events to speed things up if the same activation event is triggered multiple times.
4548 */
46- private _alreadyActivatedEvents : { [ activationEvent : string ] : boolean ; } ;
49+ private readonly _alreadyActivatedEvents : { [ activationEvent : string ] : boolean ; } ;
4750
48- constructor ( isReadyByDefault : boolean ) {
49- if ( isReadyByDefault ) {
50- this . _isReady = true ;
51- this . _onReady = TPromise . as ( true ) ;
52- this . _onReadyC = ( v : boolean ) => { /*no-op*/ } ;
53- } else {
54- this . _isReady = false ;
55- this . _onReady = new TPromise < boolean > ( ( c , e , p ) => {
56- this . _onReadyC = c ;
57- } , ( ) => {
58- console . warn ( 'You should really not try to cancel this ready promise!' ) ;
59- } ) ;
60- }
51+ constructor ( registry : ExtensionDescriptionRegistry , host : IExtensionsManagerHost < T > ) {
52+ this . _registry = registry ;
53+ this . _host = host ;
6154 this . _activatingExtensions = { } ;
6255 this . _activatedExtensions = { } ;
63- this . _registry = new ExtensionDescriptionRegistry ( ) ;
6456 this . _alreadyActivatedEvents = Object . create ( null ) ;
6557 }
6658
67- protected _triggerOnReady ( ) : void {
68- this . _isReady = true ;
69- this . _onReadyC ( true ) ;
70- }
71-
72- public onReady ( ) : TPromise < boolean > {
73- return this . _onReady ;
74- }
75-
76- public readExtensionPointContributions < T > ( extPoint : IExtensionPoint < T > ) : TPromise < ExtensionPointContribution < T > [ ] > {
77- return this . onReady ( ) . then ( ( ) => {
78- let availableExtensions = this . _registry . getAllExtensionDescriptions ( ) ;
79-
80- let result : ExtensionPointContribution < T > [ ] = [ ] , resultLen = 0 ;
81- for ( let i = 0 , len = availableExtensions . length ; i < len ; i ++ ) {
82- let desc = availableExtensions [ i ] ;
83-
84- if ( desc . contributes && hasOwnProperty . call ( desc . contributes , extPoint . name ) ) {
85- result [ resultLen ++ ] = new ExtensionPointContribution < T > ( desc , desc . contributes [ extPoint . name ] ) ;
86- }
87- }
88-
89- return result ;
90- } ) ;
91- }
92-
93- public getExtensions ( ) : TPromise < IExtensionDescription [ ] > {
94- return this . onReady ( ) . then ( ( ) => {
95- return this . _registry . getAllExtensionDescriptions ( ) ;
96- } ) ;
59+ public isActivated ( extensionId : string ) : boolean {
60+ return hasOwnProperty . call ( this . _activatedExtensions , extensionId ) ;
9761 }
9862
99- public getExtensionsStatus ( ) : { [ id : string ] : IExtensionsStatus } {
100- return null ;
63+ public getActivatedExtension ( extensionId : string ) : T {
64+ if ( ! hasOwnProperty . call ( this . _activatedExtensions , extensionId ) ) {
65+ throw new Error ( 'Extension `' + extensionId + '` is not known or not activated' ) ;
66+ }
67+ return this . _activatedExtensions [ extensionId ] ;
10168 }
10269
103- public isActivated ( extensionId : string ) : boolean {
104- return hasOwnProperty . call ( this . _activatedExtensions , extensionId ) ;
70+ public setActivatedExtension ( extensionId : string , value : T ) : void {
71+ this . _activatedExtensions [ extensionId ] = value ;
10572 }
10673
10774 public activateByEvent ( activationEvent : string ) : TPromise < void > {
10875 if ( this . _alreadyActivatedEvents [ activationEvent ] ) {
10976 return NO_OP_VOID_PROMISE ;
11077 }
111- if ( this . _isReady ) {
112- return this . _activateByEvent ( activationEvent ) ;
113- } else {
114- return this . _onReady . then ( ( ) => this . _activateByEvent ( activationEvent ) ) ;
115- }
116- }
117-
118- private _activateByEvent ( activationEvent : string ) : TPromise < void > {
11978 let activateExtensions = this . _registry . getExtensionDescriptionsForActivationEvent ( activationEvent ) ;
12079 return this . _activateExtensions ( activateExtensions , 0 ) . then ( ( ) => {
12180 this . _alreadyActivatedEvents [ activationEvent ] = true ;
12281 } ) ;
12382 }
12483
12584 public activateById ( extensionId : string ) : TPromise < void > {
126- return this . _onReady . then ( ( ) => {
127- let desc = this . _registry . getExtensionDescription ( extensionId ) ;
128- if ( ! desc ) {
129- throw new Error ( 'Extension `' + extensionId + '` is not known' ) ;
130- }
85+ let desc = this . _registry . getExtensionDescription ( extensionId ) ;
86+ if ( ! desc ) {
87+ throw new Error ( 'Extension `' + extensionId + '` is not known' ) ;
88+ }
13189
132- return this . _activateExtensions ( [ desc ] , 0 ) ;
133- } ) ;
90+ return this . _activateExtensions ( [ desc ] , 0 ) ;
13491 }
13592
13693 /**
@@ -147,17 +104,17 @@ export abstract class AbstractExtensionService<T extends ActivatedExtension> imp
147104
148105 if ( ! depDesc ) {
149106 // Error condition 1: unknown dependency
150- this . _showMessage ( Severity . Error , nls . localize ( 'unknownDep' , "Extension `{1}` failed to activate. Reason: unknown dependency `{0}`." , depId , currentExtension . id ) ) ;
151- this . _activatedExtensions [ currentExtension . id ] = this . _createFailedExtension ( ) ;
107+ this . _host . showMessage ( Severity . Error , nls . localize ( 'unknownDep' , "Extension `{1}` failed to activate. Reason: unknown dependency `{0}`." , depId , currentExtension . id ) ) ;
108+ this . _activatedExtensions [ currentExtension . id ] = this . _host . createFailedExtension ( ) ;
152109 return ;
153110 }
154111
155112 if ( hasOwnProperty . call ( this . _activatedExtensions , depId ) ) {
156113 let dep = this . _activatedExtensions [ depId ] ;
157114 if ( dep . activationFailed ) {
158115 // Error condition 2: a dependency has already failed activation
159- this . _showMessage ( Severity . Error , nls . localize ( 'failedDep1' , "Extension `{1}` failed to activate. Reason: dependency `{0}` failed to activate." , depId , currentExtension . id ) ) ;
160- this . _activatedExtensions [ currentExtension . id ] = this . _createFailedExtension ( ) ;
116+ this . _host . showMessage ( Severity . Error , nls . localize ( 'failedDep1' , "Extension `{1}` failed to activate. Reason: dependency `{0}` failed to activate." , depId , currentExtension . id ) ) ;
117+ this . _activatedExtensions [ currentExtension . id ] = this . _host . createFailedExtension ( ) ;
161118 return ;
162119 }
163120 } else {
@@ -189,8 +146,8 @@ export abstract class AbstractExtensionService<T extends ActivatedExtension> imp
189146 // More than 10 dependencies deep => most likely a dependency loop
190147 for ( let i = 0 , len = extensionDescriptions . length ; i < len ; i ++ ) {
191148 // Error condition 3: dependency loop
192- this . _showMessage ( Severity . Error , nls . localize ( 'failedDep2' , "Extension `{0}` failed to activate. Reason: more than 10 levels of dependencies (most likely a dependency loop)." , extensionDescriptions [ i ] . id ) ) ;
193- this . _activatedExtensions [ extensionDescriptions [ i ] . id ] = this . _createFailedExtension ( ) ;
149+ this . _host . showMessage ( Severity . Error , nls . localize ( 'failedDep2' , "Extension `{0}` failed to activate. Reason: more than 10 levels of dependencies (most likely a dependency loop)." , extensionDescriptions [ i ] . id ) ) ;
150+ this . _activatedExtensions [ extensionDescriptions [ i ] . id ] = this . _host . createFailedExtension ( ) ;
194151 }
195152 return TPromise . as ( void 0 ) ;
196153 }
@@ -224,7 +181,7 @@ export abstract class AbstractExtensionService<T extends ActivatedExtension> imp
224181 } ) ;
225182 }
226183
227- protected _activateExtension ( extensionDescription : IExtensionDescription ) : TPromise < void > {
184+ public _activateExtension ( extensionDescription : IExtensionDescription ) : TPromise < void > {
228185 if ( hasOwnProperty . call ( this . _activatedExtensions , extensionDescription . id ) ) {
229186 return TPromise . as ( void 0 ) ;
230187 }
@@ -233,19 +190,91 @@ export abstract class AbstractExtensionService<T extends ActivatedExtension> imp
233190 return this . _activatingExtensions [ extensionDescription . id ] ;
234191 }
235192
236- this . _activatingExtensions [ extensionDescription . id ] = this . _actualActivateExtension ( extensionDescription ) . then ( null , ( err ) => {
237- this . _showMessage ( Severity . Error , nls . localize ( 'activationError' , "Activating extension `{0}` failed: {1}." , extensionDescription . id , err . message ) ) ;
193+ this . _activatingExtensions [ extensionDescription . id ] = this . _host . actualActivateExtension ( extensionDescription ) . then ( null , ( err ) => {
194+ this . _host . showMessage ( Severity . Error , nls . localize ( 'activationError' , "Activating extension `{0}` failed: {1}." , extensionDescription . id , err . message ) ) ;
238195 console . error ( 'Activating extension `' + extensionDescription . id + '` failed: ' , err . message ) ;
239196 console . log ( 'Here is the error stack: ' , err . stack ) ;
240197 // Treat the extension as being empty
241- return this . _createFailedExtension ( ) ;
198+ return this . _host . createFailedExtension ( ) ;
242199 } ) . then ( ( x : T ) => {
243200 this . _activatedExtensions [ extensionDescription . id ] = x ;
244201 delete this . _activatingExtensions [ extensionDescription . id ] ;
245202 } ) ;
246203
247204 return this . _activatingExtensions [ extensionDescription . id ] ;
248205 }
206+ }
207+
208+ export abstract class AbstractExtensionService < T extends ActivatedExtension > {
209+ public _serviceBrand : any ;
210+
211+ private _onReady : TPromise < boolean > ;
212+ private _onReadyC : ( v : boolean ) => void ;
213+ private _isReady : boolean ;
214+ protected _registry : ExtensionDescriptionRegistry ;
215+ protected _manager : ExtensionsManager < T > ;
216+
217+ constructor ( isReadyByDefault : boolean ) {
218+ if ( isReadyByDefault ) {
219+ this . _isReady = true ;
220+ this . _onReady = TPromise . as ( true ) ;
221+ this . _onReadyC = ( v : boolean ) => { /*no-op*/ } ;
222+ } else {
223+ this . _isReady = false ;
224+ this . _onReady = new TPromise < boolean > ( ( c , e , p ) => {
225+ this . _onReadyC = c ;
226+ } , ( ) => {
227+ console . warn ( 'You should really not try to cancel this ready promise!' ) ;
228+ } ) ;
229+ }
230+ this . _registry = new ExtensionDescriptionRegistry ( ) ;
231+ this . _manager = new ExtensionsManager ( this . _registry , {
232+ showMessage : ( severity : Severity , message : string ) : void => {
233+ this . _showMessage ( severity , message ) ;
234+ } ,
235+
236+ createFailedExtension : ( ) : T => {
237+ return this . _createFailedExtension ( ) ;
238+ } ,
239+
240+ actualActivateExtension : ( extensionDescription : IExtensionDescription ) : TPromise < T > => {
241+ return this . _actualActivateExtension ( extensionDescription ) ;
242+ }
243+ } ) ;
244+ }
245+
246+ protected _triggerOnReady ( ) : void {
247+ this . _isReady = true ;
248+ this . _onReadyC ( true ) ;
249+ }
250+
251+ public onReady ( ) : TPromise < boolean > {
252+ return this . _onReady ;
253+ }
254+
255+ public getExtensionsStatus ( ) : { [ id : string ] : IExtensionsStatus } {
256+ return null ;
257+ }
258+
259+ public isActivated ( extensionId : string ) : boolean {
260+ return this . _manager . isActivated ( extensionId ) ;
261+ }
262+
263+ public activateByEvent ( activationEvent : string ) : TPromise < void > {
264+ if ( this . _isReady ) {
265+ return this . _manager . activateByEvent ( activationEvent ) ;
266+ } else {
267+ return this . _onReady . then ( ( ) => this . _manager . activateByEvent ( activationEvent ) ) ;
268+ }
269+ }
270+
271+ public activateById ( extensionId : string ) : TPromise < void > {
272+ if ( this . _isReady ) {
273+ return this . _manager . activateById ( extensionId ) ;
274+ } else {
275+ return this . _onReady . then ( ( ) => this . _manager . activateById ( extensionId ) ) ;
276+ }
277+ }
249278
250279 protected abstract _showMessage ( severity : Severity , message : string ) : void ;
251280
0 commit comments